Working on native AirSpy support for dump1090-fa

Welcome @darrenchaker!

@obj or @prog Do you guys have any feel for what percentage of successfully decoded messages suffered a collision and were fixed vs how many had to be fixed for other reasons (fade, noise, etc)? I’ve read “A Simulation of Signal Collisions over the
North Atlantic for a Spaceborne ADS-B
Receiver Using Aloha Protocol”
but I’m wondering if you guys had any feel for “our” environment.

Another question… Can we assume that all of the “1” symbols in a message transmitted by an aircraft will remain in the same phase (other than doppler effects, etc)? I’m guessing “yes” since it’d be silly to start and stop a 1090 MHz LO between symbols. You’d just suppress the carrier for the “0” symbols. Also do you know if the LOs in the transponders are synchronized to anything (gps maybe) or are they free-running?

I have actually been experimenting with this myself recently.

The short answer is “it depends” :wink:

For some transponders I saw reasonably good phase stability between data symbols, but less so between the preamble and the data bits. But there is no requirement for this in the protocol. (DO-260C may introduce new requirements here as they’re looking at phase modulation to add more data to the existing format)

recent transponders will usually be pretty good about being on frequency. I doubt they run a GPSDO though (and anyway, unless you’re running one on the receive end too, it’s not very useful). but the spec says that the carrier is 1090 +/- 1 MHz (yes, really that much!) so you can in theory have transponders that are way off frequency.

My test demodulators that assumed constant phase (I tried a few variations) performed worse overall compared to one that was just looking at carrier amplitude. But, they could recover some messages that the amplitude approach couldn’t. So maybe the middle ground is to try both ways and see what sticks for each individual message.

The main two variations I tried were:
(a) average I and Q separately over the halfbit period and calculate magnitude from the averages. The idea here is that this works better than averaging magnitudes since noise will tend to have a zero mean on the I/Q channels but it’s non-zero if you take amplitudes and average them.

(b) compute Real[ x(t) . x*(t-1) ] across the halfbit (rotating each sample towards the real axis based on the phase of the previous sample). Think of this as something like FM demodulation but you’re interested in correlating the phases rather than differentiating them.

Yeah we’re on the same page. With a 12MHz sample rate and it being a nice multiple of the 2Mb/s symbol rate I’ve got more data to work with but it’s almost too much. :slight_smile: To keep the number of operations down I’d like to assume no slip but if I can assume no slip in the preamble, resync at the start of the data, the assume no slip during the message then that works.

I’ve been going back and forth between getting float-iq, float-real, int16-iq, int16-real and uint16-offset12 from the airspy. I’ve settled on the raw uint16-offset12 format because it’s the most flexible.
From that I can construct the others if needed.

I’m getting much fewer successful preamble decodes than an rtlsdr/demod_2400 but my successful message to successful preamble ratio is much higher. For rtlsdr/demod_2400, it seems to be about 1 message per 24 preambles where for the airspy with my demod it’s about 1 message per 8 preambles. Total number of decoded messages is still way too low with the my demod though.

Still moving along. The pesky day-job has been consuming more time than usual though. :slight_smile:

Definitely not. Even of the LO is not switched, many things may affect the phase. Multipath is one of them.

I read that paper a couple of months ago when trying to get an understanding of how adsb-b worked. The assumption in the paper is that any message collision results in a decode failure.

Is it actually possible to repair colliding messages and actually decode one of them?

yeah that’s why I qualified my question with “(other than doppler effects, etc)” :slight_smile:

It depends on a lot of things. Signal strength for one. If the signal strengths are different enough then it’s “possible” that you could decode whichever you locked on to first. In practice, I don’t know yet.

Oversimplification might be misleading when doing numerical stuff.

1 Like

True enough. I’d guess that the multipath effect would be changing constantly as the aircraft/terrain relationship changes. A Doppler shift would probably be less than 1 KHz or so.

Update:

I’m now running neck-and-neck with airspy_adsb in terms of usable messages and aircraft tracked. I’ve got lots of cleanup and documentation to do before I do some builds for folks to test but here’s what I’ve got…

A new multi-threaded “hirate” demodulator that will work with the following sample rates and sample formats:

  • 6 Msamples/sec IQ (12 MSamples/sec from the SDR)
  • 12 Msamples/sec IQ (24 MSamples/sec from the SDR)
  • 12 MSamples/sec unsigned 16-bit int
  • 20 MSamples/sec unsigned 16-bit int
  • 24 MSamples/sec unsigned 16-bit int
    These aren’t specific to the AirSpy but the SDR driver and the SDR has to support them.

There are new options for the following…

  • –sample-rate: 2.4, 6, 12, 20, 24. 2.4 is the default for non-AirSpy SDRs
  • –sample-format:
    • uc8: unsigned complex (IQ) 8-bit. The default for non-AirSpy.
    • sc16: signed complex (IQ) 16-bit.
    • sc16q11: signed complex (IQ) 16-bit Q11 format. The default for BladeRF SDRs.
    • s16: signed real 16-bit.
    • u16: unsigned real 16-bit. The default for AirSpy SDRs.
  • –sample-decimation: Simple decimation factor applied before conversion.
  • –sample-filter: A framework for applying filters to the input stream. I have a few filters built in but none of them produce better results than the default “noop” filter.
  • –demod: The demodulator to use.
    • 2400: The default for all non-AirSpy SDRs.
    • hirate: The High Rate demod. The default for AirSpy SDRs but can be used by any SDR that can provide at least a 6 MSample/sec sample rate.
  • –demod-threads: The number of threads the HiRate demodulator can use. The default is 1.

NOTE: Only the AirSpy and ifile SDRs support sample-format and decimation at the current time.

AirSpy specific options:

  • –lna-gain: 0-15
  • –mixer-gain: 0-15
  • –vga-gain: 0-15
  • –sensitivity-gain: 0-21 (sets one of the preconfigured lna, mixer and vga settings)
  • –linearity-gain: 0-21 (sets one of the preconfigured lna, mixer and vga settings)
  • –enable-lna-agc
  • –enable-mixer-agc
  • –enable-packing: USB packing of 16 bits to 12 bits.
  • –enable-rf-bias

I hope to have x86_64, arm and arm64/aarch64 builds for folks to test in the next few days. Getting pull requests ready for FA is going to take a little longer because I have to squash and arrange a few hundred commits into more digestible chunks. Not to mention removing a bunch of “Why the F**K doesn’t this work” comments. :slight_smile:

8 Likes

This is awesome. Waiting for build to try it.

Very nice. How does it compare with cpu usage?

Right now, it does use more CPU (almost twice that of airspy_adsb) but there are still optimizations I need to do.

Changed one line of code and it’s now using only 25% more cpu. :grinning:

1 Like

OMG stop teasing me, let me have it! :slight_smile:

I’m up for a side by side AirSpy test.

Well, it’s gonna be a bit longer. My RPi4 had been out of service for a while so I’ve been building and testing on x86_64 and aarch64 and was running about 45% CPU. I just got the RPi4 going again and with the same test input file, it was running 285% CPU. :frowning:

@obj Have you seen this before? warning: double close of net client and a subsequent SEGV.
I know why the SEGV is happening from looking at the coredump but do you know what condition could actually be triggering the double close? Seems to be happening every few hours of continuous operation with my demod even when single threaded.

Heap corruption? Unsafe calls into the main code from other threads? (Almost all of the dump1090 code is not thread safe)

I looked at the call paths for modesCloseClient and there’s no obvious path where it could get double called. What’s the call path you see?

I am looking up to test your build when it’s ready. For now I am very pleased by my Airspy performance (dynamic range) on the x86 laptop (64 bit), but if I can tinker something… why not.
BTW, I have a FlightFeeder connected to the same FA antenna (LA+splitter) and that’s my baseline.