# How to get velocity vector from GPS NMEA data?

I am writing a program to receive and interpret NMEA data from a GPS receiver. I am working with an Adafruit Ultimate GPS Receiver integrated with an Arduino.

The $GPRMC NMEA Sentence contains the Speed in Knots parameter, which I'm interested in. I want to convert this to a velocity vector, i.e. find speed in each direction (Vx, Vy, Vz). Is this possible by any mathematical calculation or through the NMEA Data? The Adafruit library for the GPS also provides a function for getting the Speed value (in knots (same as above)). • You are not "writing a code." That isn't a thing that is done. You are writing some code in your program. So far as I know, you get speed, but no velocity. To get velocity, you would have to get consecutive sets of GPS coordinates, translate from degrees to meters, then calculate the velocities from that and the elapsed time between coordinate sets. – JRE Mar 3, 2018 at 18:30 • @JRE end of the world has been narrowly avoided; "a"$\rightarrow\$ "some".
– uhoh
Mar 3, 2018 at 20:49

Unfortunately, while the receiver itself knows this, it appears to not be delivered. Most applications want only the 2D velocity, so that's what is sent by the NMEA sentences. And I'm pretty sure the Adafruit library is just reading the NMEA data.

Each GPS hipset has other methods to access the data, some of which could probably recover the 3D velocity that it is tracking, but that's going to be more work to track down and receive.

Perhaps calculating it from successive 3D locations will suffice, but that's more complex. If you have enough CPU, then converting from the NMEA Lat/Long to UTM can help. Then you can subtract successive points and have Nort/East/Altitude differences in meters, which can be easily read as a 3D velocity (relative to the surface).

• +1 While the question asks specifically about generating a velocity vector using GPS NMEA data your answer is important because it highlights that to do this right, you really need to try to move into the module's firmware sooner or later to get access to the more timely and raw parameters that are available there.
– uhoh
Mar 4, 2018 at 13:14

The Adafruit Ultimate GPS and Lady Ada's video is mentioned and linked in the question Did the NASA PhoneSat actually try to use the GPS from the phone itself?:

where the firmware has been modified to extend the altitude to at least 50km as an example.

Also, the use of commercial, consumer GPS units for spaceflight applications is discussed in the questions below, and especially their answers:

As this comment suggests, you will first need to convert a series of GPS fixes to some cartesian coordinates, and then use some form of numerical derivative to infer a velocity vector.

Most consumer hobbyist GPS modules will generate NMEA sentences that provide GPS coordinates at the 1 Hz "heartbeat" rate. You will have to read your documentation very carefully to interpret the timing, but there should be an NMEA sentence that includes BOTH the 3D GPS coordinates latitude, longitude, and altitude necessary to build a vector, and the GPS time. If you have all of those in a single sentence, you MIGHT be able to believe it, but you need to read the documentation carefully.

If you have those for two consecutive seconds, you can covert each to an XYZ coordinate in the frame of your choice in units of meters, subtract them to get a delta position, divide by the time difference (in seconds) between the two (presumably 1 second) and voilà you have an approximate velocity vector from your Adafruit Ultimate GPS NMEA data stream!

You'd then assign that velocity to the midpoint in time between those two times. You could also use three points, and use a quadratic fit to position for those three, differentiate the quadratic at the time in the middle in order to get a velocity vector that applies to that particular heartbeat instance.

Of course in any of these cases, your velocities will now be historical and not instantaneous, but it should be good enough for a simple Kalman filter application.

How to convert from GPS lat/lon/alt referenced to a geodetic reference ellipsoid (I think GPS uses WGS84) to Earth-centered coordinates (either Earth-fixed for referencing to the Earth, or "inertial" for referencing to Earth orbit) is a different question, and you can find answers here in Space SE (see @DavidHammen's answer just for example), or in other Stack Exchange sites like GIS for example.

You can also read further in these links, though much (but not all) of it applies to more advanced data inside the GPS module, not to the final NMEA results:

• Lab 2 seems to use the Great Circle Equation, the Earth is modeled as a sphere, not as an ellipsoid.
– Uwe
Mar 4, 2018 at 14:58
• @Uwe You are of course right. I wanted to include a range of difficulty levels and depths, both for the OP and for future readers.That's a calculation one can start with, but you are right a reference ellipsoid is the correct surface to use. This also makes me notice that my link to "reference sphere" is broken, and also that I should change it to "ellipsoid" there as well.
– uhoh
Mar 4, 2018 at 15:04
• GPS is frequently used with WGS84, but flexible GPS receivers allow the selection of a local reference ellipsoid like CH-1903, Potsdam, Cape, Tokyo, Australian 1954 and many more. Here is a nice map of Munic with the same coordinate values in different map systems. Differences of up to 700 m. But for most GPS receivers WGS84 is selected on delivery.
– Uwe
Mar 4, 2018 at 19:04
• @Uwe that is a fascinating article! I'm going to take some time and read it through carefully. Thanks for the clarification.
– uhoh
Mar 5, 2018 at 2:06