Saturday, April 2, 2016

Paul Breed Rocket Flight Test Data!

This post is long overdue as I've been quite busy with my day job that I've been remiss in updating the blog with the progress happening with the rocket GPS.

On February 6th, 2016 Paul Breed flew an RTL-SDR on a high power rocket to capture GPS RF data for post-processing. This was the second test flight and the first one to get good data.

Hardware Configuration

Paul shows off the payload. The blue box outlines a 6DOF IMU, the orange box is a LNA4ALL low noise amplifier. On the reverse the orange box outlines a 2S LiPo battery, the green box a Nooelec 0.5PPM TXCO in aluminum case and the blue box an Intel Compute Stick running Ubuntu, and the yellow trapezoid a quadrifilar antenna GPS antenna from antennas.us.


Backside of RF capture unit.


Frontside of RF capture unit.


Hardware Configuration

They payload is packaged inside the nosecone fairing of the rocket. Here, the rocket is mounted on the launch rail in a horizontal configuration. Before launch the rail is elevated to near vertical, but this orientation allows for easy handling of the rocket.

Rocket mounted on the launch rail

At T-2 minutes (2 minutes prior to launch) the rocket begins aquiring data - Paul SSH's over wifi into the Intel Compute Stick to trigger a script which calls rtl_sdr centered on the L1 frequency with a bandwidth of 2048000 Hz. Two minutes is sufficient time to get multiple GPS fixes of the launch site.

And at T-0, smoke and flames!

Liftoff!



Post-flight analysis

I took the output from rtl_sdr and converted it to complex for gnss-sdr. I was able to get a fix on the pad but not much after that. The last fix was at about 145 seconds - liftoff was likely between 145 and 150 seconds. I attempted to make a few tweaks to the tracking loop configuration gnss-sdr file with little success - it changed the results but not the actual character, that is not a whole lot after liftoff. I did find I was able to get a few subframes well after launch - 3 with the final configuration file - but not enough to get a fix. But there are other codes to be investigated which can get an approximate fix without a full 4 satellite solution.

One of the productive changes was decreasing the step size of the doppler search - this performs a more refined search and reveal more post-launch subframes. Initially I had one subframe and through tweaking the search step size (to 100 hz) I was able to get three. It is tempting to increase the doppler window but the max doppler shift of a GPS satellite to a stationary receiver is ~ 5kHz and the default search window is +/- 10 kHz - unless you are going orbital velocity at the satellite while it is coming at you, you are well within 10 kHz.

Here's the KML file in Google Earth. Don't get too excited about the altitude jumps! There are two of them in the file one occurs during the first few fixes and the last ones are of similar magnitude. I've seen the same thing happen with fixes at home. We know for the early jumps the rocket is sitting soundly on the pad and the latter jump is of the same magnitude.



I took the GPS time from gnss-sdr and used an online tool to back out the orientation of the satellite constellation during the rocket flight. The arrows point to the satellites which were used to get position fixes as output in the RINEX files. It is interesting to see some satellites which appear farther away on the map are useful to getting a fix where closer ones are not - however that's only half the story.


If we look at altitude (the earth is crudely pointed so the launch site is oriented up towards the top of your monitor) we see the satellites it uses are largely overhead and the "closer" satellites are on the horizon.



I also looked at the two satellites which gave valid subframes after T-0, they are PRN 3 and PRN 11, shown here.



So why didn't we get a good fix in flight? There are two likely culprits - the vibration / acclereation environment and the loop dynamics. Both vibration and acceleration affect the crystal which effects the frequency being captured. If the tracking loops are off then we'd anticipate losing satellite  directly overhead (in the direction of acceleration) and not laterally where the acceleration of the rocket doesn't effect things much. I tweaked the tracking loops as far as I could without making results worse and they didn't seem to get any better. Based on the fact that one of the satellites is fairly high in the sky my gut suspects the acceleration/vibe environment.

UPDATE: Got a brief in-flight nav solution; see this post!

But there's still work to be done to try fft-based approaches like fastgps, dig into the intermediate outputs and see if some smart people out there have ideas!

Thanks to Paul for providing the data, test hardware and ideas on how to look at and understand the data. Follow his blog or twitter!
Files
  1. Feb6.bin - raw RTLSDR binary file (interleaved shorts) you will need to convert to complex.
  2. flight.conf - gnss-sdr configuration file
  3. output.log - Console output from "gnss-sdr --config_file=flight.conf"
  4. PVT.kml - Position fixes in Google Earth format
  5. GSDR086x11.16N - Navigation data in RINEX format 
  6. GSDR086x11.16O - Observation data in RINEX format

Next Actions
  1. Investigate gnss-sdr telemetry and tracking outputs
  2. Try running through fastgps code 
  3. Get help from smart gps/sdr folk!

Sunday, March 6, 2016

An RTL-SDR dataset for gnss-sdr

I've had several requests for a dataset for users to play with. I've been recalcitrant simply because every dataset I've taken has been from my house! So this week I went to a park and took a two-minute acquisition using GNSS-SDR. My setup is a RTL-SDR stick with a 0.5PPM TXCO and aluminum case with the bias tee mod, a LNA4ALL, and a cheap active GPS antenna. (By no means are 0.5PPM TXCO, aluminum care or LNA4ALL requirements, I've gotten a good fix with a cheap dongle in a plastic case with no LNA.)

The dataset lives on my Google Drive. The .conf file is the file I used for acquisition. If you want to use it for playback with gnss-sdr, you need to make the following changes

Line 29: Change the SignalSource.implementation from Osmosdr_Signal_Source to File_Signal_Source
Line 30: Uncomment the SignalSource.filename and provide the correct path to the data file
Line 42: Change SignalSource.dump to false

gnss_sdr_pvt.nmea contains position/velocity/time (PVT) in NMEA format. The GSDR063p40.16N contains the raw navigational information and the GSDR063p40.16O contains the observables. PVT.kml is a Google Earth file with coordinates.

You might be interested in recovering the chip rate.

Saturday, February 27, 2016

Find the signal in the noise




 GPS signals are very weak, coming in at about 120 dBm ... which is below the thermal noise floor of ~ 100 dBm! If you try plotting an FFT 2 MHz wide about the L1 frequency you won't be able to distinguish the signal from the noise.



But it is there, and we can find it! 

First, we need data. I used data collected with an RTL-SDR stick converted to complex output. The output from the RTL-SDR is interleaved unsigned short, whereas the input block expects signed complex numbers. I talked about this in a prior post; I use the gcc code myself. 

So when we have data we can build a very simple flow diagram in GNURadio to play back the file and visualize it using the Fast Autocorrelation Sink. As noted in a previous post, there is a bug in GNURadio which breaks the Fast Autocorrelation Sink, but it is an easy fix!


The Fast Autcorrelation Sink is documented on Balint Seeber's blog and provides links to why the fast autcorrelation sink is indeed so fast! If you aren't familiar with autocorrelation, it is the correlation of a signal with itself. At any given time the correlation of a signal with itself is perfect, but if you insert a time delay and look at a later signal compared to a previous signal we can see just how similar the later signal. 

For example let's visualize a triangle wave with a frequency of 1000 Hz - that is, 1000 peaks per second, or 1 peak per millisecond. Since each repetition of the triangle is exactly 1 millisecond apart and since there is no noise in the system we would expect that every millisecond we'd have a perfect correlation of the shifted signal to the current signal. In between those milliseconds the correlation would get worse until we were half a millisecond apart where the peaks from the original signal would line up with the troughs of the shifted signal, resulting in a negative correlation.

Here's a simple flowgraph in GNURadio to visualize the autocorrelation using the Fast Autocorrelation Block from gr-baz. First, we create a signal source of a triangle wave with a frequency of 1000 Hz. Then we insert a throttle - this throttles the rate at which the diagram runs so we can visualize the signal. Left to its own devices GNURadio would simply pump triangle waves as quickly as it could with the given CPU resources. Then we can visualize the waveform using a WX GUI signal sink and the autocorrelation using the Fast Autocorrelation Sink:



Note the color of the block interfaces: Orange. This means floating point. Most of the blocks will default to complex, which is what you'd want for a lot of radio work but in this case it just makes things confusing as you will be plotting the triangle waves in both the Re and Im space. You can double click on each block and change the types to floating point or POWERUSER TIP: Click on the block and use up/down arrows to change the type. Once the flowgraph is complete (or download it here) hit play and you should see something like this:


We see our triangle waves with a period of 1 Hz and the Fast Autocorrelation Sink showing peaks at 1 Hz, and negative peak at a rate of 1 Hz shifted by half a Hz. 

So now let's do it with a real signal. You can use the same flowgraph, we just need to substitute the signal source block for a file source and specify our complex file. And since the file is complex, we need to change the data types. Finally, the throttle should be set to the sample rate of your input source - in my case, 2048000 Hz for the RTL-SDR. For the fast autocorrelation sink you will likely want to tweak the size to make the number of milliseconds a reasonable number. For my use I did (2**18)/2. Here's the updated diagram, running with the Fast Autocorrelation Sink, which you can download from github.


We see nice peaks every millisecond. Why every millisecond?

The coarse/acquisition code for GPS (C/A) has a period of 1023 chips which are transmitted at a rate of 1.023 MBit/s. This results in period of 1 millisecond. BAM! You can read more about the encoding on wikipedia. The L1 carrier at 1575.42 MHz has two codes, the C/A code and the navigation message. The navigation message varies with time as the satellites move through space but the C/A code does not change.  The C/A code is used for locking onto the satellites: Each satellite has a different unique C/A code. Earthside a receiver generates a particular C/A code and then shifts it in time and frequency to correlate the known C/A code with the C/A code of the satellite. Since we don't have a perfect clock we have to shift in time to line up our signal with the GPS signal timing and since the satellites are moving rapidly they frequency we receive is subject to a doppler shift of up to 5kHz (10kHz if we are moving very quickly, say, on a rocket or missile)

But that's a story for another day.

Wednesday, January 27, 2016

Fast Autocorrlelation Sink broke? Here's the fix

If this diagram doesn't work for you:


There's a very easy fix, outlined here. The issue is that GNURadio is asking wxGUI for the window size before the window is created. The fix is to edit top_block_gui.py. This file is likely located in ./usr/lib/python2.7/dist-packages/grc_gnuradio/wxgui/top_block_gui.py assuming your build prefix is /usr.


This defers creation of the GUI element and removes the error. And as you'd expect the autcorrelation of random noise is not very interesting :)




Wednesday, January 13, 2016

GNURadio: Getting audio to work in a VM

I've been going through a number of GNURadio tutorials and the waveform generator (signal sources) and display sinks have worked just fine. But then I hit a tutorial using the RTL-SDR stick as input and a flowgraph to process FM radio and an audio sink... and I get choppy audio! I started googling and most people blame the VM, but YouTube audio works just fine.

Then I stumbled across this post which contained the answer:

Ok, here are the contents of my ~/.gnuradio/config.conf:

[audio_alsa]
default_input_device = default
default_output_device = default
#period_time = 0.010                      # in seconds (default)
period_time = 0.100                      # in seconds
nperiods = 4                 # total buffering = period_time * nperiods
#verbose = false
verbose = true

The actual change I made was to increase audio_alsa/period_time from
0.010
to 0.100.  Play around with it until it works on your system.  My only
guess is that perhaps the default ALSA buffer sizes are small enough
that
they are often consumed by ALSA before GnuRadio will fill them.

Cheers,
-Remington

By default (at least in my Kali Linux VM) config.conf does not exist. Copy and paste the block of code to ~/gnuradio/config.conf.

For me, the above settings didn't work, but increasing period_time to 0.400 and nperiods to 16 and audio is crystal clear! Try the above settings, then mine, then something in between... hopefully this works!

Thursday, December 24, 2015

Acquire GPS signals from rtl_sdr recording

This one took a few evenings of head-scratching to finally resolve.

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:
  1. Acquire dump using "rtl_sdr /path/to/mydump.bin -s 2.048e6 -f 1575.420e6 &"
  2. Convert file using "rtlsdr-to-gqrx /path/to/mydump.bin /path/to/complex.bin"
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:

  1. SignalSource.implementation=File_Signal_Source
  2. SignalSource.filename=/path/to/complex.bin
  3. Change every sampling_frequency to the sampling frequency used in the initial acquisition
  4. 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,
  1. Set SignalSource.dump=true
  2. 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

Project Background

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!