Future of ROS 2 GPS Support

Hi all, your friendly neighborhood navigator here,

We had a great call this morning between:

  • Polymath Robotics
  • Open Navigation
  • Locus Robotics
  • Kiwibot
  • Firefly Automatix
  • Rudis Labs
  • AeroVironment

to discuss the future of GPS support in ROS 2. It is the expressed interest of myself and @automatom to start the process of sunsetting Robot Localization in favor of Fuse as the standard state estimation and fusion package in the ROS ecosystem. However to do so, we need to come up with a solution to replace the NavSat Transform that it provides so we don’t leave the GPS-user community’s robots high and dry (because, you know, they’d be in the garage in the mountains instead of getting dirty and wet doing-their-robot-thing).

During the discussion, Polymath Robotics (Zeerek Ahmad) came up with the following path forward so we can best leverage the current technologies and standards available to not only migrate to Fuse, but improve performance for everyone:

  • Take GPS data and translate them via ECEF instead of UTM to take advantage of its benefits
  • Create a node which can take in GPS data and re-compute covariances based on the actual sensor data because GPS vendors overly optimistically compute them causing larger localization issues
  • This node can then have an option to not broadcast its data if the confidence is sufficiently low to better localize the robot with single erroneous measurements
  • Migrate that data into Fuse via using to-be-created 3D Pose and Orientation models accordingly

If you’d like to see how we came to that conclusion and the discussion / options that led to it, please see the document notes attached compiled by Zeerek and Polymath.

7b9a43e4-ccfa-4cdf-a3b4-143744598861_SHARED_Polymath_ROS2_GPS_Proposal.pdf (116.0 KB)

If you have any concerns, questions, comments, loves, hates, or free coffee, please continue the discussion below!

Happy GP-YES-ing,



Great to see this group forming! Could I join on behalf of Czech Technical University? :slight_smile:

We were also unhappy that there’s no dedicated message type for azimuth readings. Recently, I published compass_msgs package with message Azimuth and implementation of magnetometer_compass that can read out the azimuth from magnetometers (however imprecise that is). All of that is for ROS 1, but converting it to ROS 2 shouldn’t be difficult.

I think a synchronized Azimuth message with NavSatFix could be a good representation for heading-capable GNSS receivers.

We did actually talk about that - I proposed a NavSatFixWithOrientation message (name to be workshopped) and Polymath also proposed potentially using the GeoPoseWithCovariance which also contains orientation information!

1 Like

Hi, I speak in name of Pointverse LTD, would be nice to see in this discussion the point clouds geo-referencing. I think it is at the same time , the most valuable and forgotten feature that GNSS can to do in the robotics field, and open the way to use robotics in other fields as surveying and rise a step the usability of mapping, inspection, simulation and R&D by extension.

Thanks for posting this @smac !

We absolutely want to drive a discussion about this and get community feedback. Our vehicles work outdoors, so we’re very interested in ensuring we all get this right.


We’re heavily relying on RTK gnss data for our tractors.

Some notes:

  • We’d welcome a message format which includes orientation.

  • ‘Hack: Just keep going off the same UTM zone, slightly inaccurate but “shrug"’

    • This is exactly what we do. For us this is accurate enough.
  • UTM zone jumping: Please note that this not only jumps in X and Y but also yaw. We have issues with this in the current navsat_transform implementation.

  • “We assume that we are creating tangent planes off of the robot’s initial position

    • One should be careful with this. A robots initial position can be a very random one. If during an operation a reboot is performed, all 2d positions are shifted. Leading to:
      • Different accuracies than before the reboot
      • Very difficult to create position plots (plotjuggler) as all positions are different now
      • The same repetative task cannot be compared 1-to-1 as signals depend on the initial startup position
    • Sticking to a fixed defined zone (UTM) solves this mostly. Although near the border there is still a change the last reboot was in a different zone leading to the same problems as above. So it’s not the holy grail.
  • “Supporting wgs84 vs nad83”

    • In my experience this is a non-issue. By applying RTK streams for example, the lat,lon values are modified/fixed to the ‘local’ coordinate system. In Europe for example ETRS89.
      This fix is done before any of the transformations talked about in the proposal, so out-of-scope?

All things considered, I’m happy to see this is getting some serious traction! Thank you all for the effort.

PS. While modifying things, shouldn’t we stick to the term GNSS instead of GPS as it’s just one of the implementations (Galileo is another one for example).

1 Like
  • Take GPS data and translate them via ECEF instead of UTM to take advantage of its benefits

Everything else sounds good, but this is my favorite part. UTM is such a hack for getting what most users want, which is a local cartesian coordinate system.

Though I agree with @Timple that turn-on location can be very tricky to use for the reasons they stated above. I would generally recommend having the ability to specify a monument or origin that makes the most sense for that robot’s operation.

Hi, to be honest, the topic name sounds very serious, but at the end, the conclusion at least to me, is that it would be nice to have some ROS2 node that will do a conversion from lat/lon to some kind of Pose-kind of message (similar to navsat_transform). Fine, but I guess it’s just a matter of wrapping some external library convertion code to a ROS2 node, nothing fancy here.
If we’re taking about “migrating” to factor graphs approach, there’s a chance to take advantage of raw GNSS/RTK measurments to mitigate the errors, especially those that appear in urban areas. This is an active reasearch area recently and it would be good to validate it in practice with potential benefit for “practitioners” (some Ceres and GTSAM starting examples are available on github).
Another thread that I noticed here is setting “standard state estimation and fusion package in the ROS ecosystem”. First of all, state estimation is with its diversity of approaches not something that is easy to standarize (everyone has his own needs). Second, for community benefit, it would be better to do some comparision of existing (factor graph) libraries and summarizing it pros and cons, maybe maintainers could answer to questions and provide roadmaps for future. What is common in factor graphs ecosystem unfortunately is poor (user) documentations (learning from code mostly), and here, yes, robot_localization set some high standards in the past as for documentation quality and support.


@FPSychotic Geo-referencing is where Fuse absolutely shines.

I was recently involved in a robotic surveying project where we used a factor graph like Fuse because we wanted covariances more than we wanted estimates. Once we established a few landmarks and initialised the optimiser, our localisation solution started to prefer the camera input over GPS.
UTM was much too coarse for us, we used 3d coordinates everywhere, and leaned heavily on GeographicLib in a similar way that we use TF2.
Orientation was a non-issue, we could pull that from a visible landmark and a single GPS fix.

@soldierofhell The original post is very much a who’s-who of Factor Graphs in practical robotics. Fuse runs on Ceres, and the Fuse authors wrote a large portion of GTSAM.
GTSAM has some cool features, but it lacks the tools to automatically build and prune a factor graph on the fly like Fuse can.

Fuse definitely has some way to go before it’ll please everybody, but it’s by far the most action-ready factor-graph for ROS2. ROS2 emphasises modularity, so I wouldn’t be surprised if Fuse ended up with a pluggable graph store and pluggable solvers.

You mean GTSAM is missing this fixed-lag smoother? I guess it’s the opposite, Fuse is missing iSAM2. Can you for example efficiently perform a landmark-based localization in Fuse?

I disagree. Fuse is missing important sensors models, e.g. IMU, cameras. I wonder who will drive the development of the library if authors/maintainers declare lack of resources (justified, they are medium-size private company) and the academia doesn’t use this library (Fuse doesn’t even have a paper released), so who’s left? IMO ROS community is rarely capable of developing such library. It’s not about ROS2-development at all, ROS-wrapping is usually the most straightforward task. BTW I’m a little surprised that fuse core libraries depend on ROS2 (rclcpp), usually best practice is to separate core lib from ROS API (see e.g. rtabmap, Kimera).
As for multiple “backends” I also thought about it and it’s really good idea. In fact rtabmap has this kind of approach (but AFAIK they use a “common” subset). The question is how deep is Ceres currently embedded in Fuse architecture and still probably no-one has resources for design this, not to mention actual development.

… anyhow the R_L replacement is not the subject of discussion; but tools, methods, and frames to enable GPS once R_L becomes fully deprecated so that users don’t end up high and dry. Lets stay on topic.

@smac ,

Is there an appropriate place for concerns and discussions around this transition that don’t have to do with GPS, so as to not derail this conversation?

Another thread in Discourse, I suppose!

Great to see improvements suggested in the GNSS and pose messages in ROS.

A few things I’d love to see covered:

  • Once ROS users start using things like HD Maps, absolute global location details will REALLY matter. The move to ECEF is a great start, but it’s not actually sufficient. Global frames (ECEF or LLA) need to be referenced by a Datum and Epoch. I know many will think “oh it doesn’t matter” but if you are using NAD83 vs. ITRF14 in the US, you are talking about almost 2m of error in California. That’s a lot when working with centimeter accurate GPS. Similarly, Epoch (the time the map was made) is important because places move. San Francisco slides into the Pacific Ocean at about 3-4cm per year relative to the global frame (ITRF).

The solution should be that all Pose messages at least have the ability to output their datum (ITRF/ETRS/NAD etc + Epoch). Users can choose to ignore this at their own peril. Similarly, map objects (which I can’t say I’m familiar with in ROS) should also have a similar Datum + Epoch.

  • Some companies (shameless plug, like point one nav) are making GNSS/INS solutions that output their true covariance for use in processing/sensor fusion downstream. As of now, we use the ROSGPSFix but it’s missing a ton of good information. For instance, the message can have the position covariance (great!) but it lacks the attitude covariance (which admittedly is more useful when doing sensor fusion).

Perhaps the solution here is to make a specific INS standard that combines attitude and position (i.e. pose) into a single message that can be represented with its full covariance.


Guys I’ve developed the UBLOX DGNSS driver that can get CM level accuracy. Some others have been working on changes to be able to specify the USB device to connect to thus enabling multiple high precision GPS devices ie determining orientation upon cold start.

There’s a node there that publishes the navsatfix style messages but that’s really a subset of the available data from the UBLOX F9 devices. The node uses ubx_nav_cov data from the F9 devices. There was another discussion a little while back about modifying navsatfix to include more states about the current status of the DGNSS fix but I just felt that they were really forcing change that may potentially break code that worked with the previous generation of gps devices which were unable to get CM level accuracy.

Whilst the driver as coded presently, also supports the F9R and sending wheel tick data to the device, I understand that there are issues with getting the F9R into fusion mode to take advantage of the hardware based fusion available.

This discussion has been very interesting so far. Am interested to help create nodes leveraging the ubx ROS2 messages to achieve better fusion with other sensors and to take into account when GPS might be being spoofed and/or untrustworthy.

@smac whats the best way to get involved? (Yes the driver needs better documentation - didn’t you say you’d help me with that a while back? :blush:)

I don’t think fuse can do RTK for free. It’s just a general optimization library, RTK requires specific algorithms for integer ambiguilty resolution (like LAMBDA) that won’t emerge naturally.

Fascinated and excited to see these discussions.

We operate robotic boats for marine science and in particular, seafloor mapping. Our navigation accuracy requirements can be pretty stringent, but equally important is the ability to quantify that accuracy both in real time and in the recorded data. Honestly, we achieve this with purpose-built INS aided GPS systems which integrate directly to the sonar outside of ROS, as this is the industry standard for crewed vessels. We rarely if ever use ROS for this, as it just doesn’t have to tooling, although we would like to.

Regarding ECEF vs UTM:
AaronP1 makes a terrific point that is REALLY important and worth repeating. “Global frames (ECEF or LLA) need to be referenced by a Datum and Epoch.” This is really important for any mapping application. This can be tricky. For example, a standard uncorrected GPS fix will use the WGS-84 IRTF datum/epoch, but if it is receiving RTK corrections from a reference station, the resulting fix will be in the datum of the reference station. If that reference station is a CORS station in the US, the RTK fixes will be in NAD83. A receive can gain and lose RTK corrections frequently during operations, and so the fix type must be monitored to apply the right datum metadata correctly.

Since local frames are referenced from global frames, I think TF frame definitions should probably have a place holder to record the Datum and Epoch from which they are derived.

While I think ECEF is the way to go, GPS provides notoriously poor positioning in the vertical due to the geometry of the measurements, and (as has been mentioned) this can cause all manner of problems if not ignored or constrained by another measurement. I’ll mention in passing, for marine commercial survey-grade navigation systems, when GPS corrections are not available to make the vertical uncertainty small, an INS and a complementary filter are used, which provid a zero-mean vertical offset (e.g. “heave”). Of course this is designed for vessels at sea, and would not be directly appropriate for aerial robots.

We travel far enough distances in our operations that we suffer from the bias that grows between a local tangential map reference frame and ECEF coordinates. (If I recall correctly, I think about 15 km is where this seems to start to matter.) At the moment, we know the problem exists but we don’t yet handle it in ROS.

It might be possible to add a transform to the TF tree that captures the bias that grows between the local map frame and the ECEF projected coordinate at the robot’s position. This transform would be near zero for positions near the map origin, and would grow with distance from it. If this works the way I think it should, the map frame should never need to be shifted once established, maintaining the continuity of the math applied by various nodes in that frame. [I guess I’m proposing we become flat-earthers.] As I think about it, this would limit operations to the hemisphere of operations centered on the map frame origin, but that doesn’t seem like much of a constraint.

One architectural note. In our robots we initially built a ROS Service to convert Lat/Lon to ECEF, but found this too slow for may. We now use a C++ library so the math can optionally be accomplished within the node itself.

In addition to the problems others have noted with regard to underestimation of GPS uncertainty, one should note that GPS measurement errors are correlated in time, and this too is not captured by DOP or other uncertainty measurements provided by the receiver.

There are several reasons for this, including internal kaman filters and the fact that the previous position is typically used as a seed for the solution for the next position. One can see the correlation clearly by plotting the latitude or longitude of the position with time and noting the measurements “walk” about the long term mean in a smooth way, rather than jumping stochastically from one measurement to the next. (There are sometimes discontinuities in the path, but this is usually due to a loss/gain of satellite or multi path.) This paper describes the effect and how to measure both the correlation length and long-term uncertainty of a receiver (one would have to repeat this for various fix types):

In GPS aided inertial navigation systems, this kind of correlation is typically handled in a kalman filter by the adding additional states to the state vector to model the random walk. I don’t know of a ROS based solution that does this.

Finally, one big omission in the TF library that would be wonderful to see addressed, is the inability of the TF libraries to propagate uncertainty between reference frames. (Some other packages do provide this.). Uncertainty propagation is also required for conversions to/from LLA and ECEF too, which is a little trickier since that math is not matrix based.

My 2 cents.


Perhaps one could leverage some sort of child_frame_ids for this? Just like odometry, a receiver doesn’t report a measurement w.r.t. to the center of the earth, but to a (creatively calculated) NAD83 reference frame near the center of the earth.

But first of all, this means the receiver actually has to report this value. I have seen big-brand receivers which do not even report this. So one cannot know which reference frame it corrects itself to :frowning_face:

Moreover, I believe it’s the base stations providing the correction data don’t have a means of transmitting their reference frame…

Yes that’s correct, a sad oversight in the RTCM standard. That being said, RTK providers should be providing this as part of their connection info out of band (we do). If this were standardized, I’d be happy to update the ntrip client library with a default map of known providers and their respective frames, which hopefully other providers (or their users) would follow suit.