From 3abbf4aeba4fa6334c1e766797e553b1b77ffd08 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 1 Jun 2022 01:08:22 +0200 Subject: [PATCH] DOA2: fixed blind angle and documentation (again) --- plugins/channelmimo/doa2/doa2.cpp | 7 ++++-- plugins/channelmimo/doa2/doa2gui.cpp | 6 ++--- plugins/channelmimo/doa2/readme.md | 4 ++-- sdrbase/resources/webapi/doc/html2/index.html | 6 ++++- .../webapi/doc/swagger/include/DOA2.yaml | 3 +++ .../sdrangel/api/swagger/include/DOA2.yaml | 3 +++ swagger/sdrangel/code/html2/index.html | 6 ++++- .../code/qt5/client/SWGDOA2Report.cpp | 23 +++++++++++++++++++ .../sdrangel/code/qt5/client/SWGDOA2Report.h | 6 +++++ 9 files changed, 54 insertions(+), 10 deletions(-) diff --git a/plugins/channelmimo/doa2/doa2.cpp b/plugins/channelmimo/doa2/doa2.cpp index 8fe43811e..44cce2213 100644 --- a/plugins/channelmimo/doa2/doa2.cpp +++ b/plugins/channelmimo/doa2/doa2.cpp @@ -525,8 +525,11 @@ void DOA2::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) response.getDoa2Report()->setPhi(phi); float hwl = 1.5e8 / (m_deviceCenterFrequency + m_frequencyOffset); - float cosTheta = (getPhi() * hwl * 1000.0) / (M_PI * m_settings.m_basebandDistance); - // float blindAngle = ((cosTheta < -1.0) || (cosTheta > 1.0) ? 0 : std::acos(hwl * 1000.0 / m_settings.m_basebandDistance)) * (180/M_PI); + float cosTheta = (getPhi()/M_PI) * ((hwl * 1000.0) / m_settings.m_basebandDistance); + float blindAngle = (m_settings.m_basebandDistance > hwl * 1000.0) ? + std::acos((hwl * 1000.0) / m_settings.m_basebandDistance) * (180/M_PI) : + 0; + response.getDoa2Report()->setBlindAngle((int) blindAngle); float doaAngle = std::acos(cosTheta < -1.0 ? -1.0 : cosTheta > 1.0 ? 1.0 : cosTheta) * (180/M_PI); qDebug("DOA2::webapiFormatChannelReport: phi: %f cosT: %f DOAngle: %f", getPhi(), cosTheta, doaAngle); float posAngle = normalizeAngle(m_settings.m_antennaAz - doaAngle, 360.0f); // DOA angles are trigonometric but displayed angles are clockwise diff --git a/plugins/channelmimo/doa2/doa2gui.cpp b/plugins/channelmimo/doa2/doa2gui.cpp index 5011c28cd..cef04e58f 100644 --- a/plugins/channelmimo/doa2/doa2gui.cpp +++ b/plugins/channelmimo/doa2/doa2gui.cpp @@ -475,12 +475,10 @@ void DOA2GUI::updateScopeFScale() void DOA2GUI::updateDOA() { - float cosTheta = (m_doa2->getPhi() * m_hwl * 1000.0) / (M_PI * m_settings.m_basebandDistance); + float cosTheta = (m_doa2->getPhi()/M_PI) * ((m_hwl * 1000.0) / m_settings.m_basebandDistance); float blindAngle = (m_settings.m_basebandDistance > m_hwl * 1000.0) ? std::acos((m_hwl * 1000.0) / m_settings.m_basebandDistance) * (180/M_PI) : - (m_settings.m_basebandDistance < m_hwl * 1000.0) ? - std::acos(m_settings.m_basebandDistance / (m_hwl * 1000.0)) * (180/M_PI): - 0; + 0; ui->compass->setBlindAngle(blindAngle); float doaAngle = std::acos(cosTheta < -1.0 ? -1.0 : cosTheta > 1.0 ? 1.0 : cosTheta) * (180/M_PI); float posAngle = ui->antAz->value() - doaAngle; // DOA angles are trigonometric but displayed angles are clockwise diff --git a/plugins/channelmimo/doa2/readme.md b/plugins/channelmimo/doa2/readme.md index 21f6370b7..c7bcbb8b0 100644 --- a/plugins/channelmimo/doa2/readme.md +++ b/plugins/channelmimo/doa2/readme.md @@ -199,9 +199,9 @@ In general the angle can be calculated from the baseline distance D (distance be φ = π D cos(θ) / (λ/2) ⇒ cos(θ) = (φ / π) . ((λ/2) / D) -If D is larger than half the wavelength (λ/2) then a section in front of antenna 2 and at the back of antenna 1 cannot be reached since cos(θ) will lie in an interval smaller than [-1:1]. The value of half the sector angle is calculated assuming φ/π = 1 and thus cos(θ0) = (λ/2)/D This section is shown on the compass with a darker background (C.1.4) +If D is larger than λ/2 the possible values of cos(θ) do not cover the whole [-1:1] interval and thus there is a blind sector at the front of antenna 2 and the back of antenna 1 which is shown onthe compass as a darker area (C.1.4). However signals coming from this blind sector will fold into the valid sector. Putting antennas further apart than λ/2 can give more accurate measurements inside the valid sector at the condition you already validated the assunption that the incoming wave angle is insde the valid sector and that no significant signal from the blind sector can influence the masurement. One can imagine having a pair of directive antennas placed at a distance for which the valid sector matches the antenna system lobe for final accurate measurement. -If D is smaller than half the wavelength for the larger values of φ the resulting cos(θ) will lie outside the [-1:1] interval. In order to compute the acos the value is clamped to -1 or 1. Therefore some angles are inaccessible. Half the sector angle is given by cos(θ0) = D/(λ/2). +If D is smaller than λ/2 extreme incoming angles (0 or π) yield smaller φ which will be compensated by the (λ/2) / D factor however with less accuracy. There are two possible angles for the incoming wave leading to the same phase difference. One from the port side of the antenna system (positive) and the other from the starboard side (negative). diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index e0203e2fd..3578ff455 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -4543,6 +4543,10 @@ margin-bottom: 20px; "type" : "integer", "description" : "Calculated starboard side (negative) arrival angle in degrees from 0 to 180" }, + "blindAngle" : { + "type" : "integer", + "description" : "Blind angle (half sector)" + }, "fftSize" : { "type" : "integer", "description" : "Size of FFT used in correlation" @@ -56157,7 +56161,7 @@ except ApiException as e:
- Generated 2022-05-28T12:29:36.569+02:00 + Generated 2022-05-31T23:33:55.570+02:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/DOA2.yaml b/sdrbase/resources/webapi/doc/swagger/include/DOA2.yaml index 9ed1a5880..8f0891ceb 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/DOA2.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/DOA2.yaml @@ -57,6 +57,9 @@ DOA2Report: negAz: type: integer description: Calculated starboard side (negative) arrival angle in degrees from 0 to 180 + blindAngle: + type: integer + description: Blind angle (half sector) fftSize: type: integer description: Size of FFT used in correlation diff --git a/swagger/sdrangel/api/swagger/include/DOA2.yaml b/swagger/sdrangel/api/swagger/include/DOA2.yaml index 55c006fcc..8b6e3cca4 100644 --- a/swagger/sdrangel/api/swagger/include/DOA2.yaml +++ b/swagger/sdrangel/api/swagger/include/DOA2.yaml @@ -57,6 +57,9 @@ DOA2Report: negAz: type: integer description: Calculated starboard side (negative) arrival angle in degrees from 0 to 180 + blindAngle: + type: integer + description: Blind angle (half sector) fftSize: type: integer description: Size of FFT used in correlation diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index e0203e2fd..3578ff455 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -4543,6 +4543,10 @@ margin-bottom: 20px; "type" : "integer", "description" : "Calculated starboard side (negative) arrival angle in degrees from 0 to 180" }, + "blindAngle" : { + "type" : "integer", + "description" : "Blind angle (half sector)" + }, "fftSize" : { "type" : "integer", "description" : "Size of FFT used in correlation" @@ -56157,7 +56161,7 @@ except ApiException as e:
- Generated 2022-05-28T12:29:36.569+02:00 + Generated 2022-05-31T23:33:55.570+02:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGDOA2Report.cpp b/swagger/sdrangel/code/qt5/client/SWGDOA2Report.cpp index 8d6b95acb..a9d45fa89 100644 --- a/swagger/sdrangel/code/qt5/client/SWGDOA2Report.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGDOA2Report.cpp @@ -34,6 +34,8 @@ SWGDOA2Report::SWGDOA2Report() { m_pos_az_isSet = false; neg_az = 0; m_neg_az_isSet = false; + blind_angle = 0; + m_blind_angle_isSet = false; fft_size = 0; m_fft_size_isSet = false; channel_sample_rate = 0; @@ -52,6 +54,8 @@ SWGDOA2Report::init() { m_pos_az_isSet = false; neg_az = 0; m_neg_az_isSet = false; + blind_angle = 0; + m_blind_angle_isSet = false; fft_size = 0; m_fft_size_isSet = false; channel_sample_rate = 0; @@ -65,6 +69,7 @@ SWGDOA2Report::cleanup() { + } SWGDOA2Report* @@ -84,6 +89,8 @@ SWGDOA2Report::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&neg_az, pJson["negAz"], "qint32", ""); + ::SWGSDRangel::setValue(&blind_angle, pJson["blindAngle"], "qint32", ""); + ::SWGSDRangel::setValue(&fft_size, pJson["fftSize"], "qint32", ""); ::SWGSDRangel::setValue(&channel_sample_rate, pJson["channelSampleRate"], "qint32", ""); @@ -113,6 +120,9 @@ SWGDOA2Report::asJsonObject() { if(m_neg_az_isSet){ obj->insert("negAz", QJsonValue(neg_az)); } + if(m_blind_angle_isSet){ + obj->insert("blindAngle", QJsonValue(blind_angle)); + } if(m_fft_size_isSet){ obj->insert("fftSize", QJsonValue(fft_size)); } @@ -153,6 +163,16 @@ SWGDOA2Report::setNegAz(qint32 neg_az) { this->m_neg_az_isSet = true; } +qint32 +SWGDOA2Report::getBlindAngle() { + return blind_angle; +} +void +SWGDOA2Report::setBlindAngle(qint32 blind_angle) { + this->blind_angle = blind_angle; + this->m_blind_angle_isSet = true; +} + qint32 SWGDOA2Report::getFftSize() { return fft_size; @@ -187,6 +207,9 @@ SWGDOA2Report::isSet(){ if(m_neg_az_isSet){ isObjectUpdated = true; break; } + if(m_blind_angle_isSet){ + isObjectUpdated = true; break; + } if(m_fft_size_isSet){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGDOA2Report.h b/swagger/sdrangel/code/qt5/client/SWGDOA2Report.h index 0274f389f..568fba68d 100644 --- a/swagger/sdrangel/code/qt5/client/SWGDOA2Report.h +++ b/swagger/sdrangel/code/qt5/client/SWGDOA2Report.h @@ -50,6 +50,9 @@ public: qint32 getNegAz(); void setNegAz(qint32 neg_az); + qint32 getBlindAngle(); + void setBlindAngle(qint32 blind_angle); + qint32 getFftSize(); void setFftSize(qint32 fft_size); @@ -69,6 +72,9 @@ private: qint32 neg_az; bool m_neg_az_isSet; + qint32 blind_angle; + bool m_blind_angle_isSet; + qint32 fft_size; bool m_fft_size_isSet;