Wednesday, December 16, 2015

Acquiring GPS signals with an RTLSDR dongle using gnss-sdr

Once you've installed gnss-sdr and tested your installation with prerecorded data, the next step is to try and get a live GPS solution. The following is based off this node at and this paper. The paper is a really good mix of theory and implementation and I strongly recommend reading it.

The first thing you need to do is calibrate the front end of your RTL-SDR device. The calibration procedure will do the following
  1. Download an ephemeris via SUPL. This provides your computer with advance knowledge of the GPS satellite locations, allowing you to get a quick fix.
  2. Search for GPS satellites
  3. Calculate the doppler shift assuming your RTL-SDR stick is perfect (trust me, it's not!)
  4. Using the predicted doppler shift and some fancy math (see the paper, section 5), calculate
    1. The actual sampling frequency
    2. The actual IF bias

Before running the calibration you need to update the front-end-cal.conf. Make a copy of the version installed (typically to /usr/local/share/gnss-sdr/conf/front-end-cal.conf). On the first couple of lines you will see a number of GPS lat/lon/alt locations commented out using a semicolon. You need to provide your best estimate at lat/lon/alt, bearing in mind altitude is in meters. The easiest way to do this is use a tool like the aptly named The other change I had to make was to change both SUPL servers to in place of - for some reason the nokia servers were not working. Once complete, you can run the front end calibration like so 

sudo front-end-cal --config_file=/path/to/my/front-end-cal.conf

Your output should look something like this
linux; GNU C++ version 4.9.1; Boost_105500; UHD_003.007.003-0-unknown
Initializing... Please wait.
Logging will be done at /tmp
Use front-end-cal --log_dir=/path/to/log to change that.
Trying to read ephemeris from SUPL server...
SUPL: Trying to read GPS ephemeris from SUPL server...
SUPL: Received Ephemeris for GPS SV 1
SUPL: Received Ephemeris for GPS SV 2
SUPL: Received Ephemeris for GPS SV 3
SUPL: Received Ephemeris for GPS SV 5
SUPL: Received Ephemeris for GPS SV 6
SUPL: Received Ephemeris for GPS SV 7
SUPL: Received Ephemeris for GPS SV 8
SUPL: Received Ephemeris for GPS SV 9
SUPL: Received Ephemeris for GPS SV 10
SUPL: Received Ephemeris for GPS SV 11
SUPL: Received Ephemeris for GPS SV 12
SUPL: Received Ephemeris for GPS SV 13
SUPL: Received Ephemeris for GPS SV 14
SUPL: Received Ephemeris for GPS SV 15
SUPL: Received Ephemeris for GPS SV 16
SUPL: Received Ephemeris for GPS SV 17
SUPL: Received Ephemeris for GPS SV 18
SUPL: Received Ephemeris for GPS SV 19
SUPL: Received Ephemeris for GPS SV 20
SUPL: Received Ephemeris for GPS SV 21
SUPL: Received Ephemeris for GPS SV 23
SUPL: Received Ephemeris for GPS SV 24
SUPL: Received Ephemeris for GPS SV 25
SUPL: Received Ephemeris for GPS SV 26
SUPL: Received Ephemeris for GPS SV 27
SUPL: Received Ephemeris for GPS SV 28
SUPL: Received Ephemeris for GPS SV 29
SUPL: Received Ephemeris for GPS SV 30
SUPL: Received Ephemeris for GPS SV 31
SUPL: Received Ephemeris for GPS SV 32
SUPL: Trying to read Acquisition assistance from SUPL server...
Actual RX Rate: 2000000.000000 [SPS]...
Actual RX Freq: 1575420000.000000 [Hz]...
PLL Frequency tune error 0.000000 [Hz]...Actual RX Gain: 40.200000 dB...
Front-end RAW samples captured
Using Volk machine: sse4_2_64_orc
Searching for GPS Satellites in L1 band...
[ . . . . 5 . 7 8 9 . . . . . . . . . 19 . . . 23 . . . 27 28 . 30 . . ]
Total signal acquisition run time 2.73478 [seconds]
Reference Time:
GPS Week: 851
GPS TOW: 276680 22134.400000
~ UTC: Tue Dec 15 20:51:21 2015
Current TOW obtained from SUPL assistance = 276680
Doppler analysis results:
SV ID Measured [Hz] Predicted [Hz]
5 3000.00 871.77
7 2875.00 524.39
8 2500.00 170.24
9 1125.00 -1220.17
19 6000.00 3734.82
23 -750.00 -3032.99
27 687.50 -1703.53
28 4375.00 2306.86
30 3750.00 1621.38
Parameters estimation for Elonics E4000 Front-End:
Sampling frequency =1999997.27 [Hz]
IF bias present in baseband=2151.87 [Hz]
Reference oscillator error =-1.37 [ppm]
Corrected Doppler vs. Predicted
SV ID Corrected [Hz] Predicted [Hz]
5 848.13 871.77
7 723.13 524.39
8 348.13 170.24
9 -1026.87 -1220.17
19 3848.13 3734.82
23 -2901.87 -3032.99
27 -1464.37 -1703.53
28 2223.13 2306.86
30 1598.13 1621.38GNSS-SDR Front-end calibration program ended.

The important outputs are highlighted above, the sampling frequency and the IF bias. The sampling frequency is nominally 2 MHz but deviation of a few Hz are normal. Baseband is defined as 0 Hz, so when the signal is shifted to baseband if the signal is not exactly centered at 0 Hz this bias is calculated as an IF bias. 

To receive GPS, then, we can copy the gnss-sdr_GPS_L1_rtlsdr_realtime.conf file (typically located in /usr/local/share/gnss-sdr/conf) to another directory and make a few edits. Handily enough there are comments in the file like this

; i.e. using front-end-cal as reported here:

at each place we need to make an edit. The four edits you need to make are

GNSS-SDR.internal_fs_hz=(your sampling frequency)
SignalSource.sampling_frequency=(your sampling frequency)
InputFilter.sampling_frequency=(your sampling frequency)
InputFilter.IF=(your IF bias)

Once complete, you can run the receiver 

gnss-sdr ---config_file=/path/to/your/gnss-sdr_GPS_L1_rtlsdr_realtime.conf

It will likely take a minute or two to get a fix as a certain amount of ephemeris and almanac data must be downloaded from the satellites. You also must have at least four satellites in view. Here is example output once a fix was found:

Using the KML file generated by gnss-sdr I was able to plot the locations generated in Google Earth

The red dots are individual position fixes. The blue arrow points to the skylight where my GPS antenna is mounted. The road is a two-lane road with no shoulder and the boat in the backyard is 20' long. There is a bias which may be due to the fact that the roof occludes satellites to the east (the four satellites I picked up were, at the time, overhead and eastward). I want to move the antenna up to a (plastic) roof vent in the attic to get a better view of the sky.


  1. Hello Philip,

    Thanks for the very interesting post. I have been trying in the past to acquire GNSS signals using RTL-SDR without success.

    I would like to ask you which RTL-SDR dongle you are using and which antenna you are using. I have used an active GPS antenna and I have modified the dongle to bias the antenna and I have not succeeded to detect a GPS satellite :-(.

    I have tested my setup using the software, but I could not get any solution.

    Could you give me any recommendation?


  2. I am using an RTLSDR with the 1ppm TXCO (similar to with the bias tee mod and a generic GPS patch antenna (similar to ). Have you tried using gnss-sdr? the ./front-end-cal script will try to get a snapshot of the GPS constellation and will give you an idea if your configuration is working. Also try receiving terrestrial radio with a whip antenna to ensure your RTLSDR is working properly.

  3. Hi Philip,

    Thanks for the answer! I am using the same dongle as you and a similar antenna as yours.

    I am trying to compile the gnss-sdr software following your instructions in a clean VM with Ubuntu 16.04. However, I am getting the following error:

    [ 98%] Built target gtest
    [ 98%] Building CXX object src/tests/CMakeFiles/run_tests.dir/
    c++: internal compiler error: Killed (program cc1plus)
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See for instructions.
    src/tests/CMakeFiles/run_tests.dir/build.make:62: recipe for target 'src/tests/CMakeFiles/run_tests.dir/' failed
    make[2]: *** [src/tests/CMakeFiles/run_tests.dir/] Error 4
    CMakeFiles/Makefile2:2547: recipe for target 'src/tests/CMakeFiles/run_tests.dir/all' failed
    make[1]: *** [src/tests/CMakeFiles/run_tests.dir/all] Error 2
    Makefile:138: recipe for target 'all' failed
    make: *** [all] Error 2

    Do you know how to solve this error?


  4. Fernando, did you install the Google Test framework?

    It is one of the installation prerequsites. Maybe it installed but it is not in the include path?

    Also, did you follow the 16.04 installation instructions?

  5. Hi Philip,

    I have simply followed the indications for Ubuntu available in the gnss-sdr github website. I have started from a clean Ubuntu 16.04.

    deb-src xenial universe
    to your /etc/apt/sources.list file and doing:

    $ sudo apt-get update
    $ sudo apt-get build-dep gnss-sdr

    $ git clone
    $ git checkout next
    $ cd gnss-sdr/build

    $ cmake -DENABLE_OSMOSDR=ON ../
    $ make

    I will try with Kali VM. Let's see if I am a bit more lucky.

  6. Fernando, I've only ever done Ubuntu 14.04 and Kali VM. Ubuntu I had a few false starts but Kali went smoothly. good luck, -philip

  7. When starting the config file I am getting a PLL not locked error.

    Found Rafael Micro R820T tuner
    [R82XX] PLL not locked!
    Exact sample rate is: 2000000.052982 Hz
    [R82XX] PLL not locked!

    This happens in the front end config, and the real time config. In the front end config it does seem to find some sats.

    Front-end RAW samples captured
    Searching for GPS Satellites in L1 band...
    [ 1 . . . . . . . . 10 . . . 14 . . . . . . . 22 . . . . . . . . 31 32 ]
    Total signal acquisition run time 20.9691 [seconds]

    In the real time config it never locks. The satellites seem to lock and unlock.

    Tracking start on channel 5 for satellite GPS PRN 17 (Block IIR-M)
    OOOOOOOOOOOOOOOOOOLoss of lock in channel 2!
    OOOOOOOLoss of lock in channel 7!
    OOOOOOOOOOLoss of lock in channel 1!

    Using 1PPM rtl-sdr with bias-t enabled and generic gps antenna.

    Any ideas?

    1. Sorry for the late reply - the OOOO's are GNU Radio indicating an overflow, that is, the dongle is producing more data than your computer can process in real time. What kind of computer are you using? Are you in a virtual machine?