diff --git a/src/MissionManager/MissionCommandTree.cc b/src/MissionManager/MissionCommandTree.cc index 8f486ead16b7d6db8c055f50e20c029de9a419e6..d3109f39682471ae2838dcc1a045413469ec70d3 100644 --- a/src/MissionManager/MissionCommandTree.cc +++ b/src/MissionManager/MissionCommandTree.cc @@ -219,7 +219,7 @@ const MissionCommandUIInfo* MissionCommandTree::getUIInfo(Vehicle* vehicle, MAV_ } } -QVariantList MissionCommandTree::getCommandsForCategory(Vehicle* vehicle, const QString& category) +QVariantList MissionCommandTree::getCommandsForCategory(Vehicle* vehicle, const QString& category, bool showFlyThroughCommands) { MAV_AUTOPILOT baseFirmwareType; MAV_TYPE baseVehicleType; @@ -237,7 +237,8 @@ QVariantList MissionCommandTree::getCommandsForCategory(Vehicle* vehicle, const for (MAV_CMD command: commandMap.keys()) { if (supportedCommands.contains(command)) { MissionCommandUIInfo* uiInfo = commandMap[command]; - if (uiInfo->category() == category || category == _allCommandsCategory) { + if ((uiInfo->category() == category || category == _allCommandsCategory) && + (showFlyThroughCommands || !uiInfo->specifiesCoordinate() || uiInfo->isStandaloneCoordinate())) { list.append(QVariant::fromValue(uiInfo)); } } diff --git a/src/MissionManager/MissionCommandTree.h b/src/MissionManager/MissionCommandTree.h index 13884358604949aa0c1a5a70781dcae0282112fa..e55dc081260e5c8d1f5911edb8ba0a59973953f5 100644 --- a/src/MissionManager/MissionCommandTree.h +++ b/src/MissionManager/MissionCommandTree.h @@ -62,7 +62,8 @@ public: const MissionCommandUIInfo* getUIInfo(Vehicle* vehicle, MAV_CMD command); - Q_INVOKABLE QVariantList getCommandsForCategory(Vehicle* vehicle, const QString& category); + /// @param showFlyThroughCommands - true: al commands shows, false: filter out commands which the vehicle flies through (specifiedCoordinate=true, standaloneCoordinate=false) + Q_INVOKABLE QVariantList getCommandsForCategory(Vehicle* vehicle, const QString& category, bool showFlyThroughCommands); // Overrides from QGCTool virtual void setToolbox(QGCToolbox* toolbox); diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index 74c6a109dcac8fcc02faac12608e13ab928f0117..82a60931f7ee2973c889b39dccb790b28cfd0dfa 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -2181,14 +2181,16 @@ VisualMissionItem* MissionController::currentPlanViewItem(void) const void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) { if (_visualItems && (force || sequenceNumber != _currentPlanViewIndex)) { - bool foundLand = false; - int takeoffIndex = -1; + bool foundLand = false; + int takeoffIndex = -1; + int landIndex = -1; - _splitSegment = nullptr; - _currentPlanViewItem = nullptr; - _currentPlanViewIndex = -1; - _isInsertTakeoffValid = true; - _isInsertLandValid = true; + _splitSegment = nullptr; + _currentPlanViewItem = nullptr; + _currentPlanViewIndex = -1; + _isInsertTakeoffValid = true; + _isInsertLandValid = true; + _flyThroughCommandsAllowed = true; for (int i = 0; i < _visualItems->count(); i++) { VisualMissionItem* pVI = qobject_cast(_visualItems->get(i)); @@ -2214,6 +2216,7 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) case MAV_CMD_DO_LAND_START: case MAV_CMD_NAV_RETURN_TO_LAUNCH: foundLand = true; + landIndex = i; break; default: break; @@ -2222,6 +2225,7 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) FixedWingLandingComplexItem* fwLanding = qobject_cast(pVI); if (fwLanding) { foundLand = true; + landIndex = i; } } } @@ -2248,13 +2252,23 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) } } - if (takeoffIndex != -1 && sequenceNumber <= takeoffIndex) { - // Takeoff item was found which means mission starts from ground. - // Land is only valid after the takeoff item. - _isInsertLandValid = false; - } else if (foundLand) { - // Can't have to land sequences + if (takeoffIndex != -1) { + // Takeoff item was found which means mission starts from ground + if (sequenceNumber < takeoffIndex) { + // Land is only valid after the takeoff item. + _isInsertLandValid = false; + // Fly through commands are not allowed prior to the takeoff command + _flyThroughCommandsAllowed = false; + } + } + + if (foundLand) { + // Can't have more than one land sequence _isInsertLandValid = false; + if (sequenceNumber >= landIndex) { + // Can't have fly through commands after a land item + _flyThroughCommandsAllowed = false; + } } emit currentPlanViewIndexChanged(); @@ -2262,6 +2276,7 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) emit splitSegmentChanged(); emit isInsertTakeoffValidChanged(); emit isInsertLandValidChanged(); + emit flyThroughCommandsAllowedChanged(); } } diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 1c5e226447071b77df7cdd9db62164448349fae6..bcea44bb549f1301df0723ce7cdbd3da22d7a0fe 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -92,8 +92,9 @@ public: Q_PROPERTY(QString surveyComplexItemName READ surveyComplexItemName CONSTANT) Q_PROPERTY(QString corridorScanComplexItemName READ corridorScanComplexItemName CONSTANT) Q_PROPERTY(QString structureScanComplexItemName READ structureScanComplexItemName CONSTANT) - Q_PROPERTY(bool isInsertTakeoffValid MEMBER _isInsertTakeoffValid NOTIFY isInsertTakeoffValidChanged) ///< true: Takeoff tool should be enabled - Q_PROPERTY(bool isInsertLandValid MEMBER _isInsertLandValid NOTIFY isInsertLandValidChanged) ///< true: Land tool should be enabled + Q_PROPERTY(bool isInsertTakeoffValid MEMBER _isInsertTakeoffValid NOTIFY isInsertTakeoffValidChanged) + Q_PROPERTY(bool isInsertLandValid MEMBER _isInsertLandValid NOTIFY isInsertLandValidChanged) + Q_PROPERTY(bool flyThroughCommandsAllowed MEMBER _flyThroughCommandsAllowed NOTIFY flyThroughCommandsAllowedChanged) Q_INVOKABLE void removeMissionItem(int index); @@ -228,32 +229,33 @@ public: static const QString patternSurveyName; signals: - void visualItemsChanged (void); - void waypointPathChanged (void); - void splitSegmentChanged (void); - void newItemsFromVehicle (void); - void missionDistanceChanged (double missionDistance); - void missionTimeChanged (void); - void missionHoverDistanceChanged (double missionHoverDistance); - void missionHoverTimeChanged (void); - void missionCruiseDistanceChanged (double missionCruiseDistance); - void missionCruiseTimeChanged (void); - void missionMaxTelemetryChanged (double missionMaxTelemetry); - void complexMissionItemNamesChanged (void); - void resumeMissionIndexChanged (void); - void resumeMissionReady (void); - void resumeMissionUploadFail (void); - void batteryChangePointChanged (int batteryChangePoint); - void batteriesRequiredChanged (int batteriesRequired); - void plannedHomePositionChanged (QGeoCoordinate plannedHomePosition); - void progressPctChanged (double progressPct); - void currentMissionIndexChanged (int currentMissionIndex); - void currentPlanViewIndexChanged (void); - void currentPlanViewItemChanged (void); - void missionBoundingCubeChanged (void); - void missionItemCountChanged (int missionItemCount); - void isInsertTakeoffValidChanged (void); - void isInsertLandValidChanged (void); + void visualItemsChanged (void); + void waypointPathChanged (void); + void splitSegmentChanged (void); + void newItemsFromVehicle (void); + void missionDistanceChanged (double missionDistance); + void missionTimeChanged (void); + void missionHoverDistanceChanged (double missionHoverDistance); + void missionHoverTimeChanged (void); + void missionCruiseDistanceChanged (double missionCruiseDistance); + void missionCruiseTimeChanged (void); + void missionMaxTelemetryChanged (double missionMaxTelemetry); + void complexMissionItemNamesChanged (void); + void resumeMissionIndexChanged (void); + void resumeMissionReady (void); + void resumeMissionUploadFail (void); + void batteryChangePointChanged (int batteryChangePoint); + void batteriesRequiredChanged (int batteriesRequired); + void plannedHomePositionChanged (QGeoCoordinate plannedHomePosition); + void progressPctChanged (double progressPct); + void currentMissionIndexChanged (int currentMissionIndex); + void currentPlanViewIndexChanged (void); + void currentPlanViewItemChanged (void); + void missionBoundingCubeChanged (void); + void missionItemCountChanged (int missionItemCount); + void isInsertTakeoffValidChanged (void); + void isInsertLandValidChanged (void); + void flyThroughCommandsAllowedChanged (void); private slots: void _newMissionItemsAvailableFromVehicle(bool removeAllRequested); @@ -330,8 +332,9 @@ private: QGCGeoBoundingCube _travelBoundingCube; QGeoCoordinate _takeoffCoordinate; CoordinateVector* _splitSegment; - bool _isInsertTakeoffValid = true; - bool _isInsertLandValid = true; + bool _isInsertTakeoffValid = true; + bool _isInsertLandValid = true; + bool _flyThroughCommandsAllowed = true; static const char* _settingsGroup; diff --git a/src/MissionManager/SimpleMissionItem.cc b/src/MissionManager/SimpleMissionItem.cc index a276bc7f663bd73b6e7cf95bb0ba9407531c8b9b..f8253dc5f48d88bc2dc4a9c97139aa6288972228 100644 --- a/src/MissionManager/SimpleMissionItem.cc +++ b/src/MissionManager/SimpleMissionItem.cc @@ -399,6 +399,7 @@ QString SimpleMissionItem::abbreviation() const case MAV_CMD_NAV_VTOL_LAND: return tr("VTOL Land"); case MAV_CMD_DO_SET_ROI: + case MAV_CMD_DO_SET_ROI_LOCATION: return tr("ROI"); default: return QString(); diff --git a/src/PlanView/MissionItemEditor.qml b/src/PlanView/MissionItemEditor.qml index ac8f8345b35f089f2a7f8fe321900cb76f0d44fb..870edd678788c70ea11bf9b1422cfcecc83e4cad 100644 --- a/src/PlanView/MissionItemEditor.qml +++ b/src/PlanView/MissionItemEditor.qml @@ -240,8 +240,9 @@ Rectangle { id: commandDialog MissionCommandDialog { - missionItem: _root.missionItem - map: _root.map + missionItem: _root.missionItem + map: _root.map + flyThroughCommandsAllowed: _missionController.flyThroughCommandsAllowed } } diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 9c1a71e7cda114b97edb6a31875897a543e10dd1..76bfd9fa602fa855d8900e7a302636e7c9f0937d 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -304,10 +304,8 @@ Item { /// @param coordinate Location to insert item /// @param index Insert item at this index function insertROIMissionItem(coordinate, index) { - var sequenceNumber = _missionController.insertROIMissionItem(coordinate, index) - _missionController.setCurrentPlanViewIndex(sequenceNumber, true) + _missionController.insertROIMissionItem(coordinate, index, true /* makeCurrentItem */) _addROIOnClick = false - toolStrip.lastClickedButton.checked = false } function selectNextNotReady() { @@ -491,6 +489,7 @@ Item { _addROIOnClick = false insertROIMissionItem(coordinate, _missionController.visualItems.count) } + break case _layerRallyPoints: if (_rallyPointController.supported && _addWaypointOnClick) { @@ -632,7 +631,8 @@ Item { readonly property int landButtonIndex: 6 readonly property int centerButtonIndex: 7 - property bool _isRally: _editingLayer == _layerRallyPoints + property bool _isRallyLayer: _editingLayer == _layerRallyPoints + property bool _isMissionLayer: _editingLayer == _layerMission model: [ { @@ -654,13 +654,13 @@ Item { name: qsTr("Takeoff"), iconSource: "/res/takeoff.svg", buttonEnabled: _missionController.isInsertTakeoffValid, - buttonVisible: _editingLayer == _layerMission + buttonVisible: _isMissionLayer }, { name: _editingLayer == _layerRallyPoints ? qsTr("Rally Point") : qsTr("Waypoint"), iconSource: "/qmlimages/MapAddMission.svg", - buttonEnabled: true, - buttonVisible: true, + buttonEnabled: _isRallyLayer ? true : _missionController.flyThroughCommandsAllowed, + buttonVisible: _isRallyLayer || _isMissionLayer, toggle: true, checked: _addWaypointOnClick }, @@ -668,21 +668,21 @@ Item { name: qsTr("ROI"), iconSource: "/qmlimages/MapAddMission.svg", buttonEnabled: true, - buttonVisible: !_isRally && _waypointsOnlyMode, + buttonVisible: _isMissionLayer, toggle: true }, { name: _singleComplexItem ? _missionController.complexMissionItemNames[0] : qsTr("Pattern"), iconSource: "/qmlimages/MapDrawShape.svg", - buttonEnabled: true, - buttonVisible: !_isRally, + buttonEnabled: _missionController.flyThroughCommandsAllowed, + buttonVisible: _isMissionLayer, dropPanelComponent: _singleComplexItem ? undefined : patternDropPanel }, { name: _planMasterController.controllerVehicle.fixedWing ? qsTr("Land") : qsTr("Return"), iconSource: "/res/rtl.svg", buttonEnabled: _missionController.isInsertLandValid, - buttonVisible: _editingLayer == _layerMission + buttonVisible: _isMissionLayer }, { name: qsTr("Center"), @@ -693,39 +693,49 @@ Item { } ] + function allAddClickBoolsOff() { + _addROIOnClick = false + _addWaypointOnClick = false + } + onClicked: { switch (index) { case flyButtonIndex: mainWindow.showFlyView() break case takeoffButtonIndex: + allAddClickBoolsOff() _missionController.insertTakeoffItem(mapCenter(), _missionController.currentMissionIndex, true /* makeCurrentItem */) break case waypointButtonIndex: - if(_addWaypointOnClick) { - //-- Toggle it off - _addWaypointOnClick = false - _addROIOnClick = false + if (_addWaypointOnClick) { + allAddClickBoolsOff() setChecked(index, false) } else { + allAddClickBoolsOff() _addWaypointOnClick = checked - _addROIOnClick = false } break case roiButtonIndex: + allAddClickBoolsOff() _addROIOnClick = checked - _addWaypointOnClick = false break case patternButtonIndex: + allAddClickBoolsOff() if (_singleComplexItem) { addComplexItem(_missionController.complexMissionItemNames[0]) } break case landButtonIndex: + allAddClickBoolsOff() _missionController.insertLandItem(mapCenter(), _missionController.currentMissionIndex, true /* makeCurrentItem */) break } } + + onDropped: { + allAddClickBoolsOff() + } } //----------------------------------------------------------- @@ -1257,8 +1267,6 @@ Item { } } } - - } } } diff --git a/src/QmlControls/MissionCommandDialog.qml b/src/QmlControls/MissionCommandDialog.qml index 9bc925a6572eefcecc3265e40a19e60b34586c32..c36c3ad5c32e4c23acc0a51f9ea68629baa86fae 100644 --- a/src/QmlControls/MissionCommandDialog.qml +++ b/src/QmlControls/MissionCommandDialog.qml @@ -19,8 +19,9 @@ import QGroundControl.Palette 1.0 QGCViewDialog { id: root - property var missionItem - property var map + property var missionItem + property var map + property bool flyThroughCommandsAllowed property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle @@ -40,7 +41,7 @@ QGCViewDialog { model: QGroundControl.missionCommandTree.categoriesForVehicle(_vehicle) function categorySelected(category) { - commandList.model = QGroundControl.missionCommandTree.getCommandsForCategory(_vehicle, category) + commandList.model = QGroundControl.missionCommandTree.getCommandsForCategory(_vehicle, category, flyThroughCommandsAllowed) } Component.onCompleted: { @@ -97,7 +98,7 @@ QGCViewDialog { MouseArea { anchors.fill: parent onClicked: { - missionItem.setMapCenterHintForCommandChange(map.center) + missionItem.setMapCenterHintForCommandChange(map.center) missionItem.command = mavCmdInfo.command root.reject() } diff --git a/src/QmlControls/ToolStrip.qml b/src/QmlControls/ToolStrip.qml index be668af7f2288bda4e65edfb795c0be71938ecfa..6948e0ddef3ae557b8faf8b4d4be2fac2541ceb4 100644 --- a/src/QmlControls/ToolStrip.qml +++ b/src/QmlControls/ToolStrip.qml @@ -36,6 +36,7 @@ Rectangle { property real _idealWidth: (ScreenTools.isMobile ? ScreenTools.minTouchPixels : ScreenTools.defaultFontPixelWidth * 8) + toolStripColumn.anchors.margins * 2 signal clicked(int index, bool checked) + signal dropped(int index) function setChecked(idx, check) { repeater.itemAt(idx).checked = check @@ -88,6 +89,7 @@ Rectangle { } else if (checked) { var panelEdgeTopPoint = mapToItem(_root, width, 0) dropPanel.show(panelEdgeTopPoint, height, modelData.dropPanelComponent) + _root.dropped(index) } if(_root && buttonTemplate) _root.lastClickedButton = buttonTemplate