Great to hear you are working on this! Is it set in stone you have to use GPSFix? The use of RPY to represent orientation causes issues with singularities that small aerial vehicles can violate.
This is a really interesting discussion. Thank you all for your fascinating insights.
I am one of the maintainers of the septentrio_gnss_driver. We have implemented the option to publish GPSFix but we were also unable to find a definitive meaning of dip. Thus, we eventually decided to misuse it to fill it with heading upon a user’s request. Track cannot be used for heading, since track and heading are not the same, as @RFRIEDM pointed out.
Personally, I do not use GPSFix and would very much welcome a successor of NavSatFix. Regarding the suggestions of NavSatFixWithOrientation or GeoPoseWithCovariance it has to be considered, that most GNSS receivers with heading output have only two antennas, i.e., they output either pitch or roll or just an arbitrary tilt angle, depending on how the two antennas are aligned on the platform.
We aren’t set in stone for GPSFix, it was more of a starting point.
Actually, we may want to propose something new long term that takes the best of all worlds. Information such as RTK status, accuracies etc. (part of the GPSFix message via GPSStatus) may be useful on top of cartesian covariances when deciding when to use the data and when to reject it. Long term, we would like to have some rejection criteria inside the gps to cartesian node that will not use data for initialization or odometry generation if certain conditions aren’t met. GPSFix is meant more to be a starting point, albeit a very very good one.
Regarding Orientations, I’m open to switching to quaternions and any angles not captured by the orientation would be radians ENU to match ROS Standards.
This is a good point. Didn’t think about track as we’ve mostly been working on terrestrial vehicles where track and heading are equivalent. The new standard should definitely have both. But comments would help explain it.
I think for clarity, the GPS should also say track_speed instead of just speed.
This is what I would end up doing if we use GPSFix.
The core reason for the GPSFix message or a successor to NavSatNode is to capture GPS Driver returned data in a centralized message instead of dividing information such as track, velocities, orientations into tertiary messages. If I had a wishlist for a successor message must haves (note GPSFix captures many of these, but not all). I’m sure the people in this group can think of additional things they’d like to have on top of these.
Lat, Lon, Altitude
Track
Heading
Track Speed
Angular Velocity
RTK and Fix Status (Could be simple RTK status)
Orientation instead of roll and pitch? (Quaternion? Like @thomasemter mentioned, GPS’s often do directional rotation to give either pitch or roll, or tilt angle)
The list looks good. I have a feeling people will debate endlessly on the contents of the new message. Instead of having to craft the perfect message, what if GPS drivers support synchronous publishers of primitive types? I forget what ROS feature this is called, or how to do it. Perhaps someone can remind me.
Cheap non-RTK GPS can supply:
GeoPoseWithCovariance, but set the pose.orientation.x, .y, .z, and .w to NaN in WGS-84, where variances are high
Fix status with at most 3D fix
Heading/orientation are unknown
Medium grade RTK GPS can supply:
GeoPoseWithCovariance, but set the pose.orientation.x, .y, .z, and .w to NaN in WGS-84, and position varainces are low when RTK is working
Fix status with at most RTK_FIXED
3D velocity in world frame via geometry_msgs/Twist. I don’t think track_speed is useful when you can just derive from the 2D components of twist.linear.
Heading/orientation are unknown
Dual antenna GPS can supply:
GeoPoseWithCovariance, but set the pose.orientation.x, .y, .z, and .w to NaN in WGS-84, and position varainces depend if corrections are available
Fix status with at most RTK_FIXED
A heading integer is populated if both receivers have a fix, otherwise, the heading is NaN. Perhaps some support a full orientation instead of just a heading?
Expensive GNSS-INS can supply orientation and velocity in all dimensions. Some also support RTK corrections, or the Trimble PX1 supports satellite corrections from RTX that is not RTK.
GeoPoseWithCovariance. position variances are low when RTK is working, and if the INS solution degrades to only 3D fix, then the orientation would need to be set to NaN
Fix status with at most RTK_FIXED or something similar for RTX
3D velocity in world frame via geometry_msgs/Twist, but this time the angular component of twist can be populated when the navigation filter is working.
Then, your proposed new NavSatNode can be configured to handle any set of inputs and spin up the necessary subscribers.
One thing that’s still unclear to me is how to handle receivers that can report their altitude in multiple datums. For example, the PX1 supports both WGS-84 and EGM-96. How does a consumer know which datum they are getting? In ArduPilot, it’s assumed that all GPS’s connected report their datum in the same frame, but if it’s not, the EKF has workarounds to handle jumps when the EKF switches lanes.
For land vehicles there might also be a difference between track and heading, known as slip angle.
This is a nice list. Although, I would prefer velocity in ENU instead, since it easier to directly process further. I am not yet sure what would be the best way for orientation regarding the ability to encode which angles are observable. Maybe it is possible in combination with the frame being aligned with the antennas and the according autocovariance set to -1 for the unobserved angle.
If covariances are given for position, I do not see much use for DOP, but I may be mistaken.
Also, I would like to propose:
frame_id for datum plus a child_frame_id for the GNSS antenna as inspired by nav_msgs/Odometry. Essentially it is also a (non-Euclidean) transform between two frames.
Additional stamp containing the GNSS time including uncertainty.
Use TwistWithCovariance for velocities (linear and angular)
This is a valid point. It also has the advantage that data is just not published if a receiver does not provide it so checks for valid data are not necessary downstream.
Multiple messages can be synchronously subscribed to by message_filters. Is that what you are searching for?
For this reason I would like to propose to have a frame_id for datum in the potential successor of NavSatFix. The driver for the PX1 could then just publish different datums on two topics.
This certainly can’t be the covariances reported as an estimate of position accuracy. DOP is a term expressing the suitability of the current constellation geometry overhead. It has nothing to do with quality of the received signal.
This reminds me quite a lot of the discussion about new IMU messages: Update Rep 145 (P II) by SteveMacenski · Pull Request #372 · ros-infrastructure/rep · GitHub . The conclusion there was that it would be beneficial to keep a common message containing accelerations, angular velocities and orientation, but also to create a new message type for each of these. The idea was that many IMUs can publish each of this pieces of information on a different rate, so the individual messages would allow fine-grained control. However, the overall message would keep the simple interface many people are used to (with the limitation that all data come at the same rate). It was proposed to create tooling that would convert between the two types (it should be quite easy).
This approach seems suitable for me even in the GNSS case. Let’s have a common message with most things people often use together, while also providing more detailed messages for each “subtopic”.
Not sure I understand your proposal (or you misunderstand heading-enabled receivers?). The dual antenna receivers can output heading even without having RTK fixed. They actually don’t need RTK at all for heading. The heading is computed from phase differences of the received signal on the two antennas. And the heading is often given to higher precision than integer. Why should there be a separate “heading integer” when there already is the orientation field? I guess this is where the heading and pitch-or-roll should go.
Thank you for pointing this out. This is a really nice way and then it makes even more sense to use standard message types like TwistWithCovariance for velocities.
Perhaps it would be good to split up this conversation into two
(1) Continue in this thread on GPS tooling assuming some standardized interface is being used
(2) Start a new thread for a new definition for NavSatFix2 or similar. I think this is important from the interest that we’re seeing today to have an update in the official sensor_msgs GPS data message since its clear by the existence & usage of gps_umd & the topics brought up in this thread already that it is insufficient.
I’d suggest we start from two directions for the new message, start with the existing gps_umd with a list of modifications and start with GeoPose<...> and see which we think ultimately is the best structure. Commenting over a draft PR might be the best way to have this discussion so we can discuss specific implementations line by line.
@tfoote is there any opposition from your side for a new GPS message?