The new low cost dual frequency receiver from u-blox, the ZED-F9P, is just now becoming available for purchase for those not lucky enough to get early eval samples from u-blox. CSGShop has a ZED-F9P receiver in stock for $260 which seems quite reasonable, given that it is only $20 more than their NEO-M8P single frequency receiver.
Even better, Ardusimple is advertising an F9P receiver for 158 euros (~$180) + 20 euros shipping , although their boards won’t ship until January. As far as I’m aware of, this is actually less than anybody today is selling the M8P receiver for today!
Of course, this is still a fair bit more than a u-blox M8T single frequency receiver without an internal RTK engine, which is available from CSGShop for $75, but the F9T will be coming out next year also without internal RTK engine, which should bring down the price for the lowest cost dual frequency receivers.
Unfortunately I am not one of the lucky ones who got eval boards directly from u-blox yet. However, I do have two prototype boards from Gumstix, given to me by them for evaluation. Gumstix offers both off-the-shelf boards and semi-custom boards designed from their libraries of circuits. I haven’t worked with them directly but it looks like an interesting and useful concept. The F9P boards from Gumstix won’t be available for sale until at least Feburary next year but I thought I would share the results of some initial testing. From a performance perspective, I would expect these boards to be similar to F9P boards from other suppliers.
For a first look, I chose to compare the F9P to an M8T for one of my typical driving-around-the-neighborhood exercises. I looked at both the internal real-time F9P solution and the RTKLIB solutions, both real-time and post-processed.
For the base stations, I connected a CSGShop M8T receiver and a Gumstix F9P receiver through an antenna splitter to a ComNav AT330 dual frequency antenna on my roof. Since RTKLIB doesn’t yet fully support the receiver commands needed to setup the F9P, I used the most recent version (18.08) of the u-blox u-Center app run on a Windows laptop to configure the F9P receiver using the documentation on the u-blox website. I then saved the settings to flash. The receivers were connected to a laptop with USB cables and I broadcast the base observations over the internet on a couple of NTRIP streams using STRSVR and RTK2GO.com as I’ve described previously. I configured the F9P to send RTCM3 1005, 1077, 1087, 1097, 1127, and 1230 messages which include base location, raw observations, and GLONASS biases.
For the most part the u-blox documentation is well written and this exercise was fairly straightforward, but I did run into a couple of issues. First of all, when I plugged the F9P receiver into the laptop, Windows chose the standard Windows COM port driver instead of the u-blox GNSS COM port driver that it chose for the M8T receiver. You can see this in the screen snapshot below where COM17 is the M8T and COM21 is the F9P.
Both drivers allow the user to set the baudrate in the properties menu available by right clicking on the device name. With the u-blox driver, the baudrate setting doesn’t seem to matter which makes sense since it is a USB connection. I have always left the u-blox driver baudrate at the default of 9600 baud without any issue. With the windows driver, however, I found that I had to increase the baudrate setting to 115200 to avoid data loss issues. I have run into a similar problem before for sample rates greater than 5 Hz when the M8T is accessed through it’s UART interface and an FTDI converter is used to translate to USB, rather than communicating directly through it’s USB interface. I verified though, that in this case the board is using the USB interface on the receiver and not the UART interface. Not a big deal, and it may be unique to this board, but something to be aware of in case you run into a similar problem.
The second problem I ran into is that the F9P module seems to be sensitive to my antenna splitter, a standard SMA DC block and tee which I have used on many other receivers before without issue. It works fine if the F9P power is blocked but if the M8T power is blocked, the F9P seems to detect the tee and shut off the antenna power. Again, not a big deal, but something to be aware of.
For the rovers, I used a u-blox ANN-MB-00 dual-frequency antenna for the F9P receiver. This is the antenna u-blox provides with its F9P eval units. I had planned to split this antenna signal to both receivers as I usually do, but I ran into the problem described above, and not fully understanding the issue yet, ended up using a separate Tallysman TW4721 L1 antenna for the M8T receiver. Both antennas were attached directly to the car roof which acted as a large ground plane.
I used a hot spot on my cellphone to stream the NTRIP base station observations from the phone to a laptop and then to the F9P receiver and to two instances of RTKNAVI, one for each rover receiver.
Streaming the base observations to the F9P, while simultaneously logging the internal RTK solution and the raw rover observations, and also sending the raw rover observations to RTKNAVI, all over a single serial port can be challenging since only a single application can be connected to the serial port at one time. Fortunately RTKLIB has a little trick to deal with this. If the “Output Received Stream to TCP Port” box is checked in STRSVR and a port number specified as shown below, all data coming from the other direction on the serial port will be redirected to a local TCP/IP port. This data can then be accessed by any of the other RTKLIB apps as a TCP Client with server address “localhost” using the specified port number.
I set up the F9P rover to output both raw observation and navigation messages (UBX-RXM-RAWX/ UBX-RXM-SFRBX) and solution position messages (UBX-NAV-POSLLH). RTKNAVI then logged all of these messages to a single log file. RTKCONV and RTKPLOT can both extract the messages they need from this file and ignore the rest so combining them was not an issue.
The POSLLH messages from the F9P default to a resolution of 1e-7 degrees of latitude and longitude which works out to roughly 1 cm. For higher resolution you can use the POSHLLH message or you can increase the resolution of the POSLLH message by setting a bit in the UBX-CFG-NMEA message. RTKLIB only understands the POSLLH message so that is what I used. Unfortunately I did not realize the resolution issue until after I collected the data and so my results for the internal F9P solution for this experiment were slightly deteriorated by the lower resolution.
I used the most recent demo5 b31 code to calculate all of the RTKLIB solutions. Both the demo5 and the 2.4.3 versions of RTKLIB have been updated to translate the new dual frequency u-blox binary messages. The demo5 solution code will process all the dual frequency observations but I don’t believe 2.4.3 code is able to process the E5b Galileo measurements yet. The RTKLIB 2.4.2 code however does not have any of these updates.
The demo5 code updates made in the recent B30/B31 versions are based on the updates from the 2.4.3 B30 code but include some modifications to the u-blox cycle slip handling that I had previously added to the demo5 code for the M8T. Since the demo5 code is primarily aimed at low cost receivers I also made some changes to make the E5b frequency a little easier to specify and faster to process.
To run the RTKNAVI F9P real-time solution, the only significant change I needed to make to the default M8T config file was to change the frequency option from “L1” to “L1+L2+E5b”. I should have also changed the base station position to “RTCM Antenna Position” to take advantage of the F9 base station RTCM 1005 base location messages but neglected to do this. This caused the RTKNAVI solution to differ from the F9P solution by small constant values due to the approximate base location used in the RTKNAVI solution. I later used exact base locations for the RTKLIB post-processing solutions to verify that the different solutions did in fact all match.
Once I had everything set up, I then drove around the local neighborhood, emphasizing the streets with most challenging sky views since I knew both receivers would perform well and be difficult to distinguish if the conditions were not challenging enough.
I first converted the binary log files to observation files using RTKCONV and verified that the F9P was logging both L1 and L2 measurements for GPS, GLONASS, and Galileo. I had the Bediou constellation enabled as well but as I verified later, there were no fully operational Bediou satellites overhead when I collected the data.
Here is an plot of the L1 observations for the M8T on the left and the F9P on the right. I have zoomed into just two minutes during some of the more difficult conditions to compare the two. The red ticks are cycle slips and the grey ticks are half cycle ambiguities.
First, notice that the F9P does not log observations for the SBAS satellites, while the M8T does, giving the M8T a couple more satellites to work with. However, what’s also interesting, and I don’t know why, is that the F9P collected quite good measurements from the Galileo E27 satellite, while the M8T did not pick up this one at all. Of course the F9P also got a second set of measurements from the second frequency on each satellite and so overall ended up with nearly twice as many raw observations as the M8T.
Also notice that the F9P reports somewhat less cycle slips and many less half cycle ambiguities than the M8T. Some of this might be because of the different antennas, but particularly the large difference in half cycle ambiguities suggests that u-blox has made other improvements to the new module besides just adding the second frequencies.
Another thing to notice is the number of Galileo satellites. If you compare these plots to earlier experiments I’ve posted, you’ll notice there are more Galileo satellites now as more and more of them are starting to come online. The extra satellites really help the M8T solutions because as you can see, they tend to have the highest quality observations through the most difficult times. Again I don’t know why this is. It doesn’t appear to be as true for the F9P though.
Next I looked at the real-time solutions. First, the RTKLIB solutions with RTKNAVI for both receivers. For the full driving route, the M8T solution had a 77.3% fix rate and the F9P solution had a 96.4% fix rate. Here is a zoom into the most challenging part of the drive, an older neighborhood with narrower streets and larger trees, the M8T is on the left, and the F9P on the right. Fixed solutions are in green and float in yellow. Clearly here the F9P significantly outperformed the M8T.
The F9P internal solution did even better with a 99.2% fix rate, as shown in the plot below. All three solutions agreed within 2 cm horizontal, a little more in vertical, and none of them showed any sign of any false fixes.
I didn’t do any static testing to characterize time to first fix as I sometimes do, but for this one run the RTKLIB time to first fix for the M8T was 18 seconds while the RTKLIB F9P solution reached first fix in 6 seconds. In both cases, RTKLIB was started after the hardware had time to lock to the satellites and acquire navigation data for all satellites. The demo5 RTKLIB code has an additional fix constraint based on the kalman filter position variance to minimize false fixes while the filter is converging and so this can sometimes affect time to first fix. I had increased this parameter to 0.1 meter for this experiment since the large number of measurements reduces the chance of a false fix. This constraint did not limit the M8T time to first fix but it did so for the F9P, meaning the F9P would have reached first fix even faster if this constraint were opened up more. I can’t tell what the equivalent number would be for the internal F9P solution from this data since it had already been running and achieved a fix before I started logging the data but generally the F9P seems to acquire first fix very quickly.
Next I post-processed both data sets with RTKLIB using the combined-mode setting to run the kalman filter both forwards and backwards over the data. This noticeably improved the results, bringing the fix rate for the M8T up from 77.3% to 96.1% and the F9P fix rate from 96.4% to 98.8%.
Obviously this is not enough data to make any definitive conclusions, but so far I am very impressed with the F9P! Both the raw observations and the internal RTK solutions for the F9P look as good as anything I’ve seen from receivers costing many times what this one cost.
If anybody would like to look at the data from this experiment more closely, I have uploaded it to here. I should mention that all the fix rates I specify in this post and other posts won’t exactly match the fix rates in the raw solutions, since I adjust the data start and end times to be consistent between data sets and to start after all solutions have achieved first fix. I believe this is the fairest way to compare multiple solutions, especially when there is a mix of internal and RTKLIB solutions
Also, I’d like to thank Gumstix again for making these modules available to me for evaluation!
Reviewing the config files I used for this experiment I discovered that, while I had intended the real-time and post-processing config files to be identical, there were in fact some small differences between them. One difference in particular, that appears to have affected the results as described above, is that I reduced the minimum number of consecutive samples required to hold ambiguities (pos2-arminfix) from 100 to 20 for the post-processed config files. A value of 100 corresponds to 20 seconds at the experiment’s 5 Hz sample rate which is a value I have typically used. However, with lower ambiguity tracking gain (pos2-varholdamb=0.1) and the increase in observations coming from including Galileo, the chances of false fixes is reduced and I have been tending to use lower values of arminfix in more recent experiments. Reducing this value appears to explain a large part of the jump in percent fix for the M8T between real-time and post-processing, rather than the switch from forward-only to combined that I attribute it to above. These differences only affect the comparisons between RTKLIB real-time and post-processed results, and not between the M8T and the F9P since the config files were consistent between the two receivers.
This was only intended to be a quick first look at the F9P. It will require more data and more analysis to properly characterize the F9P so I won’t try to do that here but I will share the table shown below which includes a few cases I have run since the original post. I hope to dig into the details in future posts.
One last point worth making is that while at first glance the post-process fix percent increase from M8T=96.0% to F9P=99.3% may not sound that significant, it is in fact a factor of nearly six if you consider it as a decrease in float from 4.0% to 0.7%.