Kinematic solution with RTKPOST

Kinematic solution with RTKPOST

RTKPOST is the GUI tool in RTKLIB to calculate position solutions. Most of the time I find the CUI version (RNX2RTKP) better fits my needs, but just to check everything is working, it is probably easier to use RTKPOST the first time.

For a demonstration of using RTKPOST to find a kinematic position solution, I will use the ZDV1 (COREX station data) for base station data and the “EBAY” (Ublox M8N receiver data) for rover data. Zipped versions of this data is available here.  Since the exact location of ZDV1 is known and is in the observation file header, the kinematic solution will give us an absolute position by solving for the relative distance between the rover and the base, and then adding that to the base location. I set up the GUI inputs as shown below to point the program to the correct observation and navigation files. If you use my data, be sure to change the paths to match where you saved the data to.


For this first run, to keep things as simple as possible, we will make just two changes from the default setup. Use the “Options” button to get to the options menu. Under the “Setting 1” tab, change “Positioning mode” from “Single” to “Kinematic”. This will give us a differential solution using carrier phase info instead of an absolute solution using only pseudorange. Next, under the “Positions” tab, change the first field under “Base Station” from “Lat/Lon/Height” to RINEX Header Position. This will tell RTKPOST to get the base station location from the header of the observation file.

While you are in the options menu, click the “Save” button, and save the options setup to a location you will remember later. We will use this file as the configuration input file for the CUI version. Then click OK to exit the Options menu.

Click the “Execute” button to calculate position and then “Plot” to see the solution. Select “Gnd Trk” and zoom in and it should look like this. The two rectangles are parking lots. The yellow represents a float solution, the green a fixed solution. The fact that we were able to get a fixed solution at least part of the time is a sign things are working reasonably well.



Zooming into the initial time period when the car was stationary we see the plot below. Since the receiver is not moving during this time, any movement in the solution represents error. During the initial convergence of the kalman filter we see quite a lot of error, but once it does converge, we do get a fixed solution for 5 of the 20 minutes which appears as green in the plot below. During this time you can see the error is roughly +/- 1cm in the xy direction which again is a good sign things are working.


Note about restoring RTKPOST default options:  There is no button in RTKPOST to reset the options to defaults and it remembers the options from the previous session when restarted, so there is no obvious way to put it back to defaults.  The best way I have found to do this is to delete the “rtkpost.ini” file saved in the rtklib\bin folder before starting RTKPOST.


7 thoughts on “Kinematic solution with RTKPOST”

  1. Excellent blog, rtklibexplorer! I’ve been tying to do something similar and am glad to have found someone in the same boat, as it were. Unfortunately, I haven’t been able to get my setup to work yet. I am using the same eBay module as you (mine includes the magnetometer) and the stock antenna. I have the module working with rtknavi and am streaming base station data from a local (~10km away) NTRIP server. I have a clear view of the sky with no tall buildings or trees and am holding the rover in a fixed location. The problem is the RTK solution is almost always float and is not precise at all. Only rarely does it enter the fix state and only very briefly. I have tried a few other base stations, with the same results. My instinct is to blame the antenna, but the reported SNRs are in the mid-high 40s, which I understand to be good enough. Is there something obvious I’m missing?


    1. Hi Janame. Glad you enjoyed the blog! Given your conditions you should be getting good fixes. Are you using a decent ground plane for the antenna? Ublox recommends a 50 to 75 mm square centimeter ground plane, but larger should be OK too. There are more good suggestions for improving your data collection environment in this document from Ublox.

      If that doesn’t help I would suggest downloading the code/configuration files/data from my Github repository and running your data with my code/configuration and vice-versa to determine if the problem is in the data, code, or input configuration.


  2. I made some test with my current setup: 2 Tallysman TW3040 connected to the M8T base receiver (1hz) and to the LEA6T for rover position set at 5 Hz output rate.
    I found some improvements changing the errratio1 from 100 to 300 (even if I don’t completely understand the meaning of this parameter)
    While I found very bad results adding rows:”pos2-arthres1 =0.9999; pos2-arthres2=0.25; pos2-arthres3 =0.1;
    pos2-arthres4 =0.05; since my starting conf file didn’t have them. Very short fix time and very poor ratio value.
    Even for these parameters I don’t know exactly what are affecting. Have you some info about this?

    In the next days I will apply changes to fix the “pos2-arlockcount” bug then recompile for the Raspberry model 2.

    From my experience I noticed that better results exist when low number of satellites are taking into account for ambiguity resolution and then fix-and-hold. Around 6 satellites (good results also with 7 or 8 max).
    Instead to cut down satellites with SNRmask filter could it be possible to process only the best 6-7 satellites with best SNR? May I’m wrong?
    I’m an electronic engineer but I’m not an expert about GNSS.


    1. Hi generaldin. Eratio1 is a user estimate of the ratio of standard deviations of pseudorange errors to carrier‐phase errors. My understanding is that increasing this number causes RTKLIB to increase emphasis on the carrier phase measurements over the pseudorange measurements in its updates to the kalman filter.

      arthres1-5 were new with the default config file for 2.4.3 release. None of them are used by the code however and it should not make any difference what these values are set to.

      In general, the more high quality satellite signals used for ambiguity resolution the better since it increases the confidence in the solution, but I agree that excluding lower quality signals can be important since a single bad satellite can prevent a fix no matter how many good satellites you have. The SNRmask filter can help with this with the existing code.

      I have also had some success with experimental code I have been playing with that qualifies each new satellite before adding it to the fixed solution set. Satellites are not qualified if they break or severely degrade the AR ratio and are re-qualified at specified intervals to catch satellites that have degraded. I hope to write a post on this once I’ve had a little more time to work out the details.


    1. Sorry … I don’t know why the link isn’t working, it’s supposed to be shared for anyone. You can find all the raw data at my github page in the demo1/data in the demo1/data/demo1 folder. The complete .conf config file is there as well.


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 )

Google+ photo

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

Connecting to %s