From 9024d3f6fa51dca60566a38a6dbe15e17f848c16 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 9 Nov 2020 07:28:43 +0100 Subject: [PATCH] ADS-B: reworked correlation threshold. Added RSSI. Corrected latitude negative shift. Implements #696 --- plugins/channelrx/demodadsb/adsbdemodgui.cpp | 26 ++++++++++--- plugins/channelrx/demodadsb/adsbdemodgui.h | 9 ++++- plugins/channelrx/demodadsb/adsbdemodgui.ui | 34 ++++++++++------ plugins/channelrx/demodadsb/adsbdemodreport.h | 19 +++++++-- .../channelrx/demodadsb/adsbdemodsettings.cpp | 2 +- .../demodadsb/adsbdemodsinkworker.cpp | 39 +++++++++---------- .../channelrx/demodadsb/adsbdemodsinkworker.h | 3 +- plugins/channelrx/demodadsb/readme.md | 3 +- 8 files changed, 89 insertions(+), 46 deletions(-) diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.cpp b/plugins/channelrx/demodadsb/adsbdemodgui.cpp index 60c69866f..08b8ca36f 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.cpp +++ b/plugins/channelrx/demodadsb/adsbdemodgui.cpp @@ -70,6 +70,7 @@ #define ADSB_COL_TIME 20 #define ADSB_COL_FRAMECOUNT 21 #define ADSB_COL_CORRELATION 22 +#define ADSB_COL_RSSI 23 const char *Aircraft::m_speedTypeNames[] = { "GS", "TAS", "IAS" @@ -529,7 +530,11 @@ QIcon *ADSBDemodGUI::getFlagIcon(const QString &country) } } -void ADSBDemodGUI::handleADSB(const QByteArray data, const QDateTime dateTime, float correlation) +void ADSBDemodGUI::handleADSB( + const QByteArray data, + const QDateTime dateTime, + float correlation, + float correlationOnes) { const char idMap[] = "?ABCDEFGHIJKLMNOPQRSTUVWXYZ????? ???????????????0123456789??????"; const QString categorySetA[] = { @@ -621,6 +626,7 @@ void ADSBDemodGUI::handleADSB(const QByteArray data, const QDateTime dateTime, f ui->adsbData->setItem(row, ADSB_COL_TIME, aircraft->m_timeItem); ui->adsbData->setItem(row, ADSB_COL_FRAMECOUNT, aircraft->m_adsbFrameCountItem); ui->adsbData->setItem(row, ADSB_COL_CORRELATION, aircraft->m_correlationItem); + ui->adsbData->setItem(row, ADSB_COL_RSSI, aircraft->m_rssiItem); // Look aircraft up in database if (m_aircraftInfo != nullptr) { @@ -709,7 +715,9 @@ void ADSBDemodGUI::handleADSB(const QByteArray data, const QDateTime dateTime, f .arg(CalcDb::dbPower(aircraft->m_minCorrelation), 3, 'f', 1) .arg(CalcDb::dbPower(aircraft->m_correlation), 3, 'f', 1) .arg(CalcDb::dbPower(aircraft->m_maxCorrelation), 3, 'f', 1)); - + m_correlationOnesAvg(correlationOnes); + aircraft->m_rssiItem->setText(QString("%1") + .arg(CalcDb::dbPower(m_correlationOnesAvg.instantAverage()), 3, 'f', 1)); // ADS-B, non-transponder ADS-B or TIS-B rebroadcast of ADS-B (ADS-R) if ((df == 17) || ((df == 18) && ((ca == 0) || (ca == 1) || (ca == 6)))) { @@ -796,9 +804,13 @@ void ADSBDemodGUI::handleADSB(const QByteArray data, const QDateTime dateTime, f latEven = dLatEven * ((j % 60) + aircraft->m_cprLat[0]); if (latEven >= 270.0f) latEven -= 360.0f; + else if (latEven <= -270.0f) + latEven += 360.0f; latOdd = dLatOdd * ((j % 59) + aircraft->m_cprLat[1]); if (latOdd >= 270.0f) latOdd -= 360.0f; + else if (latOdd <= -270.0f) + latOdd += 360.0f; if (aircraft->m_cprTime[0] >= aircraft->m_cprTime[1]) latitude = latEven; else @@ -980,8 +992,10 @@ bool ADSBDemodGUI::handleMessage(const Message& message) { ADSBDemodReport::MsgReportADSB& report = (ADSBDemodReport::MsgReportADSB&) message; handleADSB( - report.getData(), report.getDateTime(), - report.getPreambleCorrelation()); + report.getData(), + report.getDateTime(), + report.getPreambleCorrelation(), + report.getCorrelationOnes()); return true; } else if (ADSBDemodReport::MsgReportDemodStats::match(message)) @@ -1516,7 +1530,7 @@ void ADSBDemodGUI::on_displaySettings_clicked(bool checked) if (dialog.exec() == QDialog::Accepted) { bool unitsChanged = m_settings.m_siUnits != dialog.m_siUnits; - + m_settings.m_removeTimeout = dialog.m_removeTimeout; m_settings.m_airportRange = dialog.m_airportRange; m_settings.m_airportMinimumSize = dialog.m_airportMinimumSize; @@ -1867,6 +1881,7 @@ void ADSBDemodGUI::resizeTable() ui->adsbData->setItem(row, ADSB_COL_TIME, new QTableWidgetItem("99:99:99")); ui->adsbData->setItem(row, ADSB_COL_FRAMECOUNT, new QTableWidgetItem("Frames")); ui->adsbData->setItem(row, ADSB_COL_CORRELATION, new QTableWidgetItem("0.001/0.001/0.001")); + ui->adsbData->setItem(row, ADSB_COL_RSSI, new QTableWidgetItem("-100.0")); ui->adsbData->resizeColumnsToContents(); ui->adsbData->removeCellWidget(row, ADSB_COL_ICAO); ui->adsbData->removeCellWidget(row, ADSB_COL_FLIGHT); @@ -1891,5 +1906,6 @@ void ADSBDemodGUI::resizeTable() ui->adsbData->removeCellWidget(row, ADSB_COL_TIME); ui->adsbData->removeCellWidget(row, ADSB_COL_FRAMECOUNT); ui->adsbData->removeCellWidget(row, ADSB_COL_CORRELATION); + ui->adsbData->removeCellWidget(row, ADSB_COL_RSSI); ui->adsbData->setRowCount(row); } diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.h b/plugins/channelrx/demodadsb/adsbdemodgui.h index 0da28b19f..d00c6c961 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.h +++ b/plugins/channelrx/demodadsb/adsbdemodgui.h @@ -147,6 +147,7 @@ struct Aircraft { QTableWidgetItem *m_timeItem; QTableWidgetItem *m_adsbFrameCountItem; QTableWidgetItem *m_correlationItem; + QTableWidgetItem *m_rssiItem; Aircraft(ADSBDemodGUI *gui) : m_icao(0), @@ -201,6 +202,7 @@ struct Aircraft { m_timeItem = new QTableWidgetItem(); m_adsbFrameCountItem = new QTableWidgetItem(); m_correlationItem = new QTableWidgetItem(); + m_rssiItem = new QTableWidgetItem(); } }; @@ -458,6 +460,7 @@ private: AzEl m_azEl; // Position of station Aircraft *m_trackAircraft; // Aircraft we want to track in Channel Report MovingAverageUtil m_correlationAvg; + MovingAverageUtil m_correlationOnesAvg; Aircraft *m_highlightAircraft; // Aircraft we want to highlight, when selected in table float m_currentAirportRange; // Current settings, so we only update if changed @@ -479,7 +482,11 @@ private: void displayStreamIndex(); bool handleMessage(const Message& message); void updatePosition(Aircraft *aircraft); - void handleADSB(const QByteArray data, const QDateTime dateTime, float correlation); + void handleADSB( + const QByteArray data, + const QDateTime dateTime, + float correlation, + float correlationOnes); void resizeTable(); QString getDataDir(); QString getAirportDBFilename(); diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.ui b/plugins/channelrx/demodadsb/adsbdemodgui.ui index 1829da1d0..582c8ba0b 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.ui +++ b/plugins/channelrx/demodadsb/adsbdemodgui.ui @@ -6,7 +6,7 @@ 0 0 - 350 + 384 1046 @@ -36,7 +36,7 @@ 0 0 - 340 + 381 141 @@ -327,7 +327,7 @@ - + Demodulate all Mode-S frames, not just ADS-B @@ -347,7 +347,7 @@ - + Correlate against full preamble. @@ -378,16 +378,16 @@ Correlation threshold in dB. Lower values will increase the number of frames that can be received, but require more processing and possibly result in invalid frames. - -450 + 0 - 0 + 200 1 - 0 + 100 @@ -400,7 +400,7 @@ - -15.0 + 20.0 @@ -451,7 +451,7 @@ - + Display flight paths @@ -471,7 +471,7 @@ - + Enable feeding of received ADS-B messages to the specifed server. Right click for settings. @@ -547,7 +547,7 @@ 0 140 - 341 + 381 291 @@ -765,6 +765,11 @@ Correlation values for received frames. min/avg/max + + + RSSI + + @@ -774,7 +779,7 @@ 10 450 - 331 + 361 581 @@ -857,6 +862,11 @@
gui/valuedialz.h
1 + + ButtonSwitch + QToolButton +
gui/buttonswitch.h
+
deltaFrequency diff --git a/plugins/channelrx/demodadsb/adsbdemodreport.h b/plugins/channelrx/demodadsb/adsbdemodreport.h index cf8ccee72..9c4223480 100644 --- a/plugins/channelrx/demodadsb/adsbdemodreport.h +++ b/plugins/channelrx/demodadsb/adsbdemodreport.h @@ -38,21 +38,32 @@ public: QByteArray getData() const { return m_data; } QDateTime getDateTime() const { return m_dateTime; } float getPreambleCorrelation() const { return m_preambleCorrelation; } + float getCorrelationOnes() const { return m_correlationOnes; } - static MsgReportADSB* create(QByteArray data, float preambleCorrelation) + static MsgReportADSB* create( + QByteArray data, + float preambleCorrelation, + float correlationOnes + ) { - return new MsgReportADSB(data, preambleCorrelation); + return new MsgReportADSB(data, preambleCorrelation, correlationOnes); } private: QByteArray m_data; QDateTime m_dateTime; float m_preambleCorrelation; + float m_correlationOnes; - MsgReportADSB(QByteArray data, float preambleCorrelation) : + MsgReportADSB( + QByteArray data, + float preambleCorrelation, + float correlationOnes + ) : Message(), m_data(data), - m_preambleCorrelation(preambleCorrelation) + m_preambleCorrelation(preambleCorrelation), + m_correlationOnes(correlationOnes) { m_dateTime = QDateTime::currentDateTime(); } diff --git a/plugins/channelrx/demodadsb/adsbdemodsettings.cpp b/plugins/channelrx/demodadsb/adsbdemodsettings.cpp index b7a820ac8..a41153b89 100644 --- a/plugins/channelrx/demodadsb/adsbdemodsettings.cpp +++ b/plugins/channelrx/demodadsb/adsbdemodsettings.cpp @@ -34,7 +34,7 @@ void ADSBDemodSettings::resetToDefaults() { m_inputFrequencyOffset = 0; m_rfBandwidth = 2*1300000; - m_correlationThreshold = -20.0f; + m_correlationThreshold = 10.0f; //m_samplesPerFrame - 1; @@ -127,7 +127,7 @@ void ADSBDemodSinkWorker::run() } } - // Use the difference rather than absolute value, as we don't care how powerful the signal + // Use the ratio of ones power over zeros power, as we don't care how powerful the signal // is, just whether there is a good correlation with the preamble. The absolute value varies // too much with different radios, AGC settings and and the noise floor is not constant // (E.g: it's quite possible to receive multiple frames simultaneously, so we don't @@ -135,11 +135,11 @@ void ADSBDemodSinkWorker::run() // a stronger signals 0 chip position. Similarly a strong signal in an adjacent // channel may casue AGC to reduce gain, reducing the ampltiude of an otherwise // strong signal, as well as the noise floor) - // The scale factors account for different values of samplesPerBit and the different - // number of zeros and ones in the preamble + // The threshold accounts for the different number of zeros and ones in the preamble // If the sum of ones is exactly 0, it's probably no signal - Real preambleCorrelation = (preambleCorrelationOnes * m_correlationZerosScale) - - (preambleCorrelationZeros * m_correlationOnesScale); + + Real preambleCorrelation = preambleCorrelationOnes/preambleCorrelationZeros; // without one/zero ratio correction + if ((preambleCorrelation > m_correlationThresholdLinear) && (preambleCorrelationOnes != 0.0f)) { m_demodStats.m_correlatorMatches++; @@ -203,7 +203,8 @@ void ADSBDemodSinkWorker::run() { ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create( QByteArray((char*)data, sizeof(data)), - preambleCorrelation); + preambleCorrelation * m_correlationScale, + preambleCorrelationOnes / samplesPerChip); m_sink->getMessageQueueToGUI()->push(msg); } // Pass to worker to feed to other servers @@ -211,7 +212,8 @@ void ADSBDemodSinkWorker::run() { ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create( QByteArray((char*)data, sizeof(data)), - preambleCorrelation); + preambleCorrelation * m_correlationScale, + preambleCorrelationOnes / samplesPerChip); m_sink->getMessageQueueToWorker()->push(msg); } } @@ -244,7 +246,8 @@ void ADSBDemodSinkWorker::run() { ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create( QByteArray((char*)data, sizeof(data)), - preambleCorrelation); + preambleCorrelation * m_correlationScale, + preambleCorrelationOnes / samplesPerChip); m_sink->getMessageQueueToWorker()->push(msg); } } @@ -325,23 +328,19 @@ void ADSBDemodSinkWorker::handleInputMessages() ADSBDemodSettings settings = cfg->getSettings(); bool force = cfg->getForce(); + if (settings.m_correlateFullPreamble) { + m_correlationScale = 3.0; + } else { + m_correlationScale = 2.0; + } + if ((m_settings.m_correlationThreshold != settings.m_correlationThreshold) || force) { m_correlationThresholdLinear = CalcDb::powerFromdB(settings.m_correlationThreshold); + m_correlationThresholdLinear /= m_correlationScale; qDebug() << "m_correlationThresholdLinear: " << m_correlationThresholdLinear; } - if (settings.m_correlateFullPreamble) - { - m_correlationOnesScale = 1.0f / settings.m_samplesPerBit; - m_correlationZerosScale = 2.0 * 1.0f / settings.m_samplesPerBit; // As 2x more 0s than 1s - } - else - { - m_correlationOnesScale = 1.0f / settings.m_samplesPerBit; - m_correlationZerosScale = 3.0 * 1.0f / settings.m_samplesPerBit; // As 3x more 0s than 1s - } - m_settings = settings; delete message; } diff --git a/plugins/channelrx/demodadsb/adsbdemodsinkworker.h b/plugins/channelrx/demodadsb/adsbdemodsinkworker.h index 15b9bf04f..f1c1e7a71 100644 --- a/plugins/channelrx/demodadsb/adsbdemodsinkworker.h +++ b/plugins/channelrx/demodadsb/adsbdemodsinkworker.h @@ -74,8 +74,7 @@ private: ADSBDemodSink *m_sink; ADSBDemodStats m_demodStats; Real m_correlationThresholdLinear; - Real m_correlationZerosScale; - Real m_correlationOnesScale; + Real m_correlationScale; crcadsb m_crc; //!< Have as member to avoid recomputing LUT }; diff --git a/plugins/channelrx/demodadsb/readme.md b/plugins/channelrx/demodadsb/readme.md index 47867a44e..34cfecd82 100644 --- a/plugins/channelrx/demodadsb/readme.md +++ b/plugins/channelrx/demodadsb/readme.md @@ -116,7 +116,8 @@ The table displays the decoded ADS-B data for each aircraft along side data avai * Owner - The owner of the aircraft. (DB) * Updated - The local time at which the last ADS-B message was received. * RX Frames - A count of the number of ADS-B frames received from this aircraft. -* Correlation - Displays the minimun, average and maximum of the preamable correlation in dB for each recevied frame. These values can be used to help select a threshold setting. +* Correlation - Displays the minimun, average and maximum of the preamable correlation in dB for each recevied frame. These values can be used to help select a threshold setting. This correlation value is the ratio between the presence and absence of the signal corresponding to the "ones" and the "zeros" of the sync word adjusted by the bits ratio. It can be interpreted as a SNR estimation. +* RSSI - This Received Signal Strength Indicator is based on the signal power during correlation estimation. This is the power sum during the expected presence of the signal i.e. the "ones" of the sync word. If an ADS-B frame has not been received from an aircraft for 60 seconds, the aircraft is removed from the table and map. This timeout can be adjusted in the Display Settings dialog.