km4kfl/rsadsbma: A proof of concept for ADS-B decoding using two antennas and beamforming.
I noticed you have support for the BladeSDR. So, I thought, why not utilize the card to its full potential. The idea is to get more messages per second by finding messages that normally would have been missed by a single antenna. The cost is more CPU and core usage.
The idea is very simple. You take two coherent antenna sample streams, such as from the BladeSDR, and then you rotate one of the streams in phase, scale its amplitude or not, and then combine it with the first stream. This creates different antenna patterns and in general can sweep the beam created across space. This means some packets/messages/frame end up with an SNR that is high enough to be decoded.
The problem is it consumes much more CPU and it pretty much requires threads which means it’s going to work best on a system with multiple cores. I have a beefy computer. You’re milage may vary which is part of the reason I wanted to share it.
The program is very minimal. It is only meant to give you guys something to test and see if there is any who think it is worth the extra CPU.
First, you clone the repository. Then make sure you have Rustup installed which you can find at rustup.rs - The Rust toolchain installer. Also make sure Python 3.x is installed. Next, you go into the cloned directory and type python bladesdr.py --serial 9da --freq-offset 0 but use the serial for your BladeRF card and if you know it’s frequency inaccuracy you can type it in but zero should work fine. Now, if that succeeds the small Python frontend is running that will shovel raw samples out over TCP.
Next, you type something like cargo run --release – --thread-count 16 --cycle-count 20 and this runs the programs with 16 threads and 20 cycles per thread. The number of cycles is per thread, and it is the number of times the program randomly guesses a phase adjustment and amplitude. You need the number of threads to be no more than the number of cores in the machine. You can also try doubling the number if you have hyper-threading but I have not tested that. You may have to increase or decrease the cycles if you see a message that says TOO SLOW because what is happening is your losing samples because you’re not processing the buffers in time.
The idea is to find not the absolute maximum of cycles but a comfortable number that still gives some headroom without triggering the TOO SLOW message. That means your maximizing CPU usage to a comfortable level. This means more power consumption, heat, and all the other bad things about running your CPU hard. I’m not sure but you might get good results with a lower amount of CPU usage and the returns on using more CPU are diminishing. This I can not say which is why I only wrote a minimal program for testing.
As the program runs it prints elapsed and buffer time. You want elapsed to be lower than buffer time. It also prints statistics that look like this:
========= ANTENNA A =============
DF11: 1.3 24
DF17: 0.1 2
DF18: 0.0 0
OTHER: 1049.0 18997
ALL : 1050.5 19023
========= ANTENNA B =============
DF11: 0.7 13
DF17: 0.1 1
DF18: 0.0 0
OTHER: 1049.8 19010
ALL : 1050.5 19024
========= BOTH ANTENNAS =============
DF11: 2.9 53
DF17: 1.0 19
DF18: 0.2 3
OTHER: 21244.6 384718
ALL : 21248.8 384793
What this says is the rate per second and total count of each message type. It does that for DF11, DF17, and DF18. Anything else is other. The ALL column is for all messages even ones that could not decode - I might have to check that.
The interesting part is that it does the statistics for each of the antennas individually and then it does it for using both antennas. You should capture more messages using both antennas and it should be worth the extra CPU and power you are now consuming.
The antennas that you use should be the same, but you could use different ones. If you use directional antennas, you can try pointing them in the same direction or different. It shouldn’t hurt the program. You also want the same gear on each antenna and for it to be the same as possible. For example, if you use an LNA on one antenna then you want it on the other. If you use a filter on one antenna then you want to use the same brand and type of filter on the other. You can try using different brands of filters but your milage may vary and that goes for all gear. You essentially want the two antennas to be as identical as possible.
The idea here being used is the same as with beamforming. We are just simply searching around for packets in both time and space.
Feel free to fork the project, copy it, and do whatever you like. You can call it your own or send changes in the form of pull requests. I am not sure if I will work on it anymore. It might be that it isn’t worth it. This point here was to get the idea out and see if it’s worth it.



