-
Notifications
You must be signed in to change notification settings - Fork 96
add gps_time method #967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add gps_time method #967
Conversation
generator/sbpg/targets/rust.py
Outdated
def gps_time(msg, all_messages): | ||
def time_aware_header(type_id): | ||
for m in all_messages: | ||
if m.identifier == type_id: | ||
return any([f.identifier == "t" for f in m.fields]) | ||
return False | ||
|
||
has_tow = False | ||
has_wn = False | ||
|
||
for f in msg.fields: | ||
if f.identifier == "header" and time_aware_header(f.type_id): | ||
return GPS_TIME_HEADER | ||
elif f.identifier == "tow": | ||
has_tow = True | ||
elif f.identifier == "wn": | ||
has_wn = True | ||
|
||
if has_tow and has_wn: | ||
return GPS_TIME | ||
elif has_tow: | ||
return GPS_TIME_ONLY_TOW | ||
else: | ||
return 'None' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is the best way to determine which messages are time-aware/how that time is stored but it seems to work so far
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good starting point at the very least. I'd have to peruse all the message definitions to figure out if there's other ways we include a GPS time in messages, but this should cover the vast majority if not all of them.
I think it should be noted that the time values can have different meanings depending on the message type they're in. For instance the time value in MSG_OBS
is the time that the observations were made, but in MSG_EPHEMERIS_GPS
(or any ephemeris message) it's a center point in the period of time the data is valid so it is typically several minutes to a couple of hours in the future from when the message was actually generated. We can discuss offline if this is a problem for what you're working on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this use case the "time of event" or "time of occurrence" is the meaning of .gps_time()
-- that is, we want to define a linear time ordering of the messages for use in things like the "sbp chopper" and the interleaver.
I talked with @notoriaga about this briefly and I agree that "t"/"wn"/"tow" covers most of the use case correctly, but we should do an audit of everything that gets grabbed by this and then maybe introduce a "time_ordering" property that we can expose to the yaml spec for this purpose.
Should definitely be swapped, without swapping it makes it kind of hard to use with
👍
Maybe |
It depends on if your function returns Option or Result. Maybe a custom enum with three variants is best, with two helpers to convert to option or result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with
Option<Result<swiftnav_rs::time::GpsTime, crate::GpsTimeError>>
, but maybe the Result/Option should be swapped?
I'd vote to keep the Option
on the outside, it seems more logical to me. Getting the time is the first operation, and the not having a time isn't an error per se. The second operation is converting the message's time representation into a common format which is a fallible operation. I think the ?
operator also works with Option
, assuming that the function is returning an Option
as well.
LGTM thank you for doing this!! |
👍 |
generator/sbpg/targets/rust.py
Outdated
MESSAGES_TEMPLATE_NAME = "sbp_messages_template.rs" | ||
MESSAGES_MOD_TEMPLATE_NAME = "sbp_messages_mod.rs" | ||
|
||
GPS_TIME = """\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mentioned offline, but if the type uses GPSTime, then we potentially have the "nanosecond residual" available... but digging in to this deeper I don't think we need to worry about this (maybe?). The bare GPSTime
object is only used in MSG_TRACKING_STATE_DETAILED_DEP_A
, MSG_SPECAN
, and (the only one that might matter) is MSG_OBS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not really a technical problem since the two structs with the same name are defined in different crates, so they're in different name spaces. It's mostly a potential cause for confusion among developers, right? I'd like to think that's less likely to happen since the libsbp GPSTime
struct typically won't be instantiated directly. I imagine it would be accessed as a member of a larger SBP message most of the time. Maybe some clarification in the docs would help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not really a technical problem since the two structs with the same name are defined in different crates, so they're in different name spaces. It's mostly a potential cause for confusion among developers, right? I'd like to think that's less likely to happen since the libsbp
GPSTime
struct typically won't be instantiated directly. I imagine it would be accessed as a member of a larger SBP message most of the time. Maybe some clarification in the docs would help?
Yeah, that's probably sufficient, I was also thinking a wrapper type might be appropriate in libsbp to disambiguate MessageTime(GpsTime)
or something similar.
|
||
//! (((description | replace("\n", "\n//! ")))) | ||
#[allow(unused_imports)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could remove the need for this, and other lint exclusion rules with
diff --git a/generator/sbpg/targets/resources/sbp_messages_template.rs b/generator/sbpg/targets/resources/sbp_messages_template.rs
index e2f85da1..ffd7729c 100644
--- a/generator/sbpg/targets/resources/sbp_messages_template.rs
+++ b/generator/sbpg/targets/resources/sbp_messages_template.rs
@@ -15,16 +15,10 @@
//! (((description | replace("\n", "\n//! "))))
-#[allow(unused_imports)]
-use std::convert::TryFrom;
-
-#[allow(unused_imports)]
-use byteorder::{LittleEndian,ReadBytesExt};
-
#[allow(unused_imports)]
use crate::SbpString;
#[allow(unused_imports)]
-use crate::serialize::SbpSerialize;
+use byteorder::ReadBytesExt;
((*- for i in includes *))
use super::(((i)))::*;
diff --git a/generator/sbpg/targets/rust.py b/generator/sbpg/targets/rust.py
index cf1e0268..adedd574 100644
--- a/generator/sbpg/targets/rust.py
+++ b/generator/sbpg/targets/rust.py
@@ -46,6 +46,8 @@ Some(swiftnav_rs::time::GpsTime::new(0, tow_s).map_err(Into::into))
GPS_TIME_IMPL = """\
#[cfg(feature = "swiftnav-rs")]
fn gps_time(&self) -> Option<std::result::Result<swiftnav_rs::time::GpsTime, crate::GpsTimeError>> {{
+ #[allow(unused_imports)]
+ use std::convert::TryFrom;
{}
}}
"""
@@ -110,7 +112,7 @@ def parse_type(field):
return '_buf.read_i8()'
elif field.type_id in TYPE_MAP.keys():
# Primitive java types have extractor methods in SBPMessage.Parser
- return '_buf.read_%s::<LittleEndian>()' % TYPE_MAP[field.type_id]
+ return '_buf.read_%s::<byteorder::LittleEndian>()' % TYPE_MAP[field.type_id]
if field.type_id == 'array':
# Call function to build array
t = field.options['fill'].value
clippy doesnt seem to mind; it does however have another 150 warnings :/
fn gps_time( | ||
&self, | ||
) -> Option<std::result::Result<crate::time::MessageTime, crate::time::GpsTimeError>> { | ||
let tow_s = (self.tow as f64) / 1000.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is is correct to assume that the tow field always is in milliseconds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbangelo @denniszollo are there some messages that report tow in seconds, not ms?
@notoriaga there is a "units" field in the yaml spec that we could potentially inspect here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an assert that the units are ms. Only one wasn't IMU_MSG_RAW
. For now just skipping that msg, it seems like it might not actually be representing 'rover' time - but rather 'Time since reference epoch in milliseconds' which seems like not what we want
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great!
I pulled together a list of all the rover-time messages
would be nice to get some eyes on this. One thing I'm wondering is that we have MSG_OBS as base time, but we have MSG_OBS_DEP_{A,B,C} here - is that correct? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this to note that we decided to add something custom to handle IMU_RAW and WHEELTICKS messages from thachoppa: https://github.com/swift-nav/thachoppa/blob/master/src/lib.rs#L148
Adds
to the
SBPMessage
trait behind aswiftnav-rs
feature flag. Also reexports GpsTime assbp::messages::GpsTime
Option<Result<swiftnav_rs::time::GpsTime, crate::GpsTimeError>>
, but maybe the Result/Option should be swapped?gps_time
that returnsNone
instead of actually implementing a bunch of functions that returnNone
. would make it easier to search for the impls and validate they are correct (also tests would be nice)libsbp/rust/sbp/src/messages/gnss.rs
Line 92 in f2a1804