Stream1090

One thing i forgot: You know that you can specify multiple sample streams for one plot? You may actually then see by visual inspection how far the two streams are apart. Same holds for the messages. In your case this will plot both sample streams and overlay the two messages:

python3 vis_util.py --file /Users/jrg/Desktop/sample106-3.raw --format iq_int16 --fs 10000000 --file /Users/jrg/Desktop/sample107-3.raw --format iq_int16 --fs 10000000 --message "@0000000dcd958d7c6a589908859a28041552a7c0;@00000012ddd0a8001a8c9d500030a8000041313c;"

Thanks for the explanation - I was confused, as usual. I was thinking that the input to vis_util was a “message identifier” but it is actually the time stamp followed by the decoded message.

So the program just overlays a binary representation of that message on the amplitude data in the specified file at the timestamp provided. So you can overlay the message anywhere you like by adjusting the time stamp, or overlay the message in completely different file from the one it was decoded from.

Re specifying multiple message streams in one plot. I did that too, but didn’t post it.

Is this what you expected?

The previous plot was my earlier effort - it spanned both message pairs:

python3 vis_util.py --file /Users/jrg/Desktop/sample106-3.raw --format iq_int16 --fs 10000000 --file /Users/jrg/Desktop/sample107-3.raw --format iq_int16 --fs 10000000 --message "@0000000dcd958d7c6a589908859a28041552a7c0;@00000004f9d58d7c6a589908859a28041552a7c0;"

Here is the output of your suggested command looking at just one message.

1 Like

Ah sorry, that was me doing two things at the same time and copy pasted the wrong messages. The most interesting case is to look at two messages that are very close together.
First pair (ADS-B)

python3 vis_util.py --file /Users/jrg/Desktop/sample106-3.raw --format iq_int16 --fs 10000000 --file /Users/jrg/Desktop/sample107-3.raw --format iq_int16 --fs 10000000 --message @00000004f9d58d7c6a589908859a28041552a7c0;@0000000dcd958d7c6a589908859a28041552a7c0;"

Second Pair (COMM-B)

python3 vis_util.py --file /Users/jrg/Desktop/sample106-3.raw --format iq_int16 --fs 10000000 --file /Users/jrg/Desktop/sample107-3.raw --format iq_int16 --fs 10000000 --message "@0000001bb18fa8001a8c9d500030a8000041313c;@00000012ddd0a8001a8c9d500030a8000041313c;"

To answer this question:

Yes exactly that is the idea. You may now wonder why the hell i want to do something like this. The reason is that i have base raw recordings, these are being reprocessed to do for example upsampling, downsampling, DC removal or/and being sent through different low-pass filters. I need to be able to compare things and for this you need to be able to map them to a common time domain including messages you extracted. It really just a plotting script and does not do any signal processing.

Once you understand how the bits are being generated (1-Bit = high signal followd by low signal, 0 = low followed by high, the dashed line is the half bit boundary), you get a feeling for how much things are shifted. One side note: Do not think too much about gain. Gain is being computed based on the linear magnitude (left side). Only the gain of two signals from the same sample stream are comparable.

1 Like

So here is a quick update what is going on currently. Some of you who did some more extensive tests know that currently there are two ways to feed stream1090 from airspy_rx. There is the default and the raw way. Stream1090 will perform better on the default output. Why is that?

  1. Raw output works in a simple way: Take the data, output the 12-bit ADC values as 16-bit values (higher 4 bits not used).
  2. Default output is different (holds also for some other outputs except raw). The raw values are being converted and first some DC removal is applied. Afterwards the IQ-pairs are being run through a low-pass filter. And then finally being sent to the output.

So why not just removing the raw-way of things for stream1090, when airspy_rx already does DC removal and a lowpass? The answer is that i believe i can do it quicker. So i will move the DC-removal (done) and the low-pass into stream1090 (done but not in the repo). I also would like to properly separate the filters for input sampling speeds. In addition to that i am using some very inefficient script to “train” the filters. It is also not clear if the filter is also dependent on the internal sampling speed of stream1090.

My computer was hard at work today. In practice those filters look like that:

The idea is to use some black box optimizer, give it some decent initial filter. This is then modified (more guessing) and run through stream1090. Currently the score is the messages/second. Then repeat. After a few hours it will come up with a slightly better filter.

2 Likes

Here are the two charts

Message 1

Message 2

Those black bars at the very beginning and at the end are where the interesting part is. Can you zoom in, for example, on the beginning black bar to see the detail?

In another thread, obj and prog had a nice 19-tap FIR lowpass filter:

1 Like

Thx, i will have a look. For now i pushed a preliminary version to the repo.

It would be nice if some people give it a try. It is something along these lines (i know, i really have to update the Readme) :blush:

airspy_rx -t 5 -b 1 -g 15 -f 1090.00 -a 12000000 -r - | ./build/stream1090_6M -r -u 12 | ... whatever socat

So i am currently running this now for a few hours in a 6Msps → 12Msps config. It seems to do quite well on long messages. Maybe not the total messages/sec, but so far it looks good. However, today has been a bad day for testing due to heavy snowfall and the corresponding holding patterns to wait for the plows to finish their job.

Please if you report anything: I need to know the input speed and the internal upsampling speed. Edit: and also if you are doing 200 msg/s or 2000 msgs/s

rtl_sdr @2.4 will get some love at some point. But this requires some changes in the pipeline and at least the noolec dongles are not a big fan of DC removal at least how i do it. But i will get there.

Edit: Both the 6Msps and 10Msps are not running on the latest coefficients. The reason for this is simple. They both were setup for a passthrough setting, so 6:6 and 10:10 while the previous runs were not. We stick for now for the settings 6:12 and 10:24.

If you are the one who upsamples from 10 to 24. Update please. The training run came to an end finally.
Edit: raw mode of course.

1 Like

Digital Envelope Detection: The Good, the Bad, and the Ugly - Rick Lyons may be useful reading here.

The demodulator in dump1090 (and I guess stream1090 in IQ-input mode) is using the “asynchronous complex envelope detection” case in Fig 7, with the first few steps happening before samples arrive in dump1090.

from a quick read it looks like stream1090 in raw mode is a variation on “asynchronous real square-law envelope detection” in Fig 3 (with a different filtering arrangement). [if you’re continuing with that approach: you’re currently summing pairs of adjacent samples, but that’s actually not anything really quadrature-related, it’s just acting something like an extra LPF; you could roll that directly into the real LPF]

1 Like

Good article. I didn’t realize there were that many variations for envelope detection. All along, I was assuming Figure 7 approach.

One comment was pretty interesting. Instead of explicitly doing magnitude = sqrt(I^2 + Q^2) , you could do an approximation: magnitude = max(abs(I), abs(Q)) +(3/8)*min(abs(I), abs(Q)) to reduce processor load.

This sentence reminds me of a very old movie of the same name :wink:

1 Like

I guess you didn’t read the article.

The article itself hosted photos from the movie without mentioning these photos are from the movie of the same name :wink:

1 Like

If people are interested, i can also put the filter optimization code into the repo. Currently, i am running things for a 33 tap filter instead of 31. 33 is a bit more friendly to CPUs. One center element and 16 to each side.

It would also be very nice if someone of the 2k msg/s people can provide a sample. 30s or 60s raw mode. Something like this for 6Msps:

timeout 30s airspy_rx -t 5 -b 1 -g 16 -f 1090.0 -a 12000000 -r - > samples.raw

Or for 10msps

timeout 30s airspy_rx -t 5 -b 1 -g 16 -f 1090.0 -a 20000000 -r - > samples.raw

DM me if you want to provide a sample.

Sent over a 10msps example. Thanks.

1 Like