Inspiration
When a spacecraft is 20 light-minutes away, nobody on the ground can retune a radio in time. We wanted to know what that looks like on real data, so we picked SONATE-2, a CubeSat in orbit right now, and pulled its recordings from SatNOGS, a global network of volunteer ground stations.
What surprised us is how much gets thrown away. Near the horizon the signal weakens, a couple of bits flip, the packet's checksum fails, and the ground station discards the entire frame. We wondered how many of those "ghost frames" could be brought back automatically, with no human tuning.
How we built it
We worked in two stages: benchmark data first, then a real satellite.
1. RadioML (in the lab). We trained a 1-D CNN on RadioML 2016.10A (220,000 synthetic signals, 11 modulations) to classify modulation from raw I/Q samples. It reaches 84% accuracy at SNR ≥ 0 dB, matching published baselines. We also built a feature-based random forest as an interpretable alternative.
2. SONATE-2 (in the sky). SONATE-2 transmits 9600-baud GMSK. The SatNOGS audio is sampled at 48 kHz, so each bit spans
$$\frac{48\,000\ \text{samples/s}}{9600\ \text{bits/s}} = 5\ \text{samples per bit}.$$
Our decoder:
- removes Doppler drift with a 0.2 s moving average;
- searches 10 timing offsets per bit, so no clock setting is needed;
- undoes the G3RUH scrambler, $1 + x^{12} + x^{17}$, then NRZI, which makes signal polarity irrelevant;
- finds AX.25 packets and checks each one's CRC-16 checksum.
The key idea is repair. Every sampled bit keeps its confidence, meaning how far it was from zero. When a checksum fails, we flip the least-confident bits and re-check, a technique called Chase decoding. With the 8 weakest bits, single and double flips give
$$\binom{8}{1} + \binom{8}{2} = 8 + 28 = 36\ \text{attempts per failed packet.}$$
A teammate built a blind front end that finds packet bursts using FM "quieting" (noise drops when a carrier appears), with a threshold of $\text{median} + k \cdot \text{MAD}$ computed from each recording. It also estimates the baud rate blindly, getting 9574–9621 baud against the true 9600.
Results
- 780 checksum-verified telemetry packets from 3 real passes, with zero settings changed between passes or stations.
- 10 ghost frames: valid packets that SatNOGS's own decoder missed on the same recording. 8 came from repair, and 7 were confirmed by other ground stations.
- The receiver measures its own losses. We found a packet counter in the payload, so every gap is a missed packet: just 3% loss on the strongest pass, with no answer key needed.
- Re-acquisition within 0.4 s after every injected signal dropout.
- Repair doubles packets near the noise limit on the real recording, and lifts recovery from 52.5% to 85% at 9 dB in a controlled simulation, with zero false accepts.
Challenges we ran into
- Downloading the wrong satellites. Our first API query silently ignored the satellite filter, and we briefly "found" data from four unrelated satellites. We now verify the satellite ID on every download.
- The venue Wi-Fi blocked the storage server holding SatNOGS's decoded frames, so we switched to the SatNOGS DB API, which also meant working around its rate limits.
- Filtering made things worse. A textbook high-pass filter distorted the bits, because scrambled data has real content down to a few Hz. Replacing it with a gentle moving average took one test minute from 15 to 24 packets.
- Repair can lie. A 16-bit CRC passes random noise with probability $2^{-16} \approx \frac{1}{65\,536}$, and repair makes many attempts. We caught 3 junk frames with nonsense callsigns and added a second check that every real frame passes.
- Synthetic-to-real transfer. On real SONATE-2 audio our RadioML model says "FSK family" (correct), but noise does too once I/Q is rebuilt from audio. We report it as promising, not proven.
What we learned
- Real data humbles simulations. Every assumption, from filters to sample timing, needed checking against actual recordings.
- A checksum is evidence, not proof. Once you start repairing bits, you need a second line of defence against false accepts.
- Autonomy comes from structure in the signal. Self-synchronising scramblers, packet flags and an embedded counter let a receiver acquire, re-acquire and even audit itself, with no human in the loop.
- Honest negative results are worth reporting. The RadioML transfer test and our weak-pass losses point straight to the next steps: a tracking timing loop and raw I/Q input.

Log in or sign up for Devpost to join the conversation.