RTKLIB on Raspberry Pi

High accuracy GNSS positioning has always been associated with expensive commercial solutions. So I was pretty thrilled when I first heard about RTKLIB. Developed for the past seven years by Tomoji Takasu, RTKLIB is a free open source software for GNSS data processing. It has an impressive list of features, decoding of multiple formats (including the latest RTCM 3.2), NTRIP support, multiple constellations support, post processing and real-time processing ranging from single point positioning to RTK to PPP.

A great thing about RTKLIB is that it is highly portable. It is written in standard C and can be compiled on many different operating systems and platforms, including the hugely popular Raspberry Pi. Run the free RTKLIB on a fifty bucks Raspberry Pi connected to a low cost GNSS board (such as the u-blox LEA-xT series), now you have access to centimetre level positioning without the thousands of dollars price tag.

Compiling RTKLIB on Raspberry Pi

The RTKLIB suite consists of a dozen programs which can be grouped into those with graphical user interface (GUI) and those with command line interface (CLI). The GUI programs run on Microsoft Windows only but the CLIs can be compiled to run on other operating systems and hardware platforms including the Raspberry Pi. I use Raspbian (Wheezy) on the RPi here.

The complete source package of RTKLIB (rtklib_<ver>.zip) can be downloaded from rtklib.com. The CLI program that does real-time positioning is called RTKRCV. Unzip the package and locate the source code for RTKRCV in rtklib_<ver>\app\rtkrcv. Navigate to the gcc directory underneath it.

cd rtklib_2.4.2/app/rtkrcv/gcc

The makefile can be used out of the box but if you prefer you can customise it. Raspberry Pi has a pretty slow CPU so I added several compile options in a – probably vain – attempt to optimise RTKRCV for the RPi. Edit the makefile and modify the CTARGET line to include the options below. Keep the existing options.

CTARGET = -march=armv6 -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -ffast-math

Now run ‘make’ to build RTKRCV. Go and get coffee.

The install routine in the makefile will copy the rtkrcv binary into /usr/local/bin. Personally, I just setup a separate directory for RTKRCV in my home directory and keep all related files in there.

sudo mkdir ~/rtkrcv
sudo cp rtkrcv ~/rtkrcv
sudo cp *.sh ~/rtkrcv
sudo cp ../*.conf ~/rtkrcv

Test that the build was completed properly by running RTKRCV.

cd ~/rtkrcv

RTKRCV might complain about missing options file and navigation data but you will get to its console like below.

Configuring RTKRCV

RTKLIB is highly configurable and there are numerous options in RTKRCV which makes setting it up pretty daunting. For my initial test, I wanted to see RTKRCV solving RTK solutions, the most accurate solution possible. There are too many options to discuss here but you can download this zip file (rtkrcv) which includes the RTKRCV binary and two configuration files, single.conf (for single point positioning) and rtk.conf. Obviously you will need to change the connection settings to match your equipment.

When running, RTKRCV goes into console mode from which you can issue a number of commands. You may need to memorise the commands if you are going to use RTKRCV regularly. Alternatively, for most applications, these would be scripted. In the screenshot below, I started rtkrcv, loaded a config file (rtk.conf), restarted it to enable the new config file and then asked it to show the solutions. The fix solution was obtained within 4 seconds and you can see the accuracy increasing immediately from metre level to centimetre level.

A bunch of numbers are not that fun to look at so I used RTKPLOT (part of RTKLIB) running on a separate Windows PC to connect to the Raspberry Pi and plot the coordinates computed by RTKRCV. The plot below shows two instances of RTKRCV running. The green dots (Number 1) are the RTK solutions while the red dots are the standard single point solutions.

We can zoom into the green dots (RTK solutions) to see what sort of accuracy they have. As you can see from the plot below, the coordinates produced are within 2 cm.


GPS/GNSS board to use

Okay, so it is fun to have a free RTK software running on cheap and small computer but a suitable GPS/GNSS board is still needed to make the actual raw measurements. Things get tricky here. There are no shortage of cheap and small modules that produce coordinates but there are very few that would produce raw measurements suitable for processing by RTKLIB. I mentioned earlier the timing series board from u-blox. You can buy an evaluation kit from u-blox for $349. Alternatively, you might want to try the RasPiGNSS expansion board. It is around $200 and you can attach it directly to the Raspberry Pi.

These products track single frequency only. If you want cm-level accuracy within seconds like the example above, dual frequency tracking is needed. This is where it gets expensive. An L1/L2 board like the Trimble BD920 has a list price of around $1,200.

46 thoughts on “RTKLIB on Raspberry Pi

  1. Hi Thomas,
    thank you for mentioning our RasPiGNSS expansion board in your blog. Please note (and correct) that the expansion board is in fact providing code and high quality phase measurements at a very competitive price. We are using it for our PiGNSS product (see: pi-gnss.com) routinely achieving cm-accuracies with RTK and dm-accuracies with PPP (word-wide with minimal effort)!
    Best regards,
    – Raoul

  2. Hi Thomas,
    I had a question for you. I am relatively new to raspberry pi and in fact computing itself. I want to get rtk signals on a drone to be used for precision agriculture. It seems that this is the lightest/ easy route. As far as my knowledge guides me, you need 2 gps modules. I am planning to use one as a ground station and the other as a rover on the drone. On the top of my head, I plan on putting the raspberry pi and one gps on the drone and using a high speed data transmitter to get the data from the base station gps, calculating the gps position on the drone in real time and sending that to the flight controller for correction.

    My question is, how would the raspberry read the raw carrier phase data coming from both the gps? (via usb?) Also, does this situation sound realistic in your opinion? You mentioned raspberry pi being too slow. I was thinking of using the beaglebone black instead.

    Let me know what you think

    Thanks in advance

    – Rai Gohalwar

    1. Rai, it depends on what sort of interface is on the GPS/GNSS board you use. The u-blox board I mentioned has USB. The RasPiGNSS board uses the Pi’s expansion connector. The Trimble BD900 board has RS-232, USB and Ethernet. Your proposed application is pretty common. The Pi is powerful enough to run RTKLIB. But keep in mind that if you want RTK-level performance (1 cm within a few seconds) you really need dual-frequency board and they are fairly expensive.

      1. Thomas,
        Does the NEO-M8T or similar Modules support Dual frequency? The data sheet says it does glonass and GPS at the same time, and mentions Dual frequency; but you mention that the units that support that are much more expensive? Would you recommend those modules for high accuracy? Or the Trimble unit?

        Also, in my application I need a middle man between my base station and rover, is there a time limit that the correction data needs to reach the rover by?
        Topology like this :
        (RTKBaseStation GroundStation RTKRover)

        1. I don’t think so and I don’t see any mentions of dual frequency on the product summary sheet. The Trimble unit will definitely produce higher accuracy. As for latency, the maximum threshold depends on the rover’s firmware/software. For 1 Hz application you’d ideally want latency of less than one second but most rovers I’ve come across work fine with 2-3s latency.

  3. Hi Thomas,
    I compiled rtkrcv.exe by cygwin. And I am trying to run it. But there is an error msg like:
    $ ./rtkrcv.exe -s
    statup script ok
    rtk server start error

    I’ve modified some items such as inpstr1-path, inpstr1-format, and file-cmdfile1 in rtkrcv.conf. Is there anything I missed?
    Any help will be appreciated.

    Best Ragrads,

      1. Hi Thomas,
        I couldn’t find “rtkrcv.exe” in “rtklib_2.4.2>bin.” So I tried to compile “rtkrcv.exe” in “rtklib_2.4.2>app>rtkrcv.” But I didn’t success. There were many error messages. ( I used “start>command prompt.” ) So I asked someone else to compile this “rtkrcv.exe” for me. And he used cygwin to compile. So I have to use cygwin to execute. I was wondering if you could tell me how to generate the “rtkrcv.exe” or where to find win32. I would really appreciate that.

        Best Regards,
        – Annie

        1. Hi Annie, you’re right actually. I thought it was included but it looks like only the binary Windows GUI programs are included. I’m not sure why it didn’t run under your Cygwin, I haven’t tried Cygwin myself. Windows uses different socket library so you might want to check that? Alternatively you can always use RTKNAVI but I suppose you have certain requirement for CLI?

  4. Hi Thomas,

    Do you mind explaining why I need dual frequency ( l1 l2) receiver modules for rtk. I have been doing a lot of research and haven’t anywhere else read that this is required. I am sure it will help get a faster gps lock, but I can’t really find one for cheap. I saw the ashtech mb100 or their other line of gps receiver modules but they are very expensive. DO you not think using the ublox 6t , 6p, 7p, m8f, or something cheaper like 4t or 5t would get the RTK working.

    Thanks in advance
    – Rai

    1. Hi Rai, using two frequencies allows several error sources to be cancelled instantly. With only one frequency this is more difficult. You can search on Google for ‘single frequency RTK’ to find papers on the current possible performance.

  5. Hi Thomas,

    I´m actually working in a GNSS RTKLib station using the str2str in a laptop (base) and the rtkrcv in a drone (rover). The rtkrcv worked fine in a Roboard Mini-PC, but I changed it to a Raspberry Pi where I have found the following problem: RTK FIX is achieved and position is correct but velocities have an error whose mean is constant and non-zero. Relative position and velocities movements are shown correctly, but over the constant velocity error. Any idea??

    Thanks in advance and congratulations for your work!


    1. Hello :
      I use two Ublox lea-6t to testing RTKLIB on PI,First,I use one for base station,I use str2str to transfer data from UBX to RTCM3 the command is :
      ./str2str -in serial://ttyUSB0:115200:8:n:1:off#ubx -out serial://ttyAMA0:115200:8:n:1:off#rtcm3
      from the screen I can see the data is send out.Then I use another as rover station,in the config file I set the right inpstr2-type/path,and fromat is rtcm3. I run the rtkrcv on the rover station,after 20 minutes the solution is single ,I can’t get float or fix solution.what’s wrong?
      I think the problem is str2str command,the rover station can’t get the right base station,because I didn’t use RTKLIB before so I don’t know How to slove it.Can you tell me?

  6. Hi Thomas,

    I am new with RaspberryPi and I need to use it for a school project. I want to use RTKLIB 2.4.2 on my RaspberrPi but I currently lost and do not have a single idea on how to use it. I am looking through your tutorial and following it but I am stuck at the “run ‘make'” section. Can you explain to me this and how do I “run ‘make'”? I am a beginner at this and I hope that you can help me.

    Thank you.

    1. Hi Syafiq, after changing the current directory to rtklib_2.4.2/app/rtkrcv/gcc simply type ‘make’ from the command prompt. If you are using the Raspbian distribution like I do, the ‘make’ utility is already installed. It will compile rtkrcv based on the instructions specified in the ‘makefile’ file and produce the binary.

  7. Hi Thomas,

    Can you check what velocities you get in FIX/FLOAT solution, please? You can see it using for example “rtkrcv> status 1”. Moreover, do you use a special parameters configuration?

    I’m very stressed with the strange behaviour that I commented you in the last message.

    Thanks in adveance!

    1. Hi Ricardo, my equipment setup is static (the rover is not moving) and I get 0.000, 0.000, 0.000 for vel enu (m/s) rover. My configuration is pretty generic. If there’s any particular parameter you’d like me to check just let me know.

  8. hi thomas
    how can we fix the command line ” no navigation data: rtkrcv.nav” i cant find the file rtkrcv.nav in any folder.
    Thank you so much

    1. Hi Duy, just make sure ephemeris stream is available to RTKLIB. From memory that file will be created automatically once RTKLIB connects to the ephemeris stream.

  9. Hello

    I want to implement this RTKLIB on STM32 for making standalone system, but I want to know that how to use C programming files on my STM. I want to take input RAW data from serial port and output in form on NMEA or RTCM v3.x. Kindly answer me.

  10. Hi to everybody,

    Congratulations Thomas, the post is very clear. Only one question ¿Does anybody know why once the server is correctly started when I type ‘solution’ command it is not shown any text on the screen?¿Is there any fact that causes that? I am a begginer in the linux environment and I think that I could not be able to understand very advanced info. I am trying to integrate the rtklib in a raspberry pi.

    Thank you!

      1. Yes I did. The fact is that all seems to work properly until I want to get the solutions. Also, when I connect the GPS module to a Windows computer and I can receive all the data without problems with the rtknavi app. Now I’m trying to finish the project with a microstack gps module, but if anyone has any idea about the problem above mentioned (with the ublox GPS module) please tell me.

  11. Hi Thomas!

    A short question about the Articel. It’s very interesting.
    Are these solutions made with a Trimble BD920 receiver?
    For these application two BD920 receivers and the RTKlib are necessary?
    Is this right?
    Which antennas are used?

    Thanks for your help!

    1. Hi Otti, Ferro,

      Not a BD920 but similar type (dual frequency carrier phase). Yes, you need two receivers to do differential/RTK. I used geodetic-grade antennas, can’t remember exactly which now, might’ve been a Trimble Zephyr Geodetic II.

  12. Hello Thomas,

    first of all, thank you for taking your time to provide us with all this information!

    You mentioned that you need dual frequency modules for 1cm in 1s accuracy. This is opposed to 2cm/s accuracy with a single frequency, judging from the plot of your RTK solution? Or does that only count when the GPS module is not moving?

    Also, you used RTK with a single GPS module on a Pi? Could you imagine achieving similar-to-dual-frequency results by using two single-frequency modules in a rover with fixed base setup? Or am I mistaken, and you did use two modules for RTK in your example?


    Best regards,

    1. Hi Andreas,

      The typical accuracy for commercial RTK software is around 10mm +/- 1ppm. This is for a base and rover setup (a pair of dual-frequency GPS/GNSS receivers). That’s the setup I used. I haven’t come across the accuracy specs for RTKLIB but I’d think it’d be similar.

      I don’t think you can use two single-frequency receivers for a rover because you’d then double the source of errors (eg. clock error). I also haven’t come across any modules that track L2 only. Interesting idea though.

  13. Hello Thomas :
    I use two Ublox lea-6t to testing RTKLIB on PI,First,I use one for base station,I use str2str to transfer data from UBX to RTCM3 the command is :
    ./str2str -in serial://ttyUSB0:115200:8:n:1:off#ubx -out serial://ttyAMA0:115200:8:n:1:off#rtcm3
    from the screen I can see the data is send out.Then I use another as rover station,in the config file I set the right inpstr2-type/path,and fromat is rtcm3. I run the rtkrcv on the rover station,after 20 minutes the solution is single ,I can’t get float or fix solution.what’s wrong?
    I think the problem is str2str command,the rover station can’t get the right base station,because I didn’t use RTKLIB before so I don’t know How to slove it.Can somebody tell me?

  14. Hello.
    I successfully run RTKRCV version 2.4.3 in ‘single mode’ on Raspberry Pi 2 (Raspian / Jessie). I used the GPS u-blox LEA-4T. Before compilation, I have not changed existing options CTARGET. I changed the settings in the file ‘rtkrcv.conf’ and works well.
    Thank you for your help.

  15. Hi Thomas Yan,

    thank you for sharing the link with the compatible devices.
    I bougth a NVS device (RasPiGNSS) which is compatible to the Raspberry Pi models. I installed everthing and now I have a base station and mobile unit for my robots up and running.

    It makes a lot of fun to use presice GPS data for navigation.

    Best Regards,


  16. Hi Thomas,
    I installed RTKLIB in raspberry. Unfortunately, i had a rtk server start error only when loading rtkrcv.conf. Everything is going fine for both single.conf and rtk.conf . However, the solution can not be shown.
    I figure out that the single.conf is in running mode but there is no status for solution.
    i tried to change the options in single.conf or to use other .conf files even installing differents versions of rtklib but i had always the same problem, so please can you help me resolving it.
    Thank you for help.
    Best regards,

  17. Hello!

    I am trying to do this with 2x Neo M8T and A 433 Mhz Radio Telemetry kit (SiK radio) on a Raspberry Pi 3. Could you, please, suggest what configurations should I choose to make it work? I am banging my head against the wall for 2 weeks already and cannot make it.

    Thanks in advance!
    Jivomir Arnaudov

  18. Hello, everyone!

    I am currently doing a university project and my goal is to find the position of a rover in real time.

    My set up is the following: 2x NEO M8T boards connected to a Raspberry Pi 3 (updated to latest version GNU/Linux 8).

    The reason that they are both connected to the Pi is that I am not sure that my SiK telemetry transmits anything as even in RTK Navi on a laptop I don’t get base station data. (the radios are matched)

    The M8Ts are set to 115000 baud rate by using u-center (latest version). NMEA messages are turned off and UBX messages are turned on.

    I installed the latest version of RTKLIB from tomojitakasu’s github on the Pi. Ran make in the rtkrcv folder.
    Ran chmod +x rtkstart.sh and chmod +x rtkshut.sh as it wanted permissions.

    Started rtkrcv with sudo ./rtkrcv

    I get “invalid option value pos-1snrmask” but the program still runs.
    I run a conf file which I created but I DONT KNOW if it is correct.

    It says “startup script ok” “rtk server start error” and thats it… nothing else.
    The conf file I use is as following:
    # RTKRCV options for RTK (2014/10/24, tyan)

    console-passwd =admin
    console-timetype =gpst # (0:gpst,1:utc,2:jst,3:tow)
    console-soltype =dms # (0:dms,1:deg,2:xyz,3:enu,4:pyl)
    console-solflag =1 # (0:off,1:std+2:age/ratio/ns)
    ## Specify connection type for Rover (1), Base (2) and Correction (3) streams
    inpstr1-type =serial # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
    inpstr2-type =serial # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
    ##inpstr3-type =serial # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
    ## Specify connection parameters for each stream
    inpstr1-path = ttyACM0:115200:8n:1off
    inpstr2-path = ttyACM1:115200:8n:1off
    ##inpstr3-path =
    ## Specify data format for each stream
    inpstr1-format =ubx # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:sp3)
    inpstr2-format =ubx # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:sp3)
    ##inpstr3-format = # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:sp3)
    ## Configure the NMEA string to send to get Base stream. Required for VRS.
    inpstr2-nmeareq =off # (0:off,1:latlon,2:single)
    inpstr2-nmealat =0 # (deg)
    inpstr2-nmealon =0 # (deg)
    ## Configure where to send the solutions
    outstr1-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
    outstr2-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)

    ## Specify here which stream contains the navigation message.
    misc-navmsgsel =corr # (0:all,1:rover,1:base,2:corr)
    misc-startcmd =./rtkstart.sh
    misc-stopcmd =./rtkshut.sh
    ## Set the command file to send prior to requesting stream (if required)
    file-cmdfile1 =/home/pi/rtklib/app/rtkrcv/gcc/m8t.cmd
    file-cmdfile2 =/home/pi/rtklib/app/rtkrcv/gcc/m8t.cmd
    ## file-cmdfile3 =
    pos1-posmode =static # (0:single,1:dgps,2:kinematic,3:static,4:movingbase,5:fixed,6:ppp-kine,7:ppp-static)
    pos1-frequency =l1 # (1:l1,2:l1+l2,3:l1+l2+l5)
    pos1-soltype =forward # (0:forward,1:backward,2:combined)
    pos1-elmask =15 # (deg)
    pos1-snrmask_L1 =0 # (dBHz)
    pos1-dynamics =off # (0:off,1:on)
    pos1-tidecorr =off # (0:off,1:on)
    pos1-ionoopt =brdc # (0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec)
    pos1-tropopt =saas # (0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad)
    pos1-sateph =brdc # (0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom)
    pos1-exclsats = # (prn …)
    ## Set which GNSS to use. 1 is GPS only, 4 is GLONASS only. Add codes for multiple systems. Eg. (1+4)=5 is GPS+GLONASS.
    pos1-navsys =7 # (1:gps+2:sbas+4:glo+8:gal+16:qzs+32:comp)
    ## Ambiguity Resolution mode, set to continuous to obtain fixed solutions
    pos2-armode =fix-and-hold # (0:off,1:continuous,2:instantaneous,3:fix-and-hold)
    pos2-gloarmode =off # (0:off,1:on,2:autocal)
    pos2-arthres =3
    pos2-arlockcnt =0
    pos2-arelmask =0 # (deg)
    pos2-aroutcnt =5
    pos2-arminfix =10
    pos2-slipthres =0.05 # (m)
    pos2-maxage =30 # (s)
    pos2-rejionno =30 # (m)
    pos2-niter =1
    pos2-baselen =0 # (m)
    pos2-basesig =0 # (m)
    out-solformat =llh # (0:llh,1:xyz,2:enu,3:nmea)
    out-outhead =on # (0:off,1:on)
    out-outopt =off # (0:off,1:on)
    out-timesys =gpst # (0:gpst,1:utc,2:jst)
    out-timeform =tow # (0:tow,1:hms)
    out-timendec =3
    out-degform =deg # (0:deg,1:dms)
    out-fieldsep =
    out-height =ellipsoidal # (0:ellipsoidal,1:geodetic)
    out-geoid =internal # (0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000)
    out-solstatic =all # (0:all,1:single)
    out-nmeaintv1 =0 # (s)
    out-nmeaintv2 =0 # (s)
    out-outstat =off # (0:off,1:state,2:residual)
    stats-errratio =100
    stats-errphase =0.003 # (m)
    stats-errphaseel =0.003 # (m)
    stats-errphasebl =0 # (m/10km)
    stats-errdoppler =1 # (Hz)
    stats-stdbias =30 # (m)
    stats-stdiono =0.03 # (m)
    stats-stdtrop =0.3 # (m)
    stats-prnaccelh =1 # (m/s^2)
    stats-prnaccelv =0.1 # (m/s^2)
    stats-prnbias =0.0001 # (m)
    stats-prniono =0.001 # (m)
    stats-prntrop =0.0001 # (m)
    stats-clkstab =5e-12 # (s/s)
    ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm)
    ant1-pos1 =0 # (deg|m)
    ant1-pos2 =0 # (deg|m)
    ant1-pos3 =0 # (m|m)
    ant1-anttype =
    ant1-antdele =0 # (m)
    ant1-antdeln =0 # (m)
    ant1-antdelu =0 # (m)

Leave a Reply

Your email address will not be published. Required fields are marked *