AIS-catcher icon indicating copy to clipboard operation
AIS-catcher copied to clipboard

AIS receiver for RTL SDR dongles, Airspy R2, Airspy Mini, Airspy HF+, HackRF, SDRplay and SoapySDR

AIS-catcher - A multi-platform AIS receiver

This package will add the AIS-catcher command - a dual channel AIS receiver for RTL-SDR dongles (including the ShipXplorer AIS dongle), Airspy (Mini/R2/HF+), HackRF, SDRplay (RSP1/RSP1A/RSPDX for now), SoapySDR, input from file as well as from ZMQ and TCP servers (RTL-TCP/SpyServer). Output is send in the form of NMEA messages to either screen or broadcasted over UDP. The program provides the option to read and decode the raw discriminator output of a VHF receiver as well.

Image

Purpose

The aim of AIS-catcher is to provide a platform to facilitate continuous improvement of receiver models. Any suggestions, observation or sharing of recordings for setups where the current models are struggling is highly appreciated!

Disclaimer

AIS-catcher is created for research and educational purposes under the GPGL v3 license. It is a hobby project and not tested and designed for reliability and correctness. You can play with the software but it is the user's responsibility to use it prudently. So, DO NOT rely upon this software in any way including for navigation and/or safety of life or property purposes. There are variations in the legislation concerning radio reception in the different administrations around the world. It is your responsibility to determine whether or not your local administration permits the reception and handling of AIS messages from ships. It is specifically forbidden to use this software for any illegal purpose whatsoever. Only use this software in regions where such use is permitted.

Installation and Windows Binaries

Building instructions are provided below for many systems. Pre-built container images containing AIS-catcher are available from the GitHub Container Registry.

Links to fully built Windows binaries of version v0.38 and older are provided in below table, with and without SDRPlay support (which requires a running SDRPlay API). Running AIS-catcher should be a simple matter of unpacking the ZIP file in one directory and start the executable on the command line with the required parameters or by clicking start.bat which you can edit with Notepad to set desired parameters. It will likely run out of the box in case you have already RTL-SDR software running on your PC. In case you encounter an issue, you might want to try first:

  • check whether RTL-SDR drivers are installed via Zadig.
  • on new Windows systems it might be that you have to install the Visual Studio runtime libraries.

Recent releases:

Version Win32 x64 Win32 + SDRPlay x64 + SDRPlay
v0.38 ZIP ZIP ZIP ZIP
v0.37 ZIP ZIP ZIP ZIP
v0.36 ZIP ZIP
v0.35 ZIP ZIP
v0.34 ZIP ZIP
v0.33 ZIP ZIP

If you are looking for a Windows-version for the latest development version, it is automatically produced by the standard workflow (see Actions).

What's new?

Development version

  • -o 4 is now -o 5 and -o 4 now shows a subset of the AIS message data relevant for map plotting.
  • ...

Version 0.38

  • Option -o renamed to -c (switch to select AIS channels)
  • Signal power (in dB) and applied frequency correction (in ppm) calculated with option -M D
  • NMEA messages are timestamped with option -M T. To activate both additional calculations use -M DT or -M TD.
  • Screen output can now be defined with -o switch, see below.
  • -T switch that stops the program after a specified number of seconds to facilitate experiments.
  • start.bat added to Windows binaries to make it easier to set up parameters for less experienced command-line users..
  • ...

Android version available here.

If you are travelling and looking for a portable system that can be used on an Android phone, check out the link. The following screenshot was taken in July 2022 with AIS-catcher receiving signals for a few minutes on a Samsung Galaxy S6 on a beach near The Hague with a simple antenna. Ship positions are plotted with the BoatBeacon app.

You can download the APK from the mentioned project page.

Usage

use: AIS-catcher [options]

	[-h display this message and terminate (default: false)]
	[-s xxx sample rate in Hz (default: based on SDR device)]
	[-c [AB/CD] [optional: AB] select AIS channels and optionally the NMEA channel designations]
	[-p xxx set frequency correction for device in PPM (default: zero)]
	[-a xxx set tuner bandwidth in Hz (default: off)]
	[-v [option: 1+] enable verbose mode, optional to provide update frequency in seconds (default: false)]
	[-M xxx set additional meta data to generate: T = NMEA timestamp, D = decoder related (signal power, ppm) (default: none)]
	[-T xx auto terminate run with SDR after xxx seconds (default: off)]
	[-o set output mode (0 = quiet, 1 = NMEA only, 2 = NMEA+, 3 = NMEA+ in JSON, 4 JSON Sparse, 5 JSON Full (default: 2)]
	[-n show NMEA messages on screen without detail (-o 1)]
	[-q suppress NMEA messages to screen (-o 0)]
	[-u xxx.xx.xx.xx yyy - UDP destination address and port (default: off)]

	[-r [optional: yy] filename - read IQ data from file, short for -r -ga FORMAT yy FILE filename, for stdin input use filename equals stdin or .]
	[-w filename - read IQ data from WAV file, short for -w -gw FILE filename]
	[-t [host [port]] - read IQ data from remote RTL-TCP instance]
	[-y [host [port]] - read IQ data from remote SpyServer]
	[-z [optional [format]] [optional endpoint] - read IQ data from [endpoint] in [format] via ZMQ (default: format is CU8)]

	[-l list available devices and terminate (default: off)]
	[-L list supported SDR hardware and terminate (default: off)]
	[-d:x select device based on index (default: 0)]
	[-d xxxx select device based on serial number]

	[-m xx run specific decoding model (default: 2), see README for more details]
	[-b benchmark demodulation models for time - for development purposes (default: off)]
	[-F run model optimized for speed at the cost of accuracy for slow hardware (default: off)]

	Device specific settings:

	[-gr RTLSDRs: TUNER [auto/0.0-50.0] RTLAGC [on/off] BIASTEE [on/off] ]
	[-gm Airspy: SENSITIVITY [0-21] LINEARITY [0-21] VGA [0-14] LNA [auto/0-14] MIXER [auto/0-14] BIASTEE [on/off] ]
	[-gh Airspy HF+: TRESHOLD [low/high] PREAMP [on/off] ]
	[-gs SDRPLAY: GRDB [0-59] LNASTATE [0-9] AGC [on/off] ]
	[-gf HACKRF: LNA [0-40] VGA [0-62] PREAMP [on/off] ]
	[-gu SOAPYSDR: DEVICE [string] GAIN [string] AGC [on/off] STREAM [string] SETTING [string] CH [0+] PROBE [on/off] ANTENNA [string] ]
	[-gt RTLTCP: HOST [address] PORT [port] TUNER [auto/0.0-50.0] RTLAGC [on/off] FREQOFFSET [-150-150] PROTOCOL [none/rtltcp] TIMEOUT [1-60] ]
	[-gy SPYSERVER: HOST [address] PORT [port] GAIN [0-50] ]
	[-ga RAW file: FILE [filename] FORMAT [CF32/CS16/CU8/CS8] ]
	[-gw WAV file: FILE [filename] ]
	[-gz ZMQ: ENDPOINT [endpoint] FORMAT [CF32/CS16/CU8/CS8] ]

	Model specific settings:

	[-go Model: FP_DS [on/off] PS_EMA [on/off] SOXR [on/off] SAMPLERATE [on/off] ]

Basic usage

To test that the installation and/or compilation was succesful (see below for instructions), a good start is the following command which lists the devices available for AIS reception:

AIS-catcher -l

The output depends on the available devices but will look something like:

Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001

A specific device can be selected with the d-switch using the device number -d:0 or the serial number -d 00000001. If you were expecting a particular device that is missing, you might want to try:

AIS-catcher -L

which lists all supported devices and confirms that the executable was correctly build for your hardware.

To start AIS demodulation, print some occasional statistics (every 10 seconds) and broadcast AIS messages via UDP, we can use the following command:

AIS-catcher -v 10 -u 127.0.0.1 10110 -u 127.0.0.1 10111

If successful, NMEA messages will start to come in, appear on the screen and send as UDP messages to 127.0.0.1 port 10110 and port 10111. These UDP messages are the key tool to use the output of AIS-catcher and visualize that in OpenCPN. See below for more pointers on how this can be set up. The screen messages can be suppressed with the option -q. That's all there is.

AIS-catcher can read from stdin using -r .. The following command records a signal with rtl_sdr at a sampling rate of 288K Hz and pipes it to AIS-catcher for decoding:

rtl_sdr -s 288K -f 162M  - | AIS-catcher -r . -s 288K -v

The same mechanism can be used to apply other transformations on the signal, e.g. downsampling with sox:

sox -c 2 -r 1536000 -b 8 -e unsigned -t raw posterholt.raw -t raw -b 16 -e signed -r 96000 - |AIS-catcher -s 96K -r CS16 . -v

For reference, as per version 0.36, AIS-catcher has the option to use the internal sox library directly if included in your build:

AIS-catcher -s 1536K -r CU8 posterholt.raw -v -go SOXR on 

Deep dives

Screen output

The output to screen can be regulated with the -o switch. To surpress any messages to screen use -o 0 or -q. This can be useful if you run AIS-catcher as a background process. To show only simple and pure NMEA lines, use the switch -o 1 or -n. Example output:

!AIVDM,1,1,,B,33L=LN051HQj3HhRJd7q1W=`0000,0*03

By default, and using the command -o 2, AIS-catcher displays NMEA messages with some additional information:

!AIVDM,1,1,,B,33L=LN051HQj3HhRJd7q1W=`0000,0*03 ( MSG: 3, REPEAT: 0, MMSI: 230907000, signalpower: -44.0, ppm: 0, timestamp: 20220729191340)

This same information but wrapped in JSON to facilitate further processing downstream is generated with the switch -o 3 :

{"class":"AIS","device":"AIS-catcher","channel":"B","rxtime":"20220729191502","signalpower":-44.0,"ppm":0,"mmsi":230907000,"type":3,"nmea":["!AIVDM,1,1,,B,33L=LN051HQj3HhRJd7q1W=`0000,0*03"]}

Some examples on how this meta-data can be processed you can find below in the next section. And finally, full decoding of the AIS message is activated via -o 4:

{"class":"AIS","device":"AIS-catcher","rxtime":"20220729191610","scaled":true,"channel":"B","nmea":["!AIVDM,1,1,,B,33L=LN051HQj3HhRJd7q1W=`0000,0*03"],"signalpower":-44.0,"ppm":0.000000,"type":3,"repeat":0,"mmsi":230907000,"status":0,"status_text":"Under way using engine","turn":18,"speed":8.800000,"accuracy":true,"lon":24.915239,"lat":60.148106,"course":231.000000,"heading":230,"second":52,"maneuver":0,"raim":false,"radio":0}

There are many libraries for decoding AIS messages to JSON format. I encourage you to use your favourite library (libais, gpsdecode, pyais, etc). However, there does not seem to be clear consensus yet on the format. We have tried as much as possible to align the implementation and the output with the proposal here which is a great piece of work by the open source community.

Further downstream handling of messages

As an example on how to further process some of the meta data generated by AIS-catcher, we used a few lines of JavaScript and Python that take the JSON output (generated with switch -o 3) and use that to plot the location of ships on a map as a circle (Channel A/B corresponds to Blue/Red) whereby the radius is proportional to the measured power of the received signal (code and video):

Please notice that the NMEA lines in the JSON output do not include the required <CR><LF> as per standard so need to be added downstream if you write code that forwards messages to a AIS service like MarineTraffic or AISHub.

Setting up OpenCPN

In this example we have AIS-catcher running on a Raspberry PI and want to receive the messages in OpenCPN running on a Windows computer with IP address 192.168.1.239. We have chosen to use port 10101. On the Raspberry we start AIS-catcher with the following command to send the NMEA messages to the Windows machine:

 AIS-catcher -u 192.168.1.239 10101

In OpenCPN the only thing we need to do is create a Connection with the following settings:

Running on hardware with performance limitations

AIS-catcher implements a trick to speed up downsampling for RTLSDR input at 1536K samples/second by using fixed point calculations (-m 2 -go FP_DS on). In essence the downsampling is done in 16 bit integers performed in parallel for the I and Q channel using only 32 bit integers. Furthermore a new model was introduced which uses exponential moving averages in the determination of the phase instead of a standard moving average as for the default model (-m 2 -go PS_EMA on).

Both features can be activated with the -F switch. To give an idea of the performance improvement on a Raspberry Pi Model B Rev 2 (700 MHz), I used the following command to decode from a file on the aforementioned Raspberry Pi:

AIS-catcher -r posterholt.raw -s 1536K -b -q -v

Resulting in 38 messages and the -b switch prints the timing used for decoding:

[AIS engine v0.31]	: 17312.1 ms

Adding the -F switch yielded the same number of messages but timing is now:

[AIS engine (speed optimized) v0.31]	: 7722.32 ms

This and other performance updates make the full version of AIS-catcher run on an early version of the Raspberry Pi with reasonable processor load.

Connecting to GNU Radio via ZMQ

The latest code base of AIS-catcher can take streaming data via ZeroMQ (ZMQ) as input. This allows for an easy interface with packages like GNU Radio. The steps are simple and will be demonstrated by decoding the messages in the AIS example file from here. AIS-catcher cannot directly decode this file as the file contains only one channel, the frequency is shifted away from the center at 162Mhz and the sample rate of 62.5 KHz is not supported in our program. We can however perform decoding with some help from GNU Radio. First start AIS-catcher to receive a stream (data format is complex float and sample rate is 96K) at a defined ZMQ endpoint:

AIS-catcher -z CF32 tcp://127.0.0.1:5555 -s 96000

Next we can build a simple GRC model that performs all the necessary steps and has a ZMQ Pub Sink with the chosen endpoint: Image Running this model, will allow us to successfully decode the messages in the file:

Image

The ZMQ interface is useful if a datastream from a SDR needs to be shared and processed by multiple decoders or for experimentation with different decoder models with support from GNU Radio.

Multiple receiver models

The command line provides the -m option which allows for the selection of the specific receiver models. In the current version 4 different receiver models are embedded:

  • Default Model (-m 2): the default demodulation engine.
  • Base Model (non-coherent) (-m 1): using FM discriminator model, similar to RTL-AIS (and GNUAIS/Aisdecoder) with tweaks to the Phase Locked Loop and main receiver filter (computed with a stochastic search algorithm).
  • Standard Model (non-coherent) (-m 0): as the Base Model with brute force timing recovery.
  • FM Discriminator model: (-m 3) as the Standard Model but with the input already assumed to be the output of a FM discriminator. Hence no FM demodulation takes place which allows AIS-catcher to be used as GNUAIS and AISdecoder.

The Default Model is the most time and memory consuming but experiments suggest it to be the most effective. In my home station it improves message count by a factor 2 - 3. The reception quality of the Standard Model over the Base Model is more modest at the expense of roughly a 20% increase in computation time. Advice is to start with the Default Model, which should run fine on most modern hardware including a Raspberry 4B and then scale down to -m 0or even -m 1, if needed.

Notice that you can execute multiple models in one run for benchmarking purposes but only the messages from the first model specified are displayed on screen. To benchmark different models specify -b for timing and/or -v to compare message count, e.g.

AIS-catcher -s 1536K -r posterholt.raw -m 2 -m 0 -m 1 -q -b -v

The program will run and summarize the performance (count and timing) of three decoding models (on a Raspberry Pi 4B):

[AIS engine v0.35]:                      38 msgs at 6.3 msg/s
[Standard (non-coherent)]:               4 msgs at 0.7 msg/s
[Base (non-coherent)]:                   3 msgs at 0.5 msg/s
[AIS engine v0.35]:                      1036.54 ms
[Standard (non-coherent)]:               932.47 ms
[Base (non-coherent)]:                   859.065 ms

In this example the Default Model performs quite well in contrast to the Standard non-coherent engine with 38 messages identified versus 4 for the standard engine. This is typical when there are messages of poor quality. However, it increases the decoding time a bit and has a slightly higher memory usage so needs more powerful hardware. Please note that the improvements seen for this particular file are an exception.

Input from FM discriminator

We can run AIS-catcher on a RAW audio file as in this tutorial:

wget "https://github.com/freerange/ais-on-sdr/wiki/example-data/helsinki-210-messages.raw"
AIS-catcher  -m 3 -v -s 48K -r cs16 helsinki-210-messages.raw

On this file we should extract roughly 362 AIVDM lines. Notice that with switch -m 3 on the command line AIS-catcher runs a decoding model that assumes the input is the output of an FM discriminator. In this case the program is similar to the following usage of GNUAIS:

gnuais -l helsinki-210-messages.raw

which produces:

INFO: A: Received correctly: 153 packets, wrong CRC: 49 packets, wrong size: 4 packets
INFO: B: Received correctly: 52 packets, wrong CRC: 65 packets, wrong size: 10 packets

Device specific settings

The command line allows you to set some device specific parameters. AIS-catcher follows the settings and naming conventions for the devices as much as possible so that parameters and settings determined by SDR software for signal analysis (e.g. SDR#, SDR++, SDRangel) can be directly copied. Below some examples. Note that these settings are not selecting the device used for decoding itself, this needs to be done via the -d switch. If a device is not connected or used for decoding any specific settings are simply ignored.

RTL SDR

Gain and other settings specific for the RTL SDR can be set on the command line with the -gr switch. For example, the following command sets the tuner gain to +33.3 and switches the RTL AGC on:

AIS-catcher -gr tuner 33.3 rtlagc ON

Settings are not case sensitive.

Airspy HF+

Gain settings specific for the Airspy HF+ can be set on the command line with the -gh switch. The following command switches off the preamp:

AIS-catcher -gh preamp OFF

Please note that only AGC mode is supported so there are limited options.

Airspy Mini/R2

The Airspy Mini/R2 requires careful gain configuration as described here. As outlined in that reference there are three different gain modes: linearity, sensitivity and so-called free. These can be set via the -gmswitch when using the Airspy. We can activate 'linearity' mode with gain 10using the following AIS-catcher command line:

AIS-catcher -gm linearity 10

Finally, gains at different stages can be set as follows:

AIS-catcher -gm lna AUTO vga 12 mixer 12

More guidance on setting the gain model and levels can be obtained in the mentioned link.

SDRplay RSP1/RSP1A/RSPDX (API 3.x)

Settings specific for the SDRplay can be set on the command line with the -gs switch, e.g.:

AIS-catcher -gs lnastate 5

HackRF

Settings specific for the HackRF can be set on the command line with the -gf switch, e.g.:

AIS-catcher -gf lna 16 vga 16 preamp OFF

RTL TCP and SpyServer

AIS-catcher can process the data from a rtl_tcp process running remotely, e.g. if the server is on 192.168.1.235 port 1234 with a sampling rate of 240K samples/sec:

AIS-catcher -t 192.168.1.235 1234 -gt TUNER auto

For SpyServer use the -y switch like:

AIS-catcher -y 192.168.1.235 5555 -gy GAIN 14

SoapySDR

In general we recommend to use the built-in drivers for supported SDR devices. However, AIS-catcher also supports a wide variety of other devices via the SoapySDR library which is an independent SDR support library. SoapySDR is not included by default in the standard build. To enable SoapySDR support follow the build instructions as per below but replace the cmake call with:

cmake .. -DSOAPYSDR=ON

The result is that AIS-catcher adds a few additional "devices" to the device list (-l): a generic SoapySDR device and one device for each receiving channel for each device, e.g. with one RTL-SDR dongle connected this would look like:

Found 3 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001
1: SOAPYSDR, 1 device(s), SN: SOAPYSDR
2: SOAPYSDR, driver=rtlsdr,serial=00000001, SN: SCH0-00000001

To start streaming via Soapy we can use:

AIS-catcher -d SCH0-00000001

Note that the serial number has a prefix of SCH0 (short for SoapySDR Channel 0) to distinguish it from the device accessed via the native SDR library. Alternative, we can use a device-string to select the device:

AIS-catcher -d SOAPYSDR -gu device "serial=00000001,driver=rtlsdr" -s 1536K

Stream arguments and gain arguments can be set similarly via -gu STREAM and -gu GAIN followed by an argument string (if it contains spaces use ""). Please note that SoapySDR does not signal if the input parameters for the device are not set properly. We therefore added the -gu PROBE on switch which displays the actual settings used, e.g.

AIS-catcher -d SOAPYSDR -s 1536K -gu GAIN "TUNER=37.3" PROBE on SETTINGS "biastee=true"

To complete the example, this command also sets the tuner gain for the RTL-SDR to 37.3 and switches on the bias-tee via the SETTING command gives access to the device's extra settings.

If the sample rates for a device are not supported by AIS-catcher, the SOXR functionality could be considered (e.g. -go SOXR on). Again, we advice to use the built-in drivers and included resampling functionality where possible.

Validation

Experimenting with recorded signals

The functionality to receive radio input from rtl_tcp provides a route to compare different receiver packages on a deterministic input from a file. I have tweaked the callback function in rtl_tcp so that it instead sends over input from a file to an AIS receiver like AIS-catcher and AISrec. The same trick can be easily done for rtl-ais. The sampling rate of the input file was converted using sox to 240K samples/second for rtl-tcp and 1.6M samples/second for rtl-ais. These programs, and others like gnuais have been the pioneers in the field of open source AIS decoding and without them many related programs including this one would arguably not exist. The output of the various receivers was sent via UDP to AISdispatcher which removes any duplicates and counts messages. The results in terms of number of messages/distinct vessels:

File AIS-catcher v0.35 AIS-catcher v0.33 rtl-ais AISrec 2.208 (trial - super fast) AISrec 2.208 (pro - slow2) AISrec 2.301 (pro - slow2) Source
Scheveningen 44/37 43/37 17/16 30/27 37/31 39/33 recorded @ 1536K with rtl-sdr (auto gain)
Moscow 213/35 210/32 146/27 195/31 183/34 198/35 shared by user @ 1920K in discussion
Vlieland 93/54 93/53 51/31 72/44 80/52 82/50 recorded @ 1536K with rtl-sdr (auto gain)
Posterholt 39/22 39/22 2/2 13/12 31/21 31/20 recorded @ 1536K with rtl-sdr (auto gain)

Update 1: AISrec had a version update of 2.208 (October 23, 2021) with improved stability and reception quality and the table above has been updated to include the results from this recent version.

Update 2: Feverlaysoft has kindly provided me with a license for version 2.208 of AISrec allowing access to additional decoding models. Some experimentation suggests that "Slow2" works best for these particular examples and has been included in the above overview.

Update 3: AISrec had a version update to 2.301 (April 17, 2022) with reduced runtime and the table above has been updated to include the results from this recent version.

Some stations mentioning the use of AIS-catcher

A list of some stations mentioning using AIS-catcher:

Build process

Ubuntu, Raspberry Pi, macOS, MSVC

The steps to compile AIS-catcher for RTL-SDR dongles are fairly straightforward on most systems. There are various options including a standard Makefile, a solution file for MSVC (see next section) and you can use cmake, as we will detail now.

First step is to ensure you have the necessary dependencies and build tools installed for your device(s). For example, the following installs the minimum build tools for Ubuntu and Raspberry Pi:

sudo apt-get update
sudo apt-get upgrade

sudo apt-get install git make gcc g++ cmake pkg-config -y

AIS-catcher requires libraries for the particular hardware you want to use. The following table summarizes the installation instructions for all supported hardware:

System Linux/Raspberry macOS MSVC/vcpkg MSVC/PothosSDR
Command sudo apt install ... brew install ... vcpkg install ... Download
RTL-SDR librtlsdr-dev librtlsdr rtlsdr rtlsdr:x64-windows included
Airspy libairspy-dev airspy - included
Airspy HF+ libairspyhf-dev airspyhf - included
HackRF libhackrf-dev hackrf - included
SDRplay 1A API 3.x - API 3.x API 3.x
SoapySDR libsoapysdr-dev X
ZeroMQ libzmq3-dev zeromq ZeroMQ ZeroMQ:x64-windows included

Once the dependencies are in place, the process to install AIS-catcher then on Linux based systems becomes:

git clone https://github.com/jvde-github/AIS-catcher.git
cd AIS-catcher
mkdir build
cd build
cmake ..
make
sudo make install

For the SDRPlay the software needs to be downloaded and installed from the website of the manufacturer. Once installed, the AIS-catcher build process automatically includes it in the build if available.

For Windows, clone the project and open the directory with AIS-catcher in Visual Studio 2019 or above. The cmake file provides two options as source for the libraries. The first is to install all the drivers via PothosSDR from here. The cmake file will locate the installation directory and link against these libraries. The alternative is to use vcpkg which currently only offers the libraries for RTL-SDR and ZeroMQ (see next section as well). Of course, you can save yourself the hassle and download the Windows binaries from above.

Microsoft Visual Studio 2019+ via solution file (RTL-SDR/ZMQ only)

Ensure that you have vcpkg installed and integrated into Visual Studio via vcpkg integrate install (as Administrator). Then install the rtl-sdr drivers as follows:

vcpkg install rtlsdr rtlsdr:x64-windows ZeroMQ ZeroMQ:x64-windows soxr soxr:x64-windows

The included solution file in the mscv directory allows you to build AIS-catcher with RTL-SDR/ZMQ support in the Visual Studio IDE.

Container images

Pre-built container images containing AIS-catcher are available from the GitHub Container Registry. Available container tags are documented on the package's page, with latest (the latest release) and edge (the bleeding edge of the main branch) being the two main ones.

The following docker run command provides an example of the usage of this container image, running the latest release of AIS-catcher interactively:

docker run --rm -it --pull always --device /dev/bus/usb ghcr.io/jvde-github/ais-catcher:latest <ais-catcher command line options>

Alternatively, the following docker-compose.yml configuration provides a good starting point should you wish to use Docker Compose:

services:
  ais-catcher:
    command: <ais-catcher command line options>
    container_name: ais-catcher
    devices:
      - "/dev/bus/usb:/dev/bus/usb"
    image: ghcr.io/jvde-github/ais-catcher:latest
    restart: always

Please note that the SDRplay devices are currently not supported in the Docker images.

Considerations

A note on device sample rates

AIS-catcher automatically sets an appropriate sample rate depending on your device but provides the option to overwrite this default using the -s switch. For example for performance reasons you can decide to use a lower rate or improve the sensitivity by picking a higher rate than the default. The decoding model supports the following rates:

96K, 192K, 288K, 384K, 576K, 768K, 1152K, 1536K, 2304K, 3072K, 6144K, 12288K 

Before splitting the signal in two separate signals for channel A and B, AIS-catcher downsamples the signal to 96K samples/second by successively decimating the signal by a factor 2 and/or 3. Input on all other sample rates is upsampled to a nearby higher rate to make it fit in this computational structure. Hence, there is no efficiency advantage of using these other rates. In recent versions of AIS-catcher you can use the SOXR or libsamplerate library for downsampling. In fact, you can compare the four different downsampling approaches with a command like:

AIS-catcher -r posterholt.raw -m 2 -m 2 -go FP_DS on  -m 2 -go SOXR on -m 2 -go SAMPLERATE on -b -q -v

which produces:

[AIS engine v0.35 ]:                     41 msgs at 4.1 msg/s
[AIS engine v0.35 FP-DS ]:               41 msgs at 4.1 msg/s
[AIS engine v0.35 SOXR ]:                41 msgs at 4.1 msg/s
[AIS engine v0.35 SRC]:                  41 msgs at 4.1 msg/s

with the following timings:

[AIS engine v0.35 ]:                     320.624 ms
[AIS engine v0.35 FP-DS ]:               254.341 ms
[AIS engine v0.35 SOXR ]:                653.716 ms
[AIS engine v0.35 SRC]:                  3762.6 ms

Note that some libraries will require significant hardware resources. The advice is to use the native build-in downsampling functionality.

Frequency offset

AIS-catcher tunes in on a frequency of 162 MHz. However, due to deviations in the internal oscillator of RTL-SDR devices, the actual frequency can be slightly off which will result in no or poor reception of AIS signals. It is therefore important to provide the program with the necessary correction in parts-per-million (ppm) to offset this deviation where needed. For most of our testing we have used the RTL-SDR v3 dongle where in principle no frequency correction is needed as deviations are guaranteed to be small. For optimal reception though ensure you determine the necessary correction, e.g. see and provide as input via the -p switch on the command line.

System USB performance

On some laptops we observed that Windows was struggling with high volume of data transferred from the RTL SDR dongle to the PC. I am not sure why (likely some driver issue as Ubuntu on the same machine worked fine) but it is worthwhile to check if your system supports transferring from the dongle at a sampling rate of 1.536 MHz with the following command which is part of the osmocom rtl-sdr package:

rtl_test -s 1536000

In case you observe a high number of lost data, the advice is to run AIS-catcher at a lower sampling rate for RTL SDR dongles:

AIS-catcher -s 288000

If your system allows for it you might opt to run AIS-catcher at a sample rate of 2304000.

Known issues

  • call of rtlsdr_close on Windows can result in a crash. This is a problem with the rtlsdr library and not AIS-catcher. Solution: ensure you have the latest version of the library with this patch rtlsdr. For the shared Windows binaries I have included this version of the library in which I did a proper patch to fix this issue (essentially ensuring all usb transfers have been closed before freeing memory.
  • pkg-config on Raspberry Pi returns -L as library path which results in a build error. Temporarily fixed by assuming lib is in standard location, long term fix: switch to cmake
  • ...

To do

  • On going: testing and improving receiver, seems to be some room for certain Class broadcast

  • Simultaneously receive Marine VHF audio and DSC signals from SDR input signal

  • Unit testing of the JSON decoder

  • Adding additional messages to the JSON decoder (Message 8, 6, etc).

  • Implement websocket interface, store/write configuration files (JSON)

  • Channel AB+CD for high sample rates

  • Optional filter for invalid messages

  • DSP: improve filters (e.g. add droop compensation, larger rate reductions), etc

  • Decoding: add new improved models (e.g. using matched filters, alternative freq correction models), software gain control, document current model

  • Testing: more set ups, assess gap with commercial equipment

  • System support and GUI: Windows, Android, Web interface

  • Multi-channel SDRs: validate location from signal (e.g. like MLAT)

  • Output: ZeroMQ, APRS, ...

  • SpyServer support

  • Reporting signal strength per message and estimated frequency correction (e.g. to facilitate auto calibration ppm for rtl sdr dongles)

  • Resolving crash when Airspy HF+ is disconnected, does not seem to be a specific AIS-catcher issue. Use latest airspyhf lib.

  • RTL-TCP setting for timeout on connection (system default takes way too long)

  • Input: ZeroMQ/TCP-IP protocols, SoapySDR, SpyServer, LimeSDR mini, ...

  • ....