diff --git a/src/FlightDisplay/VehicleWarnings.qml b/src/FlightDisplay/VehicleWarnings.qml index 595822e32072..d54b76e02e6b 100644 --- a/src/FlightDisplay/VehicleWarnings.qml +++ b/src/FlightDisplay/VehicleWarnings.qml @@ -12,6 +12,7 @@ import QtQuick import QGroundControl import QGroundControl.ScreenTools import QGroundControl.Controls +import QGroundControl.FactSystem Rectangle { anchors.margins: -ScreenTools.defaultFontPixelHeight @@ -19,11 +20,20 @@ Rectangle { width: warningsCol.width color: Qt.rgba(1, 1, 1, 0.5) radius: ScreenTools.defaultFontPixelWidth / 2 - visible: _noGPSLockVisible || _prearmErrorVisible + visible: _noGPSLockVisible || _prearmErrorVisible || (_showAltitudeWarning && (_vehicleAltitudeBelowMin || _vehicleAltitudeAboveMax || !_terrainDataAvailable.value)) property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle property bool _noGPSLockVisible: _activeVehicle && _activeVehicle.requiresGpsFix && !_activeVehicle.coordinate.isValid - property bool _prearmErrorVisible: _activeVehicle && !_activeVehicle.armed && _activeVehicle.prearmError && !_activeVehicle.healthAndArmingCheckReport.supported + property bool _prearmErrorVisible: _activeVehicle && !_activeVehicle.armed && _activeVehicle.prearmError + + property Fact _altitudeWarnThresholdEnabled: QGroundControl.settingsManager.flyViewSettings.altitudeWarnThresholdEnabled + property Fact _altitudeWarnMinAGL: QGroundControl.settingsManager.flyViewSettings.altitudeWarnMinAGL + property Fact _altitudeWarnMaxAGL: QGroundControl.settingsManager.flyViewSettings.altitudeWarnMaxAGL + property Fact _altitudeAboveTerrain: _activeVehicle ? _activeVehicle.altitudeAboveTerr : null + property Fact _terrainDataAvailable: _activeVehicle ? _activeVehicle.terrainDataAvailable : null + property bool _vehicleAltitudeBelowMin: _altitudeAboveTerrain ? (_altitudeAboveTerrain.value < _altitudeWarnMinAGL.value) : false + property bool _vehicleAltitudeAboveMax: _altitudeAboveTerrain ? (_altitudeAboveTerrain.value > _altitudeWarnMaxAGL.value) : false + property bool _showAltitudeWarning: _activeVehicle && _activeVehicle.flying && !_activeVehicle.landing && _altitudeWarnThresholdEnabled.value Column { id: warningsCol @@ -45,6 +55,30 @@ Rectangle { text: _activeVehicle ? _activeVehicle.prearmError : "" } + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + visible: _showAltitudeWarning && _terrainDataAvailable.value && _vehicleAltitudeBelowMin + color: "black" + font.pointSize: ScreenTools.largeFontPointSize + text: visible ? qsTr("Altitude below minimum threshold of %1 %2 above terrain: (%3 %4)").arg(_altitudeWarnMinAGL.value).arg(_altitudeWarnMinAGL.units).arg(_altitudeAboveTerrain.value.toFixed(2)).arg(_altitudeAboveTerrain.units) : "" + } + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + visible: _showAltitudeWarning && _terrainDataAvailable.value && _vehicleAltitudeAboveMax + color: "black" + font.pointSize: ScreenTools.largeFontPointSize + text: visible ? qsTr("Altitude above maximum threshold of %1 %2 above terrain: (%3 %4)").arg(_altitudeWarnMaxAGL.value).arg(_altitudeWarnMaxAGL.units).arg(_altitudeAboveTerrain.value.toFixed(2)).arg(_altitudeAboveTerrain.units) : "" + } + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + visible: _showAltitudeWarning && !_terrainDataAvailable.value + color: "black" + font.pointSize: ScreenTools.largeFontPointSize + text: qsTr("Terrain data not available at vehicle pos, altitude warning thresholds are disabled") + } + QGCLabel { anchors.horizontalCenter: parent.horizontalCenter visible: _prearmErrorVisible diff --git a/src/Settings/FlyView.SettingsGroup.json b/src/Settings/FlyView.SettingsGroup.json index 28469ed762b0..ed5945c5dd4f 100644 --- a/src/Settings/FlyView.SettingsGroup.json +++ b/src/Settings/FlyView.SettingsGroup.json @@ -102,6 +102,33 @@ "min": 3, "max": 60, "default": 10 +}, +{ + "name": "altitudeWarnThresholdEnabled", + "shortDesc": "Altitude warning threshold enabled", + "longDesc": "If this option is enabled, warn user if drone flies above or below altitude threshold.", + "type": "bool", + "default": false +}, +{ + "name": "altitudeWarnMinAGL", + "shortDesc": "Minimum altitude AGL for warning", + "longDesc": "Minimum altitude warning threshold in meters above ground level.", + "type": "double", + "default": 2.0, + "min": 0.0, + "units": "m", + "decimalPlaces": 1 +}, +{ + "name": "altitudeWarnMaxAGL", + "shortDesc": "Minimum altitude AGL for warning", + "longDesc": "Minimum altitude warning threshold in meters above ground level.", + "type": "double", + "default": 121.92, + "min": 0.0, + "units": "m", + "decimalPlaces": 1 } ] } diff --git a/src/Settings/FlyViewSettings.cc b/src/Settings/FlyViewSettings.cc index 883a400cd318..5c0bef2ea793 100644 --- a/src/Settings/FlyViewSettings.cc +++ b/src/Settings/FlyViewSettings.cc @@ -31,3 +31,6 @@ DECLARE_SETTINGSFACT(FlyViewSettings, updateHomePosition) DECLARE_SETTINGSFACT(FlyViewSettings, instrumentQmlFile2) DECLARE_SETTINGSFACT(FlyViewSettings, requestControlAllowTakeover) DECLARE_SETTINGSFACT(FlyViewSettings, requestControlTimeout) +DECLARE_SETTINGSFACT(FlyViewSettings, altitudeWarnThresholdEnabled) +DECLARE_SETTINGSFACT(FlyViewSettings, altitudeWarnMinAGL) +DECLARE_SETTINGSFACT(FlyViewSettings, altitudeWarnMaxAGL) diff --git a/src/Settings/FlyViewSettings.h b/src/Settings/FlyViewSettings.h index 706f7a03d0ed..e257b9e6cc18 100644 --- a/src/Settings/FlyViewSettings.h +++ b/src/Settings/FlyViewSettings.h @@ -34,4 +34,7 @@ class FlyViewSettings : public SettingsGroup DEFINE_SETTINGFACT(instrumentQmlFile2) DEFINE_SETTINGFACT(requestControlAllowTakeover) DEFINE_SETTINGFACT(requestControlTimeout) + DEFINE_SETTINGFACT(altitudeWarnThresholdEnabled) + DEFINE_SETTINGFACT(altitudeWarnMinAGL) + DEFINE_SETTINGFACT(altitudeWarnMaxAGL) }; diff --git a/src/UI/AppSettings/FlyViewSettings.qml b/src/UI/AppSettings/FlyViewSettings.qml index d314d64a690c..553927b387ee 100644 --- a/src/UI/AppSettings/FlyViewSettings.qml +++ b/src/UI/AppSettings/FlyViewSettings.qml @@ -114,6 +114,34 @@ SettingsPage { } } + SettingsGroupLayout { + Layout.fillWidth: true + heading: qsTr("Altitude above ground level warning threshold") + + FactCheckBoxSlider { + Layout.fillWidth: true + text: qsTr("Altitude warning enabled") + visible: fact.visible + fact: _flyViewSettings.altitudeWarnThresholdEnabled + } + + LabelledFactTextField { + Layout.fillWidth: true + label: qsTr("Minimum Altitude") + fact: _flyViewSettings.altitudeWarnMinAGL + visible: fact.visible + enabled: _flyViewSettings.altitudeWarnThresholdEnabled.value + } + + LabelledFactTextField { + Layout.fillWidth: true + label: qsTr("Maximum Altitude") + fact: _flyViewSettings.altitudeWarnMaxAGL + visible: fact.visible + enabled: _flyViewSettings.altitudeWarnThresholdEnabled.value + } + } + SettingsGroupLayout { Layout.fillWidth: true heading: qsTr("Guided Commands") diff --git a/src/Vehicle/FactGroups/VehicleFact.json b/src/Vehicle/FactGroups/VehicleFact.json index 8ecd9382b862..5dd92d49ceb1 100644 --- a/src/Vehicle/FactGroups/VehicleFact.json +++ b/src/Vehicle/FactGroups/VehicleFact.json @@ -87,6 +87,12 @@ "decimalPlaces": 1, "units": "m" }, +{ + "name": "terrainDataAvailable", + "shortDesc": "Terrain Data Available", + "type": "bool", + "defaultValue": false +}, { "name": "flightDistance", "shortDesc": "Flight Distance", diff --git a/src/Vehicle/FactGroups/VehicleFactGroup.cc b/src/Vehicle/FactGroups/VehicleFactGroup.cc index 0bc4d4fb2cc7..160cdd64135e 100644 --- a/src/Vehicle/FactGroups/VehicleFactGroup.cc +++ b/src/Vehicle/FactGroups/VehicleFactGroup.cc @@ -30,6 +30,7 @@ VehicleFactGroup::VehicleFactGroup(QObject *parent) _addFact(&_altitudeRelativeFact); _addFact(&_altitudeAMSLFact); _addFact(&_altitudeAboveTerrFact); + _addFact(&_terrainDataAvailableFact); _addFact(&_altitudeTuningFact); _addFact(&_altitudeTuningSetpointFact); _addFact(&_xTrackErrorFact); diff --git a/src/Vehicle/FactGroups/VehicleFactGroup.h b/src/Vehicle/FactGroups/VehicleFactGroup.h index bd99a9ab2432..702199741796 100644 --- a/src/Vehicle/FactGroups/VehicleFactGroup.h +++ b/src/Vehicle/FactGroups/VehicleFactGroup.h @@ -27,6 +27,7 @@ class VehicleFactGroup : public FactGroup Q_PROPERTY(Fact *altitudeRelative READ altitudeRelative CONSTANT) Q_PROPERTY(Fact *altitudeAMSL READ altitudeAMSL CONSTANT) Q_PROPERTY(Fact *altitudeAboveTerr READ altitudeAboveTerr CONSTANT) + Q_PROPERTY(Fact *terrainDataAvailable READ terrainDataAvailable CONSTANT) Q_PROPERTY(Fact *altitudeTuning READ altitudeTuning CONSTANT) Q_PROPERTY(Fact *altitudeTuningSetpoint READ altitudeTuningSetpoint CONSTANT) Q_PROPERTY(Fact *xTrackError READ xTrackError CONSTANT) @@ -61,6 +62,7 @@ class VehicleFactGroup : public FactGroup Fact *altitudeRelative() { return &_altitudeRelativeFact; } Fact *altitudeAMSL() { return &_altitudeAMSLFact; } Fact *altitudeAboveTerr() { return &_altitudeAboveTerrFact; } + Fact *terrainDataAvailable() { return &_terrainDataAvailableFact; } Fact *altitudeTuning() { return &_altitudeTuningFact; } Fact *altitudeTuningSetpoint() { return &_altitudeTuningSetpointFact; } Fact *xTrackError() { return &_xTrackErrorFact; } @@ -105,6 +107,7 @@ class VehicleFactGroup : public FactGroup Fact _altitudeRelativeFact = Fact(0, QStringLiteral("altitudeRelative"), FactMetaData::valueTypeDouble); Fact _altitudeAMSLFact = Fact(0, QStringLiteral("altitudeAMSL"), FactMetaData::valueTypeDouble); Fact _altitudeAboveTerrFact = Fact(0, QStringLiteral("altitudeAboveTerr"), FactMetaData::valueTypeDouble); + Fact _terrainDataAvailableFact = Fact(0, QStringLiteral("terrainDataAvailable"), FactMetaData::valueTypeBool); Fact _altitudeTuningFact = Fact(0, QStringLiteral("altitudeTuning"), FactMetaData::valueTypeDouble); Fact _altitudeTuningSetpointFact = Fact(0, QStringLiteral("altitudeTuningSetpoint"), FactMetaData::valueTypeDouble); Fact _xTrackErrorFact = Fact(0, QStringLiteral("xTrackError"), FactMetaData::valueTypeDouble); diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 42046b6db24a..1f95324dfc18 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -3766,11 +3766,19 @@ void Vehicle::_updateAltAboveTerrain() void Vehicle::_altitudeAboveTerrainReceived(bool success, QList heights) { if (!success) { - qCDebug(VehicleLog) << "_altitudeAboveTerrainReceived: terrain data not available for vehicle coordinate"; + qCDebug(VehicleLog) << "terrain data not available for vehicle coordinate"; + if (_coordinate.isValid() && + SettingsManager::instance()->flyViewSettings()->altitudeWarnThresholdEnabled()->rawValue().toBool() && _flying) { + _terrainDataAvailableFact.setRawValue(false); + } + _altitudeAboveTerrFact.setRawValue(qQNaN()); // Reset the altitude above terrain fact to NaN } else { + if (!_terrainDataAvailableFact.rawValue().toBool()) { + _terrainDataAvailableFact.setRawValue(true); + } // Query was succesful, save the data. - double terrainAltitude = heights[0]; - double altitudeAboveTerrain = altitudeAMSL()->rawValue().toDouble() - terrainAltitude; + const double terrainAltitude = heights[0]; + const double altitudeAboveTerrain = altitudeAMSL()->rawValue().toDouble() - terrainAltitude; _altitudeAboveTerrFact.setRawValue(altitudeAboveTerrain); } // Clean up