discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss-gnuradio] Automatic Identification System receiver for GR


From: Nick Foster
Subject: [Discuss-gnuradio] Automatic Identification System receiver for GR
Date: Mon, 27 Jul 2009 22:33:48 +0000

Hi all,

Just wanted to let you know I've committed the first version of the AIS receiver I wrote to CGRAN. The project home page is at http://www.cgran.org/wiki/AIS. It's still under development, but the current version is more than serviceable. The project can be checked out from CGRAN's repository via:

svn co https://www.cgran.org/svn/projects/gr-ais/trunk


I'm currently building this project against the latest svn build of GR. Earlier builds probably work but I can't vouch for them.


Below is the README, if you're interested. If you do use the program, please let me know how it goes! Comments, suggestions, feedback are all appreciated.

Thanks,
Nick


The basics
----------
This module implements an AIS receiver for GnuRadio. AIS is the Automatic Identification System, a protocol designed to facilitate safety at sea by broadcasting ship data such as speed, heading, rate of turn, tonnage, draft, ship name, destination, etc. Ships of more than 65 feet in length or 150 tons in weight are required by Federal law to utilize an AIS transceiver, so in densely-populated ports you will receive quite a bit of traffic. The system uses VHF channels and is thus mostly line-of-sight.

The module outputs processed NMEA 0183 frames, designed to interface with any standard NMEA receiver. For a free Linux implementation, see ESR's gpsd program (http://gpsd.berlios.de/), specifically the program ais.py included with the gpsd distribution. The output of ais.py can be further parsed, to KML for instance, for a map implementation. If I had the first idea how to work the Google Maps API, I might try it myself. If you're into that sort of thing, please, pick up the baton, I'd really like to have a map interface. =)


The installation
----------------
./bootstrap
./configure
make
sudo make install


The use
-------
cd src/python
./ais_decode.py -R B -g 55 -e -2e3

The -e option is the only tricky bit, and specifies an error offset specific to your USRP, since I haven't implemented carrier synchronization yet. -2e3 means my USRP *actually* tunes 161.998MHz when I tune it to 162.000MHz, and so the USRP will tune accordingly to correct the offset. The offset will vary over time and temperature. Play with this setting for best results; you'll have to be within 1-2 kHz to get the best possible decoding. Also, I added a 162MHz front-end filter to my setup because I live like a mile from Sutro Tower and without the filter the less-than-selective TVRX would probably self-immolate.

You can also use a -F <filename> option to make the decoder receive recorded data. The -e and -g options are not used in this mode, but decimation can still be specified here.


Technical details
-----------------
AIS is a GMSK modulated packet broadcast at 9600bps on two channels: the A channel is 161.975MHz, and the B channel is 162.025MHz. The packets contain either 168 or 440 bits of information and are prefaced with a preamble and suffixed with a checksum. Packets are bit-stuffed to ensure timely bit transitions for clock recovery, and NRZI-encoded.

The receiver uses a quadrature demodulator followed by a low-pass filter to demodulate the signal. The demodulated signal is passed to a M&M clock recovery module. From there, a modified decision-feedback estimator attempts to correct ISI caused by GMSK modulation and channel distortion. The DFE is based on the gr.lms_dfe block included in GR, but with a reset input designed to accept a correlator output which is keyed to the training sequence. The DFE then resets its taps and runs through the first 150 bits of the packet 12 times, training the DFE for the channel. It then runs through the packet with the trained taps and outputs the ISI-corrected soft data, which then gets sliced. The sliced data is differentially-decoded and inverted to decode the NRZI encoding. The decoded data gets un-bitstuffed, framed, checksummed, and parsed to NMEA frames.

Two receivers are instantiated in ais_decode.py, one for each channel, by tuning the receiver to the center of both channels (162.000MHz) and using frequency-xlating filters to shift either channel to baseband.


Future improvements
-------------------
I'm sort of an idiot, so some of the coefficients (specifically in the DFE) are optimized by hand based on recorded data. If you're really bright and would like to mathematically determine more proper coefficients for the various blocks, please, be my guest.

In addition, there is no carrier recovery in this version. Future versions should use a PLL or something to make sure the demodulated signal lies at baseband. The system as it stands is rather sensitive to carrier offset, so the user has to specify an error offset using the -e option in order to precisely center the demodulated signal. I'll work on this. If you know how this should be implemented, feel free to let me know. I can't seem to get a PLL tuned to play nice with the demodulator.

If you're really good at this sort of thing, the optimal receiver for GMSK is a coherent demodulator using the Viterbi algorithm on a combined trellis. The gr-trellis module by Achilleas Anastasopolous includes basically everything necessary to do this except carrier synchronization. I personally can't figure it out to save my life. If you wanted to extend gr-trellis to include carrier synchronization, I'd be a big fan, or if you were interested in patiently holding my hand to teach me how to do this I'd be even happier. Actually, even using the quadrature demodulator to feed a Viterbi equalizer using gr-trellis should get you 1-2 dB of coding gain over the decision-feedback equalizer currently used. Again, I can't figure out how to make that work within this framework.




Windows Live™ SkyDrive™: Store, access, and share your photos. See how.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]