Updates to RTKLIB for the u-blox F9P receiver

I recently released a new version of the demo5 RTKLIB code (demo5 b33b2) with some more updates for the u-blox dual-frequency F9P receiver. Its taken a lot longer than I would have hoped, but for the first time, I feel like the demo5 code now has reasonably complete support for this receiver. Many of these improvements should help with other receivers as well, especially other dual-frequency receivers. In this post, I’ll describe some of the recent changes to the code. If you are more interested in a getting-started guide to using RTKLIB with the F9P rather than the latest code changes, then you might prefer this earlier post.

Here are the most important code changes to be aware of. They include changes made in the last couple of demo5 code versions.

  1. Support for F9P constellations/frequencies:
    I believe the latest code now supports all the F9P L1, L2, E1, E5b, B1, and B2 codes for the GPS, Glonass, Galileo, and Beidou constellations, both for u-blox raw binary formats and for the RTCM3 MSM7 messages. Raw and RTCM3 files are correctly converted to rinex format and processed in the position solution for all these codes. However, I did recently notice that there are still a few issues with RTKPLOT correctly plotting all the different codes, particularly the Beidou B2 observations.
  2. Frequency selection:
    Another change in the new code is a slight shuffling of the frequency grouping between constellations. Since RTKLIB memory use and CPU load increases significantly when enabling additional frequencies, I eliminated Galileo E5b processing in RTKLIB as a separate frequency and it is now processed with the other “L2” frequencies. This means to run a dual-frequency solution for all constellations on the F9P, you need to only enable “L1+L2” as the frequency option. Galileo E5a is still part of the “L5” frequencies so if you are using a receiver that outputs E5a instead of E5b you will need to enable “L1+L2+L5” as the frequency option when running an RTKLIB solution. Running dual frequency solutions still take longer than running single frequency solutions but the difference is smaller than it was.
  3. Receiver Configuration:
    A more significant change to the new code is that RTKLIB now much more fully supports configuration of the F9P receiver using a “.cmd” file. In the previous code, some commands still worked on the F9P such as turning on or off receiver messages or changing the observation output rate but other commands, particularly those to enable or disable constellations were broken since the format of these commands changed when going from the M8T to the F9P. In addition, only a small subset of the total commands available for either the u-blox M8T or F9P receivers were ever supported by RTKLIB.

    To make things more complicated, with the F9P, u-blox is also transitioning from the legacy UBX-CFG messages to a new configuration protocol. Although most of the legacy configuration messages still work on the F9P, they are recommending switching to the new format as stated in this quote from the F9P Integration Manual:

    “3.1.6 Legacy configuration interface compatibility There is some backwards-compatibility for the legacy UBX-CFG configuration messages. It is strongly recommended to adopt the new configuration interface, as the legacy configuration messages support will be removed in the future.

    Fortunately the latest demo5 code now fully supports the new configuration interface, thanks to code contributed by Nagarjun Redla. Under the new interface, instead of having different commands, each with its own format and various numbers of input parameters, configuration parameters are set individually using the VALSET command . For example, the legacy CFG-RATE command had 3 input parameters to set time source, measurement period, and navigation rate. Under the new interface each of these parameters has its own key and each is set with a call to the VALSET command with parameter key and value. The two examples below set the measurement rate to 200 msec and enable the Galileo observations.

    !UBX CFG-VALSET 0 1 0 0 CFG-RATE-MEAS 200
    !UBX CFG-VALSET 0 1 0 0 CFG-SIGNAL-GAL_ENA 1

    Currently, only the second of the first four numeric parameters is used and that is set to to the configuration layer to write to. In this case “1” writes to the RAM layer. Use “4” to write to the flash layer or “5” to write to both flash and RAM. “2” is used to write to the BBR (battery-backed up RAM). See the F9P Interface Description document for a list of all configuration key values as well as for more details on the VALSET command.

    All of the available key values are supported by RTKLIB, so any receiver configuration parameter that can be modified from u-center can now be modified from a command file in RTKLIB and the results can be saved to either RAM, flash, or both. The legacy commands that RTKLIB previously supported have not been removed so they will all still work as well.

    The one exception I am aware of is that the key values to set the individual frequencies do not seem to work from either u-center or RTKLIB. This is either a bug in the F9P or a misunderstanding on my part. However, in the Generation 9 Configuration View in u-center, the “Advanced Configuration” command is used for all parameters except GNSS configuration which uses the legacy command. This makes me believe it is actually a bug. Since RTKLIB does not support the legacy GNSS configuration command for dual-frequencies, this means that RTKLIB can enable and disable constellations but not individual frequencies within a constellation.
  4. Ambiguity Resolution:
    Although as I demonstrated in an earlier post, the demo5 code was working well for solutions with moving rovers, the results were less consistent for stationary rover solutions. In some examples, especially those with moderate amounts of multipath in the rover observations, the RTKLIB solution was not getting a fix even after several minutes, while the real-time internal solution and even the single frequency RTKLIB solutions were converging much more quickly.

    Most of my experiments focus on moving rovers and I tend to think of them as more challenging than stationary rovers because of the large number of cycle slips and the continuously changing set of satellites available as the rover’s sky view keeps changing and different satellites come in and out of view behind obstructions. However, stationary rovers have their own set of challenges and in particular multipath is a greater challenge in the stationary rover case than it is in the moving rover case.

    This is because, for the stationary rover, the paths from satellites to receiver antenna stay relatively constant and change only slowly as the satellites move across the sky. This means that the errors introduced by the combination of direct and indirect paths (reflections) between satellite and antenna have very long time constants. In the moving rover case, the errors are still present but are changing much more quickly with rover movement, have much shorter time constants, and average out to zero much more quickly.

    The existing partial ambiguity resolution algorithm in the demo5 code turned out to be more sensitive to the long time constant multipath when the number of observations increased with the dual frequency receivers. I had previously added a step to the ambiguity resolution algorithm to exclude a different satellite each epoch whenever the number of satellites was above a defined minimum (Min Drop Sats) to try and detect “bad” satellites. To minimize the increased risk of false fixes while the kalman filter was still converging, I had only done this after first fix. It turns out that with large numbers of observations, it becomes important to extend this test to before the first fix, and this is the change I made to the code.

    False fixes appear to be much less common with the F9P than the M8T, presumably due to the increased number of observations, so the increased vulnerability while the filter is converging is not much of a concern with the F9P. However if using the latest code with the single frequency M8T, you may need to adjust the configuration parameters slightly to avoid increasing the risk of false fixes while the kalman filter is converging. The best way to do this is usually to adjust the maximum position variance threshold (Max Pos Var for AR) to a slightly lower value. This will delay the start of ambiguity resolution attempts until after the filter is better converged. The trade-off is that if set too low it can delay time to first fix so it may require a little experimentation for best results. I might suggest starting at a value of 0.05 meter for the M8T and 0.1 meter for the F9T but optimal values will vary with configuration so adjust as needed. Time to first fix is less important if you are post-processing with a “combined” solution so you can tighten these numbers even more in this case. For post-processing high quality observations with the M8T I usually set this value to 0.004 meters.
  5. Precise ephemeris:
    This last change is not related to the F9P receiver but is worth mentioning anyways. I don’t use precise ephemeris files very often but other people do, especially for PPP solutions. Use of the MGEX files has become much more popular since they include the Galileo and Beidou orbital data as well as GPS and Glonass. These files usually have capitals in their extension unlike the older files. (.SP3 vs .sp3). Due to a bug in the RTKLIB code it was rejecting the “.SP3” files without reporting an error which could be very confusing to the user. The newest code now accepts files with “.SP3” extensions as well as “.sp3” extensions.

I think those are the most important changes but you can always review the demo5 Github repository for more details on code changes or if you want to build the code for linux platforms.

I do my best to test the code before I release it but I don’t have the time or resources to do this properly on all the different variations that RTKLIB can support so please treat new releases as beta, and if you see results that don’t make sense, it’s a good idea to compare results between the newest version of code and an older version that you have confidence in. If you do find degraded results in the new version, please let me know, and if possible, send logs of the observations and config file along with a detailed description of the issue. I rely on users to validate the code and treat any reported issues where a newer version of the demo5 code performs poorly compared to either a previous version or the official 2.4.3 code with the highest priority I can.

One last thing. You may notice that I have added an optional contribution button to the code download page. I do this work to promote low-cost precision GNSS and because I enjoy it, not to get rich and I want to emphasize that contributions are completely optional. However, if you are a regular user of the demo5 code, find value in the software, and would like to share that value, then any contribution is much appreciated.   I have also added a field to the contribute page to describe any feature or bug fix that you would like to see added to the demo5 code and will try to prioritize popular requests when making future code updates.