linuxsignal-processinggnuradiognuradio-companionsoftware-defined-radio

GNU Radio and wildlife tracking


I work with wildlife radio transmitters and I would like to build something that will listen for these signals and keep track of what it has heard. The signal is a tone that is transmitted 60 times per minute normally, or 120 if a motion sensor indicates the animal has died.

My plan is to use GNU Radio to listen and convert the signal into some type of matrix that is saved to file, and then analyzed in a second program. Is there a way to get vectors of signal strength at 500 Hz intervals across a few megahertz, and put them together into a matrix?

The secondary program would interpret this output and find the wildlife transmitters and record their pulse rates. The idea would be to get an new file every 10 seconds or so from GNU Radio, and process it with the second program as it is received.

I have been trying to use the file sink block in GNU Radio, and realized that it is in binary. Also not sure what exactly what it contains.

Any suggested approaches on how I should do this would be appreciated!


Solution

  • My plan is to use GNU Radio to listen and convert the signal

    Well, you will need hardware to do that; what kind of SDR device do you have in mind?

    In the following, I'll assume you're really using the classical SDR approach of getting a device that gives you raw I & Q samples.

    If there were a way to get vectors of signal strength at 500 Hz intervals across a few megahertz, and put them together into a matrix.

    Slow down on the matrix, let's focus on getting power from equidistant frequencies:

    That is pretty much a power spectral density (PSD) estimator. The easiest, probably fastest and classical approach would simply be taking the magnitude square of an FFT of your input signal.

    GNU Radio Companion has the log-power FFT block, which, for an input time sample stream, will give you FFT size vectors (which should then obviously be = sample rate / 500 Hz) at a Frame rate rate; for example:

    Flow Graph from GNU Radio Companion

    Saving these vectors to a file would be sufficient, because:

    I have been trying to use the file sink block in GNU, and realized that it is in binary. Also not sure what exactly what it contains.

    It's the numbers, raw, contiguous, as they would be in memory. There's always some misconceptions about that, so there's an FAQ entry on that; citing that:

    All files are in pure binary format. Just bits. That’s it. A floating point data stream is saved as 32 bits in the file, one after the other. A complex signal has 32 bits for the real part and 32 bits for the imaginary part. Reading back a complex number means reading in 32 bits, saving that to the real part of a complex data structure, and then reading in the next 32 bits as the imaginary part of the data structure. And just keep reading the data.

    So, one method to use would just be using Python/numpy, using numpy.fromfile(file, dtype=numpy.float32), and then numpy.reshape((rows,cols)) to bring the resulting 1D array of floats into the matrix shape you want.

    Regarding your file naming wishes: That's a pretty algorithmic problem (and why I think this question is very on-topic here). You will probably not get around writing a bit of code yourself; that's really not that hard to do. A Python block that always takes n vectors and writes them to a file with a name matching the current time will totally do for your application.

    Writing blocks is one of the most fun things you can do in GNU Radio; I think it is very worth pointing you to the GNU Radio Guided Tutorials. They are quite fun to read, and you can follow the examples without hardware! It's recommendable to do them in order.


    A few comments:

    1. The FFT is a good, easy to use, fast, efficient estimator.
      However, depending on the characteristics of your trackers, using a filterbank would probably outperform it with respect to accuracy/error probability. As soon as you feel comfortable with GNU Radio and DSP, have a look at the Polyphase Filter Banks that come with GNU Radio. They allow you to take one "good" low pass filter to select a single channel, and replicate them in even intervals.
    2. I'm very used to not doing the analysis outside of GNU Radio.
      I find it much easier to write another python block that just takes the samples that come out of an estimator (in your case, e.g. the log power FFT) and do useful things with them, and connecting the output of that e.g. to a Qt GUI frequency sink, than let's say taking measurement samples and push them trough Matlab or R.
      Most of the time, I'm generating a Python file that runs my measurement flow graph, which saves its results in a vector sink. From that Python file, after the flowgraph has completed running, I use numpy to do my own offline analysis immediately.
      Comes with the advantage of being instantaneously repeatable!

    Final remarks: You say you already have an SDR device (an RTL dongle). That's great!

    Attach it to your PC; use librtl/gr-osmosdr by using osmocom -s 1e6 -W to get 1 MHz of bandwidth "displayed"; tune to your transmitter's frequency and watch the spectrum. You'll learn a lot!

    If you don't have all that software yet: Just download and boot the GNU Radio live SDR environment. Plug and play!

    In GNU Radio Companion, just replace the UHD: USRP Source by the osmocom source (which can talk to RTL dongles).