You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
22 KiB
417 lines
22 KiB
/**************************************************************************** |
|
* |
|
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
|
* |
|
* QGroundControl is licensed according to the terms in the file |
|
* COPYING.md in the root of the source code directory. |
|
* |
|
****************************************************************************/ |
|
|
|
import QtQuick 2.3 |
|
import QtQuick.Controls 1.2 |
|
import QtQuick.Controls.Styles 1.4 |
|
import QtQuick.Dialogs 1.2 |
|
import QtLocation 5.3 |
|
import QtPositioning 5.3 |
|
import QtQuick.Layouts 1.2 |
|
|
|
import QGroundControl 1.0 |
|
import QGroundControl.ScreenTools 1.0 |
|
import QGroundControl.Controls 1.0 |
|
import QGroundControl.Palette 1.0 |
|
import QGroundControl.Vehicle 1.0 |
|
import QGroundControl.FlightMap 1.0 |
|
|
|
/// This provides the smarts behind the guided mode commands, minus the user interface. This way you can change UI |
|
/// without affecting the underlying functionality. |
|
Item { |
|
id: _root |
|
|
|
property var missionController |
|
property var confirmDialog |
|
property var actionList |
|
property var altitudeSlider |
|
|
|
readonly property string emergencyStopTitle: qsTr("EMERGENCY STOP") |
|
readonly property string armTitle: qsTr("Arm") |
|
readonly property string disarmTitle: qsTr("Disarm") |
|
readonly property string rtlTitle: qsTr("RTL") |
|
readonly property string takeoffTitle: qsTr("Takeoff") |
|
readonly property string landTitle: qsTr("Land") |
|
readonly property string startMissionTitle: qsTr("Start Mission") |
|
readonly property string continueMissionTitle: qsTr("Continue Mission") |
|
readonly property string resumeMissionTitle: qsTr("Resume Mission") |
|
readonly property string resumeMissionUploadFailTitle: qsTr("Resume FAILED") |
|
readonly property string pauseTitle: qsTr("Pause") |
|
readonly property string changeAltTitle: qsTr("Change Altitude") |
|
readonly property string orbitTitle: qsTr("Orbit") |
|
readonly property string landAbortTitle: qsTr("Land Abort") |
|
readonly property string setWaypointTitle: qsTr("Set Waypoint") |
|
readonly property string gotoTitle: qsTr("Goto Location") |
|
readonly property string vtolTransitionTitle: qsTr("VTOL Transition") |
|
|
|
readonly property string armMessage: qsTr("Arm the vehicle.") |
|
readonly property string disarmMessage: qsTr("Disarm the vehicle") |
|
readonly property string emergencyStopMessage: qsTr("WARNING: THIS WILL STOP ALL MOTORS. IF VEHICLE IS CURRENTLY IN THE AIR IT WILL CRASH.") |
|
readonly property string takeoffMessage: qsTr("Takeoff from ground and hold position.") |
|
readonly property string startMissionMessage: qsTr("Takeoff from ground and start the current mission.") |
|
readonly property string continueMissionMessage: qsTr("Continue the mission from the current waypoint.") |
|
property string resumeMissionMessage: qsTr("Resume the current mission. This will re-generate the mission from waypoint %1, takeoff and continue the mission.").arg(_resumeMissionIndex) |
|
property string resumeMissionUploadFailMessage: qsTr("Upload of resume mission failed. Confirm to retry upload") |
|
readonly property string resumeMissionReadyMessage: qsTr("Review the modified mission. Confirm if you want to takeoff and begin mission.") |
|
readonly property string landMessage: qsTr("Land the vehicle at the current position.") |
|
readonly property string rtlMessage: qsTr("Return to the home position of the vehicle.") |
|
readonly property string changeAltMessage: qsTr("Change the altitude of the vehicle up or down.") |
|
readonly property string gotoMessage: qsTr("Move the vehicle to the specified location.") |
|
property string setWaypointMessage: qsTr("Adjust current waypoint to %1.").arg(_actionData) |
|
readonly property string orbitMessage: qsTr("Orbit the vehicle around the specified location. Warning: WORK IN PROGRESS!") |
|
readonly property string landAbortMessage: qsTr("Abort the landing sequence.") |
|
readonly property string pauseMessage: qsTr("Pause the vehicle at it's current position, adjusting altitude up or down as needed.") |
|
readonly property string mvPauseMessage: qsTr("Pause all vehicles at their current position.") |
|
readonly property string vtolTransitionFwdMessage: qsTr("Transition VTOL to fixed wing flight.") |
|
readonly property string vtolTransitionMRMessage: qsTr("Transition VTOL to multi-rotor flight.") |
|
|
|
readonly property int actionRTL: 1 |
|
readonly property int actionLand: 2 |
|
readonly property int actionTakeoff: 3 |
|
readonly property int actionArm: 4 |
|
readonly property int actionDisarm: 5 |
|
readonly property int actionEmergencyStop: 6 |
|
readonly property int actionChangeAlt: 7 |
|
readonly property int actionGoto: 8 |
|
readonly property int actionSetWaypoint: 9 |
|
readonly property int actionOrbit: 10 |
|
readonly property int actionLandAbort: 11 |
|
readonly property int actionStartMission: 12 |
|
readonly property int actionContinueMission: 13 |
|
readonly property int actionResumeMission: 14 |
|
readonly property int actionResumeMissionReady: 15 |
|
readonly property int actionResumeMissionUploadFail: 16 |
|
readonly property int actionPause: 17 |
|
readonly property int actionMVPause: 18 |
|
readonly property int actionMVStartMission: 19 |
|
readonly property int actionVtolTransitionToFwdFlight: 20 |
|
readonly property int actionVtolTransitionToMRFlight: 21 |
|
|
|
property bool showEmergenyStop: _guidedActionsEnabled && !_hideEmergenyStop && _vehicleArmed && _vehicleFlying |
|
property bool showArm: _guidedActionsEnabled && !_vehicleArmed |
|
property bool showDisarm: _guidedActionsEnabled && _vehicleArmed && !_vehicleFlying |
|
property bool showRTL: _guidedActionsEnabled && _vehicleArmed && _activeVehicle.guidedModeSupported && _vehicleFlying && !_vehicleInRTLMode |
|
property bool showTakeoff: _guidedActionsEnabled && _activeVehicle.takeoffVehicleSupported && !_vehicleFlying |
|
property bool showLand: _guidedActionsEnabled && _activeVehicle.guidedModeSupported && _vehicleArmed && !_activeVehicle.fixedWing && !_vehicleInLandMode |
|
property bool showStartMission: _guidedActionsEnabled && _missionAvailable && !_missionActive && !_vehicleFlying |
|
property bool showContinueMission: _guidedActionsEnabled && _missionAvailable && !_missionActive && _vehicleFlying && (_currentMissionIndex < missionController.visualItems.count - 1) |
|
property bool showPause: _guidedActionsEnabled && _vehicleArmed && _activeVehicle.pauseVehicleSupported && _vehicleFlying && !_vehiclePaused |
|
property bool showChangeAlt: _guidedActionsEnabled && _vehicleFlying && _activeVehicle.guidedModeSupported && _vehicleArmed && !_missionActive |
|
property bool showOrbit: _guidedActionsEnabled && !_hideOrbit && _vehicleFlying && _activeVehicle.orbitModeSupported && !_missionActive |
|
property bool showLandAbort: _guidedActionsEnabled && _vehicleFlying && _activeVehicle.fixedWing && _vehicleLanding |
|
property bool showGotoLocation: _guidedActionsEnabled && _vehicleFlying |
|
|
|
// Note: The 'missionController.visualItems.count - 3' is a hack to not trigger resume mission when a mission ends with an RTL item |
|
property bool showResumeMission: _activeVehicle && !_vehicleArmed && _vehicleWasFlying && _missionAvailable && _resumeMissionIndex > 0 && (_resumeMissionIndex < missionController.visualItems.count - 3) |
|
|
|
property bool guidedUIVisible: guidedActionConfirm.visible || guidedActionList.visible |
|
|
|
property bool _guidedActionsEnabled: (!ScreenTools.isDebug && QGroundControl.corePlugin.options.guidedActionsRequireRCRSSI && _activeVehicle) ? _rcRSSIAvailable : _activeVehicle |
|
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle |
|
property string _flightMode: _activeVehicle ? _activeVehicle.flightMode : "" |
|
property bool _missionAvailable: missionController.containsItems |
|
property bool _missionActive: _activeVehicle ? _vehicleArmed && (_vehicleInLandMode || _vehicleInRTLMode || _vehicleInMissionMode) : false |
|
property bool _vehicleArmed: _activeVehicle ? _activeVehicle.armed : false |
|
property bool _vehicleFlying: _activeVehicle ? _activeVehicle.flying : false |
|
property bool _vehicleLanding: _activeVehicle ? _activeVehicle.landing : false |
|
property bool _vehiclePaused: false |
|
property bool _vehicleInMissionMode: false |
|
property bool _vehicleInRTLMode: false |
|
property bool _vehicleInLandMode: false |
|
property int _currentMissionIndex: missionController.currentMissionIndex |
|
property int _resumeMissionIndex: missionController.resumeMissionIndex |
|
property bool _hideEmergenyStop: !QGroundControl.corePlugin.options.guidedBarShowEmergencyStop |
|
property bool _hideOrbit: !QGroundControl.corePlugin.options.guidedBarShowOrbit |
|
property bool _vehicleWasFlying: false |
|
property bool _rcRSSIAvailable: _activeVehicle ? _activeVehicle.rcRSSI > 0 && _activeVehicle.rcRSSI < 255 : false |
|
|
|
//Handy code for debugging state problems |
|
property bool __debugGuidedStates: false |
|
property bool __guidedModeSupported: _activeVehicle ? _activeVehicle.guidedModeSupported : false |
|
property bool __pauseVehicleSupported: _activeVehicle ? _activeVehicle.pauseVehicleSupported : false |
|
property bool __flightMode: _flightMode |
|
|
|
function _outputState() { |
|
if (__debugGuidedStates) { |
|
console.log(qsTr("_activeVehicle(%1) _vehicleArmed(%2) guidedModeSupported(%3) _vehicleFlying(%4) _vehicleInRTLMode(%5) pauseVehicleSupported(%6) _vehiclePaused(%7) _flightMode(%8)").arg(_activeVehicle ? 1 : 0).arg(_vehicleArmed ? 1 : 0).arg(__guidedModeSupported ? 1 : 0).arg(_vehicleFlying ? 1 : 0).arg(_vehicleInRTLMode ? 1 : 0).arg(__pauseVehicleSupported ? 1 : 0).arg(_vehiclePaused ? 1 : 0).arg(_flightMode)) |
|
} |
|
} |
|
|
|
Component.onCompleted: _outputState() |
|
on_ActiveVehicleChanged: _outputState() |
|
on_VehicleArmedChanged: _outputState() |
|
on_VehicleInRTLModeChanged: _outputState() |
|
on_VehiclePausedChanged: _outputState() |
|
on__FlightModeChanged: _outputState() |
|
on__GuidedModeSupportedChanged: _outputState() |
|
on__PauseVehicleSupportedChanged: _outputState() |
|
|
|
on_CurrentMissionIndexChanged: { |
|
if (__debugGuidedStates) { |
|
console.log("_currentMissionIndex", _currentMissionIndex) |
|
} |
|
} |
|
on_ResumeMissionIndexChanged: { |
|
if (__debugGuidedStates) { |
|
console.log("_resumeMissionIndex", _resumeMissionIndex) |
|
} |
|
} |
|
onShowResumeMissionChanged: { |
|
if (__debugGuidedStates) { |
|
console.log("showResumeMission", showResumeMission) |
|
} |
|
_outputState() |
|
} |
|
onShowStartMissionChanged: { |
|
if (__debugGuidedStates) { |
|
console.log("showStartMission", showStartMission) |
|
} |
|
_outputState() |
|
} |
|
onShowContinueMissionChanged: { |
|
if (__debugGuidedStates) { |
|
console.log("showContinueMission", showContinueMission) |
|
} |
|
_outputState() |
|
} |
|
// End of hack |
|
|
|
on_VehicleFlyingChanged: { |
|
_outputState() |
|
if (!_vehicleFlying) { |
|
// We use _vehicleWasFLying to help trigger Resume Mission only if the vehicle actually flew and came back down. |
|
// Otherwise it may trigger during the Start Mission sequence due to signal ordering or armed and resume mission index. |
|
_vehicleWasFlying = true |
|
} |
|
} |
|
|
|
property var _actionData |
|
|
|
on_FlightModeChanged: { |
|
_vehiclePaused = _activeVehicle ? _flightMode === _activeVehicle.pauseFlightMode : false |
|
_vehicleInRTLMode = _activeVehicle ? _flightMode === _activeVehicle.rtlFlightMode : false |
|
_vehicleInLandMode = _activeVehicle ? _flightMode === _activeVehicle.landFlightMode : false |
|
_vehicleInMissionMode = _activeVehicle ? _flightMode === _activeVehicle.missionFlightMode : false // Must be last to get correct signalling for showStartMission popups |
|
} |
|
|
|
// Called when an action is about to be executed in order to confirm |
|
function confirmAction(actionCode, actionData) { |
|
var showImmediate = true |
|
closeAll() |
|
confirmDialog.action = actionCode |
|
confirmDialog.actionData = actionData |
|
confirmDialog.hideTrigger = true |
|
_actionData = actionData |
|
switch (actionCode) { |
|
case actionArm: |
|
if (_vehicleFlying || !_guidedActionsEnabled) { |
|
return |
|
} |
|
confirmDialog.title = armTitle |
|
confirmDialog.message = armMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showArm }) |
|
break; |
|
case actionDisarm: |
|
if (_vehicleFlying) { |
|
return |
|
} |
|
confirmDialog.title = disarmTitle |
|
confirmDialog.message = disarmMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showDisarm }) |
|
break; |
|
case actionEmergencyStop: |
|
confirmDialog.title = emergencyStopTitle |
|
confirmDialog.message = emergencyStopMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showEmergenyStop }) |
|
break; |
|
case actionTakeoff: |
|
confirmDialog.title = takeoffTitle |
|
confirmDialog.message = takeoffMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showTakeoff }) |
|
altitudeSlider.setToMinimumTakeoff() |
|
altitudeSlider.visible = true |
|
break; |
|
case actionStartMission: |
|
showImmediate = false |
|
confirmDialog.title = startMissionTitle |
|
confirmDialog.message = startMissionMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showStartMission }) |
|
break; |
|
case actionMVStartMission: |
|
confirmDialog.title = startMissionTitle |
|
confirmDialog.message = startMissionMessage |
|
confirmDialog.hideTrigger = true |
|
break; |
|
case actionContinueMission: |
|
showImmediate = false |
|
confirmDialog.title = continueMissionTitle |
|
confirmDialog.message = continueMissionMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showContinueMission }) |
|
break; |
|
case actionResumeMission: |
|
showImmediate = false |
|
confirmDialog.title = resumeMissionTitle |
|
confirmDialog.message = resumeMissionMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showResumeMission }) |
|
break; |
|
case actionResumeMissionUploadFail: |
|
confirmDialog.title = resumeMissionUploadFailTitle |
|
confirmDialog.message = resumeMissionUploadFailMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showResumeMission }) |
|
break; |
|
case actionResumeMissionReady: |
|
confirmDialog.title = resumeMissionTitle |
|
confirmDialog.message = resumeMissionReadyMessage |
|
confirmDialog.hideTrigger = false |
|
break; |
|
case actionLand: |
|
confirmDialog.title = landTitle |
|
confirmDialog.message = landMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showLand }) |
|
break; |
|
case actionRTL: |
|
confirmDialog.title = rtlTitle |
|
confirmDialog.message = rtlMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showRTL }) |
|
break; |
|
case actionChangeAlt: |
|
confirmDialog.title = changeAltTitle |
|
confirmDialog.message = changeAltMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showChangeAlt }) |
|
altitudeSlider.reset() |
|
altitudeSlider.visible = true |
|
break; |
|
case actionGoto: |
|
confirmDialog.title = gotoTitle |
|
confirmDialog.message = gotoMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showGotoLocation }) |
|
break; |
|
case actionSetWaypoint: |
|
confirmDialog.title = setWaypointTitle |
|
confirmDialog.message = setWaypointMessage |
|
break; |
|
case actionOrbit: |
|
confirmDialog.title = orbitTitle |
|
confirmDialog.message = orbitMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showOrbit }) |
|
altitudeSlider.reset() |
|
altitudeSlider.visible = true |
|
break; |
|
case actionLandAbort: |
|
confirmDialog.title = landAbortTitle |
|
confirmDialog.message = landAbortMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showLandAbort }) |
|
break; |
|
case actionPause: |
|
confirmDialog.title = pauseTitle |
|
confirmDialog.message = pauseMessage |
|
confirmDialog.hideTrigger = Qt.binding(function() { return !showPause }) |
|
altitudeSlider.reset() |
|
altitudeSlider.visible = true |
|
break; |
|
case actionMVPause: |
|
confirmDialog.title = pauseTitle |
|
confirmDialog.message = mvPauseMessage |
|
confirmDialog.hideTrigger = true |
|
break; |
|
case actionVtolTransitionToFwdFlight: |
|
confirmDialog.title = vtolTransitionTitle |
|
confirmDialog.message = vtolTransitionFwdMessage |
|
confirmDialog.hideTrigger = true |
|
break |
|
case actionVtolTransitionToMRFlight: |
|
confirmDialog.title = vtolTransitionTitle |
|
confirmDialog.message = vtolTransitionMRMessage |
|
confirmDialog.hideTrigger = true |
|
break |
|
default: |
|
console.warn("Unknown actionCode", actionCode) |
|
return |
|
} |
|
confirmDialog.show(showImmediate) |
|
} |
|
|
|
// Executes the specified action |
|
function executeAction(actionCode, actionData, actionAltitudeChange) { |
|
var i; |
|
var rgVehicle; |
|
switch (actionCode) { |
|
case actionRTL: |
|
_activeVehicle.guidedModeRTL() |
|
break |
|
case actionLand: |
|
_activeVehicle.guidedModeLand() |
|
break |
|
case actionTakeoff: |
|
_activeVehicle.guidedModeTakeoff(actionAltitudeChange) |
|
break |
|
case actionResumeMission: |
|
case actionResumeMissionUploadFail: |
|
missionController.resumeMission(missionController.resumeMissionIndex) |
|
break |
|
case actionResumeMissionReady: |
|
_vehicleWasFlying = false |
|
_activeVehicle.startMission() |
|
break |
|
case actionStartMission: |
|
case actionContinueMission: |
|
_activeVehicle.startMission() |
|
break |
|
case actionMVStartMission: |
|
rgVehicle = QGroundControl.multiVehicleManager.vehicles |
|
for (i = 0; i < rgVehicle.count; i++) { |
|
rgVehicle.get(i).startMission() |
|
} |
|
break |
|
case actionArm: |
|
_activeVehicle.armed = true |
|
break |
|
case actionDisarm: |
|
_activeVehicle.armed = false |
|
break |
|
case actionEmergencyStop: |
|
_activeVehicle.emergencyStop() |
|
break |
|
case actionChangeAlt: |
|
_activeVehicle.guidedModeChangeAltitude(actionAltitudeChange) |
|
break |
|
case actionGoto: |
|
_activeVehicle.guidedModeGotoLocation(actionData) |
|
break |
|
case actionSetWaypoint: |
|
_activeVehicle.setCurrentMissionSequence(actionData) |
|
break |
|
case actionOrbit: |
|
_activeVehicle.guidedModeOrbit(actionData, 10 /* Hacked fixed radius */, _activeVehicle.altitudeAMSL + actionAltitudeChange) |
|
break |
|
case actionLandAbort: |
|
_activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored |
|
break |
|
case actionPause: |
|
_activeVehicle.pauseVehicle() |
|
_activeVehicle.guidedModeChangeAltitude(actionAltitudeChange) |
|
break |
|
case actionMVPause: |
|
rgVehicle = QGroundControl.multiVehicleManager.vehicles |
|
for (i = 0; i < rgVehicle.count; i++) { |
|
rgVehicle.get(i).pauseVehicle() |
|
} |
|
break |
|
case actionVtolTransitionToFwdFlight: |
|
_activeVehicle.vtolInFwdFlight = true |
|
break |
|
case actionVtolTransitionToMRFlight: |
|
_activeVehicle.vtolInFwdFlight = false |
|
break |
|
default: |
|
console.warn(qsTr("Internal error: unknown actionCode"), actionCode) |
|
break |
|
} |
|
} |
|
}
|
|
|