Glonass Ambiguity Resolution with RTKLIB Revisited

To get a high precision fixed solution in RTKLIB we need to resolve the integer ambiguities that come from the carrier phase measurements.  Resolving the integer ambiguities for the GLONASS satellites is more challenging than resolving them for the other constellations.  This is because, unlike the other constellations, the GLONASS satellites all transmit on slightly different frequencies.  This introduces an additional bias error in the receiver hardware.

These hardware biases are constant, generally the same for all receivers from the same manufacturer, are proportional to carrier frequency and are similar between L1 and L2.

In the demo5 version of RTKLIB, there are four choices for how to handle GLONASS ambiguity resolution (AR). I will cover all four briefly, but then focus on the “autocal” setting which I have enhanced in the most recent version (b29c) of the demo5 code.

Off:  If Glonass  AR is set to “Off”, then the raw measurements from the Glonass satellites will be used for the float solution but ambiguity resolution will be done only with satellites from the other constellations.  If you are not using the demo5 version of RTKLIB, this is usually your only choice when using receivers from different manufacturers for the rover and the base.  However, you are giving up a significant amount of information by ignoring the GLONASS ambiguities and so I would not recommend this setting if you are using the demo5 code, unless of course your receivers don’t support the Glonass satellites.

On:  If Glonass AR is set to “On” then RTKLIB will treat the Glonass ambiguities the same as the ambiguities from the other constellations and will not make any attempt to account for the additional hardware biases.  Use this setting if your base and rover receivers are from the same manufacturer, since in this case, the biases will cancel and can be ignored.  There are also some cases in which different manufacturers have equal or nearly equal biases as we will see later, in which case you can also use this setting.  This is your best solution for dealing with Glonass ambiguities.  I always try to use matched receivers for base and rover if possible.

Fix-and-Hold: This is an option I have added to the demo5 code for Glonass AR.  It is an extension to the “fix-and-hold” method used for other constellations but instead of using the additional feedback to track the ambiguities, it uses it to null out the hardware biases.  I recommend this setting when using the demo5 code with unmatched receivers.  It takes advantage of the additional information in the Glonass ambiguites most of the time.  However, fix-and-hold is not enabled until after a first fix has been achieved, and so the Glonass ambiguities are not available until then.  This can mean longer time to first fix and less robustness compared to the “On” option, so don’t use this option for matched receivers.

Auto-cal:  This option adds additional states to the kalman filter to estimate the receiver hardware biases as a function of carrier frequency, one state for L1, another for L2.  In previous experiments I had not had any success with it.  Recently, however, I discovered that if I adjusted the filter settings, it can be effective for a zero baseline case, where base and rover are both connected to the same antenna so that almost all other errors are completely cancelled.  With a little more experimentation I also found that for short baselines it can also be effective if the kalman filter state is pre-set to something close to the final value before the solution is started.  It will then usually converge to the correct bias value.  However, there is currently no mechanism in the code to adjust any of these values, so I have not found this mode to be useful in its current implementation.

To make the auto-cal option more flexible, and hopefully more useful, I made a few modifications to it in the b29c code.  I added the capability to pre-set the initial state value and also to adjust the internal filter settings, specifically the initial variance and process noise for this state.  The units for the state, and hence for the initial value are in meters per frequency channel and values generally are within +/-5 cm per channel.  I used some existing config parameters that are currently unused to reduce the amount of code I needed to change.  Unfortunately it means that the names are not as descriptive as they could be.  The new config parameters are:

pos2-arthres2 = relative GLONASS hardware bias in meters per frequency slot
pos2-arthres3 = initial variance of GLONASS hardware bias states
pos-arthres4 = process noise for GLONASS hardware bias states

Bias values have been published for some of the most popular geodetic quality receivers but are generally not available for lower-cost or less popular receivers.  Here is a table of values from a paper published by Lambert Wanninger in 2011 for nine receiver manufacturers.


I was able to verify these results for Trimble, Leica, and Novatel, but I found a much lower value for Septentrio so I suspect the biases may have changed in their newer receivers.

To demonstrate the modified autocal option, I will start with a zero baseline case between a ComNav receiver and a Tersus receiver.  It is easiest to measure the hardware biases in the zero baseline case because most other errors will cancel and the hardware biases will be the dominant error.  In this case, I have significantly reduced the initial variance setting from the original value of 1.0 to 1E-7 and increased the process noise from 1E-6 to 1E-3.

I have run the solution several times with the initial bias value set to different numbers between -.05 and 0.06.  Here are the results for both L1 and L2.


The convergence occurs just after first fix is achieved.  If a fix is not achieved, then the state will not converge as you can see above for the 0.06 example.   In this case, the initial value was too far from the correct value and prevented getting a fix.  As you can see, all the other cases converged towards a single value around -.022, both for L1 and for L2.

Another way to visualize the error in the initial value is to look at the GLONASS residuals after first fix is achieved.  The plot below shows the GLONASS L1 carrier phase residuals  for different initial values, for 0.03 on the left, -0.05 in the middle, and what I believe is the correct value for this receiver combination of -.022 on the right.



Here are the same plots for the L2 carrier phase residuals.


Through a slightly tedious process, I am fairly easily able to iterate the residuals down to near zero for different pairs of receivers in my possession.  Note that this gives me the relative difference in biases for each receiver pair, and not absolute values for each receiver, unlike Wanniger’s table which is for absolute biases.

Extending the table to receivers used in nearby CORS stations is a little more challenging because the initial bias value needs to be fairly close to get a first fix and hence a convergence, but still possible if the base station is not too distant.   I found data sets that included CORS data from Leica, Novatel, Trimble, and Septentrio receivers.  Using the above procedure to iterate the residuals down to near zero, I was then able to extend my table and make the values absolute by choosing the unknown offset to make my bias pairs align with Wanninger’s table.  This is the resulting table I created.

ComNav    =   2.3 cm
Leica          =   2.3 cm
Novatel      =  2.3 cm
Septentrio = -0.3 cm
SwiftNav   = -0.2 cm
Tersus        = -0.1 cm
Trimble      = -0.7 cm
u-blox         = -3.2 cm 

To generate an initial value for the bias state from this table for an RTKLIB solution, subtract the base station bias from the rover bias, then divide by 100 to convert from centimeters to meters.  This value can then be used to set the “pos2-arthres2” config parameter in the config file.  For the RTKPOST and RTKNAVI GUI option menus I have labeled this “Glo HW Bias”.

To test this code on an independent set of data after generating the table, I used a data set recently sent to me by a reader.  It consists of a u-blox  M8T receiver for rover and Leica receiver just a few kilometers away for base, and was collected in Europe.  The rover position was static but I ran the solution in kinematic mode to make the solution a little more challenging and to make any errors in the solution more visible.

To generate the correct config value for RTKLIB I  subtracted the Leica bias of 2.3 cm from the above table from the u-blox bias of -3.2 cm to get a relative bias between receivers of -5.5 cm or -0.055 m.  I added “pos2-arthres2=-0.055” to the config file and then ran the solution four times, with pos2-gloarmode set to “off”,”fix-and-hold”,”autocal”, and “on”.  Although I left the bias value set for all runs it is ignored unless gloarmode is set to autocal.

Here are the times to first fix, the number of satellite pairs used for the initial fix, and the number of satellite pairs being used for fix after 10 minutes.

  Time to # sat pairs used # sat pairs used for
GLO AR mode first fix for initial fix fix after 10 min
OFF 4:10 7 7
Fix&Hold 4:10 7 11
Autocal 1:05 14 14
On 6:47 14 14

As you would expect, the time to first fix for gloarmode=”off” was the same as “fix-and-hold” since “fix-and-hold” does not use the GLONASS satellites for initial fix.  After 10 minutes it was still only including four of the GLONASS satellites in the ambiguity resolution which was a little unusual, typically I would have expected more GLONASS satellites to be included.

With gloarmode=”autocal”, the time to first fix was reduced from 250 seconds to 65 seconds and the number of satellites included in the first fix increased from 7 to 14., both significant improvements.

The most surprising thing in this data is that when gloarmode was set to “on” it acquired a fix at all.  In many similar cases it will never get a fix.  The GLONASS carrier phase residuals after initial fix were very high though as can be seen below.  The left plot is with gloarmode set to “on”, and the right plot is with it set to “autocal”.


The ambiguity resolution ratio was also much higher when autocal was enabled as can be seen below (yellow/green=autocal, olive/blue=on) which improves robustness.


The large residuals did not affect the solution position, as the two solution did not differ by more than 2 mm at any time.  The autocal solution however is much more robust in the sense that it is less likely to lose fix.

Although I have found the results with autocal enabled are generally excellent with relatively short baselines (<10 km), I have found the results less encouraging for longer baselines (>25 km).  In these case I have found that I often get better results with pos-gloarmode set to “fix-and-hold” then I do with “autocal”.  I don’t understand exactly why this is, but suspect that the fix-and-hold correction is more general and may be correcting for more than just the GLONASS hardware biases.

The code changes for this feature are included both in my Github repository and in the newest (demo5 b29c) executables available to download from the rtkexplorer website.   If you choose to experiment with this feature, please let me know if you find any errors in my table, or can add values for any additional receivers.

[Note 6/17/18:  I had a issue with uploading the executables to the website.   If you downloaded them prior to 6/17/18, please download again to get the updated version.] 


22 thoughts on “Glonass Ambiguity Resolution with RTKLIB Revisited”

  1. Hi Tim.

    First of all, thanks for sharing, I find your posts, in my beginner’s capacity, very useful.

    I’m trying to set up my c94-m8p evaluation kit to work in the Spanish NTRIP framework. While I’m able to get a Fixed solution right away (just in a few minutes) with the u-center software, all my attempts to get a solution with rtknavi were unsuccessful.

    I attach here my configuration files and some logs, in case you may take a look. Although in this particular tryout the base was about 40 km away, I used the same exact configuration to a <300 m distance setup. The base station has a Trimble receiver, so I put the GLO HW Bias value to -0.025.

    I appreciate any help you can provide,



  2. Great article, thanks again! I am happy I could help a little at least. This is a perfect start for GLO AR. For the future the RTCM messages 1033 and 1230 as others mentioned will surely be nice expansion.


    1. Hi Salih. I’m not sure I understand. You say you are using the M8T for base and rover, yet your config file is set for autocal and a bias offset of -0.055. If you are using the same receiver manufacturer for base and rover the GLONASS biases will cancel and you should be setting GLONASS ambiguity resolution to “On”.


  3. In general, if reference station broadcast RTCm 1230 message, rover could decode carrier-phase bias(although rtklib has not implemet not yet).
    But almost all reference station broadcast rtcm1033 which contain rec. type infomation like Leica or Trimble, or any rec. type name.
    If we follow this idea, can we use the known bias data sets to set it automaticlly after we receive base rtcm data and decode rtcm1033(rtklib already implement) to determine the receiver type?


  4. It it great!
    But I just test the following data using your new version b29c.
    The base data is from leica receiver,so in theory the bias should be 5.5cm,but if I set it to 0.055,it never can get fix.
    But if I set to fix-and-hold method,it fix very soon.
    Then I try set to other value,I find out it is 0.011,it could be fix.
    you could download data from here:
    leica receiver+m8t data


    1. Hi Rinex20. The relative bias is equal to the rover bias minus the base bias. For a u-blox rover and Leica base, this is -0.032 – 0.023 = -0.055. It looks like you have the sign wrong. Using this bias with your data I got first fix in ~1.5 minutes with autocal and ~3 minutes with fix-and-hold.

      It looks like I had a wrong sign in my example in the post … that’s probably why you had it wrong. I’ve fixed it in the post now.


      1. Hi Tim, so in your article,there is a “pos2-arthres2=0.055”, you metioned you use M8T rover and leica base, it means arthres2=-0.055. It miss sign or not?


      2. thanks for your clarify.

        I tyied analysis the above data,yes it is almost meet our expectations.
        But I find -0.055 maybe is not the best value, you can try -0.097 then see the residual chart.
        I remember there was two version Leica GNSS board, one is the old leica-brand,another is new Leica-novatel board when Hexagon acquire Leica geosystem.

        This is why I think the old leica base’s bias may not be 2.3cm, maybe it should be 6.5cm.


        1. Hi Rinex20. I verified your data both by looking at residuals and by plotting the hardware bias and confirmed that -0.055 is the correct bias value. I had a little trouble getting the scaling correct in my code and I had a incorrect version posted both to the Github repository and the executables for a couple of days previous to my post. Can you verify that you have the latest code … I suspect that will clear up the discrepancy.


          1. Hi Rinex20. It looks like I had a problem with the update to the binaries on the website, the words were updated but not the actual zip file. Can you download again and confirm that the rnx2rtkp, rtkpost, and rtknavi binaries have 6/13/18 date. Sorry about that!


  5. Great results! Can you publish files (raw data, configuration RTPPOST) from your example? I try apply GLOHWBias = 0.032 (Base = Javad, Bias=0 from paper Wanninger (2011)), and any value not equal zero, but isn’t sucessfully (time to first fix > 55 minutes). If apply GLOHWBias = 0 (zero) time to first fix ~ 15 minutes. If pos2-gloarmode set to ”fix-and-hold” time to first fix ~ 8 minutes (now it’s best result). Baseline < 200 meters.
    I would be grateful if you chek my results (


    1. Hi Max. The M8N is an exception to the rule that the hardware biases cancel if the receivers are matched. It is actually the only exception I know of, although I suspect it may be true in other ultra-low cost receivers. I’ve discussed this more in some of my earlier posts on GLONASS ambiguity resolution. The “fix-and-hold” option does not rely on some of the assumptions that the “autocal” option uses (e.g. biases are proportional to frequency) and so it is really your only choice for resolving GLONASS ambiguities with the M8N.


      1. Thanks, I understand about M8N. Just I have similar example as in post- M8T (Emlid Raach RS) + Leica (Base station). In all cases gloarmode parameter (off, fix-and-hold, autocal (=0.055 and any value)) has same time for initial fix, but sat pairs for initial only GPS (8 sats). And if gloarmode = “autocal”, after 5-10 minutes initial fix – status set to float (Q=2) and not get a fix.
        This example files:
        I just want to understand and confirm your results. While I use M8N from instead of more expensive M8T as even at the forum Emlid recommend to switch off a AR GLONASS in case of non-matched receivers. It is a shortcoming, but with the help of your researches, it hope, will turn out to solve this problem and the M8T will surpass much more M8N.


        1. Hi Max. You may be using the wrong sign for the autocal bias. It should be -0.055, not 0.055. However, I can not get good results with your data with the correct sign either. Your rover data is unusual in that it starts with GPS only, then later after first fix, the GLONASS sats appear. This is why you see the same fix time with autocal or fix-and-hold, since it is a GPS-only fix. This is also going to make the autocal feature less effective since the calibration occurs for the most part at fix and you have no GLONASS data then. I tried running solutions on your data starting after GLONASS appeared, as well as backwards, and neither got a fix with either autocal or fix-and-hold. I suspect there is some other issue with this data. Are you using a ground plane for the rover antenna and is it away from any reflective surfaces that might be causing multi-path?

          In general, I think you will find that autocal will provide faster first fixes with clean data and short baselines, but overall, fix-and-hold is probably a better choice for more difficult data sets.


          1. Unfortunately, I don’t know what there was a situation around the receiver, because is not my survey. Ground plane built-in receiver and it is unknown, it is how effective. Thank you for your explanation!


  6. I was wondering how Wanninger (2011) got absolute biases, then I read in his paper that “The adjustment of all baseline solutions was repeated with the constraint that the mean bias value of the selected JPS Legacy receivers equals zero.” Maybe Unavco in Boulder could lend you a TPS Legacy receiver? For the record, I’m surprised there are still five such receivers in operation as part of the IGS network: one in Germany (SASS00DEU), another one in Ethiopia (ADIS00ETH), and three in Russia (IRKJ00RUS, MOBJ00RUS, NOVM00RUS). Just in case you’d want to try non-zero baselines, like Wanninger did.


    1. Hi Felipe. That’s interesting … I hadn’t actually noticed how he aligned his absolute biases, I had assumed they were less arbitrary. Just for clarification, in my testing, only the first sets of data with my own receivers were zero-baseline, the data sets using local CORS stations, and the validation example I gave at the end had baselines of 2-40 km.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.