Pages

Thursday, December 24, 2015

I want to be able to record I/Q off an RTL-SDR stick and then post-process it with gnss-sdr. The rtl_sdr software by default dumps interleaved unsigned shorts - that is an (uchar)i_sample, then a (uchar)q_sample, then an (uchar)i_sample, so on and so forth.

gnss-sdr has a couple of different SignalSources and a couple of different item_types and I initially tried varying combinations of those hoping something would work out of the box. Part of my confusion was the existence of an Osmosdr_Signal_Source which uses the RTL-SDR stick and outputs gr_complex without any intermediate conversion. I figured there would be a way to use this SignalSource with raw RTL-SDR dumps but this is not the case. In any case, with the current gnss-sdr infrastructure one must convert the rtl_sdr dump into a file format that gnss-sdr will read.

There are two components to getting an rtl_sdr dump into gnss-sdr. The first is converting the input file from interleaved uchars to gr_complex. The second is properly configuring your input file.

Converting rtl_sdr interleaved uchar into gr_complex

This is fairly well documented in this post at the Amateur Radio stackexchange. There are two methods proposed, one is writing up a flowgraph in GNURadio to convert the file. The second is a short C program posted by Dr. Paul Brewer which performs the exact same operation in 45 lines of code (with comments!) I opted for the C code. Once you compile the program, the process looks like this:

A third option is to write a radio receiver in GNURadio which uses the RTL-SDR stick to directly write a file in the appropriate format. I will go through this in a future post, as it is a good introduction into gnuradio using only two blocks.

Creating an input file

You can use the "gnss-sdr_GPS_L1_rtlsdr_realtime.conf" as a template and make the following changes:

SignalSource.implementation=File_Signal_Source

SignalSource.filename=/path/to/complex.bin

Change every sampling_frequency to the sampling frequency used in the initial acquisition

Change the InputFilter.IF to your IF

Once you make these changes you should be able to decode the file.

Bonus: Have your cake and eat it too!

You can skip the whole mess by modifying two line of code in gnss-sdr_GPS_L1_rtlsdr_realtime.conf which will let you dump the raw I/Q in complex format to file while in parallel running the tracking loop and getting a GPS solution.

To enable this,

Set SignalSource.dump=true

Set SignalSource.dump_filename=/path/to/dump.bin

Now you can track in realtime and generate a data file to post-process simultaneously!

As always any questions, comments or suggestions please leave a message.

Monday, December 21, 2015

A few months ago Paul Breed of Unreasonable Rocket posted on Twitter asking for help from getting GNSS-SDR running on an Intel Compute stick...

I responded and Paul provided an Intel Compute Stick, RTL-SDR stick with a 1PPM TXCO and the bias tee mod and an active antenna. It was my job, then, to make it work in parallel with Paul's investigateions.

The initial concept is simply to record the GPS L1 frequency through flight and post-process position-velocity-altitude after the fact. This would let Paul work out kinks in the hardware ad give us data to play with to tune GNSS-SDR's tracking loops to work in the high acceleration environment.

Eventually, it would be useful to do this in real time on the rocket.

So the path forward looks something like this:

Dark blue steps are complete.

Help is welcome - I'm learning GNSS-SDR but if you know GNSS-SDR and can provide a few answers via email I'd love to hear from you!

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 mapcoordinates.net. The other change I had to make was to change both SUPL servers to supl.google.com in place of supl.nokia.com - for some reason the nokia servers were not working. Once complete, you can run the front end calibration like so

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

NSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/

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

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.

Under the documentation section of gnss-sdr.org there is a post entitled "First positioning fix using Galileo" where they document getting a position fix using (at the time) all four Galileo satellites (there are now ten in orbit). They provide not only the position fix but the raw I/Q data which can be fed into gnss-sdr to replicate the fix. This makes a good first test of a gnss-sdr installation.

The page is not incredibly verbose so I will add some verbosity here. First off download and decompress the data from the link provided on the page. Inside the folder you will find the raw data file (.dat) along with a configuration file (.conf) USRP recording output log (.log) and output from their gnss-sdr run (.txt), Google Earth output (.kml) and NMEA messages (.nmea)

Unfortunately the provided configuration file doesn't work with the current gnss-sdr. However the default configuration file provided with gnss-sdr works just fine. So do the following

Copy gnss-sdr.conf from the installation location (typically /usr/local/share/gnss-sdr/conf/gnss-sdr.conf) to the directory containing the raw data file you downloaded

Update the line SignalSource.filename to the full path filename of the data file

Set GNSS-SDR.SUPL_read_gps_assistance_xml=false

Once you made those two tweaks you can execute the example by running

gnss-sdr --config_file=/path/to/my/gnss-sdr.conf

You should see similar but not identical output to the output provided with the data file. Once the run completes you should have a number of new files. The KML and NMEA files were already described, but you will also see some files named GSDR350w40.15N and GSDR350w40.15O. The file ending in "N" is the navigation solution and the file ending in "O" is the observables. Basically, the navigation solution is your 'fix' and the observables are what information you received from the satellite to generate that fix. Lastly, the gps_ephemeris.xml is an ephemeris which is a description of the satellites' orbit in space.

Here's instructions on how to set up gnss-sdr in Kali Linux virtual machine. Kali Linux is

... an open source project that is maintained and funded by Offensive Security, a provider of world-class information security training and penetration testing services. In addition to Kali Linux, Offensive Security also maintains the Exploit Database and the free online course, Metasploit Unleashed.

Most importantly, it comes with a modern version of GNURadio and up to date versions of nearly all the dependencies, making getting gnss-sdr installed quite easy.

You should now have a working copy of gnss-sdr; to test it out type gnss-sdr into your console and you should see something like this:

There is an error message because no configuration file was specified, and the default configuration file doesn't point to a valid signal source on my file system (and likely yours, either). No worries we'll fix that later. The message generated here indicates a good installation.

Useful presentation by the author of GNSS-SDRGUI for a summer school course. Also check the manuals included with GNSS-SDRLIB and RTKLIB.

Step-By-Step Implementation

Ensure RTL-SDR stick is working in Windows. If your driver is not working, try using the Zadig driver installation method outlined here.

Install GNSS-SDRLIB and RTKLIB to any convenient directory

Open GNSS-SDRGUI and select the following options

Input Type: RTL-SDR

[x] RTCM MSM, Port 9999

Change "output interval" dropdown to 10 hz

[x] Plot Tracking

[x] All GPS, GLOSNASS, Galileo satellites

(optional) enter approximate lat/lon into MISC and click the "..." button to get current satellite locations in relation to your location.

Click "Start", a number of command consoles will open then close for each satellite being tracked.

Click "M" for log

Now, open RTKNAVI

Click on the "I" button

check "rover", type TCP Client, format RTCM3

click OPT button and set address to "localhost" and port to "9999"

click OK

Click OK

Click on the "start" button

Within a few seconds you should see satellites in the Rover:Base SNR pane

Once a solution exists it will update lat/lon in the left pane

Click "Plot" to generate a plot of the random walk of lat/lon over time

This is what your GNSS-SDRGUI should look like:

This is what your RTKNAVI input should look like:

If everything is working you should get a GPS solution, as shown in this video

Next Actions

Try using GNSS-SDR and/or GNURadio to decode the GNSS signal; this would provide native, Linux compatible headless execution and a cursory Google suggests this has been done successfully with the RTL-SDR stick.

This blog is designed to document as I learn about using software-defined radios to decode GPS signals. I plan on providing references to existing projects and papers ("theory") along with my actual implementations and experiences ("practice") which any properly motivated individual could replicate for their own purposes.

For most users consumer level GPS devices are sufficient for most applications, but there are niche applications where consumer level hardware fails to satisfy and professional or unrestricted hardware are unattainable.

There is also the educational aspect. I've had my ham radio license for almost 10 years and didn't use it much beyond the first year, but the recent development of ubiquitous software-defined radios and fast, cheap computers makes learning about radios accessible in a way that involves compilers instead of solder. Nothing against solder! Working with GPS in particular also brings to light satellite communications, orbital mechanics, Doppler shifts, and other fun physical phenomenon. My children are not quite old enough to write code or solder properly, but talk to them about listening to satellites and you can just see the awe on their faces, when you explain basic triangulation and they start drawing their own triangulation intersection circles, there's a level of practicality they can connect with, which I can then develop into a curiosity about radios, and code, and solder.

RTL-SDR GPS

Movember in Memory of Micah Hahn

About

Investigations into using cheap SDR hardware to track GPS satellites. Hardware provided by Paul Breed of Unreasonable Rocket. End goal is to track high power rockets in high acceleration / speed / altitude environments.