Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPS: Add support for GNSS receiver resilience information #11781

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions qgcimages.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@
<file alias="GeoTagIcon">src/AnalyzeView/GeoTagIcon.svg</file>
<file alias="Gps.svg">src/UI/toolbar/Images/Gps.svg</file>
<file alias="Hamburger.svg">src/UI/toolbar/Images/Hamburger.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="Help.svg">src/FlightMap/Images/Help.svg</file>
<file alias="HelpBlack.svg">src/FlightMap/Images/HelpBlack.svg</file>
<file alias="HITL.svg">src/AutoPilotPlugins/PX4/Images/HITL.svg</file>
Expand Down
2 changes: 2 additions & 0 deletions qgroundcontrol.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
<file alias="VTOLModeIndicator.qml">src/UI/toolbar/VTOLModeIndicator.qml</file>
<file alias="APMSupportForwardingIndicator.qml">src/UI/toolbar/APMSupportForwardingIndicator.qml</file>
<file alias="GimbalIndicator.qml">src/UI/toolbar/GimbalIndicator.qml</file>
<file alias="GPSAuthenticationIndicator.qml">src/UI/toolbar/GPSAuthenticationIndicator.qml</file>
<file alias="GPSInterferenceIndicator.qml">src/UI/toolbar/GPSInterferenceIndicator.qml</file>
</qresource>
<qresource prefix="/checklists">
<file alias="DefaultChecklist.qml">src/FlightDisplay/DefaultChecklist.qml</file>
Expand Down
2 changes: 1 addition & 1 deletion src/Comms/MockLink/MockLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

65535);
respondWithMavlinkMessage(msg);
}

Expand Down
2 changes: 2 additions & 0 deletions src/FirmwarePlugin/FirmwarePlugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,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 @@ -138,6 +138,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
97 changes: 97 additions & 0 deletions src/UI/toolbar/GPSAuthenticationIndicator.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/****************************************************************************
*
* (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 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
}
}

function getAuthenticationText(){
if (_activeVehicle.gps.authenticationState.value === 0) {
return qsTr("Unkown")
} else if (_activeVehicle.gps.authenticationState.value === 1) {
return qsTr("Initializing...")
} else if (_activeVehicle.gps.authenticationState.value === 2) {
return qsTr("Failed")
} else if (_activeVehicle.gps.authenticationState.value === 3) {
return qsTr("OK")
} else if (_activeVehicle.gps.authenticationState.value === 4) {
return qsTr("Disabled")
}
return qsTr("n/a")
}

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(authenticationContentComponent, control)
}

Component{
id: authenticationContentComponent

ColumnLayout{
spacing: ScreenTools.defaultFontPixelHeight / 2

property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle

SettingsGroupLayout {
heading: qsTr("GPS Authentication")
contentSpacing: 0
showDividers: false

LabelledLabel {
label: qsTr("Status")
labelText: getAuthenticationText()
}

}
}
}
}
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
25 changes: 25 additions & 0 deletions src/UI/toolbar/GPSIndicatorPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ ToolIndicatorPage {
property var rtkSettings: QGroundControl.settingsManager.rtkSettings
property bool useFixedPosition: rtkSettings.useFixedBasePosition.rawValue

function errorText() {
if (_activeVehicle.gps.systemErrors.value === 1) {
return qsTr("Incoming correction")
} else if (_activeVehicle.gps.systemErrors.value === 2) {
return qsTr("Configuration")
} else if (_activeVehicle.gps.systemErrors.value === 4) {
return qsTr("Software")
} else if (_activeVehicle.gps.systemErrors.value === 8) {
return qsTr("Antenna")
} else if (_activeVehicle.gps.systemErrors.value === 16) {
return qsTr("Event congestion")
} else if (_activeVehicle.gps.systemErrors.value === 32) {
return qsTr("CPU overload")
} else if (_activeVehicle.gps.systemErrors.value === 64) {
return qsTr("Output congestion")
}
return "Multiple errors"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worthwhile to concatenate all errors or does that not fit? I'm just thinking "Multiple errors" might not be very helpful, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was worried that too many errors would make it too crowdy even if it's unlikely to happen, I could try concatenatinge all them as it would make it clearer though

}

contentComponent: Component {
ColumnLayout {
spacing: ScreenTools.defaultFontPixelHeight / 2
Expand Down Expand Up @@ -58,6 +77,12 @@ ToolIndicatorPage {
label: qsTr("Course Over Ground")
labelText: activeVehicle ? activeVehicle.gps.courseOverGround.valueString : valueNA
}

LabelledLabel {
label: qsTr("GPS Error")
labelText: errorText()
visible: _activeVehicle.gps.systemErrors.value > 0
}
}

SettingsGroupLayout {
Expand Down
123 changes: 123 additions & 0 deletions src/UI/toolbar/GPSInterferenceIndicator.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/****************************************************************************
*
* (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.spoofingState.value > 0 || _activeVehicle.gps.jammingState.value > 0

property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle

function interferenceIconColor() {
if (_activeVehicle.gps.spoofingState.value === 1 && _activeVehicle.gps.jammingState.value === 1) {
return qgcPal.colorWhite
} else if ((_activeVehicle.gps.spoofingState.value === 2 && _activeVehicle.gps.jammingState.value<3) || (_activeVehicle.gps.jammingState.value === 2 && _activeVehicle.gps.spoofingState.value<3)) {
return qgcPal.colorOrange
} else if (_activeVehicle.gps.spoofingState.value === 3 || _activeVehicle.gps.jammingState.value === 3) {
return qgcPal.colorRed
}
return qgcPal.colorGrey
}

function spoofingText() {
if (_activeVehicle.gps.spoofingState.value === 1) {
return qsTr("OK")
} else if (_activeVehicle.gps.spoofingState.value === 2) {
return qsTr("Mitigated")
} else if (_activeVehicle.gps.spoofingState.value === 3) {
return qsTr("Ongoing")
}
return qsTr("n/a")
}
function jammingText() {
if (_activeVehicle.gps.jammingState.value === 1) {
return qsTr("OK")
} else if (_activeVehicle.gps.jammingState.value === 2) {
return qsTr("Mitigated")
} else if (_activeVehicle.gps.jammingState.value === 3) {
return qsTr("Ongoing")
}
return qsTr("n/a")
}

function interferenceText() {
if (_activeVehicle.gps.spoofingState.value === 1) {
return qsTr("OK")
} else if (_activeVehicle.gps.spoofingState.value === 2) {
return qsTr("Mitigated")
} else if (_activeVehicle.gps.spoofingState.value === 3) {
return qsTr("Ongoing")
}
return Integer.class.isIntsance(_activeVehicle.gps.spoofingState.value) ? qsTr("N/A") : qsTr("n/a")
}

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(gpsSpoofingPopup, control)
}

Component {
id: gpsSpoofingPopup

ToolIndicatorPage {
showExpand: expandedComponent ? true : false
contentComponent: spoofingContentComponent
}
}

Component{
id: spoofingContentComponent

ColumnLayout{
spacing: ScreenTools.defaultFontPixelHeight / 2

property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle

SettingsGroupLayout {
heading: qsTr("GPS Interference Status")
showDividers: true

LabelledLabel {
label: qsTr("GPS Jamming")
labelText: jammingText()
}

LabelledLabel {
label: qsTr("GPS Spoofing")
labelText: spoofingText()
}
}
}
}
}
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.
Loading
Loading