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 rtkexplorer.com 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
- Adjust base position every epoch: Based on single point position result.
- 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.
- 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)
- 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.