Python-based AIS (Automatic Identification System) receiver using a Software Defined Radio.
AIS-SDR captures the maritime AIS radio signal with an SDR, demodulates and decodes the messages broadcast by nearby vessels, and exposes the decoded data through a REST API.
The receiver implements the full receive chain in software:
SDR hardware → IQ streaming → GMSK/FM demodulation → clock recovery →
HDLC framing + CRC → AIS decoding (pyais) → REST API
Both AIS channels (A at 161.975 MHz and B at 162.025 MHz) can be decoded simultaneously from a single wideband SDR.
| Device | SoapySDR Driver | Notes |
|---|---|---|
| NESDR Smart V5 / generic RTL-SDR | rtlsdr |
250 kHz sample rate, single channel |
| HackRF One | hackrf |
2 MHz minimum sample rate, supports dual-channel |
Switching hardware requires only a change to config.yaml (sdr.driver); no code changes.
The signal pipeline automatically decimates higher sample rates (e.g. HackRF's 2 MHz)
down to the ~250 kHz used internally for clock recovery.
This project performs reception only. It does not transmit.
- Python 3.11+
- A working SoapySDR installation plus the driver module for your hardware
- Python dependencies listed in
requirements.txt
SoapySDR and its device modules are native libraries and are easiest to install via conda-forge:
# RTL-SDR
conda install -c conda-forge soapysdr soapysdr-module-rtlsdr
# HackRF One
conda install -c conda-forge soapysdr soapysdr-module-hackrfThen install the Python package and its dependencies:
pip install -e ".[dev]"All runtime parameters live in config.yaml at the project root.
RTL-SDR (single channel)
sdr:
driver: "rtlsdr"
sample_rate: 250000 # 250 kHz
center_freq: 161975000 # Channel A
gain: 30.0
buffer_size: 16384
clock_recovery: "multiphase"
dual_channel: falseHackRF One (dual channel)
sdr:
driver: "hackrf"
sample_rate: 2000000 # 2 MHz minimum; decimated to 250 kHz internally
center_freq: 162000000 # midpoint between Channel A and B
buffer_size: 131072 # ~65 ms per chunk at 2 MHz
invert_polarity: true # required for HackRF hardware polarity
hackrf_lna_gain: 40 # LNA: 0-40 dB (8 dB steps)
hackrf_vga_gain: 20 # VGA: 0-62 dB (2 dB steps); keep <=20 to avoid saturation
hackrf_amp_enable: false
clock_recovery: "multiphase"
dual_channel: trueclock_recovery options:
"multiphase"— open-loop, scans 8 clock phases in parallel, no convergence time (recommended; survives the silence gaps between AIS bursts)"mueller_muller"— feedback timing-error detector that tracks timing drift within a burst; loses lock during long inter-burst silence, so it is not recommended for the intermittent AIS Class B signal
python src/main.py
# or with a custom config:
python src/main.py --config /path/to/config.yamlThe REST API is then available at http://localhost:8000, with interactive
documentation at http://localhost:8000/docs.
| Method | Endpoint | Description |
|---|---|---|
| GET | /status |
System status |
| GET | /metrics |
Runtime metrics |
| POST | /receiver/start |
Start AIS reception |
| POST | /receiver/stop |
Stop AIS reception |
| GET | /receiver/state |
Receiver state |
| GET | /ais/messages |
Decoded AIS messages (optional limit, mmsi filters) |
| GET | /ais/messages/{mmsi} |
Messages for a specific MMSI |
| GET | /ais/export |
Download all decoded messages as a JSON attachment |
| Type | Description |
|---|---|
| 1 | Position Report Class A |
| 2 | Position Report Class A (Assigned) |
| 3 | Position Report Class A (Special) |
| 4 | Base Station Report |
| 5 | Static and Voyage Related Data |
| 9 | Standard SAR Aircraft Position Report |
| 14 | Safety Related Broadcast Message |
| 18 | Standard Class B CS Position Report |
| 21 | Aid-to-Navigation Report |
| 24 | Class B CS Static Data Report |
src/
ais_sdr/
core/ # Config, logging, models, exceptions
sdr/ # SDR device abstraction (SoapySDR)
signal_processing/ # GMSK demodulation, filtering, clock recovery
ais/ # HDLC framing, CRC, AIS decoding
api/ # FastAPI server and routes
main.py # Entry point
tests/
unit/ # Unit tests (no hardware required)
integration/
config.yaml # Runtime configuration
docs/
ARCHITECTURE.md # System architecture
SIGNAL-PIPELINE.md # Receive-chain signal theory
The test suite runs entirely without hardware (all SDR access is mocked):
pytestFor a detailed walkthrough of the receive chain — FM demodulation, DC correction,
multi-phase clock recovery, HDLC framing, CRC verification, and AIS payload decoding —
see docs/SIGNAL-PIPELINE.md. The overall module layout and
design decisions are documented in docs/ARCHITECTURE.md.
MIT © 2026 mdps
Disclaimer: experimental, receive-only project provided as is, without warranty; not for navigation or safety-of-life use — operate your SDR within your local radio regulations.
Un proyecto de mdps · 2026 · desarrollado en Murcia.