Significantly improved adsb demod

Change preamble detection, reduce cpu load
This commit is contained in:
heurist1
2021-10-15 14:26:33 +01:00
parent 0fed64636a
commit be01ca6da1
8 changed files with 6632 additions and 80 deletions

View File

@@ -34,68 +34,45 @@ void ADSBRXProcessor::execute(const buffer_c8_t& buffer) {
int8_t re, im;
float mag;
uint32_t c;
uint8_t level, bit, byte { };
//bool confidence;
bool first_in_window, last_in_window;
uint8_t bit, byte{};
// This is called at 2M/2048 = 977Hz
// One pulse = 500ns = 2 samples
// One bit = 2 pulses = 1us = 4 samples
if (!configured) return;
for (size_t i = 0; i < buffer.count; i++) {
// Compute sample's magnitude
re = buffer.p[i].real();
im = buffer.p[i].imag();
mag = __builtin_sqrtf((re * re) + (im * im)) * k;
// Only used for preamble detection and visualisation
level = (mag < 0.3) ? 0 : // Blank weak signals
(mag > prev_mag) ? 1 : 0;
re = buffer.p[i].real(); // make re float and scale it
im = buffer.p[i].imag(); // make re float and scale it
mag = ((re * re) + (im * im)) * (k*k);
if (decoding) {
// Decode
// 1 bit lasts 2 samples
if (sample_count & 1) {
if ((prev_mag < threshold_low) && (mag < threshold_low)) {
// Both under window, silence.
if (null_count > 3) {
const ADSBFrameMessage message(frame);
shared_memory.application_queue.push(message);
decoding = false;
} else
null_count++;
//confidence = false;
if (bit_count >= 112)
{
const ADSBFrameMessage message(frame);
shared_memory.application_queue.push(message);
decoding = false;
if (prev_mag > mag)
bit = 1;
else
bit = 0;
}
else
{
//confidence = true;
if (prev_mag > mag)
bit = 1;
else
bit = 0;
} else {
null_count = 0;
first_in_window = ((prev_mag >= threshold_low) && (prev_mag <= threshold_high));
last_in_window = ((mag >= threshold_low) && (mag <= threshold_high));
if ((first_in_window && !last_in_window) || (!first_in_window && last_in_window)) {
//confidence = true;
if (prev_mag > mag)
bit = 1;
else
bit = 0;
} else {
//confidence = false;
if (prev_mag > mag)
bit = 1;
else
bit = 0;
}
}
byte = bit | (byte << 1);
@@ -104,34 +81,66 @@ void ADSBRXProcessor::execute(const buffer_c8_t& buffer) {
// Got one byte
frame.push_byte(byte);
}
}
} // Second sample of each bit
sample_count++;
} else {
// Look for preamble
// Shift
// FIXSBT make this a ring buffer
// FIXSBT store level in int16 for quick compare to preamble
for (c = 0; c < (ADSB_PREAMBLE_LENGTH - 1); c++)
{
shifter[c] = shifter[c + 1];
shifter[15] = std::make_pair(mag, level);
}
shifter[15] = mag;
// Compare
for (c = 0; c < ADSB_PREAMBLE_LENGTH; c++) {
if (shifter[c].second != adsb_preamble[c])
break;
}
if (c == ADSB_PREAMBLE_LENGTH) {
decoding = true;
sample_count = 0;
null_count = 0;
bit_count = 0;
frame.clear();
// Compute preamble pulses power to set thresholds
threshold = (shifter[0].first + shifter[2].first + shifter[7].first + shifter[9].first) / 4;
threshold_high = threshold * 1.414; // +3dB
threshold_low = threshold * 0.707; // -3dB
}
// First check of relations between the first 10 samples
// representing a valid preamble. We don't even investigate further
// if this simple test is not passed
if (shifter[0] > shifter[1] &&
shifter[1] < shifter[2] &&
shifter[2] > shifter[3] &&
shifter[3] < shifter[0] &&
shifter[4] < shifter[0] &&
shifter[5] < shifter[0] &&
shifter[6] < shifter[0] &&
shifter[7] > shifter[8] &&
shifter[8] < shifter[9] &&
shifter[9] > shifter[6])
{
// The samples between the two spikes must be < than the average
// of the high spikes level. We don't test bits too near to
// the high levels as signals can be out of phase so part of the
// energy can be in the near samples
float high = (shifter[0] + shifter[2] + shifter[7] + shifter[9]) / 12;
if (shifter[4] < high &&
shifter[5] < high)
{
// Similarly samples in the range 11-14 must be low, as it is the
// space between the preamble and real data. Again we don't test
// bits too near to high levels, see above
if (shifter[11] < high &&
shifter[12] < high &&
shifter[13] < high &&
shifter[14] < high)
{
//if (c == ADSB_PREAMBLE_LENGTH) {
decoding = true;
sample_count = 0;
bit_count = 0;
frame.clear();
// Compute preamble pulses power to set thresholds
//threshold = (shifter[0] + shifter[2] + shifter[7] + shifter[9]) / 4;
// FIXSBT other use max * 0.2
// FIXSBT threshold_high and threshold_low should be ditched
//threshold_high = threshold * 1.414f; // +3dB
//threshold_low = threshold * 0.707f; // -3dB
} // 11-14 low
} // 4 & 5 high
} // Check for preamble pattern
}
prev_mag = mag;
@@ -140,7 +149,6 @@ void ADSBRXProcessor::execute(const buffer_c8_t& buffer) {
void ADSBRXProcessor::on_message(const Message* const message) {
if (message->id == Message::ID::ADSBConfigure) {
null_count = 0;
bit_count = 0;
sample_count = 0;
decoding = false;
@@ -148,8 +156,10 @@ void ADSBRXProcessor::on_message(const Message* const message) {
}
}
#ifndef _WIN32
int main() {
EventDispatcher event_dispatcher { std::make_unique<ADSBRXProcessor>() };
event_dispatcher.run();
return 0;
}
#endif

View File

@@ -51,8 +51,10 @@ private:
bool configured { false };
float prev_mag { 0 };
float threshold { }, threshold_low { }, threshold_high { };
size_t null_count { 0 }, bit_count { 0 }, sample_count { 0 };
std::pair<float, uint8_t> shifter[ADSB_PREAMBLE_LENGTH];
//size_t null_count{ 0 };
size_t bit_count { 0 }, sample_count { 0 };
//std::pair<float, uint8_t> shifter[ADSB_PREAMBLE_LENGTH];
float shifter[ADSB_PREAMBLE_LENGTH];
bool decoding { };
bool preamble { }, active { };
uint16_t bit_pos { 0 };