9import QGroundControl.Controls
10import QGroundControl.FlightMap
11import QGroundControl.Logging
13/// This provides the smarts behind the guided mode commands, minus the user interface. This way you can change UI
14/// without affecting the underlying functionality.
18 property var missionController
19 property var confirmDialog
20 property var guidedValueSlider
21 property var fwdFlightGotoMapCircle
22 property var orbitMapCircle
24 readonly property string emergencyStopTitle: qsTr("EMERGENCY STOP")
25 readonly property string armTitle: qsTr("Arm")
26 readonly property string mvArmTitle: qsTr("Arm (MV)")
27 readonly property string forceArmTitle: qsTr("Force Arm")
28 readonly property string disarmTitle: qsTr("Disarm")
29 readonly property string mvDisarmTitle: qsTr("Disarm (MV)")
30 readonly property string rtlTitle: qsTr("Return")
31 readonly property string takeoffTitle: qsTr("Takeoff")
32 readonly property string landTitle: qsTr("Land")
33 readonly property string startMissionTitle: qsTr("Start Mission")
34 readonly property string mvStartMissionTitle: qsTr("Start Mission (MV)")
35 readonly property string continueMissionTitle: qsTr("Continue Mission")
36 readonly property string resumeMissionUploadFailTitle: qsTr("Resume FAILED")
37 readonly property string pauseTitle: qsTr("Pause")
38 readonly property string mvPauseTitle: qsTr("Pause (MV)")
39 readonly property string changeAltTitle: qsTr("Change Altitude")
40 readonly property string changeLoiterRadiusTitle: qsTr("Change Loiter Radius")
41 readonly property string changeCruiseSpeedTitle: qsTr("Change Max Ground Speed")
42 readonly property string changeAirspeedTitle: qsTr("Change Airspeed")
43 readonly property string orbitTitle: qsTr("Orbit")
44 readonly property string landAbortTitle: qsTr("Land Abort")
45 readonly property string setWaypointTitle: qsTr("Set Waypoint")
46 readonly property string gotoTitle: qsTr("Go To Location")
47 readonly property string roiTitle: qsTr("ROI")
48 readonly property string setHomeTitle: qsTr("Set Home")
49 readonly property string setEstimatorOriginTitle: qsTr("Set Estimator Origin")
50 readonly property string setFlightMode: qsTr("Set Flight Mode")
51 readonly property string changeHeadingTitle: qsTr("Change Heading")
53 readonly property string armMessage: qsTr("Arm the vehicle.")
54 readonly property string mvArmMessage: qsTr("Arm selected vehicles.")
55 readonly property string forceArmMessage: qsTr("WARNING: This will force arming of the vehicle bypassing any safety checks.")
56 readonly property string disarmMessage: qsTr("Disarm the vehicle")
57 readonly property string mvDisarmMessage: qsTr("Disarm selected vehicles.")
58 readonly property string emergencyStopMessage: qsTr("WARNING: THIS WILL STOP ALL MOTORS. IF VEHICLE IS CURRENTLY IN THE AIR IT WILL CRASH.")
59 readonly property string takeoffMessage: qsTr("Takeoff and hold position")
60 readonly property string startMissionMessage: qsTr("Takeoff and start the current mission")
61 readonly property string mvStartMissionMessage: qsTr("Takeoff and start the current mission for selected vehicles")
62 readonly property string continueMissionMessage: qsTr("Continue the mission from the current waypoint")
63 readonly property string resumeMissionUploadFailMessage: qsTr("Upload of resume mission failed. Confirm to retry upload")
64 readonly property string landMessage: qsTr("Land the vehicle at the current position")
65 readonly property string rtlMessage: qsTr("Return to the launch position of the vehicle")
66 readonly property string changeAltMessage: qsTr("Change the altitude of the vehicle up or down")
67 readonly property string changeLoiterRadiusMessage: qsTr("Change the forward flight loiter radius")
68 readonly property string changeCruiseSpeedMessage: qsTr("Change the maximum horizontal cruise speed")
69 readonly property string changeAirspeedMessage: qsTr("Change the equivalent airspeed setpoint")
70 readonly property string gotoMessage: qsTr("Move the vehicle to the specified location")
71 property string setWaypointMessage: qsTr("Adjust current waypoint to %1").arg(_actionData)
72 readonly property string orbitMessage: qsTr("Orbit the vehicle around the specified location")
73 readonly property string landAbortMessage: qsTr("Abort the landing sequence")
74 readonly property string pauseMessage: qsTr("Pause at current position")
75 readonly property string mvPauseMessage: qsTr("Pause selected vehicles at their current position")
76 readonly property string roiMessage: qsTr("Make the specified location a Region Of Interest")
77 readonly property string setHomeMessage: qsTr("Set vehicle home as the specified location. This will affect Return to Home position")
78 readonly property string setEstimatorOriginMessage: qsTr("Make the specified location the estimator origin")
79 readonly property string setFlightModeMessage: qsTr("Set the vehicle flight mode to %1").arg(_actionData)
80 readonly property string changeHeadingMessage: qsTr("Set the vehicle heading towards the specified location")
82 readonly property int actionRTL: 1
83 readonly property int actionLand: 2
84 readonly property int actionTakeoff: 3
85 readonly property int actionArm: 4
86 readonly property int actionDisarm: 5
87 readonly property int actionEmergencyStop: 6
88 readonly property int actionChangeAlt: 7
89 readonly property int actionGoto: 8
90 readonly property int actionSetWaypoint: 9
91 readonly property int actionOrbit: 10
92 readonly property int actionLandAbort: 11
93 readonly property int actionStartMission: 12
94 readonly property int actionContinueMission: 13
95 readonly property int actionResumeMission: 14
96 readonly property int _actionUnused: 15
97 readonly property int actionResumeMissionUploadFail: 16
98 readonly property int actionPause: 17
99 readonly property int actionMVPause: 18
100 readonly property int actionMVStartMission: 19
101 readonly property int actionROI: 20
102 readonly property int actionForceArm: 21
103 readonly property int actionChangeSpeed: 22
104 readonly property int actionSetHome: 24
105 readonly property int actionSetEstimatorOrigin: 25
106 readonly property int actionSetFlightMode: 26
107 readonly property int actionChangeHeading: 27
108 readonly property int actionMVArm: 28
109 readonly property int actionMVDisarm: 29
110 readonly property int actionChangeLoiterRadius: 30
112 readonly property int customActionStart: 10000 // Custom actions ids should start here so that they don't collide with the built in actions
114 property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
115 property var _flyViewSettings: QGroundControl.settingsManager.flyViewSettings
116 property var _unitsConversion: QGroundControl.unitsConversion
117 property bool _useChecklist: QGroundControl.settingsManager.appSettings.useChecklist.rawValue && QGroundControl.corePlugin.options.preFlightChecklistUrl.toString().length
118 property bool _enforceChecklist: _useChecklist && QGroundControl.settingsManager.appSettings.enforceChecklist.rawValue
119 property bool _checklistPassed: _activeVehicle ? (_useChecklist ? (_enforceChecklist ? _activeVehicle.checkListState === Vehicle.CheckListPassed : true) : true) : true
120 property bool _canArm: _activeVehicle ? (_checklistPassed && (!_activeVehicle.healthAndArmingCheckReport.supported || _activeVehicle.healthAndArmingCheckReport.canArm)) : false
121 property bool _canTakeoff: _activeVehicle ? (_checklistPassed && (!_activeVehicle.healthAndArmingCheckReport.supported || _activeVehicle.healthAndArmingCheckReport.canTakeoff)) : false
122 property bool _canStartMission: _activeVehicle ? (_checklistPassed && (!_activeVehicle.healthAndArmingCheckReport.supported || _activeVehicle.healthAndArmingCheckReport.canStartMission)) : false
123 property bool _initialConnectComplete: _activeVehicle ? _activeVehicle.initialConnectComplete : false
125 property bool showEmergencyStop: !_hideEmergencyStop && _vehicleArmed && _vehicleAirborne
126 property bool showArm: _guidedActionsEnabled && !_vehicleArmed && _canArm
127 property bool showForceArm: _guidedActionsEnabled && !_vehicleArmed && _flyViewSettings.allowForceArm.rawValue
128 property bool showDisarm: _vehicleArmed && !_vehicleAirborne
129 property bool showRTL: _guidedActionsEnabled && _activeVehicle && _vehicleArmed && _activeVehicle.supports.guidedMode && _vehicleUnderway && !_vehicleInRTLMode
130 property bool showTakeoff: _guidedActionsEnabled && _activeVehicle && (_activeVehicle.supports.guidedTakeoffWithAltitude || _activeVehicle.supports.guidedTakeoffWithoutAltitude) && !_vehicleUnderway && _canTakeoff
131 property bool showLand: _guidedActionsEnabled && _activeVehicle && _activeVehicle.supports.guidedMode && _vehicleArmed && !_activeVehicle.fixedWing && !_vehicleInLandMode
132 property bool showStartMission: _guidedActionsEnabled && _missionAvailable && !_missionActive && !_vehicleUnderway && _canStartMission
133 property bool showContinueMission: _guidedActionsEnabled && _missionAvailable && !_missionActive && _vehicleArmed && _vehicleUnderway && (_currentMissionIndex < _visualItemsCount - 1)
134 property bool showPause: _guidedActionsEnabled && _activeVehicle && _vehicleArmed && _activeVehicle.supports.pauseVehicle && _vehicleUnderway && !_vehiclePaused && !_fixedWingOnApproach
135 property bool showChangeAlt: _guidedActionsEnabled && _activeVehicle && _vehicleUnderway && _activeVehicle.supports.guidedMode && _vehicleArmed && !_missionActive
136 property bool showChangeLoiterRadius: _guidedActionsEnabled && _activeVehicle && _vehicleUnderway && _activeVehicle.supports.guidedMode && _vehicleArmed && !_missionActive && _vehicleInFwdFlight && fwdFlightGotoMapCircle.visible
137 property bool showChangeSpeed: _guidedActionsEnabled && _activeVehicle && _vehicleUnderway && _activeVehicle.supports.guidedMode && _vehicleArmed && !_missionActive && _speedLimitsAvailable
138 property bool showOrbit: _guidedActionsEnabled && _activeVehicle && _vehicleUnderway && __orbitSupported && !_missionActive && _activeVehicle.homePosition.isValid && !isNaN(_activeVehicle.homePosition.altitude)
139 property bool showROI: _guidedActionsEnabled && _vehicleUnderway && __roiSupported
140 property bool showLandAbort: _guidedActionsEnabled && _vehicleUnderway && _fixedWingOnApproach
141 property bool showGotoLocation: _guidedActionsEnabled && _vehicleUnderway
142 property bool showSetHome: _guidedActionsEnabled
143 property bool showSetEstimatorOrigin: _activeVehicle && !(_activeVehicle.sensorsPresentBits & MAVLinkEnums.MAV_SYS_STATUS_SENSOR_GPS)
144 property bool showChangeHeading: _guidedActionsEnabled && _vehicleUnderway
146 property string changeSpeedTitle: _vehicleInFwdFlight ? changeAirspeedTitle : changeCruiseSpeedTitle
147 property string changeSpeedMessage: _vehicleInFwdFlight ? changeAirspeedMessage : changeCruiseSpeedMessage
149 // Note: The '_visualItemsCount - 2' is a hack to not trigger resume mission when a mission ends with an RTL item
150 property bool showResumeMission: _activeVehicle && !_vehicleArmed && _vehicleWasUnderway && _missionAvailable && _resumeMissionIndex > 0 && (_resumeMissionIndex < _visualItemsCount - 2)
152 property bool guidedUIVisible: confirmDialog.visible
154 property var _corePlugin: QGroundControl.corePlugin
155 property var _corePluginOptions: QGroundControl.corePlugin.options
156 property bool _guidedActionsEnabled: (!ScreenTools.isDebug && _corePluginOptions.guidedActionsRequireRCRSSI && _activeVehicle) ? _rcRSSIAvailable : _activeVehicle
157 property string _flightMode: _activeVehicle ? _activeVehicle.flightMode : ""
158 property bool _missionAvailable: missionController.containsItems
159 property bool _missionActive: _activeVehicle ? _vehicleArmed && (_vehicleInLandMode || _vehicleInRTLMode || _vehicleInMissionMode) : false
160 property bool _vehicleArmed: _activeVehicle ? _activeVehicle.armed : false
161 property bool _vehicleUnderway: _activeVehicle ? _activeVehicle.underway : false
162 // Rover/Sub are underway whenever armed but accept a normal disarm, so only airborne vehicles need emergency stop
163 property bool _vehicleAirborne: _activeVehicle ? _activeVehicle.airborne : false
164 property bool _vehicleLanding: _activeVehicle ? _activeVehicle.landing : false
165 property bool _vehiclePaused: false
166 property bool _vehicleInMissionMode: false
167 property bool _vehicleInRTLMode: false
168 property bool _vehicleInLandMode: false
169 property int _visualItemsCount: missionController.visualItems ? missionController.visualItems.count : 0
170 property int _currentMissionIndex: missionController.currentMissionIndex
171 property int _resumeMissionIndex: missionController.resumeMissionIndex
172 property bool _hideEmergencyStop: !_corePluginOptions.flyView.guidedBarShowEmergencyStop
173 property bool _hideOrbit: !_corePluginOptions.flyView.guidedBarShowOrbit
174 property bool _hideROI: !_corePluginOptions.flyView.guidedBarShowROI
175 property bool _vehicleWasUnderway: false
176 property bool _rcRSSIAvailable: _activeVehicle ? _activeVehicle.rcRSSI.rawValue > 0 && _activeVehicle.rcRSSI.rawValue <= 100 : false
177 property bool _fixedWingOnApproach: _activeVehicle ? _activeVehicle.fixedWing && _vehicleLanding : false
178 property bool _vehicleInFwdFlight: _activeVehicle ? _activeVehicle.inFwdFlight : false
179 property bool _speedLimitsAvailable: _activeVehicle && ((_vehicleInFwdFlight && _activeVehicle.haveFWSpeedLimits) || (!_vehicleInFwdFlight && _activeVehicle.haveMRSpeedLimits))
181 // You can turn on log output for GuidedActionsController by turning on GuidedActionsControllerLog category
182 property bool __guidedModeSupported: _activeVehicle ? _activeVehicle.supports.guidedMode : false
183 property bool __pauseVehicleSupported: _activeVehicle ? _activeVehicle.supports.pauseVehicle : false
184 property bool __roiSupported: _activeVehicle ? !_hideROI && _activeVehicle.supports.roiMode : false
185 property bool __orbitSupported: _activeVehicle ? !_hideOrbit && _activeVehicle.supports.orbitMode : false
186 property bool __flightMode: _flightMode
188 // Allow custom builds to add custom actions by overriding CustomGuidedActionsController.qml
189 CustomGuidedActionsController {
192 property var _customController: customController
194 function _isGuidedActionsControllerLogEnabled() {
195 return QGCLoggingCategoryManager.isCategoryEnabled("GuidedActionsControllerLog")
198 function _outputState() {
199 if (_isGuidedActionsControllerLogEnabled()) {
200 console.log(qsTr("_activeVehicle(%1) _vehicleArmed(%2) guidedModeSupported(%3) _vehicleUnderway(%4) _vehicleWasUnderway(%5) _vehicleInRTLMode(%6) pauseVehicleSupported(%7) _vehiclePaused(%8) _flightMode(%9) _visualItemsCount(%10) roiSupported(%11) orbitSupported(%12) _missionActive(%13) _hideROI(%14) _hideOrbit(%15)").arg(_activeVehicle ? 1 : 0).arg(_vehicleArmed ? 1 : 0).arg(__guidedModeSupported ? 1 : 0).arg(_vehicleUnderway ? 1 : 0).arg(_vehicleWasUnderway ? 1 : 0).arg(_vehicleInRTLMode ? 1 : 0).arg(__pauseVehicleSupported ? 1 : 0).arg(_vehiclePaused ? 1 : 0).arg(_flightMode).arg(_visualItemsCount).arg(__roiSupported).arg(__orbitSupported).arg(_missionActive).arg(_hideROI).arg(_hideOrbit))
204 function setupSlider(actionCode) {
205 if (actionCode === actionTakeoff) {
206 guidedValueSlider.setupSlider(
207 GuidedValueSlider.SliderType.Takeoff,
208 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_activeVehicle.minimumTakeoffAltitudeMeters()),
209 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_flyViewSettings.guidedMaximumAltitude.rawValue),
210 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_activeVehicle.minimumTakeoffAltitudeMeters()),
211 qsTr("Height (rel)"))
212 } else if (actionCode === actionChangeSpeed) {
213 if (_vehicleInFwdFlight) {
214 guidedValueSlider.setupSlider(
215 GuidedValueSlider.SliderType.Speed,
216 _unitsConversion.metersSecondToAppSettingsSpeedUnits(_activeVehicle.minimumEquivalentAirspeed()).toFixed(1),
217 _unitsConversion.metersSecondToAppSettingsSpeedUnits(_activeVehicle.maximumEquivalentAirspeed()).toFixed(1),
218 _unitsConversion.metersSecondToAppSettingsSpeedUnits(_activeVehicle.airSpeed.rawValue),
220 } else if (!_vehicleInFwdFlight && _activeVehicle.haveMRSpeedLimits) {
221 guidedValueSlider.setupSlider(
222 GuidedValueSlider.SliderType.Speed,
223 _unitsConversion.metersSecondToAppSettingsSpeedUnits(0.1).toFixed(1),
224 _unitsConversion.metersSecondToAppSettingsSpeedUnits(_activeVehicle.maximumHorizontalSpeedMultirotorMetersSecond()).toFixed(1),
225 _unitsConversion.metersSecondToAppSettingsSpeedUnits(_activeVehicle.maximumHorizontalSpeedMultirotorMetersSecond()/2).toFixed(1),
228 console.error("setupSlider called for inapproproate change speed action", _vehicleInFwdFlight, _activeVehicle.haveMRSpeedLimits)
230 } else if (actionCode === actionChangeAlt || actionCode === actionOrbit || actionCode === actionGoto || actionCode === actionPause) {
231 guidedValueSlider.setupSlider(
232 GuidedValueSlider.SliderType.Altitude,
233 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_flyViewSettings.guidedMinimumAltitude.rawValue),
234 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_flyViewSettings.guidedMaximumAltitude.rawValue),
235 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_activeVehicle.altitudeRelative.rawValue),
237 } else if (actionCode === actionROI) {
238 // ROI targets a point on the ground by default, so start at 0 above home
239 guidedValueSlider.setupSlider(
240 GuidedValueSlider.SliderType.Altitude,
242 _unitsConversion.metersToAppSettingsVerticalDistanceUnits(_flyViewSettings.guidedMaximumAltitude.rawValue),
248 on_ActiveVehicleChanged: _outputState()
250 Component.onCompleted: _outputState()
251 on_VehicleArmedChanged: _outputState()
252 on_VehicleInRTLModeChanged: _outputState()
253 on_VehiclePausedChanged: _outputState()
254 on__FlightModeChanged: _outputState()
255 on__GuidedModeSupportedChanged: _outputState()
256 on__PauseVehicleSupportedChanged: _outputState()
257 on__RoiSupportedChanged: _outputState()
258 on__OrbitSupportedChanged: _outputState()
259 on_VisualItemsCountChanged: _outputState()
260 on_MissionActiveChanged: _outputState()
262 on_CurrentMissionIndexChanged: {
263 if (_isGuidedActionsControllerLogEnabled()) {
264 console.log("_currentMissionIndex", _currentMissionIndex)
267 on_ResumeMissionIndexChanged: {
268 if (_isGuidedActionsControllerLogEnabled()) {
269 console.log("_resumeMissionIndex", _resumeMissionIndex)
272 onShowResumeMissionChanged: {
273 if (_isGuidedActionsControllerLogEnabled()) {
274 console.log("showResumeMission", showResumeMission)
278 onShowStartMissionChanged: {
279 if (_isGuidedActionsControllerLogEnabled()) {
280 console.log("showStartMission", showStartMission)
283 if (showStartMission &&
284 _flyViewSettings.enableAutomaticMissionPopups.rawValue) {
285 confirmAction(actionStartMission)
288 onShowContinueMissionChanged: {
289 if (_isGuidedActionsControllerLogEnabled()) {
290 console.log("showContinueMission", showContinueMission)
293 if (showContinueMission &&
294 _flyViewSettings.enableAutomaticMissionPopups.rawValue) {
295 confirmAction(actionContinueMission)
299 if (_isGuidedActionsControllerLogEnabled()) {
300 console.log("showRTL", showRTL)
304 onShowChangeAltChanged: {
305 if (_isGuidedActionsControllerLogEnabled()) {
306 console.log("showChangeAlt", showChangeAlt)
311 if (_isGuidedActionsControllerLogEnabled()) {
312 console.log("showROI", showROI)
316 onShowOrbitChanged: {
317 if (_isGuidedActionsControllerLogEnabled()) {
318 console.log("showOrbit", showOrbit)
322 onShowGotoLocationChanged: {
323 if (_isGuidedActionsControllerLogEnabled()) {
324 console.log("showGotoLocation", showGotoLocation)
328 onShowLandAbortChanged: {
330 confirmAction(actionLandAbort)
334 on_VehicleUnderwayChanged: {
336 if (!_vehicleUnderway) {
337 // We use _vehicleWasUnderway to help trigger Resume Mission only if the vehicle actually moved and came back down.
338 // Otherwise it may trigger during the Start Mission sequence due to signal ordering or armed and resume mission index.
339 _vehicleWasUnderway = true
343 property var _actionData
345 on_FlightModeChanged: {
346 _vehiclePaused = _activeVehicle ? _flightMode === _activeVehicle.pauseFlightMode : false
347 _vehicleInRTLMode = _activeVehicle ? _flightMode === _activeVehicle.rtlFlightMode || _flightMode === _activeVehicle.smartRTLFlightMode : false
348 _vehicleInLandMode = _activeVehicle ? _flightMode === _activeVehicle.landFlightMode : false
349 _vehicleInMissionMode = _activeVehicle ? _flightMode === _activeVehicle.missionFlightMode : false // Must be last to get correct signalling for showStartMission popups
353 target: missionController
354 function onResumeMissionUploadFail() { confirmAction(actionResumeMissionUploadFail) }
359 function onArmVehicleRequest() { armVehicleRequest() }
360 function onForceArmVehicleRequest() { forceArmVehicleRequest() }
361 function onDisarmVehicleRequest() { disarmVehicleRequest() }
365 target: _unitsConversion
367 function onUnitsChanged() {
368 // Slider range and value were captured in the previous units
369 if (_activeVehicle && guidedValueSlider.visible) {
370 setupSlider(confirmDialog.action)
375 function armVehicleRequest() {
376 confirmAction(actionArm)
379 function forceArmVehicleRequest() {
380 confirmAction(actionForceArm)
383 function disarmVehicleRequest() {
384 if (showEmergencyStop) {
385 confirmAction(actionEmergencyStop)
387 confirmAction(actionDisarm)
392 function closeAll() {
393 confirmDialog.visible = false
394 guidedValueSlider.visible = false
397 // Called when an action is about to be executed in order to confirm
398 function confirmAction(actionCode, actionData, mapIndicator) {
399 var showImmediate = true
401 // Cancel any previously pending action, notifying its map indicator if it differs from the incoming one
402 confirmDialog.confirmCancelled(mapIndicator)
404 confirmDialog.action = actionCode
405 confirmDialog.actionData = actionData
406 confirmDialog.mapIndicator = mapIndicator
407 confirmDialog.optionText = ""
408 _actionData = actionData
410 setupSlider(actionCode)
412 switch (actionCode) {
414 if (_vehicleUnderway || !_guidedActionsEnabled) {
417 confirmDialog.title = armTitle
418 confirmDialog.message = armMessage
419 confirmDialog.hideTrigger = Qt.binding(function() { return !showArm })
422 confirmDialog.title = mvArmTitle
423 confirmDialog.message = mvArmMessage
426 confirmDialog.title = forceArmTitle
427 confirmDialog.message = forceArmMessage
428 confirmDialog.hideTrigger = Qt.binding(function() { return !showForceArm })
431 if (_vehicleAirborne) {
434 confirmDialog.title = disarmTitle
435 confirmDialog.message = disarmMessage
436 confirmDialog.hideTrigger = Qt.binding(function() { return !showDisarm })
439 confirmDialog.title = mvDisarmTitle
440 confirmDialog.message = mvDisarmMessage
442 case actionEmergencyStop:
443 confirmDialog.title = emergencyStopTitle
444 confirmDialog.message = emergencyStopMessage
445 confirmDialog.hideTrigger = Qt.binding(function() { return !showEmergencyStop })
448 confirmDialog.title = takeoffTitle
449 confirmDialog.message = takeoffMessage
450 confirmDialog.hideTrigger = Qt.binding(function() { return !showTakeoff })
451 guidedValueSlider.visible = _activeVehicle.supports.guidedTakeoffWithAltitude
453 case actionStartMission:
454 showImmediate = false
455 confirmDialog.title = startMissionTitle
456 confirmDialog.message = startMissionMessage
457 confirmDialog.hideTrigger = Qt.binding(function() { return !showStartMission })
459 case actionMVStartMission:
460 confirmDialog.title = mvStartMissionTitle
461 confirmDialog.message = mvStartMissionMessage
463 case actionContinueMission:
464 showImmediate = false
465 confirmDialog.title = continueMissionTitle
466 confirmDialog.message = continueMissionMessage
467 confirmDialog.hideTrigger = Qt.binding(function() { return !showContinueMission })
469 case actionResumeMission:
470 // Resume Mission is handled in mission end dialog
472 case actionResumeMissionUploadFail:
473 confirmDialog.title = resumeMissionUploadFailTitle
474 confirmDialog.message = resumeMissionUploadFailMessage
475 confirmDialog.hideTrigger = Qt.binding(function() { return !showResumeMission })
478 confirmDialog.title = landTitle
479 confirmDialog.message = landMessage
480 confirmDialog.hideTrigger = Qt.binding(function() { return !showLand })
483 confirmDialog.title = rtlTitle
484 confirmDialog.message = rtlMessage
485 if (_activeVehicle.supports.smartRTL) {
486 confirmDialog.optionText = qsTr("Smart RTL")
487 confirmDialog.optionChecked = false
489 confirmDialog.hideTrigger = Qt.binding(function() { return !showRTL })
491 case actionChangeAlt:
492 confirmDialog.title = changeAltTitle
493 confirmDialog.message = changeAltMessage
494 confirmDialog.hideTrigger = Qt.binding(function() { return !showChangeAlt })
495 guidedValueSlider.visible = true
497 case actionChangeLoiterRadius:
498 confirmDialog.title = changeLoiterRadiusTitle
499 confirmDialog.message = changeLoiterRadiusMessage
500 confirmDialog.hideTrigger = Qt.binding(function() { return !showChangeLoiterRadius })
501 confirmDialog.mapIndicator = fwdFlightGotoMapCircle
502 fwdFlightGotoMapCircle.startLoiterRadiusEdit()
505 confirmDialog.title = gotoTitle
506 confirmDialog.message = gotoMessage
507 confirmDialog.hideTrigger = Qt.binding(function() { return !showGotoLocation })
509 case actionSetWaypoint:
510 confirmDialog.title = setWaypointTitle
511 confirmDialog.message = setWaypointMessage
514 confirmDialog.title = orbitTitle
515 confirmDialog.message = orbitMessage
516 confirmDialog.hideTrigger = Qt.binding(function() { return !showOrbit })
517 guidedValueSlider.visible = true
519 case actionLandAbort:
520 confirmDialog.title = landAbortTitle
521 confirmDialog.message = landAbortMessage
522 confirmDialog.hideTrigger = Qt.binding(function() { return !showLandAbort })
525 confirmDialog.title = pauseTitle
526 confirmDialog.message = pauseMessage
527 confirmDialog.hideTrigger = Qt.binding(function() { return !showPause })
528 guidedValueSlider.visible = true
531 confirmDialog.title = mvPauseTitle
532 confirmDialog.message = mvPauseMessage
535 confirmDialog.title = roiTitle
536 confirmDialog.message = roiMessage
537 confirmDialog.hideTrigger = Qt.binding(function() { return !showROI })
538 guidedValueSlider.visible = true
540 case actionChangeSpeed:
541 confirmDialog.title = changeSpeedTitle
542 confirmDialog.message = changeSpeedMessage
543 guidedValueSlider.visible = true
546 confirmDialog.title = setHomeTitle
547 confirmDialog.message = setHomeMessage
548 confirmDialog.hideTrigger = Qt.binding(function() { return !showSetHome })
550 case actionSetEstimatorOrigin:
551 confirmDialog.title = setEstimatorOriginTitle
552 confirmDialog.message = setEstimatorOriginMessage
554 case actionSetFlightMode:
555 confirmDialog.title = setFlightMode
556 confirmDialog.message = setFlightModeMessage
558 case actionChangeHeading:
559 confirmDialog.title = changeHeadingTitle
560 confirmDialog.message = changeHeadingMessage
563 if (!customController.customConfirmAction(actionCode, actionData, mapIndicator, confirmDialog)) {
564 console.warn("Unknown actionCode", actionCode)
568 confirmDialog.show(showImmediate)
571 // Executes the specified action
572 // Returns false if the action failed and any associated map indicator should be restored
573 function executeAction(actionCode, actionData, sliderOutputValue, optionChecked) {
575 var selectedVehicles;
576 switch (actionCode) {
578 _activeVehicle.guidedModeRTL(optionChecked)
581 _activeVehicle.guidedModeLand()
584 if (_activeVehicle.supports.guidedTakeoffWithAltitude) {
585 var valueInMeters = _unitsConversion.appSettingsVerticalDistanceUnitsToMeters(sliderOutputValue)
586 _activeVehicle.guidedModeTakeoff(valueInMeters)
588 _activeVehicle.startTakeoff()
591 case actionResumeMission:
592 case actionResumeMissionUploadFail:
593 missionController.resumeMission(missionController.resumeMissionIndex)
595 case actionStartMission:
596 case actionContinueMission:
597 _activeVehicle.startMission()
599 case actionMVStartMission:
600 selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
601 for (i = 0; i < selectedVehicles.count; i++) {
602 var vehicle = selectedVehicles.get(i)
603 if (vehicle.armed === true){
604 vehicle.startMission()
609 _activeVehicle.armed = true
612 selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
613 for (i = 0; i < selectedVehicles.count; i++) {
614 selectedVehicles.get(i).armed = true
618 _activeVehicle.forceArm()
621 _activeVehicle.armed = false
624 selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
625 for (i = 0; i < selectedVehicles.count; i++) {
626 selectedVehicles.get(i).armed = false
629 case actionEmergencyStop:
630 _activeVehicle.emergencyStop()
632 case actionChangeAlt:
633 var valueInMeters = _unitsConversion.appSettingsVerticalDistanceUnitsToMeters(sliderOutputValue)
634 var altitudeChangeInMeters = valueInMeters - _activeVehicle.altitudeRelative.rawValue
635 _activeVehicle.guidedModeChangeAltitude(altitudeChangeInMeters, false /* pauseVehicle */)
637 case actionChangeLoiterRadius:
638 if (!_activeVehicle.guidedModeGotoLocation(
639 fwdFlightGotoMapCircle.coordinate,
640 (fwdFlightGotoMapCircle.clockwiseRotation ? 1 : -1) *
641 Math.abs(fwdFlightGotoMapCircle.radius.rawValue)
647 if (!_activeVehicle.guidedModeGotoLocation(
649 _vehicleInFwdFlight /* forwardFlightLoiterRadius */
650 ? _flyViewSettings.forwardFlightGoToLocationLoiterRad.rawValue
656 case actionSetWaypoint:
657 _activeVehicle.setCurrentMissionSequence(actionData)
660 var valueInMeters = _unitsConversion.appSettingsVerticalDistanceUnitsToMeters(sliderOutputValue)
661 _activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius() * (orbitMapCircle.clockwiseRotation ? 1 : -1), _activeVehicle.homePosition.altitude + valueInMeters)
663 case actionLandAbort:
664 _activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored
667 var valueInMeters = _unitsConversion.appSettingsVerticalDistanceUnitsToMeters(sliderOutputValue)
668 var altitudeChangeInMeters = valueInMeters - _activeVehicle.altitudeRelative.rawValue
669 _activeVehicle.guidedModeChangeAltitude(altitudeChangeInMeters, true /* pauseVehicle */)
672 selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
673 for (i = 0; i < selectedVehicles.count; i++) {
674 selectedVehicles.get(i).pauseVehicle()
678 const roiRelativeAltitudeMeters = _unitsConversion.appSettingsVerticalDistanceUnitsToMeters(sliderOutputValue)
679 if (!_activeVehicle.guidedModeROI(actionData, roiRelativeAltitudeMeters)) {
684 case actionChangeSpeed:
685 if (_activeVehicle) {
686 // We need to convert back to m/s as that is what mavlink standard uses for MAV_CMD_DO_CHANGE_SPEED
687 var metersSecondSpeed = _unitsConversion.appSettingsSpeedUnitsToMetersSecond(sliderOutputValue)
688 if (_vehicleInFwdFlight) {
689 _activeVehicle.guidedModeChangeEquivalentAirspeedMetersSecond(metersSecondSpeed)
691 _activeVehicle.guidedModeChangeGroundSpeedMetersSecond(metersSecondSpeed)
696 _activeVehicle.doSetHome(actionData)
698 case actionSetEstimatorOrigin:
699 _activeVehicle.setEstimatorOrigin(actionData)
701 case actionSetFlightMode:
702 _activeVehicle.flightMode = actionData
704 case actionChangeHeading:
705 _activeVehicle.guidedModeChangeHeading(actionData)
708 if (!customController.customExecuteAction(actionCode, actionData, sliderOutputValue, optionChecked)) {
709 console.warn(qsTr("Internal error: unknown actionCode"), actionCode)