Integer ambiguity resolution is done by RTKLIB after calculating a float solution to the carrier phase ambiguities to attempt to take advantage of the fact that the carrier phase ambiguities must be integers. Constraining the solution to integers improves both the accuracy and convergence time.

RTKLIB provides three options for the integer ambiguity resolution: instantaneous, continuous, and fix-and-hold. “Instantaneous” is the most conservative and relies on recalculating the phase bias estimates every epoch. “Continuous” is the default option and uses the kalman filter to estimate the phase biases continuously over many epochs. In general, this provides much less noisy estimates of the phase biases and is essential for working with low cost receivers. The downside of the continuous solution is that if bad data is allowed to get into the filter outputs it can remain for multiple epochs and corrupt subsequent solutions, so some care must be taken to avoid that.

“Fix-and-Hold” takes the concept of feeding information derived from the current epoch forward to subsequent epochs one step farther. In the “Continuous” method, only the float solution is used to update the phase bias states in the kalman filter. In the “Fix-and-Hold” method, an additional kalman filter update is done using pseudo-measurements derived from the fixed solution. This is only done if the fixed solution is determined to be valid. All of this is explained in greater detail in Appendix E.7(5) of the RTKLIB user manual.

In general, taking advantage of all the information we have this epoch to improve the solution for the following epochs seems to be a good idea, especially given the high levels of noise in the low-cost receivers and antennas. Even more so than in the “Continuous” method, however, we need to be careful about feeding erroneous data into the kalman filter which may take a long time to work its way out.

Testing the “Fix-and-Hold” method on a few data sets shows the results we would expect, the solution usually does improve but can occasionally cause it to have difficulty recovering from a period of bad data where we have corrupted the phase-bias estimates.

To minimize the chance of this happening, we need to do a better job of validating the solution before feeding it forward. Looking at a couple examples of bad data, what I find is that the errors are introduced when solutions are derived from a very small number of valid satellites. The current integer ambiguity validation is based only on the ratio of residuals between the best solution and the second best solution and does not take into account the number of satellites used to find the solutions.

I have introduced two new input parameters, “minfixsats”, and “minholdsats” into the code. These set the number of satellites required to declare a fixed solution as valid, and the number of satellites required to implement the fix-and-hold feature. I have found setting the minimum number of satellites for fix to 4 and fix-and-hold to 5 seems to work quite well for my data, but I have made them input parameters in the config file to allow them to be set to any value.

I won’t include all the code here, but it is available on GitHub at https://github.com/rtklibexplorer/RTKLIB on the demo1 branch

The two key changes are:

For minfix, in resamb_LAMBDA() from:

if ((nb=ddmat(rtk,D))<=0) {

errmsg(rtk,”no valid double-difference\n”);

to:

if ((nb=ddmat(rtk,D))<(rtk->opt.minfixsats-1)) { // nb is sat pairs

errmsg(rtk,”not enough valid double-differences\n”);

and for minhold, in holdamb() from:

if (nv>0) {

R=zeros(nv,nv);

for (i=0;i<nv;i++) R[i+i*nv]=VAR_HOLDAMB;

/* update states with constraints */

if ((info=filter(rtk->x,rtk->P,H,v,R,rtk->nx,nv))) {

errmsg(rtk,”filter error (info=%d)\n”,info);

}

to:

if (nv>=rtk->opt.minholdsats-1) { // nv=sat pairs, so subtract 1

R=zeros(nv,nv);

for (i=0;i<nv;i++) R[i+i*nv]=VAR_HOLDAMB;

/* update states with constraints */

if ((info=filter(rtk->x,rtk->P,H,v,R,rtk->nx,nv))) {

errmsg(rtk,”filter error (info=%d)\n”,info);

}

Again, the changes to the position solution are subtle and difficult to see in a plot, but are much more obvious in the Ratio Factor for AR validation. A higher ratio represents greater confidence in the solution. The green is before the changes, the blue is after. The RTKLIB code limits the AR ratio to a maximum of 1000.

As you can see, there is a very significant increase in the AR ratio with the change. The improvement is coming from switching the ambiguity resolution from continuous to fix-and-hold, not from the code changes which we made to try and reduce the occasional occurence of corrupting the filter states with bad data.

Let’s also look at the metrics described earlier for both this change and the bug fix described in the previous post. On the x-axis, 1-3 are from before the two previous changes, 4 is with the bias sum bug fix and 5 is with fix-and-hold and the min sat thresholds for fix and hold.

From the metric plots you can see that at this point we have maxed out the % fixed solutions and median AR ratio metrics and have got the distance metric down below 0.5 cm so I will stop here and declare success, at least for this data set.

If you’d like to try this code with your data, the code for all the changes I have made so far are available at https://github.com/rtklibexplorer/RTKLIB on the demo1 branch.

If anyone does try this code on their own data sets please let me know how it goes. I’m hoping these changes are fairly universally useful, at least for open skies and low velocities, but the only way to know is to test it on multiple data sets.

**Update 4/17/16: ** Enabling the “fix-and-hold” feature on other data sets has had mixed success. I still see “fix-and-hold” locking to bad fixes and corrupting the states. It looks like the extra checks I added are not sufficient to prevent this. So, for know,I recommend turning off this feature, or if you do use it, be aware that it can cause problems. I hope to take another look at this soon.