GPS Module and Library Recommendations

samscudd

Member
Hi All,

I'm working on reading UART GPS messages, parsing them, and then sending them via MAVLink to a ground control station with the Teensy 4.1. At the moment, we're working with the MatekSys M10Q-5883. With the Teensy handling a few other processes (PWM input from a controller, reading and writing CAN messages to various components, and reading and writing MAVLink messages to/from our GCS) this is actually the first time I've seen any significant impact in performance. I admit I'm using a bit of brute force to deal with the GPS messages, so I suspect this might be part of the issue.

Thus, I figured I'd reach out to see if anyone has any recommendations for libraries that they have used to parse NMEA messages on the Teensy 4.1. Ideally, we'd work with a C/C++ library rather than something Arduino specific.

I'm also a bit concerned with our GPS module of choice at the moment. I've tried a couple different boards with the same ublox M10Q gps module, and have gotten much more accurate GPS readings in the past. Does anyone have any recommendations for small GPS boards that they've used with the Teensy?

Per usual, thanks everyone!

Sam
 
I'm currently using BN-880 GPS module (active antenna) to record race car lines and record car performance at points along the track. I'm taking readings every 500 ms. I have mixed feelings about this and other similar units.

+
relatively low cost ~$28 per unit
great library support (https://github.com/mikalhart/TinyGPSPlus)
slightly better than passive antenna modules
takes a few seconds to start when warmed up
seem to be very reliable in always getting GPS points (I record ~11,000 per race and never miss a datapoint)

-
accuracy is not great as I get +/- 2 meters
can take several minutes to start when cold (sometimes 5min to get them working)


I'm considering the units in this vid for improving tracking car race lines (10 cm accuracy)

Hope this helps
 
I've found the ardafruit ultimate gps module to be pretty good. It does support an external antennae as well, has updates of 10hz and fast warm/cold start times. Good accuracy and a spot for a coin battery to improve start times.

There library is bloated though and uses an interrupt to read one character at a time from the uart.

I rolled my own. Increased the serial buffer size and take a reading from the serial buffer each update loop (60hz) which gets stored in a circular completed message buffer.

With some help from a few other librarys parsing technics I've used my own nmea parser and it's very quick. It parses any completed messages in the circular completed message buffer.
 
+1 for the Ada Ultimate GPS Module for my own very similar application (race car dashboard) at 5Hz, you will not get better than 2-3 meter absolute accuracy, but relative accuracy over the course of a race is good enough to show lines, etc. I tried 10Hz but it didnt actually make much of a difference to my predictive timing alogrithm, besides I found updating a display more than 5 times a second becomes redundant as the eye cannot keep up (not true when updating an analogue style gauge!).
 
I use uBlox modules and the UBX binary format. I like the SAM modules if I'm looking for something low cost and the ZED-F9P modules if I need accuracy or am planning on using CORS or RTK. Parsing the binary data is much more efficient than parsing NMEA.

I have a library that parses the UBX format:

It's been forked a bunch, so you'll find other libraries based on it as well.

There is the SparkFun library that seems to work well also:

I also have a MAV Link library that you might be interested in:

My company makes both SAM and ZED F9P receiver boards with PixHawk style connectors:
 
A bit of a Me Too!!! post but Ublox and binary UBX messages would be my recommended route too.

For most applications once you configure the GPS (which could be done using a PC and saving those settings as the power up default) you can get away with only needing to handle the UBX NAV-PVT message. Only one message to worry about makes life a lot simpler. You could use a library for this but to be honest it's hardly worth it. Define a packed data structure with the same format as the message, wait for a start of message marker. Write data into a buffer until you have all the data. Cast the buffer to a PVT message structure. Read the values.

The F9P is good if you want high accuracy, it claims multi-constellation RTK at 10 Hz but struggles to do both at once. Keep in mind that to get 2-3 cm accuracy you will need an RTK correction source (which could be another F9P) within a reasonable distance (ideally under 10 miles) and a real time link between the two. The corrections data isn't very large so you don't need lots of bandwidth but you do need a constant link to maintain accuracy. Also you need to use a second UBX message to get the high accuracy position out.

The M8 or later will do multi-constellation at 10 Hz or higher (up to 25 on the M10) at a far lower price. In good conditions they will give you sub meter accuracy.

Also keep in mind all GPS receivers, no matter the brand, will always be at the mercy of the environment. Give them a crappy antenna or put them next to an electrically noisy piece of equipment and the performance will suffer.
 
Agree with Andy, most of the time we setup the module using u-center and then just parse the messages. UBX-NAV-PVT is good for most situations. If you use the ZED-F9P, you would probably also want UBX-NAV-HPPOSLLH in addition to the UBX-NAV-PVT packet to get better accuracy in the results. If you're going to do RTK the UBX-NAV-RELPOSNED can also be useful.

We designed, built, and installed the data acquisition system for some manned helicopter flight testing in August that used RTK with two ZED-F9P receivers. We maintained RTK fixed solutions at 10 Hz throughout about 15 hours of flight test with no drops. We were using some very good radio modems from FreeWave (the MM3 modules) to maintain the wireless link between the helicopter and the ground station and stayed within a few miles between the two. Position accuracies were about 2 cm both horizontally and vertically throughout the tests. Compared to how hard RTK and CORS corrections were before, the ZED-F9P is amazing to work with.

If you use a SAM receiver from uBlox, be aware that many manufacturers don't use a large enough ground plane in an effort to keep the receiver small and the performance suffers.
 
We maintained RTK fixed solutions at 10 Hz throughout about 15 hours of flight test with no drops.
Do you mean no drops in output rate or no drops of RTK? Were you GPS only or multi-constellation?

In our testing 10 Hz multi-constellation RTK will maintain RTK fine but it'll skip 1-2% of the outputs. Every now and then time will increase by 0.2 of a second rather than 0.1. The newer firmware versions seem to be worse for this than the older ones.
This is normal for all ublox systems when you are pushing them to the limit, if they don't have time to process everything they drop the entire output rather than producing a solution using less satellites.
 
I meant no drops of RTK, but I understand what you're saying now. I'd have to go back and sift through the data. We were feeding the GPS data through an EKF with IMU data to get a state estimate at a higher rate, so an occasional frame drop from the GPS wouldn't have been a big deal. I'll update when I have a chance to review how we setup the receivers and look through the full data set.
 
Thanks everyone! This is a great thread. I'm looking forward to testing a bunch of these ideas. To start, we actually aren't too concerned with accuracy. +/- 2m would absolutely be acceptable. We are just using GPS to share the location of the vehicle with remote users. It would be great to reduce the startup time though, so maybe I'll try the Adafruit to compare it with our current device. Do any of you have recommendations for reducing the startup time with a Ublox module?


This was awesome, I was trying the TinyGPS library, but was immediately able to get the TinyGPSPlus working. I still haven't tried in with our full control loop though.


I use uBlox modules and the UBX binary format. I like the SAM modules if I'm looking for something low cost and the ZED-F9P modules if I need accuracy or am planning on using CORS or RTK. Parsing the binary data is much more efficient than parsing NMEA.
If I continue to see some performance issues, I'll definitely be trying this out. I also saw your MAVLink libraries, and while I've opted to use MAVLink's standard library, seeing your work definitely influenced my decision to use a Teensy although I was originally hoping to use a small STM32 based dev board of some sort!


For most applications once you configure the GPS (which could be done using a PC and saving those settings as the power up default) you can get away with only needing to handle the UBX NAV-PVT message
As of now, I've gotten away with not using the u-center software, but it seems that I'll need to dive into this to use the UBX format. I'll definitely test out the library but I'm also open to parsing the message myself if needed. I'm not too concerned about this lift.

It sounds like if I try running it with the UBX messages, I'm gonna go for the simplest solution first, and I'll try working with just the UBX-NAV-PVT.

When it comes to the performance, we aren't too concerned with the frequency of the GPS messages as well. I'm more concerned with how processing the GPS messages will impact the performance of reading PWM signals and sending out the CAN messages that control our motors.

Thanks again everyone!
 
To start, we actually aren't too concerned with accuracy. +/- 2m would absolutely be acceptable.

In that case most modules will work fine but do pay attention to where you put things. While just about any modern system will be better than that on paper. But the on paper performance is always assuming good conditions. A good view of the sky is important and GPS is a weak signal so it can get jammed by other noise sources if they are close together, not normally enough to stop it working but enough to cost you some accuracy.

It would be great to reduce the startup time though
Then no matter the receiver ensure you connect a battery backup power source to the appropriate pins. It allows the receiver to store satellite orbit information and an approximate location. This can give a significant speed up in the time required to get a position solution.
 
I'm currently using BN-880 GPS module (active antenna) to record race car lines and record car performance at points along the track. I'm taking readings every 500 ms. I have mixed feelings about this and other similar units.

+
relatively low cost ~$28 per unit
great library support (https://github.com/mikalhart/TinyGPSPlus)
slightly better than passive antenna modules
takes a few seconds to start when warmed up
seem to be very reliable in always getting GPS points (I record ~11,000 per race and never miss a datapoint)

-
accuracy is not great as I get +/- 2 meters
can take several minutes to start when cold (sometimes 5min to get them working)


I'm considering the units in this vid for improving tracking car race lines (10 cm accuracy)

Hope this helps
I used a UBlox ZED09F9R in a logger developed last year. It's expensive, but it includes acceleration sensors and wheel-tick inputs. Since it will work with all major GNSS constellations, it gives pretty good accuracy. Like all GPS systems without local differential correction, it is subject to a few meters of drift over an hour or two. We logged data from cars in the Porsche NW club at the Ridge Motor Sports track near Shelton, Washington. The logger collects binary packets at 25Hz and stores them on the T4.1 SD Card. The files are retrieved using MTP and processed in MatLab on a PC. The processing software sorts out and aligns lap data from one or more cars for performance comparison. The movie at this link: shows some results from last fall.
 
@mborgerson I'm just getting started with my ZED-F9P with plans to add a ZED-F9R later.
Your impressve data logger is close to where I'm aiming.
Any chance you can share your (whole) sketch? :)
TIA
 
Last edited:
Sparkfun ship the ZED-F9P with the ANN-MB-00 GNSS multiband antenna but u-blox also sell the ANN-MB1-00 antenna with extra coverage of the L5 band (but no L2) for same price.

According to Google Gemini (I hear you groaning :cool: ) the MB1 offers superior positional accuracy:
Code:
ANN-MB: This antenna supports L1, L2/E5b, and B2I bands. It's ideal for applications using GPS, GLONASS, Galileo, and BeiDou systems.

ANN-MB1: This antenna offers support for L1, L5, E5a, B2a, and NavIC bands.  While it covers L1 like the ANN-MB, it adds L5 which can improve accuracy. It's also suited for BeiDou and Galileo systems that utilize the additional bands.

Wondering if anyone has tried this and is it a betterchoice for positional accuracy?
 
@mborgerson I'm just getting started with my ZED-F9P with plans to add a ZED-F9R later.
Your impressve data logger is close to where I'm aiming.
Any chance you can share your (whole) sketch? :)
TIA
You asked for it! I've attached a zip file with the tracklogger6 sketch. This a few revisions back and uses the Sparkfun UBlox GNSS library. I started programming embedded systems about 50 years ago and have avoided using dynamic variables as much as possible. The Sparkfun library uses dynamic allocation for most of the logger variables, so I wrote m own handlers for the ZED-F9R that use static allocation and implements only the functions I need. The source code for both the old and new versions of my sketches is about 750 lines each. But with the new code I don't have to scroll through the 1800 lines of source code for the Sparkfun .h file, or the 1200-line file of defined constants or the 18,600 lines of source in the .cpp file.
In addition, my aging mind is protected from the 200 to 300 instances of new [] and delete []!
 

Attachments

  • TrackLogger6.zip
    1.9 MB · Views: 25
Back
Top