地面站终端 App
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.

541 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 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
Item {
id: _root
property alias guidedModeBar: _guidedModeBar
property bool gotoEnabled: _activeVehicle && _activeVehicle.guidedMode && _activeVehicle.flying
property var qgcView
property bool useLightColors
property var missionController
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property bool _isSatellite: _mainIsMap ? (_flightMap ? _flightMap.isSatelliteMap : true) : true
property bool _lightWidgetBorders: _isSatellite
// Guided bar properties
property bool _missionAvailable: missionController.containsItems
property bool _missionActive: _activeVehicle ? _activeVehicle.flightMode === _activeVehicle.missionFlightMode : false
property bool _missionInProgress: missionController.missionInProgress
property bool _showEmergenyStop: QGroundControl.corePlugin.options.guidedBarShowEmergencyStop
property bool _showOrbit: QGroundControl.corePlugin.options.guidedBarShowOrbit
readonly property real _margins: ScreenTools.defaultFontPixelHeight * 0.5
QGCMapPalette { id: mapPal; lightColors: useLightColors }
QGCPalette { id: qgcPal }
function getPreferredInstrumentWidth() {
if(ScreenTools.isMobile) {
return ScreenTools.isTinyScreen ? mainWindow.width * 0.2 : mainWindow.width * 0.15
}
var w = mainWindow.width * 0.15
return Math.min(w, 200)
}
function _setInstrumentWidget() {
if(QGroundControl.corePlugin.options.instrumentWidget.source.toString().length) {
instrumentsLoader.source = QGroundControl.corePlugin.options.instrumentWidget.source
switch(QGroundControl.corePlugin.options.instrumentWidget.widgetPosition) {
case CustomInstrumentWidget.POS_TOP_RIGHT:
instrumentsLoader.state = "topMode"
break;
case CustomInstrumentWidget.POS_BOTTOM_RIGHT:
instrumentsLoader.state = "bottomMode"
break;
case CustomInstrumentWidget.POS_CENTER_RIGHT:
default:
instrumentsLoader.state = "centerMode"
break;
}
} else {
var useAlternateInstruments = QGroundControl.settingsManager.appSettings.virtualJoystick.value || ScreenTools.isTinyScreen
if(useAlternateInstruments) {
instrumentsLoader.source = "qrc:/qml/QGCInstrumentWidgetAlternate.qml"
instrumentsLoader.state = "topMode"
} else {
instrumentsLoader.source = "qrc:/qml/QGCInstrumentWidget.qml"
instrumentsLoader.state = QGroundControl.settingsManager.appSettings.showLargeCompass.value == 1 ? "centerMode" : "topMode"
}
}
}
Connections {
target: QGroundControl.settingsManager.appSettings.virtualJoystick
onValueChanged: _setInstrumentWidget()
}
Connections {
target: QGroundControl.settingsManager.appSettings.showLargeCompass
onValueChanged: _setInstrumentWidget()
}
Component.onCompleted: {
_setInstrumentWidget()
}
//-- Map warnings
Column {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
visible: _activeVehicle && !_activeVehicle.coordinateValid && _mainIsMap
z: QGroundControl.zOrderTopMost
color: mapPal.text
font.pointSize: ScreenTools.largeFontPointSize
text: qsTr("No GPS Lock for Vehicle")
}
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
visible: _activeVehicle && _activeVehicle.prearmError
z: QGroundControl.zOrderTopMost
color: mapPal.text
font.pointSize: ScreenTools.largeFontPointSize
text: _activeVehicle ? _activeVehicle.prearmError : ""
}
}
//-- Instrument Panel
Loader {
id: instrumentsLoader
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right
z: QGroundControl.zOrderWidgets
property var qgcView: _root.qgcView
property real maxHeight:parent.height - (anchors.margins * 2)
states: [
State {
name: "topMode"
AnchorChanges {
target: instrumentsLoader
anchors.verticalCenter: undefined
anchors.bottom: undefined
anchors.top: _root ? _root.top : undefined
}
},
State {
name: "centerMode"
AnchorChanges {
target: instrumentsLoader
anchors.top: undefined
anchors.bottom: undefined
anchors.verticalCenter: _root ? _root.verticalCenter : undefined
}
},
State {
name: "bottomMode"
AnchorChanges {
target: instrumentsLoader
anchors.top: undefined
anchors.verticalCenter: undefined
anchors.bottom: _root ? _root.bottom : undefined
}
}
]
}
//-- Guided mode buttons
Rectangle {
id: _guidedModeBar
anchors.margins: _barMargin
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: guidedModeColumn.width + (_margins * 2)
height: guidedModeColumn.height + (_margins * 2)
radius: ScreenTools.defaultFontPixelHeight * 0.25
color: _isSatellite ? Qt.rgba(qgcPal.mapWidgetBorderLight.r, qgcPal.mapWidgetBorderLight.g, qgcPal.mapWidgetBorderLight.b, 0.8) : Qt.rgba(qgcPal.mapWidgetBorderDark.r, qgcPal.mapWidgetBorderDark.g, qgcPal.mapWidgetBorderDark.b, 0.75)
visible: _activeVehicle
z: QGroundControl.zOrderWidgets
state: "Shown"
property real _fontPointSize: ScreenTools.isMobile ? ScreenTools.largeFontPointSize : ScreenTools.defaultFontPointSize
states: [
State {
name: "Shown"
PropertyChanges { target: showAnimation; running: true }
PropertyChanges { target: guidedModeHideTimer; running: true }
},
State {
name: "Hidden"
PropertyChanges { target: hideAnimation; running: true }
}
]
PropertyAnimation {
id: hideAnimation
target: _guidedModeBar
property: "_barMargin"
duration: 1000
easing.type: Easing.InOutQuad
from: _guidedModeBar._showMargin
to: _guidedModeBar._hideMargin
}
PropertyAnimation {
id: showAnimation
target: _guidedModeBar
property: "_barMargin"
duration: 250
easing.type: Easing.InOutQuad
from: _guidedModeBar._hideMargin
to: _guidedModeBar._showMargin
}
Timer {
id: guidedModeHideTimer
interval: 7000
running: true
onTriggered: {
if (ScreenTools.isTinyScreen) {
_guidedModeBar.state = "Hidden"
}
}
}
readonly property int confirmHome: 1
readonly property int confirmLand: 2
readonly property int confirmTakeoff: 3
readonly property int confirmArm: 4
readonly property int confirmDisarm: 5
readonly property int confirmEmergencyStop: 6
readonly property int confirmChangeAlt: 7
readonly property int confirmGoTo: 8
readonly property int confirmRetask: 9
readonly property int confirmOrbit: 10
readonly property int confirmAbort: 11
readonly property int confirmStartMission: 12
readonly property int confirmResumeMission: 13
property int confirmActionCode
property real _showMargin: _margins
property real _hideMargin: _margins - _guidedModeBar.height
property real _barMargin: _showMargin
function actionConfirmed() {
switch (confirmActionCode) {
case confirmHome:
_activeVehicle.guidedModeRTL()
break;
case confirmLand:
_activeVehicle.guidedModeLand()
break;
case confirmTakeoff:
_activeVehicle.guidedModeTakeoff()
break;
case confirmResumeMission:
case confirmStartMission:
_activeVehicle.startMission()
break;
case confirmArm:
_activeVehicle.armed = true
break;
case confirmDisarm:
_activeVehicle.armed = false
break;
case confirmEmergencyStop:
_activeVehicle.emergencyStop()
break;
case confirmChangeAlt:
var altitude2 = altitudeSlider.getValue()
if (!isNaN(altitude2)) {
_activeVehicle.guidedModeChangeAltitude(altitude2)
}
break;
case confirmGoTo:
_activeVehicle.guidedModeGotoLocation(_flightMap._gotoHereCoordinate)
break;
case confirmRetask:
_activeVehicle.setCurrentMissionSequence(_flightMap._retaskSequence)
break;
case confirmOrbit:
//-- All parameters controlled by RC
_activeVehicle.guidedModeOrbit()
//-- Center on current flight map position and orbit with a 50m radius (velocity/direction controlled by the RC)
//_activeVehicle.guidedModeOrbit(QGroundControl.flightMapPosition, 50.0)
break;
case confirmAbort:
_activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored
break;
default:
console.warn(qsTr("Internal error: unknown confirmActionCode"), confirmActionCode)
}
}
function rejectGuidedModeConfirm() {
guidedModeConfirm.visible = false
_guidedModeBar.visible = true
altitudeSlider.visible = false
_flightMap._gotoHereCoordinate = QtPositioning.coordinate()
guidedModeHideTimer.restart()
}
function confirmAction(actionCode) {
guidedModeHideTimer.stop()
confirmActionCode = actionCode
switch (confirmActionCode) {
case confirmArm:
guidedModeConfirm.confirmText = qsTr("arm")
break;
case confirmDisarm:
guidedModeConfirm.confirmText = qsTr("disarm")
break;
case confirmEmergencyStop:
guidedModeConfirm.confirmText = qsTr("STOP ALL MOTORS!")
break;
case confirmTakeoff:
guidedModeConfirm.confirmText = qsTr("takeoff")
break;
case confirmStartMission:
guidedModeConfirm.confirmText = qsTr("start mission")
break;
case confirmResumeMission:
guidedModeConfirm.confirmText = qsTr("resume mission")
break;
case confirmLand:
guidedModeConfirm.confirmText = qsTr("land")
break;
case confirmHome:
guidedModeConfirm.confirmText = qsTr("return to land")
break;
case confirmChangeAlt:
altitudeSlider.visible = true
altitudeSlider.setInitialValueAppSettingsDistanceUnits(_activeVehicle.altitudeRelative.value)
guidedModeConfirm.confirmText = qsTr("change altitude")
break;
case confirmGoTo:
guidedModeConfirm.confirmText = qsTr("move vehicle")
break;
case confirmRetask:
guidedModeConfirm.confirmText = qsTr("activate waypoint change")
break;
case confirmOrbit:
guidedModeConfirm.confirmText = qsTr("enter orbit mode")
break;
case confirmAbort:
guidedModeConfirm.confirmText = qsTr("abort landing")
break;
}
_guidedModeBar.visible = false
guidedModeConfirm.visible = true
}
Column {
id: guidedModeColumn
anchors.margins: _margins
anchors.top: parent.top
anchors.left: parent.left
spacing: _margins
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
color: _isSatellite ? qgcPal.mapWidgetBorderDark : qgcPal.mapWidgetBorderLight
text: "Click in map to move vehicle"
visible: gotoEnabled
}
Row {
spacing: _margins * 2
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Emergency Stop")
visible: _showEmergenyStop && _activeVehicle && _activeVehicle.armed && _activeVehicle.flying
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmEmergencyStop)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Disarm")
visible: _activeVehicle && _activeVehicle.armed && !_activeVehicle.flying
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmDisarm)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("RTL")
visible: _activeVehicle && _activeVehicle.armed && _activeVehicle.guidedModeSupported && _activeVehicle.flying
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmHome)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Takeoff")
visible: _activeVehicle && _activeVehicle.guidedModeSupported && !_activeVehicle.flying && !_activeVehicle.fixedWing
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmTakeoff)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Land")
visible: _activeVehicle && _activeVehicle.guidedModeSupported && _activeVehicle.armed && !_activeVehicle.fixedWing
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmLand)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Start Mission")
visible: _activeVehicle && !_activeVehicle.flying && _missionAvailable
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmStartMission)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Resume Mission")
visible: _activeVehicle && _activeVehicle.guidedModeSupported && !_activeVehicle.flying && _missionAvailable && _missionInProgress
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmResumeMission)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: _missionActive ? qsTr("Pause Mission") : qsTr("Pause")
visible: _activeVehicle && _activeVehicle.armed && _activeVehicle.pauseVehicleSupported && _activeVehicle.flying
onClicked: _activeVehicle.pauseVehicle()
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Change Altitude")
visible: (_activeVehicle && _activeVehicle.flying) && _activeVehicle.guidedModeSupported && _activeVehicle.armed
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmChangeAlt)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Orbit")
visible: _showOrbit && _activeVehicle && _activeVehicle.flying && _activeVehicle.orbitModeSupported && _activeVehicle.armed
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmOrbit)
}
QGCButton {
pointSize: _guidedModeBar._fontPointSize
text: qsTr("Abort")
visible: _activeVehicle && _activeVehicle.flying && _activeVehicle.fixedWing
onClicked: _guidedModeBar.confirmAction(_guidedModeBar.confirmAbort)
}
} // Row
} // Column
} // Rectangle - Guided mode buttons
MouseArea {
anchors.fill: parent
enabled: guidedModeConfirm.visible
onClicked: _guidedModeBar.rejectGuidedModeConfirm()
}
// Action confirmation control
SliderSwitch {
id: guidedModeConfirm
anchors.bottomMargin: _margins
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
visible: false
z: QGroundControl.zOrderWidgets
fontPointSize: _guidedModeBar._fontPointSize
onAccept: {
guidedModeConfirm.visible = false
_guidedModeBar.visible = true
_guidedModeBar.actionConfirmed()
altitudeSlider.visible = false
guidedModeHideTimer.restart()
}
onReject: _guidedModeBar.rejectGuidedModeConfirm()
}
//-- Altitude slider
Rectangle {
id: altitudeSlider
anchors.margins: _margins
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
color: qgcPal.window
width: ScreenTools.defaultFontPixelWidth * 10
opacity: 0.8
visible: false
function setInitialValueMeters(meters) {
altSlider.value = QGroundControl.metersToAppSettingsDistanceUnits(meters)
}
function setInitialValueAppSettingsDistanceUnits(height) {
altSlider.value = height
}
/// Returns NaN for bad value
function getValue() {
var value = parseFloat(altField.text)
if (!isNaN(value)) {
return QGroundControl.appSettingsDistanceUnitsToMeters(value);
} else {
return value;
}
}
Column {
id: headerColumn
anchors.margins: _margins
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Alt (rel)")
}
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: QGroundControl.appSettingsDistanceUnitsString
}
QGCTextField {
id: altField
anchors.left: parent.left
anchors.right: parent.right
text: altSlider.value.toFixed(1)
}
}
Slider {
id: altSlider
anchors.margins: _margins
anchors.top: headerColumn.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
orientation: Qt.Vertical
minimumValue: QGroundControl.metersToAppSettingsDistanceUnits(0)
maximumValue: QGroundControl.metersToAppSettingsDistanceUnits((_activeVehicle && _activeVehicle.flying) ? Math.round((_activeVehicle.altitudeRelative.value + 100) / 100) * 100 : 10)
}
}
}