Skip to content

Commit

Permalink
Add support for GNSS receiver resilience information
Browse files Browse the repository at this point in the history
Add GNSS signal authentication and interference indicators to the user
interface and get the required data from MAVLink.
  • Loading branch information
flyingthingsintothings committed May 6, 2024
1 parent 7614a91 commit a5377f6
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 34 deletions.
2 changes: 2 additions & 0 deletions qgcimages.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
<file alias="GeoFenceLight.svg">src/AutoPilotPlugins/PX4/Images/GeoFenceLight.svg</file>
<file alias="GeoTagIcon">src/AnalyzeView/GeoTagIcon.svg</file>
<file alias="Gps.svg">src/ui/toolbar/Images/Gps.svg</file>
<file alias="GpsAuthentication.svg">src/ui/toolbar/Images/GpsAuthentication.svg</file>
<file alias="GpsInterference.svg">src/ui/toolbar/Images/GpsInterference.svg</file>
<file alias="Hamburger.svg">src/ui/toolbar/Images/Hamburger.svg</file>
<file alias="Help.svg">src/FlightMap/Images/Help.svg</file>
<file alias="HelpBlack.svg">src/FlightMap/Images/HelpBlack.svg</file>
Expand Down
2 changes: 2 additions & 0 deletions qgroundcontrol.qrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<RCC>
<qresource prefix="/toolbar">
<file alias="ArmedIndicator.qml">src/ui/toolbar/ArmedIndicator.qml</file>
<file alias="GPSAuthenticationIndicator.qml">src/ui/toolbar/GPSAuthenticationIndicator.qml</file>
<file alias="GPSInterferenceIndicator.qml">src/ui/toolbar/GPSInterferenceIndicator.qml</file>
<file alias="GPSIndicator.qml">src/ui/toolbar/GPSIndicator.qml</file>
<file alias="GPSRTKIndicator.qml">src/ui/toolbar/GPSRTKIndicator.qml</file>
<file alias="JoystickIndicator.qml">src/ui/toolbar/JoystickIndicator.qml</file>
Expand Down
2 changes: 2 additions & 0 deletions src/FirmwarePlugin/FirmwarePlugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ const QVariantList& FirmwarePlugin::toolIndicators(const Vehicle*)
QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Controls/FlightModeIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/MessageIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSInterferenceIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSAuthenticationIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/TelemetryRSSIIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Controls/BatteryIndicator.qml")),
Expand Down
1 change: 1 addition & 0 deletions src/QmlControls/QGCPalette.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void QGCPalette::_buildMap()
DECLARE_QGC_COLOR(mapIndicator, "#585858", "#be781c", "#585858", "#be781c")
DECLARE_QGC_COLOR(mapIndicatorChild, "#585858", "#766043", "#585858", "#766043")
DECLARE_QGC_COLOR(colorGreen, "#009431", "#009431", "#00e04b", "#00e04b")
DECLARE_QGC_COLOR(colorYellow, "#ffdb00", "#ffdb00", "#e1c100", "#e1c100")
DECLARE_QGC_COLOR(colorOrange, "#b95604", "#b95604", "#de8500", "#de8500")
DECLARE_QGC_COLOR(colorRed, "#ed3939", "#ed3939", "#f32836", "#f32836")
DECLARE_QGC_COLOR(colorGrey, "#808080", "#808080", "#bfbfbf", "#bfbfbf")
Expand Down
1 change: 1 addition & 0 deletions src/QmlControls/QGCPalette.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class QGCPalette : public QObject
DEFINE_QGC_COLOR(brandingPurple, setBrandingPurple)
DEFINE_QGC_COLOR(brandingBlue, setBrandingBlue)
DEFINE_QGC_COLOR(colorGreen, setColorGreen)
DEFINE_QGC_COLOR(colorYellow, setColorYellow)
DEFINE_QGC_COLOR(colorOrange, setColorOrange)
DEFINE_QGC_COLOR(colorRed, setColorRed)
DEFINE_QGC_COLOR(colorGrey, setColorGrey)
Expand Down
15 changes: 15 additions & 0 deletions src/Vehicle/GPSFact.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@
"name": "count",
"shortDesc": "Sat Count",
"type": "uint32"
},
{
"name": "systemErrors",
"shortDesc": "General System Errors",
"type": "uint32"
},
{
"name": "spoofingState",
"shortDesc": "Signal Spoofing State",
"type": "uint8"
},
{
"name": "authenticationState",
"shortDesc": "Signal Authentication State",
"type": "uint8"
}
]
}
41 changes: 25 additions & 16 deletions src/Vehicle/VehicleGPSFactGroup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@

VehicleGPSFactGroup::VehicleGPSFactGroup(QObject* parent)
: FactGroup(1000, ":/json/Vehicle/GPSFact.json", parent)
, _latFact (0, _latFactName, FactMetaData::valueTypeDouble)
, _lonFact (0, _lonFactName, FactMetaData::valueTypeDouble)
, _mgrsFact (0, _mgrsFactName, FactMetaData::valueTypeString)
, _hdopFact (0, _hdopFactName, FactMetaData::valueTypeDouble)
, _vdopFact (0, _vdopFactName, FactMetaData::valueTypeDouble)
, _courseOverGroundFact (0, _courseOverGroundFactName, FactMetaData::valueTypeDouble)
, _countFact (0, _countFactName, FactMetaData::valueTypeInt32)
, _lockFact (0, _lockFactName, FactMetaData::valueTypeInt32)
, _latFact (0, _latFactName, FactMetaData::valueTypeDouble)
, _lonFact (0, _lonFactName, FactMetaData::valueTypeDouble)
, _mgrsFact (0, _mgrsFactName, FactMetaData::valueTypeString)
, _hdopFact (0, _hdopFactName, FactMetaData::valueTypeDouble)
, _vdopFact (0, _vdopFactName, FactMetaData::valueTypeDouble)
, _courseOverGroundFact (0, _courseOverGroundFactName, FactMetaData::valueTypeDouble)
, _countFact (0, _countFactName, FactMetaData::valueTypeInt32)
, _lockFact (0, _lockFactName, FactMetaData::valueTypeInt32)
, _systemErrorsFact (0, _systemErrorsFactName, FactMetaData::valueTypeUint32)
, _spoofingStateFact (0, _spoofingStateFactName, FactMetaData::valueTypeUint8)
, _authenticationStateFact (0, _authenticationStateFactName, FactMetaData::valueTypeUint8)
{
_addFact(&_latFact, _latFactName);
_addFact(&_lonFact, _lonFactName);
Expand All @@ -30,6 +33,9 @@ VehicleGPSFactGroup::VehicleGPSFactGroup(QObject* parent)
_addFact(&_courseOverGroundFact, _courseOverGroundFactName);
_addFact(&_lockFact, _lockFactName);
_addFact(&_countFact, _countFactName);
_addFact(&_systemErrorsFact, _systemErrorsFactName);
_addFact(&_spoofingStateFact, _spoofingStateFactName);
_addFact(&_authenticationStateFact, _authenticationStateFactName);

_latFact.setRawValue(std::numeric_limits<float>::quiet_NaN());
_lonFact.setRawValue(std::numeric_limits<float>::quiet_NaN());
Expand Down Expand Up @@ -61,14 +67,17 @@ void VehicleGPSFactGroup::_handleGpsRawInt(mavlink_message_t& message)
mavlink_gps_raw_int_t gpsRawInt;
mavlink_msg_gps_raw_int_decode(&message, &gpsRawInt);

lat()->setRawValue (gpsRawInt.lat * 1e-7);
lon()->setRawValue (gpsRawInt.lon * 1e-7);
mgrs()->setRawValue (convertGeoToMGRS(QGeoCoordinate(gpsRawInt.lat * 1e-7, gpsRawInt.lon * 1e-7)));
count()->setRawValue (gpsRawInt.satellites_visible == 255 ? 0 : gpsRawInt.satellites_visible);
hdop()->setRawValue (gpsRawInt.eph == UINT16_MAX ? qQNaN() : gpsRawInt.eph / 100.0);
vdop()->setRawValue (gpsRawInt.epv == UINT16_MAX ? qQNaN() : gpsRawInt.epv / 100.0);
courseOverGround()->setRawValue (gpsRawInt.cog == UINT16_MAX ? qQNaN() : gpsRawInt.cog / 100.0);
lock()->setRawValue (gpsRawInt.fix_type);
lat()->setRawValue (gpsRawInt.lat * 1e-7);
lon()->setRawValue (gpsRawInt.lon * 1e-7);
mgrs()->setRawValue (convertGeoToMGRS(QGeoCoordinate(gpsRawInt.lat * 1e-7, gpsRawInt.lon * 1e-7)));
count()->setRawValue (gpsRawInt.satellites_visible == 255 ? 0 : gpsRawInt.satellites_visible);
hdop()->setRawValue (gpsRawInt.eph == UINT16_MAX ? qQNaN() : gpsRawInt.eph / 100.0);
vdop()->setRawValue (gpsRawInt.epv == UINT16_MAX ? qQNaN() : gpsRawInt.epv / 100.0);
courseOverGround()->setRawValue (gpsRawInt.cog == UINT16_MAX ? qQNaN() : gpsRawInt.cog / 100.0);
lock()->setRawValue (gpsRawInt.fix_type);
systemErrors()->setRawValue (gpsRawInt.system_errors);
spoofingState()->setRawValue (gpsRawInt.spoofing_state);
authenticationState()->setRawValue (gpsRawInt.authentication_state);
}

void VehicleGPSFactGroup::_handleHighLatency(mavlink_message_t& message)
Expand Down
44 changes: 28 additions & 16 deletions src/Vehicle/VehicleGPSFactGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,29 @@ class VehicleGPSFactGroup : public FactGroup
public:
VehicleGPSFactGroup(QObject* parent = nullptr);

Q_PROPERTY(Fact* lat READ lat CONSTANT)
Q_PROPERTY(Fact* lon READ lon CONSTANT)
Q_PROPERTY(Fact* mgrs READ mgrs CONSTANT)
Q_PROPERTY(Fact* hdop READ hdop CONSTANT)
Q_PROPERTY(Fact* vdop READ vdop CONSTANT)
Q_PROPERTY(Fact* courseOverGround READ courseOverGround CONSTANT)
Q_PROPERTY(Fact* count READ count CONSTANT)
Q_PROPERTY(Fact* lock READ lock CONSTANT)
Q_PROPERTY(Fact* lat READ lat CONSTANT)
Q_PROPERTY(Fact* lon READ lon CONSTANT)
Q_PROPERTY(Fact* mgrs READ mgrs CONSTANT)
Q_PROPERTY(Fact* hdop READ hdop CONSTANT)
Q_PROPERTY(Fact* vdop READ vdop CONSTANT)
Q_PROPERTY(Fact* courseOverGround READ courseOverGround CONSTANT)
Q_PROPERTY(Fact* count READ count CONSTANT)
Q_PROPERTY(Fact* lock READ lock CONSTANT)
Q_PROPERTY(Fact* systemErrors READ systemErrors CONSTANT)
Q_PROPERTY(Fact* spoofingState READ spoofingState CONSTANT)
Q_PROPERTY(Fact* authenticationState READ authenticationState CONSTANT)

Fact* lat () { return &_latFact; }
Fact* lon () { return &_lonFact; }
Fact* mgrs () { return &_mgrsFact; }
Fact* hdop () { return &_hdopFact; }
Fact* vdop () { return &_vdopFact; }
Fact* courseOverGround () { return &_courseOverGroundFact; }
Fact* count () { return &_countFact; }
Fact* lock () { return &_lockFact; }
Fact* lat () { return &_latFact; }
Fact* lon () { return &_lonFact; }
Fact* mgrs () { return &_mgrsFact; }
Fact* hdop () { return &_hdopFact; }
Fact* vdop () { return &_vdopFact; }
Fact* courseOverGround () { return &_courseOverGroundFact; }
Fact* count () { return &_countFact; }
Fact* lock () { return &_lockFact; }
Fact* systemErrors () { return &_systemErrorsFact; }
Fact* spoofingState () { return &_spoofingStateFact; }
Fact* authenticationState () { return &_authenticationStateFact; }

// Overrides from FactGroup
virtual void handleMessage(Vehicle* vehicle, mavlink_message_t& message) override;
Expand All @@ -53,6 +59,9 @@ class VehicleGPSFactGroup : public FactGroup
const QString _courseOverGroundFactName = QStringLiteral("courseOverGround");
const QString _countFactName = QStringLiteral("count");
const QString _lockFactName = QStringLiteral("lock");
const QString _systemErrorsFactName = QStringLiteral("systemErrors");
const QString _spoofingStateFactName = QStringLiteral("spoofingState");
const QString _authenticationStateFactName = QStringLiteral("authenticationState");

Fact _latFact;
Fact _lonFact;
Expand All @@ -62,4 +71,7 @@ class VehicleGPSFactGroup : public FactGroup
Fact _courseOverGroundFact;
Fact _countFact;
Fact _lockFact;
Fact _systemErrorsFact;
Fact _spoofingStateFact;
Fact _authenticationStateFact;
};
6 changes: 5 additions & 1 deletion src/comm/MockLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,11 @@ void MockLink::_sendGpsRawInt(void)
0, // Altitude uncertainty in meters * 1000 (positive for up).
0, // Speed uncertainty in meters * 1000 (positive for up).
0, // Heading / track uncertainty in degrees * 1e5.
65535); // Yaw not provided
65535, // Yaw not provided
0, // No system errors
0, // No authentication info provided
0, // No jamming info provided
0); // No spoofing info provided
respondWithMavlinkMessage(msg);
}

Expand Down
2 changes: 2 additions & 0 deletions src/ui/toolbar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ add_custom_target(UiToolbarQml
ArmedIndicator.qml
BatteryIndicator.qml
FlightModeMenuIndicator.qml
GPSAuthenticationIndicator.qml
GPSInterferenceIndicator.qml
GPSIndicator.qml
GPSIndicatorPage.qml
GPSRTKIndicator.qml
Expand Down
68 changes: 68 additions & 0 deletions src/ui/toolbar/GPSAuthenticationIndicator.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/

import QtQuick
import QtQuick.Layouts

import QGroundControl
import QGroundControl.Controls
import QGroundControl.ScreenTools
import QGroundControl.Palette

//-------------------------------------------------------------------------
//-- GPS Authentication Indicator
Item {
id: control
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom

property bool showIndicator: _activeVehicle.gps.authenticationState.value !== 0

property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle

function authenticationIconColor() {
if (_activeVehicle.gps.authenticationState.value === 0) {
return qgcPal.colorGrey
} else if (_activeVehicle.gps.authenticationState.value === 1) {
return qgcPal.colorYellow
} else if (_activeVehicle.gps.authenticationState.value === 2) {
return qgcPal.colorRed
} else if (_activeVehicle.gps.authenticationState.value === 3) {
return qgcPal.colorGreen
} else if (_activeVehicle.gps.authenticationState.value === 4) {
return qgcPal.colorGrey
}
}

QGCColoredImage {
id: gpsAuthenticationIcon
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom
source: "/qmlimages/GpsAuthentication.svg"
fillMode: Image.PreserveAspectFit
sourceSize.height: height
opacity: 1
color: authenticationIconColor()
}

MouseArea {
anchors.fill: parent
onClicked: mainWindow.showIndicatorDrawer(gpsIndicatorPage, control)
}

Component {
id: gpsIndicatorPage

GPSIndicatorPage {

}
}
}
2 changes: 1 addition & 1 deletion src/ui/toolbar/GPSIndicator.qml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Item {
fillMode: Image.PreserveAspectFit
sourceSize.height: height
opacity: (_activeVehicle && _activeVehicle.gps.count.value >= 0) ? 1 : 0.5
color: qgcPal.buttonText
color: (_activeVehicle && _activeVehicle.gps.systemErrors.value !== 0) ? qgcPal.colorRed : qgcPal.buttonText
}

Column {
Expand Down
64 changes: 64 additions & 0 deletions src/ui/toolbar/GPSInterferenceIndicator.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/****************************************************************************
*
* (c) 2009-2024 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/

import QtQuick
import QtQuick.Layouts

import QGroundControl
import QGroundControl.Controls
import QGroundControl.ScreenTools
import QGroundControl.Palette

//-------------------------------------------------------------------------
//-- GPS Interference Indicator
Item {
id: control
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom

property bool showIndicator: _activeVehicle.gps.authenticationState.value !== 0

property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle

function interferenceIconColor() {
if (_activeVehicle.gps.spoofingState.value === 1) {
return qgcPal.colorGreen
} else if (_activeVehicle.gps.spoofingState.value === 2) {
return qgcPal.colorRed
} else if (_activeVehicle.gps.spoofingState.value === 3) {
return qgcPal.colorBlue
}
}

QGCColoredImage {
id: gpsSpoofingIcon
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom
source: "/qmlimages/GpsInterference.svg"
fillMode: Image.PreserveAspectFit
sourceSize.height: height
opacity: 1
color: interferenceIconColor()
}

MouseArea {
anchors.fill: parent
onClicked: mainWindow.showIndicatorDrawer(gpsIndicatorPage, control)
}

Component {
id: gpsIndicatorPage

GPSIndicatorPage {

}
}
}
4 changes: 4 additions & 0 deletions src/ui/toolbar/Images/GpsAuthentication.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/ui/toolbar/Images/GpsInterference.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a5377f6

Please sign in to comment.