diff --git a/src/FactSystem/FactControls/AltitudeFactTextField.qml b/src/FactSystem/FactControls/AltitudeFactTextField.qml index f47f24da06627d30ce8e6318f1a2e9bd99781c8a..52d6529cca99f7f876cedce324d734c80a38b31f 100644 --- a/src/FactSystem/FactControls/AltitudeFactTextField.qml +++ b/src/FactSystem/FactControls/AltitudeFactTextField.qml @@ -21,34 +21,13 @@ FactTextField { showUnits: true showHelp: true - property int altitudeMode: QGroundControl.AltitudeModeNone - property bool showAboveTerrainWarning: true + property int altitudeMode: QGroundControl.AltitudeModeNone - readonly property string _altModeNoneExtraUnits: "" - readonly property string _altModeRelativeExtraUnits: qsTr("(Rel)") - readonly property string _altModeAbsoluteExtraUnits: qsTr("(AMSL)") - readonly property string _altModeAboveTerrainExtraUnits: qsTr("(Abv Terr)") - readonly property string _altModeTerrainFrameExtraUnits: qsTr("(TerrF)") - - property string _altitudeModeExtraUnits: _altModeNoneExtraUnits + property string _altitudeModeExtraUnits onAltitudeModeChanged: updateAltitudeModeExtraUnits() function updateAltitudeModeExtraUnits() { - if (altitudeMode === QGroundControl.AltitudeModeNone) { - _altitudeModeExtraUnits = _altModeNoneExtraUnits - } else if (altitudeMode === QGroundControl.AltitudeModeRelative) { - //_altitudeModeExtraUnits = _altModeRelativeExtraUnits - _altitudeModeExtraUnits = "" // Showing (rel) all the time is too noisy - } else if (altitudeMode === QGroundControl.AltitudeModeAbsolute) { - _altitudeModeExtraUnits = _altModeAbsoluteExtraUnits - } else if (altitudeMode === QGroundControl.AltitudeModeAboveTerrain) { - _altitudeModeExtraUnits = _altModeAboveTerrainExtraUnits - } else if (missionItem.altitudeMode === QGroundControl.AltitudeModeTerrainFrame) { - _altitudeModeExtraUnits = _altModeTerrainFrameExtraUnits - } else { - console.log("AltitudeFactTextField Internal error: Unknown altitudeMode", altitudeMode) - _altitudeModeExtraUnits = "" - } + _altitudeModeExtraUnits = QGroundControl.altitudeModeExtraUnits(altitudeMode); } } diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index 8af27ee18297bf2d15977377cc3a71df520a42f2..4a25e9593a77af9fdd9581476d08986c7e5f0fe9 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -46,6 +46,7 @@ const char* MissionController::_jsonVehicleTypeKey = "vehicleType"; const char* MissionController::_jsonCruiseSpeedKey = "cruiseSpeed"; const char* MissionController::_jsonHoverSpeedKey = "hoverSpeed"; const char* MissionController::_jsonParamsKey = "params"; +const char* MissionController::_jsonGlobalPlanAltitudeModeKey = "globalPlanAltitudeMode"; // Deprecated V1 format keys const char* MissionController::_jsonComplexItemsKey = "complexItems"; @@ -65,11 +66,10 @@ MissionController::MissionController(PlanMasterController* masterController, QOb _resetMissionFlightStatus(); _updateTimer.setSingleShot(true); - connect(&_updateTimer, &QTimer::timeout, this, &MissionController::_updateTimeout); - connect(_planViewSettings->takeoffItemNotRequired(), &Fact::rawValueChanged, this, &MissionController::_takeoffItemNotRequiredChanged); - - connect(this, &MissionController::missionDistanceChanged, this, &MissionController::recalcTerrainProfile); + connect(&_updateTimer, &QTimer::timeout, this, &MissionController::_updateTimeout); + connect(_planViewSettings->takeoffItemNotRequired(), &Fact::rawValueChanged, this, &MissionController::_takeoffItemNotRequiredChanged); + connect(this, &MissionController::missionDistanceChanged, this, &MissionController::recalcTerrainProfile); // The follow is used to compress multiple recalc calls in a row to into a single call. connect(this, &MissionController::_recalcMissionFlightStatusSignal, this, &MissionController::_recalcMissionFlightStatus, Qt::QueuedConnection); @@ -614,6 +614,8 @@ bool MissionController::_loadJsonMissionFileV1(const QJsonObject& json, QmlObjec return false; } + setGlobalAltitudeMode(QGroundControlQmlGlobal::AltitudeModeNone); // Mixed mode + // Read complex items QList surveyItems; QJsonArray complexArray(json[_jsonComplexItemsKey].toArray()); @@ -711,11 +713,14 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec { _jsonVehicleTypeKey, QJsonValue::Double, false }, { _jsonCruiseSpeedKey, QJsonValue::Double, false }, { _jsonHoverSpeedKey, QJsonValue::Double, false }, + { _jsonGlobalPlanAltitudeModeKey, QJsonValue::Double, false }, }; if (!JsonHelper::validateKeys(json, rootKeyInfoList, errorString)) { return false; } + setGlobalAltitudeMode(QGroundControlQmlGlobal::AltitudeModeNone); // Mixed mode + qCDebug(MissionControllerLog) << "MissionController::_loadJsonMissionFileV2 itemCount:" << json[_jsonItemsKey].toArray().count(); AppSettings* appSettings = qgcApp()->toolbox()->settingsManager()->appSettings(); @@ -746,6 +751,9 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec if (json.contains(_jsonHoverSpeedKey)) { appSettings->offlineEditingHoverSpeed()->setRawValue(json[_jsonHoverSpeedKey].toDouble()); } + if (json.contains(_jsonGlobalPlanAltitudeModeKey)) { + setGlobalAltitudeMode(json[_jsonGlobalPlanAltitudeModeKey].toVariant().value()); + } QGeoCoordinate homeCoordinate; if (!JsonHelper::loadGeoCoordinate(json[_jsonPlannedHomePositionKey], true /* altitudeRequired */, homeCoordinate, errorString)) { @@ -1044,6 +1052,8 @@ bool MissionController::loadTextFile(QFile& file, QString& errorString) QByteArray bytes = file.readAll(); QTextStream stream(bytes); + setGlobalAltitudeMode(QGroundControlQmlGlobal::AltitudeModeNone); // Mixed mode + QmlObjectListModel* loadedVisualItems = new QmlObjectListModel(this); if (!_loadTextMissionFile(stream, loadedVisualItems, errorStr)) { errorString = errorMessage.arg(errorStr); @@ -1080,11 +1090,12 @@ void MissionController::save(QJsonObject& json) } QJsonValue coordinateValue; JsonHelper::saveGeoCoordinate(settingsItem->coordinate(), true /* writeAltitude */, coordinateValue); - json[_jsonPlannedHomePositionKey] = coordinateValue; - json[_jsonFirmwareTypeKey] = _controllerVehicle->firmwareType(); - json[_jsonVehicleTypeKey] = _controllerVehicle->vehicleType(); - json[_jsonCruiseSpeedKey] = _controllerVehicle->defaultCruiseSpeed(); - json[_jsonHoverSpeedKey] = _controllerVehicle->defaultHoverSpeed(); + json[_jsonPlannedHomePositionKey] = coordinateValue; + json[_jsonFirmwareTypeKey] = _controllerVehicle->firmwareType(); + json[_jsonVehicleTypeKey] = _controllerVehicle->vehicleType(); + json[_jsonCruiseSpeedKey] = _controllerVehicle->defaultCruiseSpeed(); + json[_jsonHoverSpeedKey] = _controllerVehicle->defaultHoverSpeed(); + json[_jsonGlobalPlanAltitudeModeKey] = _globalAltMode; // Save the visual items @@ -2588,3 +2599,25 @@ MissionController::SendToVehiclePreCheckState MissionController::sendToVehiclePr } return SendToVehiclePreCheckStateOk; } + +QGroundControlQmlGlobal::AltitudeMode MissionController::globalAltitudeMode(void) +{ + return _globalAltMode; +} + +QGroundControlQmlGlobal::AltitudeMode MissionController::globalAltitudeModeDefault(void) +{ + if (_globalAltMode == QGroundControlQmlGlobal::AltitudeModeNone) { + return QGroundControlQmlGlobal::AltitudeModeRelative; + } else { + return _globalAltMode; + } +} + +void MissionController::setGlobalAltitudeMode(QGroundControlQmlGlobal::AltitudeMode altMode) +{ + if (_globalAltMode != altMode) { + _globalAltMode = altMode; + emit globalAltitudeModeChanged(); + } +} diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 0e466ff8391bbd00504911255b7b02a393086f17..473c9b17dd5da04b48ac21023a276dfbbb2a341a 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -15,6 +15,7 @@ #include "QGCLoggingCategory.h" #include "KMLPlanDomDocument.h" #include "QGCGeoBoundingCube.h" +#include "QGroundControlQmlGlobal.h" #include @@ -105,6 +106,9 @@ public: Q_PROPERTY(double minAMSLAltitude MEMBER _minAMSLAltitude NOTIFY minAMSLAltitudeChanged) ///< Minimum altitude associated with this mission. Used to calculate percentages for terrain status. Q_PROPERTY(double maxAMSLAltitude MEMBER _maxAMSLAltitude NOTIFY maxAMSLAltitudeChanged) ///< Maximum altitude associated with this mission. Used to calculate percentages for terrain status. + Q_PROPERTY(QGroundControlQmlGlobal::AltitudeMode globalAltitudeMode READ globalAltitudeMode WRITE setGlobalAltitudeMode NOTIFY globalAltitudeModeChanged) ///< AltitudeModeNone indicates the plan can used mixed modes + Q_PROPERTY(QGroundControlQmlGlobal::AltitudeMode globalAltitudeModeDefault READ globalAltitudeModeDefault NOTIFY globalAltitudeModeChanged) ///< Default to use for newly created items + Q_INVOKABLE void removeVisualItem(int viIndex); /// Add a new simple mission item to the list @@ -246,6 +250,10 @@ public: bool isEmpty (void) const; + QGroundControlQmlGlobal::AltitudeMode globalAltitudeMode(void); + QGroundControlQmlGlobal::AltitudeMode globalAltitudeModeDefault(void); + void setGlobalAltitudeMode(QGroundControlQmlGlobal::AltitudeMode altMode); + signals: void visualItemsChanged (void); void waypointPathChanged (void); @@ -284,6 +292,7 @@ signals: void recalcTerrainProfile (void); void _recalcMissionFlightStatusSignal (void); void _recalcFlightPathSegmentsSignal (void); + void globalAltitudeModeChanged (void); private slots: void _newMissionItemsAvailableFromVehicle (bool removeAllRequested); @@ -383,6 +392,8 @@ private: double _maxAMSLAltitude = 0; bool _missionContainsVTOLTakeoff = false; + QGroundControlQmlGlobal::AltitudeMode _globalAltMode = QGroundControlQmlGlobal::AltitudeModeRelative; + static const char* _settingsGroup; // Json file keys for persistence @@ -394,6 +405,7 @@ private: static const char* _jsonItemsKey; static const char* _jsonPlannedHomePositionKey; static const char* _jsonParamsKey; + static const char* _jsonGlobalPlanAltitudeModeKey; // Deprecated V1 format keys static const char* _jsonMavAutopilotKey; diff --git a/src/MissionManager/PlanMasterController.cc b/src/MissionManager/PlanMasterController.cc index 2d711b0892695951a2cbada26cc18d2d47714fe4..100eea3b7c14c7044bc946eaeb610d23a1376a7d 100644 --- a/src/MissionManager/PlanMasterController.cc +++ b/src/MissionManager/PlanMasterController.cc @@ -64,9 +64,9 @@ PlanMasterController::PlanMasterController(MAV_AUTOPILOT firmwareType, MAV_TYPE void PlanMasterController::_commonInit(void) { - connect(&_missionController, &MissionController::dirtyChanged, this, &PlanMasterController::dirtyChanged); - connect(&_geoFenceController, &GeoFenceController::dirtyChanged, this, &PlanMasterController::dirtyChanged); - connect(&_rallyPointController, &RallyPointController::dirtyChanged, this, &PlanMasterController::dirtyChanged); + connect(&_missionController, &MissionController::dirtyChanged, this, &PlanMasterController::dirtyChanged); + connect(&_geoFenceController, &GeoFenceController::dirtyChanged, this, &PlanMasterController::dirtyChanged); + connect(&_rallyPointController, &RallyPointController::dirtyChanged, this, &PlanMasterController::dirtyChanged); connect(&_missionController, &MissionController::containsItemsChanged, this, &PlanMasterController::containsItemsChanged); connect(&_geoFenceController, &GeoFenceController::containsItemsChanged, this, &PlanMasterController::containsItemsChanged); @@ -77,11 +77,7 @@ void PlanMasterController::_commonInit(void) connect(&_rallyPointController, &RallyPointController::syncInProgressChanged, this, &PlanMasterController::syncInProgressChanged); // Offline vehicle can change firmware/vehicle type - connect(_controllerVehicle, &Vehicle::capabilityBitsChanged, this, &PlanMasterController::_updateSupportsTerrain); - connect(_controllerVehicle, &Vehicle::vehicleTypeChanged, this, &PlanMasterController::_updateSupportsTerrain); - connect(_controllerVehicle, &Vehicle::vehicleTypeChanged, this, &PlanMasterController::_updatePlanCreatorsList); - - _updateSupportsTerrain(); + connect(_controllerVehicle, &Vehicle::vehicleTypeChanged, this, &PlanMasterController::_updatePlanCreatorsList); } @@ -134,7 +130,6 @@ void PlanMasterController::_activeVehicleChanged(Vehicle* activeVehicle) disconnect(_managerVehicle->missionManager(), nullptr, nullptr, nullptr); disconnect(_managerVehicle->geoFenceManager(), nullptr, nullptr, nullptr); disconnect(_managerVehicle->rallyPointManager(), nullptr, nullptr, nullptr); - disconnect(_managerVehicle, &Vehicle::capabilityBitsChanged, this, &PlanMasterController::_updateSupportsTerrain); } bool newOffline = false; @@ -160,9 +155,6 @@ void PlanMasterController::_activeVehicleChanged(Vehicle* activeVehicle) connect(_managerVehicle->rallyPointManager(), &RallyPointManager::sendComplete, this, &PlanMasterController::_sendRallyPointsComplete); } - // Change in capabilities will affect terrain support - connect(_managerVehicle, &Vehicle::capabilityBitsChanged, this, &PlanMasterController::_updateSupportsTerrain); - emit managerVehicleChanged(_managerVehicle); // Vehicle changed so we need to signal everything @@ -171,7 +163,6 @@ void PlanMasterController::_activeVehicleChanged(Vehicle* activeVehicle) emit syncInProgressChanged(); emit dirtyChanged(dirty()); emit offlineChanged(offline()); - _updateSupportsTerrain(); if (!_flyView) { if (!offline()) { @@ -630,12 +621,3 @@ void PlanMasterController::_updatePlanCreatorsList(void) } } } - -void PlanMasterController::_updateSupportsTerrain(void) -{ - bool supportsTerrain = _managerVehicle->capabilityBits() & MAV_PROTOCOL_CAPABILITY_TERRAIN; - if (supportsTerrain != _supportsTerrain) { - _supportsTerrain = supportsTerrain; - emit supportsTerrainChanged(supportsTerrain); - } -} diff --git a/src/MissionManager/PlanMasterController.h b/src/MissionManager/PlanMasterController.h index f48f806b83e82807ed94d17cf0b838199d31eecf..cd25156e564d4892829e389afdf60d3a58620eb2 100644 --- a/src/MissionManager/PlanMasterController.h +++ b/src/MissionManager/PlanMasterController.h @@ -51,7 +51,6 @@ public: Q_PROPERTY(QStringList loadNameFilters READ loadNameFilters CONSTANT) ///< File filter list loading plan files Q_PROPERTY(QStringList saveNameFilters READ saveNameFilters CONSTANT) ///< File filter list saving plan files Q_PROPERTY(QmlObjectListModel* planCreators MEMBER _planCreators NOTIFY planCreatorsChanged) - Q_PROPERTY(bool supportsTerrain READ supportsTerrain NOTIFY supportsTerrainChanged) /// Should be called immediately upon Component.onCompleted. Q_INVOKABLE void start(void); @@ -94,7 +93,6 @@ public: QStringList loadNameFilters (void) const; QStringList saveNameFilters (void) const; bool isEmpty (void) const; - bool supportsTerrain (void) const { return _supportsTerrain; } void setFlyView(bool flyView) { _flyView = flyView; } @@ -117,7 +115,6 @@ signals: void currentPlanFileChanged (); void planCreatorsChanged (QmlObjectListModel* planCreators); void managerVehicleChanged (Vehicle* managerVehicle); - void supportsTerrainChanged (bool supportsTerrain); private slots: void _activeVehicleChanged (Vehicle* activeVehicle); @@ -128,7 +125,6 @@ private slots: void _sendGeoFenceComplete (void); void _sendRallyPointsComplete (void); void _updatePlanCreatorsList (void); - void _updateSupportsTerrain (void); #if defined(QGC_AIRMAP_ENABLED) void _startFlightPlanning (void); #endif @@ -152,5 +148,4 @@ private: QString _currentPlanFile; bool _deleteWhenSendCompleted = false; QmlObjectListModel* _planCreators = nullptr; - bool _supportsTerrain = false; }; diff --git a/src/MissionManager/SimpleMissionItem.cc b/src/MissionManager/SimpleMissionItem.cc index 345f6aa11102011796b387f117f3c662e8705201..37bfd1fbda9313884e187d353ff8330d74df793e 100644 --- a/src/MissionManager/SimpleMissionItem.cc +++ b/src/MissionManager/SimpleMissionItem.cc @@ -103,10 +103,10 @@ SimpleMissionItem::SimpleMissionItem(PlanMasterController* masterController, boo }; const struct MavFrame2AltMode_s rgMavFrame2AltMode[] = { - { MAV_FRAME_GLOBAL_TERRAIN_ALT, QGroundControlQmlGlobal::AltitudeModeTerrainFrame }, - { MAV_FRAME_GLOBAL, QGroundControlQmlGlobal::AltitudeModeAbsolute }, - { MAV_FRAME_GLOBAL_RELATIVE_ALT, QGroundControlQmlGlobal::AltitudeModeRelative }, -}; + { MAV_FRAME_GLOBAL_TERRAIN_ALT, QGroundControlQmlGlobal::AltitudeModeTerrainFrame }, + { MAV_FRAME_GLOBAL, QGroundControlQmlGlobal::AltitudeModeAbsolute }, + { MAV_FRAME_GLOBAL_RELATIVE_ALT, QGroundControlQmlGlobal::AltitudeModeRelative }, + }; _altitudeMode = QGroundControlQmlGlobal::AltitudeModeRelative; for (size_t i=0; itoolbox()->settingsManager()->appSettings()->defaultMissionItemAltitude()->rawValue().toDouble(); _altitudeFact.setRawValue(defaultAlt); _missionItem._param7Fact.setRawValue(defaultAlt); + setAltitudeMode(_missionController->globalAltitudeModeDefault()); } else { _altitudeFact.setRawValue(0); _missionItem._param7Fact.setRawValue(0); diff --git a/src/PlanView/CameraCalcGrid.qml b/src/PlanView/CameraCalcGrid.qml index f651208b18d2f9dffb3c483f5998500e217a847f..a2b5e985d3fc4e5b175e4afa5e0d96c4e011e423 100644 --- a/src/PlanView/CameraCalcGrid.qml +++ b/src/PlanView/CameraCalcGrid.qml @@ -96,7 +96,6 @@ Column { AltitudeFactTextField { fact: cameraCalc.distanceToSurface altitudeMode: distanceToSurfaceAltitudeMode - showAboveTerrainWarning: false enabled: fixedDistanceRadio.checked Layout.fillWidth: true } @@ -130,7 +129,6 @@ Column { AltitudeFactTextField { fact: cameraCalc.distanceToSurface altitudeMode: distanceToSurfaceAltitudeMode - showAboveTerrainWarning: false Layout.fillWidth: true } diff --git a/src/PlanView/MissionSettingsEditor.qml b/src/PlanView/MissionSettingsEditor.qml index 54751cfd30105586950433a1dd1630f6200e6abf..d0189e03453d8f1358fc60d3f982746258266f04 100644 --- a/src/PlanView/MissionSettingsEditor.qml +++ b/src/PlanView/MissionSettingsEditor.qml @@ -24,7 +24,6 @@ Rectangle { property var _missionController: _masterControler.missionController property var _controllerVehicle: _masterControler.controllerVehicle property bool _vehicleHasHomePosition: _controllerVehicle.homePosition.isValid - property bool _enableOfflineVehicleCombos: _noMissionItemsAdded property bool _showCruiseSpeed: !_controllerVehicle.multiRotor property bool _showHoverSpeed: _controllerVehicle.multiRotor || _controllerVehicle.vtol property bool _multipleFirmware: QGroundControl.supportedFirmwareCount > 2 @@ -46,7 +45,7 @@ Rectangle { QGCPalette { id: qgcPal } QGCFileDialogController { id: fileController } - Column { + ColumnLayout { id: valuesColumn anchors.margins: _margin anchors.left: parent.left @@ -54,20 +53,87 @@ Rectangle { anchors.top: parent.top spacing: _margin - GridLayout { - anchors.left: parent.left - anchors.right: parent.right - columnSpacing: ScreenTools.defaultFontPixelWidth - rowSpacing: columnSpacing - columns: 2 + QGCLabel { + text: qsTr("All Altitudes") + font.pointSize: ScreenTools.smallFontPointSize + } + QGCComboBox { + id: altModeCombo + model: enumStrings + Layout.fillWidth: true + enabled: _noMissionItemsAdded + onActivated: _missionController.globalAltitudeMode = enumValues[index] + Component.onCompleted: buildEnumStrings() - QGCLabel { - text: qsTr("Waypoint alt") + readonly property var enumStringsBase: [ QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeRelative), + QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeAbsolute), + QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeAboveTerrain), + QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeTerrainFrame), + qsTr("Mixed Modes") ] + readonly property var enumValuesBase: [QGroundControl.AltitudeModeRelative, QGroundControl.AltitudeModeAbsolute, QGroundControl.AltitudeModeAboveTerrain, QGroundControl.AltitudeModeTerrainFrame, QGroundControl.AltitudeModeNone ] + + property var enumStrings: [ ] + property var enumValues: [ ] + + function buildEnumStrings() { + var newEnumStrings = enumStringsBase.slice(0) + var newEnumValues = enumValuesBase.slice(0) + if (!_controllerVehicle.supportsTerrainFrame) { + // We need to find and pull out the QGroundControl.AltitudeModeTerrainFrame values + var deleteIndex = newEnumValues.lastIndexOf(QGroundControl.AltitudeModeTerrainFrame) + newEnumStrings.splice(deleteIndex, 1) + newEnumValues.splice(deleteIndex, 1) + if (_missionController.globalAltitudeMode == QGroundControl.AltitudeModeTerrainFrame) { + _missionController.globalAltitudeMode = QGroundControl.AltitudeModeAboveTerrain + } + } + enumStrings = newEnumStrings + enumValues = newEnumValues + currentIndex = enumValues.lastIndexOf(_missionController.globalAltitudeMode) } - FactTextField { - fact: QGroundControl.settingsManager.appSettings.defaultMissionItemAltitude - Layout.fillWidth: true + + Connections { + target: _controllerVehicle + onSupportsTerrainFrameChanged: altModeCombo.buildEnumStrings() } + } + QGCLabel { + Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + font.pointSize: ScreenTools.smallFontPointSize + text: switch(_missionController.globalAltitudeMode) { + case QGroundControl.AltitudeModeAboveTerrain: + qsTr("Specified altitudes are distance above terrain. Actual altitudes sent to vehicle are calculated from terrain data and sent in AMSL") + break + case QGroundControl.AltitudeModeTerrainFrame: + qsTr("Specified altitudes are distance above terrain. The actual altitude flown is controlled by the vehicle either from terrain height maps being sent to vehicle or a distance sensor.") + break + case QGroundControl.AltitudeModeNone: + qsTr("The altitude mode can differ for each individual item.") + break + default: + "" + break + } + visible: _missionController.globalAltitudeMode == QGroundControl.AltitudeModeAboveTerrain || _missionController.globalAltitudeMode == QGroundControl.AltitudeModeTerrainFrame || _missionController.globalAltitudeMode == QGroundControl.AltitudeModeNone + } + + QGCLabel { + text: qsTr("Initial Waypoint Alt") + font.pointSize: ScreenTools.smallFontPointSize + } + AltitudeFactTextField { + fact: QGroundControl.settingsManager.appSettings.defaultMissionItemAltitude + altitudeMode: _missionController.globalAltitudeModeDefault + Layout.fillWidth: true + } + + GridLayout { + Layout.fillWidth: true + columnSpacing: ScreenTools.defaultFontPixelWidth + rowSpacing: columnSpacing + columns: 2 QGCCheckBox { id: flightSpeedCheckBox @@ -85,10 +151,9 @@ Rectangle { } Column { - anchors.left: parent.left - anchors.right: parent.right - spacing: _margin - visible: !_simpleMissionStart + Layout.fillWidth: true + spacing: _margin + visible: !_simpleMissionStart CameraSection { id: cameraSection @@ -132,11 +197,11 @@ Rectangle { fact: QGroundControl.settingsManager.appSettings.offlineEditingFirmwareType indexModel: false Layout.preferredWidth: _fieldWidth - visible: _multipleFirmware && _enableOfflineVehicleCombos + visible: _multipleFirmware && _noMissionItemsAdded } QGCLabel { text: _controllerVehicle.firmwareTypeString - visible: _multipleFirmware && !_enableOfflineVehicleCombos + visible: _multipleFirmware && !_noMissionItemsAdded } QGCLabel { @@ -148,11 +213,11 @@ Rectangle { fact: QGroundControl.settingsManager.appSettings.offlineEditingVehicleType indexModel: false Layout.preferredWidth: _fieldWidth - visible: _multipleVehicleTypes && _enableOfflineVehicleCombos + visible: _multipleVehicleTypes && _noMissionItemsAdded } QGCLabel { text: _controllerVehicle.vehicleTypeString - visible: _multipleVehicleTypes && !_enableOfflineVehicleCombos + visible: _multipleVehicleTypes && !_noMissionItemsAdded } QGCLabel { diff --git a/src/PlanView/SimpleItemEditor.qml b/src/PlanView/SimpleItemEditor.qml index 8b3a269d1228d4b4a9cca87ff45a39d6016f3bea..bd96d1984de89c3b0668228c97a9007358142643 100644 --- a/src/PlanView/SimpleItemEditor.qml +++ b/src/PlanView/SimpleItemEditor.qml @@ -21,6 +21,8 @@ Rectangle { property real _margin: ScreenTools.defaultFontPixelHeight / 2 property bool _supportsTerrainFrame: missionItem.masterController.supportsTerrain property var _controllerVehicle: missionItem.masterController.controllerVehicle + property int _globalAltMode: missionItem.masterController.missionController.globalAltitudeMode + property bool _globalAltModeIsMixed: _globalAltMode == QGroundControl.AltitudeModeNone property string _altModeRelativeHelpText: qsTr("Altitude relative to launch altitude") property string _altModeAbsoluteHelpText: qsTr("Altitude above mean sea level") @@ -29,16 +31,16 @@ Rectangle { function updateAltitudeModeText() { if (missionItem.altitudeMode === QGroundControl.AltitudeModeRelative) { - altModeLabel.text = qsTr("Altitude") + altModeLabel.text = QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeRelative) altModeHelp.text = _altModeRelativeHelpText } else if (missionItem.altitudeMode === QGroundControl.AltitudeModeAbsolute) { - altModeLabel.text = qsTr("Above Mean Sea Level") + altModeLabel.text = QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeAbsolute) altModeHelp.text = _altModeAbsoluteHelpText } else if (missionItem.altitudeMode === QGroundControl.AltitudeModeAboveTerrain) { - altModeLabel.text = qsTr("Above Terrain") + altModeLabel.text = QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeAboveTerrain) altModeHelp.text = Qt.binding(function() { return _altModeAboveTerrainHelpText }) } else if (missionItem.altitudeMode === QGroundControl.AltitudeModeTerrainFrame) { - altModeLabel.text = qsTr("Terrain Frame") + altModeLabel.text = QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeTerrainFrame) altModeHelp.text = _altModeTerrainFrameHelpText } else { altModeLabel.text = qsTr("Internal Error") @@ -149,37 +151,39 @@ Rectangle { } } + // This control needs to morph between a simple altitude entry field to a more complex alt mode picker based on the global plan alt mode Rectangle { anchors.left: parent.left anchors.right: parent.right height: altColumn.y + altColumn.height + _margin - color: qgcPal.windowShade + color: _globalAltModeIsMixed ? qgcPal.windowShade: qgcPal.window visible: _specifiesAltitude - Column { + ColumnLayout { id: altColumn - anchors.margins: _margin + anchors.margins: _globalAltModeIsMixed ? _margin : 0 anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - spacing: _margin + spacing: _globalAltModeIsMixed ? _margin : 0 QGCLabel { - width: parent.width - wrapMode: Text.WordWrap - font.pointSize: ScreenTools.smallFontPointSize - text: qsTr("Altitude below specifies the approximate altitude of the ground. Normally 0 for landing back at original launch location.") - visible: missionItem.isLandCommand + Layout.fillWidth: true + wrapMode: Text.WordWrap + font.pointSize: ScreenTools.smallFontPointSize + text: qsTr("Altitude below specifies the approximate altitude of the ground. Normally 0 for landing back at original launch location.") + visible: missionItem.isLandCommand } Item { - width: altHamburger.x + altHamburger.width - height: altModeLabel.height + width: altModeDropArrow.x + altModeDropArrow.width + height: altModeLabel.height + visible: _globalAltModeIsMixed QGCLabel { id: altModeLabel } QGCColoredImage { - id: altHamburger + id: altModeDropArrow anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 4 anchors.left: altModeLabel.right anchors.verticalCenter: altModeLabel.verticalCenter @@ -192,21 +196,21 @@ Rectangle { QGCMouseArea { anchors.fill: parent - onClicked: altHamburgerMenu.popup() + onClicked: altModeMenu.popup() } QGCMenu { - id: altHamburgerMenu + id: altModeMenu QGCMenuItem { - text: qsTr("Altitude Relative To Launch") + text: QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeRelative) checkable: true checked: missionItem.altitudeMode === QGroundControl.AltitudeModeRelative onTriggered: missionItem.altitudeMode = QGroundControl.AltitudeModeRelative } QGCMenuItem { - text: qsTr("Altitude Above Mean Sea Level") + text: QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeAbsolute) checkable: true checked: missionItem.altitudeMode === QGroundControl.AltitudeModeAbsolute visible: QGroundControl.corePlugin.options.showMissionAbsoluteAltitude @@ -214,7 +218,7 @@ Rectangle { } QGCMenuItem { - text: qsTr("Altitude Above Terrain") + text: QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeAboveTerrain) checkable: true checked: missionItem.altitudeMode === QGroundControl.AltitudeModeAboveTerrain onTriggered: missionItem.altitudeMode = QGroundControl.AltitudeModeAboveTerrain @@ -222,7 +226,7 @@ Rectangle { } QGCMenuItem { - text: qsTr("Terrain Frame") + text: QGroundControl.altitudeModeShortDescription(QGroundControl.AltitudeModeTerrainFrame) checkable: true checked: missionItem.altitudeMode === QGroundControl.AltitudeModeTerrainFrame visible: _supportsTerrainFrame && (missionItem.specifiesCoordinate || missionItem.specifiesAltitudeOnly) @@ -231,20 +235,25 @@ Rectangle { } } + QGCLabel { + text: qsTr("Altitude") + font.pointSize: ScreenTools.smallFontPointSize + visible: !_globalAltModeIsMixed + } + AltitudeFactTextField { id: altField + Layout.fillWidth: true fact: missionItem.altitude altitudeMode: missionItem.altitudeMode - anchors.left: parent.left - anchors.right: parent.right } QGCLabel { id: altModeHelp + Layout.fillWidth: true wrapMode: Text.WordWrap font.pointSize: ScreenTools.smallFontPointSize - anchors.left: parent.left - anchors.right: parent.right + visible: _globalAltModeIsMixed } } } diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index 8ab82bcd7294afb06315666c20902244939fc55f..a302aa8d8ad8e03dc56a8e5e0601e477224a2d6a 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -267,3 +267,42 @@ QString QGroundControlQmlGlobal::qgcVersion(void) const #endif return versionStr; } + +QString QGroundControlQmlGlobal::altitudeModeExtraUnits(AltitudeMode altMode) +{ + switch (altMode) { + case AltitudeModeNone: + return QString(); + case AltitudeModeRelative: + // Showing (Rel) all the time ends up being too noisy + return QString(); + case AltitudeModeAbsolute: + return tr("(AMSL)"); + case AltitudeModeAboveTerrain: + return tr("(Abv Terr)"); + case AltitudeModeTerrainFrame: + return tr("(TerrF)"); + } + + // Should never get here but makes some compilers happy + return QString(); +} + +QString QGroundControlQmlGlobal::altitudeModeShortDescription(AltitudeMode altMode) +{ + switch (altMode) { + case AltitudeModeNone: + return QString(); + case AltitudeModeRelative: + return tr("Relative To Launch"); + case AltitudeModeAbsolute: + return tr("Above Mean Sea Level"); + case AltitudeModeAboveTerrain: + return tr("Above Terrain"); + case AltitudeModeTerrainFrame: + return tr("Terrain Frame"); + } + + // Should never get here but makes some compilers happy + return QString(); +} diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index 57f5e89e3fe072e55cf3a79c37e584b703f8ddea..8036a8b9e5fca1468653a3ff01dd759d75eb44bf 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.h +++ b/src/QmlControls/QGroundControlQmlGlobal.h @@ -148,6 +148,9 @@ public: Q_INVOKABLE bool linesIntersect(QPointF xLine1, QPointF yLine1, QPointF xLine2, QPointF yLine2); + Q_INVOKABLE QString altitudeModeExtraUnits(AltitudeMode altMode); ///< String shown in the FactTextField.extraUnits ui + Q_INVOKABLE QString altitudeModeShortDescription(AltitudeMode altMode); ///< String shown when a user needs to select an altitude mode + // Property accesors QString appName () { return qgcApp()->applicationName(); } @@ -268,6 +271,7 @@ private: #endif bool _skipSetupPage = false; + QStringList _altitudeModeEnumString; static const char* _flightMapPositionSettingsGroup; static const char* _flightMapPositionLatitudeSettingsKey; diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 3dd30e93ca5ec903b1e90147db8210a622ce35aa..f689d346d90f837ce1c53279a950d77c1255bb40 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -3038,7 +3038,7 @@ bool Vehicle::supportsMotorInterference() const bool Vehicle::supportsTerrainFrame() const { - return _capabilityBits & MAV_PROTOCOL_CAPABILITY_TERRAIN; + return !px4Firmware(); } QString Vehicle::vehicleTypeName() const { diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index 2d16619ad453aa4b86ee25d18a74b83d0dd6b2b5..0077ebece43dd9f286e52a48e111f911352968f7 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -627,7 +627,7 @@ public: Q_PROPERTY(QString hobbsMeter READ hobbsMeter NOTIFY hobbsMeterChanged) Q_PROPERTY(bool vtolInFwdFlight READ vtolInFwdFlight WRITE setVtolInFwdFlight NOTIFY vtolInFwdFlightChanged) Q_PROPERTY(bool highLatencyLink READ highLatencyLink NOTIFY highLatencyLinkChanged) - Q_PROPERTY(bool supportsTerrainFrame READ supportsTerrainFrame NOTIFY capabilityBitsChanged) + Q_PROPERTY(bool supportsTerrainFrame READ supportsTerrainFrame NOTIFY firmwareTypeChanged) Q_PROPERTY(QString priorityLinkName READ priorityLinkName WRITE setPriorityLinkByName NOTIFY priorityLinkNameChanged) Q_PROPERTY(QVariantList links READ links NOTIFY linksChanged) Q_PROPERTY(LinkInterface* priorityLink READ priorityLink NOTIFY priorityLinkNameChanged)