Moving-base solutions (part 2)

In my last post I discussed solving for moving-base data sets using the ordinary fixed-base solution modes and promised to discuss solutions using the RTKLIB “movingbase” method in my next post.

Let me start by saying I had hoped to have had more success with this method by the time I got to writing this post but that has not been the case.  I have tried both the most recent demo5 code and the 2.4.3 release code and neither gives me clean reliable solutions if I turn on the “movingbase” option.

[Note 4/2/19:  Sorry, I’ve been meaning to update this post for a while.  The reason I was not previously successful enabling moving-base mode is because it is not compatible with dynamics mode.  The random fluctuations in the base location due to its position being calculated in standard precision result in very large accelerations which get filtered by the dynamics mode, introducing error into the solution.  I would still recommend in most cases using kinematic mode and not moving-base mode even when the base is moving, but if you insist on using moving-base mode be sure to turn off dynamics mode first.]

In the previous post I had picked a fairly challenging data set to demonstrate with.  In case that was interfering with the solution, I first switched to a cleaner data set for this experiment.  This is a data set taken with two Emlid Reach M8T receivers, one mounted on each end of a kayak while out in the ocean near Sussex England and was sent to me by Matt. Here is the solution using the same input configuration file I used in my previous post, with “movingbase” turned off.


The distance between the receivers in this case is larger and the deviations from a circle are very small.  This result should provide very accurate heading measurements.  The two visible deviations from the circle in the plot above are caused by rolling the kayak over an embankment at at launch and retrieval.  These large z-axis movements violate the assumption that movements are all in the x-y direction and cause the solution to leave the circle onto a sphere but are not actual errors.

Here’s a solution using the latest 2.4.3 code with “movingbase” enabled.


It may be that I am doing something silly but I did spend a fair bit of time trying to get a decent solution without success.  If anybody more familiar with “movingbase”solutions would like to take a shot at it, I’ve uploaded this data set to here on the website.  Please let me know if you are able to get a decent “movingbase” solution with this data.

I went back to the more challenging original data set from last post since I actually had slightly more success with that one, although still quite limited.

In my first attempt with “movingbase” enabled, I ran into the same problem as last post where the missing measurements in the base data caused large spikes in the solution.  This was true even with the max age of differential set to less than one sample time, which is what fixed the problem previously.  Looking at the code, this is because the “maxage” input parameter is ignored when “movingbase” is set and a hard-coded value is used instead (more about this below).   I modified the code so that it did check the “maxage” limit for “movingbase” and then got the following solution.


The spikes are much smaller now that the missing samples are removed but they are still occurring, this time when both measurements are present.  The spikes are large enough to make this solution useless.  At this point I have given up trying to get useful results with the “movingbase” solution but again would be very interested if someone else can show good results for this data as well.  The raw data is located at the same link as the previous data set.

I am not completely surprised that the “movingbase” solutions are not working well, since the only other case I’m aware of that RTKLIB allows the base to move also has caused me problems.  That occurs when running real-time solutions and setting the base location to “Average of Single Positions” and then setting the number of averages greater than one.   Whenever I have done this, the solution takes a long time to converge.  I get much faster first fixes if I set the number of averages to one which then prevents the base location moving after the first measurement.

Since I did spend some time going through the code to understand how the “movingbase” solution is supposed to work, I thought I would share that here.  Setting the solution mode to “movingbase” sets the opt->mode variable in the code to “PMODE_MOVEB” so I started by searching the code base for this.  There is also a section in the RTKLIB manual in Appendix E that describes the moving-base model.  Here’s a quick summary for the significant differences I found that occur when in “movingbase” mode

  1. Adjust base position every epoch: Based on single point position result.
  2.  Synchronize rover/base measurements:  The measurement times between the two receivers may vary slightly (usually less than 2 msec).  This can degrade accuracy in the case of very fast-moving rovers.  To prevent this, the base measurements are adjusted for their time difference.  Uses a hard-coded value (1.01 sec) for max age of differential instead of the “maxage”input config parameter.
  3. Constrain baseline: Add a pseudo-measurement to the kalman filter measurement update based on the error from the baseline length specified in “pos2-baselen” and “pos2-basesig” input parameters. (Only applied if pos2-baselen>0)
  4. Increase kalman filter update iterations:  Add two iterations to the number of iterations specified by the “pos2-niter” input parameter.  This should improve the response in the case of large non-linearities introduced by short baselines or rotational accelerations.

So, based on these results, my recommendation for processing moving-base data is to use the ordinary fixed-base solution parameters I described in my previous post.  This will usually give good results but be aware that there will be limitations in the cases where the rover moves a very long distance away from it’s starting point or if is moving fast relative to any sampling time deviations between the two rovers.




17 thoughts on “Moving-base solutions (part 2)”

    1. Hi Schumipush. Good catch! Not sure how that happened but I’ve updated the download data to replace the incorrect solution with one using the same config file and the latest demo5 RTKLIB code (demo5_b34c).


  1. I’ve downloaded the data that you set on the rtklib, but there isn’t velocity data in the file. Is it possible to have velocity data from rtklib when “moving base” is enabled?
    PS: Congratulations for your work, is very well done.


    1. Hi Guilherme. Yes it is possible to output velocity data in the solution for “moving base” mode but it will be relative velocity between the two receivers. To include velocity data in the solution, set the “out-outvel” option to “on” in the config file.


  2. Thank you for sharing your data and experience.
    I have problem reiterate your experiment using your data. I’m using “mat-kayak” data-set with RTKlib 2.4.3. Here is my config to be specified: rover and base are assigned with two “.ubx” file in the data-set. for the solution setting, I loaded the “movebase.conf”. But it results in no solution.
    Did I miss something? it would be great if you could describe the experiment in more detail or check to see if anything missed.


    1. Hi Dezdeepblue. I would suggest enabling the debug trace feature and then scanning the trace file for error messages. Usually if you are getting no solution at all, it is a simple configuration issue or missing/misplace input file.


    1. I’ve never met such option. I think, there isn’t such option in rtklib. You can get xyz coordinates of baseline only.


  3. While playing around with Static-Start I found that in rtknavi while in the RTK monitor the “Positioning mode” is shown as “Moving Base”.
    That is because in mondlg.cpp in ShowRTK, the line:
    AnsiString mode[]={“Single”,”DGPS”,”Kinematic”,”Static”,”Moving-Base”,
    is missing an entry for “Static-Start”
    This doesn’t effect much of anything other than the incorrectly displayed mode.


    1. Hi Cynfab. Thanks for catching that … I’ll fix it in the next code release. Actually I thought I fixed that once before but maybe it never made it into a release or maybe it was just a similar issue in a different file.


  4. For debugging purposes, how about inputting the same rover data for the moving base? It should output all zeros for position coordinates. Just as a sanity check..


  5. Very interesting. Thank you. have you have any pitch and roll results using moving base mode? I am wondering GPS may not sensitive to pitch and roll changes. Not sure we can get the same accuracy for pitch and roll compare to heading



    1. Hi Dan. With two receivers, if they are aligned on one of the axes, you will only measure two of the three axis (heading, pitch, roll). If the two receivers are aligned front to back you can measure pitch, but not roll. If they are aligned side to side, you can measure roll, but not pitch. If the receivers are mounted at a 45 degree angle, then in theory you can measure all three axes. Because the z-axis component of the position measurement is less accurate than the xy-axis components, the pitch or roll measurements will have a little more error than the heading. In the kayak data, the change in pitch is very obvious when the kayak is rolled over an embankment during launch and retrieval, but otherwise there is not much z-axis movement in either data set.

      Liked by 1 person

      1. No. It’s slightly incorrect. I had this problem before.
        If the two receivers are aligned front to back you can measure heading and pitch. It’s true. But if the receivers are aligned side to side, in general case you can measure nothing. You need pitch to compute heading and roll from side-to-side vector, but pitch is unmeasurable in this case. So, your idea works only if pitch is zero.
        The similar reasoning works in case 45 degree mounting too. The system will have one degree of freedom (rotation around vector antenna1-antenna2), and this unmeasurable parameter will affect on the all orientation angles (heading, pitch and roll).
        PS Sorry for my English.


        1. Hi Malcontent. Yes, I think you are correct. When I wrote my comments, I was thinking more of situations where the rover motion outside a two-dimensional plane was relatively small like a car going up a hill or a sailboat heeling in the wind. I should have considered a more general three-dimensional case as well in which case everything you say applies.


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 )

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.

%d bloggers like this: