Using SSR corrections with RTKLIB for PPP solutions

If you have been following recent announcements in precision GNSS, you may have been hearing a lot about SSR (State State Representation).  SwiftNav recently announced their Skylark corrections service, and u-blox announced a partnership with Sapcorda to provide correction service for their upcoming F9 receivers.  Both of these services are based on SSR corrections.

So, what is SSR?  Very briefly, it refers to the form of the corrections.  In traditional RTK with physical base stations or virtual reference stations (VRS), the corrections come in the form of observations in which all of the different error source are lumped together as part of the observation.  This is referred to as OSR (Observation Space Representation).  In SSR corrections, the different error source (satellite clocks,  satellite orbits, satellite signal biases, ionospheric delay, and tropospheric delay) are modeled and distributed separately.  There are many advantages to this form but what seems to be driving industry towards it now is that it allows the current VRS model where each user requires a unique data stream with observations tailored for their location to be replaced with a single universal stream that can be used by all observers.  This is a requirement if the technology is going to be adopted for the mass-market automotive industry for self-driving cars, since it is not practical to provide every car with it’s own data stream.

For more detailed information on SSR, Geo++ has a one page summary here and IGS has an 18 minute video presentation on the topic here.  Both are excellent.

Below is an image I borrowed from the IGS presentation which shows the flexibility of the SSR format.  It is intended to show how the same SSR data stream can be used globally for PPP quality corrections and also regionally for RTK quality corrections but it is also a good visual for understanding the message details I describe below.


The RTCM standards committee is still in the process of finalizing the messages used to send the different correction components.  They have split the work into three phases.  Phase 1 includes the satellite clock, orbit, and code biases.  Phase 2 includes satellite phase biases and vertical ionosphere corrections, and phase 3 includes ionospheric slant corrections and tropospheric corrections.

There are several real-time SSR streams accessible for free today.  Unlike the paid services, they do not contain enough detailed regional atmospheric corrections to use as a replacement for a VRS base but they can easily be used for static PPP solutions.

I used the CLK93 stream from CNES for an experiment to test how well RTKLIB handled the SSR corrections.  It includes the Phase 1 and Phase 2 RTCM messages but not the Phase 3 messages.  Here is the format of the the messages in the CLK93 data stream:


You can register for free access to the CLK93 (and other) streams from any of these locations:

Unfortunately, RTKLIB currently only supports the Phase 1 RTCM messages and even this is not complete in the release version.  I have gone through the code and made a few changes to make the Phase 1 SSR functional and have checked those changes into the demo5 Github repository.  I also added some code to handle the mixed L2 and L2C observations from the ComNav and Tersus receivers.  After a little more testing I plan to release this code into the demo5 executables, hopefully in the next week or two.

With only phase 1 measurements, the RTKLIB PPP solutions will work much better with dual frequency receivers than with single frequency receivers.  This is because single frequency receivers require ionospheric corrections for longer baselines.  For this reason, I did not bother with collecting any single frequency data.  Instead, I collected both L1/L2C data with a Swiftnav Piksi Multi receiver and L1/L2/L2C data with a ComNav K708 receiver and a Tersus BX306 receiver.

RTKLIB is usually used to calculate PPP solutions without SSR corrections but this requires downloading multiple correction files for orbital errors, clock errors, and code bias errors and it is usually done with post-processing rather than real-time, after the corrections are available.  With SSR, the process is simpler because the solution can be done real-time and there is no need to download any additional files.  It does, however, require access to the internet to receive the real-time SSR data stream from an NTRIP caster.  The solution can be calculated real-time or the SSR corrections and receiver observation streams can be recorded and the solution post-processed.

To enable the use of SSR corrections in RTKLIB, you need to set the “Satellite Ephemeris/Clock (pos1-sateph) input parameter to either “Broadcast+SSR APC” or “Broadcast+SSR CoM”.  Note that CoM stands for Center of Mass and APC for Antenna Phase Center.  They refer to the reference point for the corrections.  The CLK93 corrections are based on antenna phase centers.

To generate my PPP solution I set the solution mode to “PPP-Static”,  ephemeris/clock (pos1-sateph) to “brdc+ssrapc”, ionosphere correction (pos1-ionopt) to “dual-freq”, and troposphere correction (pos1-tropopt) to “est-ztd”.  I also enabled most of the other PPP options including  earth tides,  satellite PCVs, receiver PCVs, phase windup, and eclipse rejection.

RTKLIB PPP solutions don’t support ambiguity resolution so the ambiguity resolution settings are ignored.  I specified the satellite antenna file as “ngs14.atx” which is the standard antenna correction file and is available as part of the demo5 executable package.  I also needed to include the CLK93 data stream as one of the inputs in addition to the receiver observations (and navigation file if post-processing).

I collected a couple hundred hours of observations with the SwiftNav receiver connected to a ComNav AT-330 antenna on my roof with moderately good sky visibility.  I then ran many four hour static solutions over randomly selected data windows.  I also collected a small amount of raw data from a ComNav K708 receiver and a Tersus BX306 receiver.

Below is a typical 12 hour static solution for a SwiftNav and a ComNav receiver.  The SwiftNav solution is in green and the ComNav solution is in purple.  Zero in these plots represents an online PPP solution from CSRS from data collected over a month earlier.  In this particular example, the SwiftNav solution is slightly better but this was not always the case.



Here is a shorter data set from a Tersus BX306 receiver.  With the relatively small amount of Tersus and ComNav data I collected, I did not notice any differences in convergence rates or final accuracy between any of the three receivers.


The solutions generally all converged to less than 6 cm of error in each axis after 4 hours with one or two minor exceptions that seemed to involve small anomalies at the day boundary.  Since the RTKLIB PPP solutions don’t include ambiguity resolution they do take longer to converge but the eventual accuracy should be similar.

I’ve uploaded some of the raw observation data for the different receivers and the CLK93 data stream as well as the config file that I used for the solution here.

This seems like a good start and I hope that RTKLIB will support phase 2 and phase 3 corrections in the future.


27 thoughts on “Using SSR corrections with RTKLIB for PPP solutions”

  1. Hi!
    Just to let you know that the CLK93 stream was renamed
    “SSRC00CNE0 and SSRA00CNE0, instead of CLK90/CLK92 and CLK91/CLK93 respectively (short mountpoint names streams are hidden in the sourcetable but still accessible UNTIL AUGUST 31, 2020). See [IGS-RTWG-232] “


  2. Hello Tim,
    I have been trying to repeat the same actions you described in this post, but without success.
    I am trying to use ComNav receiver with K708 board and your Demo5 b33c version.
    I entered the same parameters as you noted but the Q flag remains Q=5.
    I have even tried to apply the configuration file you uploaded but without success as well.

    What I did wrong?


    1. Hi Andrey. It’s hard for me to guess why this isn’t working for you. My best suggestion would be to download the sample data I used for this demonstration first to verify your setup. If this doesn’t work, then I would suggest downloading the older code as well. It’s always possible that the newer code is somehow broken. If you find this to be the case, let me know and I will investigate.


      1. Dear Tim,

        I have tried to get PPP solution in your latest revision dated May 2020 and it works now!
        I suppose that you have changed something in RTKLib settings and now PPP solution happens after 5-10 seconds after start. In previous versions in the end of March I didn’t came to success in PPP, now it works.
        On the other hand I get more skills in PPP since March, so maybe I do it in right way now, while previously I did some mistake.

        In any case thank you for your application!

        By the way: I can’t find the time counter (in seconds) in the bottom part of application’s window, where GPS time, coordinates and mode are located. I saw this type of a counter in other RTKLib app and I have found that very useful for understanding how many time in which mode the application in (for example: PPP – 120 seconds (10%), single – 1080 seconds (90%).

        It could be great if you can add this feature in your app.



        1. Hi Andrey. The GUI output of the demo5 b33c version of RTKNAVI should be identical or nearly identical to the 2.4.3 version. In both versions you can display elapsed time by clicking on the RTK Monitor button (small square directly above the Stop button). This is a very useful but well hidden feature that can display all sorts of information by changing the menu option of the RTK monitor window in the upper left corner.


          1. Dear Tim,

            After clicking on the RTK monitor button (right above Stop button) in RTKNAVI app there is the separate window appears containing different information.
            I can choose any type of information I need clicking on the button in the upper left corner of RTKPLOT app (the first one is RTK, the second is Obs Data), but no changes in the bottom field of RTKPLOT happens. There is still coordinates with time and Q flag only.
            I would like to have there elapsed time since start in seconds and percentage of time in different modes (Q=6 – 120 seconds (10%), Q=1 – 1080 seconds (90%).

            How I can get this? What I did wrong?



          2. Hi Andrey. I don’t think I fully understand your question. GUI inputs into the RTK monitor window will not affect the RTKPLOT window. You can bring up an RTKPLOT window from RTKNAVI by clicking on the “Plot” button but the real-time RTKPLOT window will not have the full functionality that you get using RTKPLOT on a solution file. The percent times in different Q modes will appear when plotting solution files but not when plotting data in real-time.


    1. Hi Ale. Thanks for tracking this down. I will include your changes in the next release of the demo5 code. In the meantime, anyone that needs Galileo for SSR processing should pull your changes into their code.


  3. Hi Tim. I’ve downloaded the zip file to perform rtcm post-processing and I’m using the last binary version of your application. When I start the post-processing I got the following error: Access violation at address … in module rtkpost.exe.
    If a load the same config file in the official version of rtklib everything works fine.
    Do you experience the same problem with your last version?


    1. Hi Ale. I did see this problem in the RTKLIB demo5 b31 code that was posted from 11/26/18 to 12/2/18 and was related to my switching to a newer version of the Embarcadero compiler. The code posted after 12/2/18 should be OK however. I just now downloaded the executables and ran a solution with RTKPOST to verify this and did not see a problem. I would suggest downloading the code again and if you still see the problem let me know.


      1. Hi Tim, thank you for your reply. Unfortunatly I’m experiencing this problem with both demo31 and demo 30 versions (I’ve downloaded again the bin folders). I’ve investigated a bit and I have discovered that rtkpost produces this error only when setting the option “Satellite Ephemeris/Clock” to Broadcast+SSR Com or APC.


        1. Hi Tim, it seems that the problem is due to Galileo option. If I disable that constellation rtkpost works fine. In the next days I will debug the code to see why this happens.

          I have another question: I’ve seen that if I set the option “Frequencies” to L1 or L1+L2, and so on, I get the exact same output files (I’m using a dual frequency Ublox F9). When using RTCM, does the program consider only L1?


  4. You mention that one could get the CLK93 stream from CDDIS. But seems to share through HTTPS/SSL port 443 only. Does RTKLIB handle SSL NTRIP ? Or can you use alternate NTRIP clients like BKG?


    1. Answering my own question: Yes, you can use the BKG BNC NTRIP Client to pull from CDDIS’s stream, but it’s awkward. You have to re-publish the raw (RTCM3) output on a TCP port through BNC’s ‘Miscellaneous’ menu, and then pull the corrections into RTKNAVI Inputs as a Correction / TCP server / options =localhost & port.

      Also, you can monitor the correction stream in RTKNAVI in the monitor “RTCM SSR/(3) Corrections” window.


  5. Thank you so much for great contents…

    I want to establish Real Time PPP with RTKnavi, but I have a problem. Is it possible to use RT-PPP for a station that its observations are exists in casters? I use CUT07 station for testing RTKnavi for RT-PPP. I introduce it as rover station and use RTCM3EPH as input stream correction. ( I even use IGS03 too). but nothing happen.
    in Error/warning section the “no obs data” is depicted. I change the station but nothing happen. Would you please help me?


    1.         Yes, you can do real-time PPP using an NTRIP stream from a CORS station.  I would recommend including SSR corrections as I describe in <a href="">this post</a> using the demo5 version of RTKLIB.      


  6. This is a great site to learn about RTK positioning. The data and experiments are always very interesting. I am starting to look at some RTK data. I was surprised that very little information is available online related to the .osr data format. Any suggestions of a tool to read/view/convert such data files will be very helpful. I can’t find any after an exhausting web search.


  7. Interesting. Ive seen some of the stuff already, but from what I understand for cm precision regional corrections are still needed even with SSR. This also means there needs to be a newtork of base stations where do these corrections derive from. The only improvement of regional SSR over traditional VRS (OSR) that I see is somewhat lower bandwidth. Is that correct? The bandwidth of traditional VRS may not really be an issue though until a really globally mass-scale adoption of autonomous vehicles takes place, which may be decades away. Current LTE networks will probably be able to handle many VRS streams in the same area. I logged a VRS observations during a 2 hour drive and only 3 packets were lost from a ping that run each second.

    Liked by 1 person

    1. Hi Kozuch. Much of what you say is true. Regional ionospheric corrections are probably necessary for single frequency solutions or kinematic dual frequency solutions but I find the global SSR streams like CLK93 that are available for free are useful for real-time static PPP solutions with a dual frequency receiver.


  8. Ok. Just tried it with the stream from CDDIS for CLK93 stream. Question is how to you set up the input files for that option.



      1. Thanks for posting the updated info on using the M8T. Now not so curious about testing it out for now. The problem I was having was the actual connection to the CDDIS server, couldn’t get the data stream. Do I need the ssl certificate in the same folder as rtklib?


  9. Thank you for the explanation of SSR. I was wondering what that was when I was compiling testing rtkrcv executable with the latest demo5 code.

    From the brief read above, it should kind of work with a Ublox m8n or m8t as well if I just wanted to test it. To be honest, things like the switfnav and comnav are a little out of my price range 🙂 maybe the F9 will be better, I doubt it.


    Liked by 1 person

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: