dump1090 icon indicating copy to clipboard operation
dump1090 copied to clipboard

Feedback: Multi and Hirate Demodulators

Open gtjoseph opened this issue 4 years ago • 16 comments

I added your demod to my airspy/hirate stack and using the same 10 second capture file...

HiRate Multi
preambles 155088 55043
usable messages 12828 11383
unique acrft 178 170
cpu 32% 11%

HiRate doesn't yet use the starch stuff yet.

I think I'm going to look at your preamble detection code since your preamble/usable ratio is much better.

gtjoseph avatar Feb 08 '21 20:02 gtjoseph

I cut my CPU utilization down 5 points using boxcar_u16 but I'm still letting way too many unusable preambles through, which is where the CPU time is. I'll look more at that tomorrow as well as looking at if there's anything I can do to bring the demod_multi usable messages and aircraft up.

gtjoseph avatar Feb 09 '21 12:02 gtjoseph

Since the only thing changing in the demod function variations is DEMOD_SAMPLES_PER_HALFBIT, why not just pass it in to the function? Saves the complexity of the includes which allows editors like Eclipse to function better, and the Makefile to detect changes and there's no decrease in performance as far as I can see.

Might want to consider parameterizing the boxcar window for tuning purposes. Using a 12 MS/s rate, more messages are decoded if the boxcar window is actually 4 rather than 6 (DEMOD_SAMPLES_PER_HALFBIT).

What's your plan for signal and noise? Right now I'm keeping track of the message marks and spaces and using the average of the marks for the signal and the average of the spaces for the noise.

gtjoseph avatar Feb 10 '21 02:02 gtjoseph

why not just pass it in to the function?

The halfbit value is used in busy parts of the loop; I wanted to encourage the compiler to take advantage of it being constant without relying on constant propagation. More generally I wanted to vary a bunch of parameters that might not be so easy to pass in as arguments. I'm sure you can convince Eclipse etc to treat it as C (that's what the emacs mode line does for emacs..)

Might want to consider parameterizing the boxcar window for tuning purposes.

Yes, my previous experimentation showed something similar, I haven't got as far as reimplementing that in the clean version. Most of my testing so far has been done at 6MHz for USB bandwidth reasons (was running a rtlsdr in parallel on the same USB bus) where it has less of an effect.

What's your plan for signal and noise?

Average of marks is a reasonable thing for signal (I'm considering updating the definition for the 2.4MHz demodulator too).

Noise is an interesting one and I have been playing with a few ideas there, both for overall stats & for computing the noise estimate fed into the threshold calculation. The general shape so far is:

  1. break demodulation up into predictable blocks (probably implemented as a wrapper around the actual demodulator); do noise calculations aligned with those block boundaries only, so that demodulation that depends on the noise values is independent of the SDR block size and can be made independent of the sampling rate. (The current multirate demodulator will not produce identical results with different block sizes, because it doesn't do this and just averages the whole block it was given; it may also behave subtly differently at different sampling rates since that effectively makes it average over a different time period)

  2. look at blocks of non-signal data, skip over decoded messages. That is, when a message gets decoded or we hit the end of the calculation block, feed the data from the end of the last good message to the start of the next message (or end of block) into the noise calculation

  3. perhaps look at a subset of raw data per processing block, or only every Nth block, if the calculation is expensive (on the assumption that the noise level isn't expected to change rapidly)

  4. perhaps do some smoothing (EMA, something like that) of the noise value

  5. do something smarter than just a mean across each block. Some ideas: a) Nth-percentile of magnitudes. Since we only have 16 bits of magnitude this can actually be done in O(n) with essentially a radix sort into 64k buckets. b) FFT of the original IQ data, sort bins by power level, take the Nth percentile. In other contexts I've found this works well for signals with sharp peaks, but I'm not sure how good it would be with ADS-B data.

I've tested with a combination of 2+3+4+5a and it seemed to work out OK

mutability avatar Feb 10 '21 03:02 mutability

Cool!!

I'm sure you can convince Eclipse etc to treat it as C (that's what the emacs mode line does for emacs..)

Oh yeah. I had by something similar. :) demod_multi.inc does need to be added to the Makefile as a dependency though.

perhaps look at a subset of raw data per processing block, or only every Nth block, if the calculation is expensive (on the assumption that the noise level isn't expected to change rapidly)

I was actually thinking along these lines to create some sort of adaptive tuning mechanism. I.E. every "so often" run the same block through the decoder several times (not capturing and maybe in another thread) with a range of parameters and use the parameters of the best decode for the subsequent N blocks.

Just a few FYIs...

I had to change fabs to abs in tables.c and add -Wno-error=address-of-packed-member to the compile options. gcc-10 complains about alignment...

dsp/generated/../impl/magnitude_power_uc8.c:27:5: warning: converting a packed ‘uc8_t’ pointer (alignment 1) to a ‘uc8_u16_t’ pointer (alignment 2) may result in an unaligned pointer value [-Waddress-of-packed-member]
   27 |     const uc8_u16_t * restrict in_align = (const uc8_u16_t *) STARCH_ALIGNED(in);
      |     ^~~~~

gtjoseph avatar Feb 10 '21 14:02 gtjoseph

I had to change fabs to abs in tables.c and add -Wno-error=address-of-packed-member to the compile options. gcc-10 complains about alignment...

Huh, I thought I already fixed those: https://github.com/flightaware/dump1090/commit/3eb2783cdf85688e7babef7b912cd02210901cfe https://github.com/flightaware/dump1090/commit/dbdf18dcc0c90b2fce178f317c40db3eb8c8c024

mutability avatar Feb 10 '21 16:02 mutability

Yeah in the dev branch, bu they weren't cherry-picked to the pxsdr branch.

gtjoseph avatar Feb 10 '21 17:02 gtjoseph

I just pushed up a branch to my fork that has everything in it. https://github.com/gtjoseph/dump1090/tree/airspy-multi-hirate-complete

It's NOT meant to be a source of pull requests but rather a consolidation of what I've done for information, testing and feedback. It has the AirSpy support plus the 3 demodulators and a bunch of options to tune the multi and hirate demods. I also took the things common to both new demodulators and pull them up into demod.c (preamble search and signal/noise reporting).

I've been running both new demods side-by-side (2 airspys connected through a splitter to the same antenna) as well as using a 10 second 12MS/s file and the ifile sdr. The results are interesting. :)

When/If you're ready, just ell me what chunks you want in each poll request and I'll create new branches with 1 commit/pull request each.

I also picked up the latest mode_s changes you made.

gtjoseph avatar Feb 21 '21 22:02 gtjoseph

Great! Thanks for looking at this. I'm working through a bit of a backlog of other stuff at the moment but I should be back on demodulator work soon.

Did you have some results somewhere that I could look at?

mutability avatar Feb 22 '21 04:02 mutability

Did you have some results somewhere that I could look at?

I'm running an automated script to test all the combinations of parameters and collecting the results into a json file. There are 2688 combinations at about 12 seconds apiece. :) Should be done sometime overnight. I'll zip and attach the results in the (GMT-7) morning.

gtjoseph avatar Feb 23 '21 00:02 gtjoseph

Here are some results...

Tested on a [email protected] desktop. Input file for all runs was the same 10 seconds at 12MS/s unsigned 12-bit offset captured by airspy_rx. Contains about 13500 messages but it's hard to tell.

The attached zip file contains...

  • looptester: Runs all possible combinations of demodulator and demodulator options (5040 runs) and creates a zip file for each run containing the normal json output plus the new demod.json. The zip files for each run aren't included here.
  • demodtosql: Extracts the demod.json file from each run's zip file, concatenates them all into a single demod.json, creates a demod_brief.json file containing the info needed to asses demod performance, and creates an sqlite database of the results.
  • demodstats: Just runs the SQL queries that produced the below results.
  • demod.json: The combined demod.json from all runs.
  • demod_brief.json: Just the info from demod.json needed to asses demod performance.
  • demod_brief.csv: A CSV version of the above for import to the sqlite3 database.
  • demod.db; The sqlite3 database with one "stats" table with the results.

results.zip

Demod Ptdb Sw Pwl Pwh Dwl Dwh NML CPU Preambles No Fix 1-Bit Fix messages
multi 1 4 0 0 0 0 0 969 130477 11715 973 12688
multi 1 4 0 0 0 0 0 933 130477 11715 973 12688
multi 1 5 0 0 0 0 0 870 105965 11925 751 12676
multi 1 5 0 0 0 0 0 985 105965 11925 751 12676
multi 1 4 -1 1 0 0 0 1045 149081 11906 677 12583
multi 1 4 -1 1 0 0 0 1011 149081 11906 677 12583
multi 2 4 0 0 0 0 0 973 120731 11634 937 12571
multi 2 4 0 0 0 0 0 951 120731 11634 937 12571
multi 1 3 0 0 0 0 0 1070 153769 11510 1049 12559
multi 1 3 0 0 0 0 0 1061 153769 11510 1049 12559
Demod Ptdb Sw Pwl Pwh Mwl Mwh NML CPU Preambles No Fix 1-Bit Fix messages
hirate 1 4 0 0 -6 6 0 1520 117650 11478 1714 13192
hirate 1 4 0 0 -5 5 0 1485 117651 11478 1714 13192
hirate 1 4 0 0 -6 6 0 1637 117650 11478 1714 13192
hirate 1 4 0 0 -5 5 0 1491 117651 11478 1714 13192
hirate 1 4 0 0 -4 4 0 1354 117659 11477 1713 13190
hirate 1 4 0 0 -4 4 0 1419 117659 11477 1713 13190
hirate 1 4 0 0 -3 3 0 1352 117835 11470 1711 13181
hirate 1 4 0 0 -3 3 0 1401 117835 11470 1711 13181
hirate 1 4 0 0 -2 2 0 1212 118435 11460 1695 13155
hirate 1 4 0 0 -2 2 0 1209 118435 11460 1695 13155
Column Option Notes
Ptdb preamble-threshold
Sw smoother-window
Pwl preamble-window-low
PwH preamble-window-high
Mwl msg-window-low only hirate
Mwh msg-window-high only hirate
NML no-marl-limits only hirate
CPU ms over 10 second run

Example command line:

$ ./dump1090 --device-type ifile --net-bo-port 33005 --quiet --stats --wisdom [email protected] \
    --ifile ../../airspy/dump109012u2.bin --sample-format u16o12 --sample-rate 12 \
    --demod hirate --demod-preamble-threshold 1.0 --demod-smoother-window 4 \
     --demod-preamble-window -3:3 --demod-msg-window -5:5 --fix --demod-no-mark-limits

gtjoseph avatar Feb 25 '21 00:02 gtjoseph

@mutability Had a chance to look at any of this stuff yet?

gtjoseph avatar Mar 16 '21 13:03 gtjoseph

Not yet, sorry :/ Quite a lot of balls in the air at the moment.

mutability avatar Mar 16 '21 14:03 mutability

@mutability Any update?

gtjoseph avatar Apr 26 '21 02:04 gtjoseph

Hi! Unfortunately I've got a lot of other work going on at the moment and it'll probably be at least a month before I can get back to looking at this.

mutability avatar Apr 29 '21 05:04 mutability

@mutability Is there any hope at all here? Would you be OK with me creating a fork with the demod and airspy stuff and would you be OK with announcing it in the forums?

gtjoseph avatar Jun 03 '21 17:06 gtjoseph

Oh hey I don't want to slow you down with this - if you've got stuff you'd like to release yourself, absolutely go for it!

I'd definitely like to get this integrated in some form eventually, but higher priority stuff keeps popping up, sorry :(

We need a high-rate demodulator for some new hardware support, but that has been somewhat delayed by a pandemic + a global semiconductor shortage; once it bubbles back to the top I'll be working on this again.

mutability avatar Jun 04 '21 01:06 mutability