Unverified Commit 8a162006 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #6555 from DonLakeFlyer/PreFlightSupport

Even more PreFlight reorg/support
parents 0801e473 9dd768a3
......@@ -154,11 +154,11 @@
<file alias="QGroundControl/FlightDisplay/GuidedActionsController.qml">src/FlightDisplay/GuidedActionsController.qml</file>
<file alias="QGroundControl/FlightDisplay/GuidedAltitudeSlider.qml">src/FlightDisplay/GuidedAltitudeSlider.qml</file>
<file alias="QGroundControl/FlightDisplay/MultiVehicleList.qml">src/FlightDisplay/MultiVehicleList.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightAHRSCheck.qml">src/FlightDisplay/PreFlightAHRSCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightBatteryCheck.qml">src/FlightDisplay/PreFlightBatteryCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightCheckModel.qml">src/FlightDisplay/PreFlightCheckModel.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightGPSCheck.qml">src/FlightDisplay/PreFlightGPSCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightRCCheck.qml">src/FlightDisplay/PreFlightRCCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSensorsCheck.qml">src/FlightDisplay/PreFlightSensorsCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSensorsHealthCheck.qml">src/FlightDisplay/PreFlightSensorsHealthCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSoundCheck.qml">src/FlightDisplay/PreFlightSoundCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/qmldir">src/FlightDisplay/qmldir</file>
<file alias="QGroundControl/FlightMap/CameraTriggerIndicator.qml">src/FlightMap/MapItems/CameraTriggerIndicator.qml</file>
......
/****************************************************************************
*
* (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 QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Vehicle 1.0
PreFlightCheckButton {
name: qsTr("Global position estimate")
telemetryTextFailure: qsTr("AHRS Unhealthy. Check console.")
telemetryFailure: _unhealthySensors & Vehicle.SysStatusSensorAHRS
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property int _unhealthySensors: _activeVehicle ? _activeVehicle.sensorsUnhealthyBits : 0
}
......@@ -15,17 +15,18 @@ import QGroundControl.Vehicle 1.0
// This class stores the data and functions of the check list but NOT the GUI (which is handled somewhere else).
PreFlightCheckButton {
name: qsTr("Battery")
manualText: qsTr("Healthy & charged > %1. Battery connector firmly plugged?").arg(failureVoltage)
telemetryTextFailure: _batUnHealthy ?
qsTr("Not healthy. Check console.") :
("Low (below %1). Please recharge.").arg(failureVoltage)
name: qsTr("Battery")
manualText: qsTr("Battery connector firmly plugged?")
telemetryFailure: _batLow
telemetryTextFailure: allowTelemetryFailureOverride ?
qsTr("Warning - Battery charge below %1%.").arg(failurePercent) :
qsTr("Battery charge below %1%. Please recharge.").arg(failurePercent)
allowTelemetryFailureOverride: allowFailurePercentOverride
property int failureVoltage: 40
property int failurePercent: 40
property bool allowFailurePercentOverride: false
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property int _unhealthySensors: _activeVehicle ? _activeVehicle.sensorsUnhealthyBits : 0
property var _batPercentRemaining: _activeVehicle ? _activeVehicle.battery.percentRemaining.value : 0
property bool _batUnHealthy: _unhealthySensors & Vehicle.SysStatusSensorBattery
property bool _batLow: _batPercentRemaining < failureVoltage
property bool _batLow: _batPercentRemaining < failurePercent
}
......@@ -23,22 +23,24 @@ ObjectModel {
// Standard check list items (group 0) - Available from the start
PreFlightCheckButton {
id: buttonHardware
name: qsTr("Hardware")
manualText: qsTr("Props mounted? Wings secured? Tail secured?")
}
PreFlightBatteryCheck {
id: buttonBattery
failureVoltage: 40
failurePercent: 40
allowFailurePercentOverride: false
}
PreFlightSensorsCheck {
id: buttonSensors
PreFlightSensorsHealthCheck {
}
PreFlightRCCheck {
id: buttonRC
PreFlightGPSCheck {
failureSatCount: 9
allowOverrideSatCount: true
}
PreFlightAHRSCheck {
id: buttonEstimator
PreFlightRCCheck {
}
}
......@@ -46,26 +48,21 @@ ObjectModel {
name: qsTr("Please arm the vehicle here")
PreFlightCheckButton {
id: buttonActuators
name: qsTr("Actuators")
group: 1
manualText: qsTr("Move all control surfaces. Did they work properly?")
}
PreFlightCheckButton {
id: buttonMotors
name: qsTr("Motors")
group: 1
manualText: qsTr("Propellers free? Then throttle up gently. Working properly?")
}
PreFlightCheckButton {
id: buttonMission
name: qsTr("Mission")
group: 1
manualText: qsTr("Please confirm mission is valid (waypoints valid, no terrain collision).")
}
PreFlightSoundCheck {
id: buttonSoundOutput
group: 1
}
}
......@@ -74,21 +71,17 @@ ObjectModel {
// Check list item group 2 - Final checks before launch
PreFlightCheckButton {
id: buttonPayload
name: qsTr("Payload")
group: 2
manualText: qsTr("Configured and started? Payload lid closed?")
}
PreFlightCheckButton {
id: buttonWeather
name: "Wind & weather"
group: 2
manualText: qsTr("OK for your platform? Lauching into the wind?")
}
PreFlightCheckButton {
id: buttonFlightAreaFree
name: qsTr("Flight area")
group: 2
manualText: qsTr("Launch area and path free of obstacles/people?")
}
}
......
/****************************************************************************
*
* (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 QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Vehicle 1.0
PreFlightCheckButton {
name: qsTr("GPS")
telemetryFailure: _3dLockFailure || _satCountFailure
telemetryTextFailure: _3dLockFailure ?
qsTr("Waiting for 3D lock.") :
(_satCountFailure ? _satCountFailureText : "")
allowTelemetryFailureOverride: !_3dLockFailure && _satCountFailure && allowOverrideSatCount
property bool allowOverrideSatCount: false ///< true: sat count above failureSatCount reguired to pass, false: user can click past satCount <= failureSetCount
property int failureSatCount: -1 ///< -1 indicates no sat count check
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property bool _3dLock: _activeVehicle ? _activeVehicle.gps.lock.rawValue >= 3 : false
property int _satCount: _activeVehicle ? _activeVehicle.gps.count.rawValue : 0
property bool _3dLockFailure: !_3dLock
property bool _satCountFailure: failureSatCount !== -1 && _satCount <= failureSatCount
property string _satCountFailureText: allowOverrideSatCount ? qsTr("Warning - Sat count below %1.").arg(failureSatCount + 1) : qsTr("Waiting for sat count above %1.").arg(failureSatCount)
}
......@@ -15,24 +15,18 @@ import QGroundControl.Vehicle 1.0
PreFlightCheckButton {
name: qsTr("Sensors")
telemetryFailure: (_unhealthySensors & _allCheckedSensors) || !_gpsLock || _satCountFailure
property int failureSatCount: -1 ///< -1 indicates no sat count check
telemetryFailure: _unhealthySensors & _allCheckedSensors
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property int _unhealthySensors: _activeVehicle ? _activeVehicle.sensorsUnhealthyBits : 0
property bool _gpsLock: _activeVehicle ? _activeVehicle.gps.lock.rawValue >= 3 : 0
property int _satCount: _activeVehicle ? _activeVehicle.gps.count.rawValue : 0
property bool _satCountFailure: failureSatCount !== -1 && _satCount <= failureSatCount
property int _allCheckedSensors: Vehicle.SysStatusSensor3dMag |
Vehicle.SysStatusSensor3dAccel |
Vehicle.SysStatusSensor3dGyro |
Vehicle.SysStatusSensorAbsolutePressure |
Vehicle.SysStatusSensorDifferentialPressure |
Vehicle.SysStatusSensorGPS
Vehicle.SysStatusSensorGPS |
Vehicle.SysStatusSensorAHRS
on_GpsLockChanged: updateTelemetryTextFailure()
on_SatCountFailureChanged: updateTelemetryTextFailure()
on_UnhealthySensorsChanged: updateTelemetryTextFailure()
Component.onCompleted: updateTelemetryTextFailure()
......@@ -44,11 +38,8 @@ PreFlightCheckButton {
else if(_unhealthySensors & Vehicle.SysStatusSensor3dGyro) telemetryTextFailure = qsTr("Failure. Gyroscope issues. Check console.")
else if(_unhealthySensors & Vehicle.SysStatusSensorAbsolutePressure) telemetryTextFailure = qsTr("Failure. Barometer issues. Check console.")
else if(_unhealthySensors & Vehicle.SysStatusSensorDifferentialPressure) telemetryTextFailure = qsTr("Failure. Airspeed sensor issues. Check console.")
else if(_unhealthySensors & Vehicle.SysStatusSensorGPS) telemetryTextFailure = qsTr("Failure. No valid or low quality GPS signal. Check console.")
} else if (!_gpsLock) {
telemetryTextFailure = qsTr("Pending. Waiting for GPS lock.")
} else if (_satCountFailure) {
telemetryTextFailure = qsTr("Pending. Waiting for Sat Count > %1.").arg(failureSatCount)
else if(_unhealthySensors & Vehicle.SysStatusSensorAHRS) telemetryTextFailure = qsTr("Failure. AHRS issues. Check console.")
else if(_unhealthySensors & Vehicle.SysStatusSensorGPS) telemetryTextFailure = qsTr("Failure. GPS issues. Check console.")
}
}
}
......@@ -10,9 +10,9 @@ GuidedActionList 1.0 GuidedActionList.qml
GuidedAltitudeSlider 1.0 GuidedAltitudeSlider.qml
MultiVehicleList 1.0 MultiVehicleList.qml
PreFlightBatteryCheck 1.0 PreFlightBatteryCheck.qml
PreFlightAHRSCheck 1.0 PreFlightAHRSCheck.qml
PreFlightCheckModel 1.0 PreFlightCheckModel.qml
PreFlightGPSCheck 1.0 PreFlightGPSCheck.qml
PreFlightRCCheck 1.0 PreFlightRCCheck.qml
PreFlightSensorsCheck 1.0 PreFlightSensorsCheck.qml
PreFlightSensorsHealthCheck 1.0 PreFlightSensorsHealthCheck.qml
PreFlightSoundCheck 1.0 PreFlightSoundCheck.qml
......@@ -35,8 +35,8 @@ Item {
readonly property int dropUp: 3
readonly property int dropDown: 4
readonly property real _arrowBaseWidth: radius // Width of long side of arrow
readonly property real _arrowPointHeight: radius * 0.666 // Height is long side to point
readonly property real _arrowBaseHeight: radius // Height of vertical side of arrow
readonly property real _arrowPointWidth: radius * 0.666 // Distance from vertical side to point
readonly property real _dropCornerRadius: ScreenTools.defaultFontPixelWidth * 0.5
readonly property real _dropCornerRadiusX2: _dropCornerRadius * 2
readonly property real _dropMargin: _dropCornerRadius
......@@ -44,9 +44,10 @@ Item {
property var _dropEdgeTopPoint
property real _dropEdgeHeight
property alias _dropDownComponent: dropDownLoader.sourceComponent
property alias _dropDownComponent: panelLoader.sourceComponent
property real _viewportMaxTop: 0
property real _viewportMaxBottom: parent.parent.height - parent.y
property real _viewportMaxHeight: _viewportMaxBottom - _viewportMaxTop
property var _dropPanelCancel
function show(panelEdgeTopPoint, panelEdgeHeight, panelComponent) {
......@@ -70,37 +71,29 @@ Item {
}
function _calcPositions() {
var dropComponentWidth = dropDownLoader.item.width
var dropComponentHeight = dropDownLoader.item.height
var dropRectWidth = dropComponentWidth + _dropMarginX2
var dropRectHeight = dropComponentHeight + _dropMarginX2
var panelComponentWidth = panelLoader.item.width
var panelComponentHeight = panelLoader.item.height
dropItemHolderRect.width = dropRectWidth
dropItemHolderRect.height = dropRectHeight
dropDownItem.width = dropComponentWidth + _dropMarginX2
dropDownItem.height = dropComponentHeight + _dropMarginX2
dropDownItem.width += _arrowPointHeight
dropDownItem.y = _dropEdgeTopPoint.y -(dropDownItem.height / 2) + radius
dropItemHolderRect.y = 0
dropDownItem.width = panelComponentWidth + _dropMarginX2 + _arrowPointWidth
dropDownItem.height = panelComponentHeight + _dropMarginX2
dropDownItem.x = _dropEdgeTopPoint.x + _dropMargin
dropItemHolderRect.x = _arrowPointHeight
dropDownItem.y = _dropEdgeTopPoint.y -(dropDownItem.height / 2) + radius
// Validate that dropdown is within viewport
dropDownItem.y = Math.min(dropDownItem.y + dropDownItem.height, _viewportMaxBottom) - dropDownItem.height
dropDownItem.y = Math.max(dropDownItem.y, _viewportMaxTop)
// Adjust height to not exceed viewport bounds
dropDownItem.height = Math.min(dropDownItem.height, _viewportMaxHeight - dropDownItem.y)
// Arrow points
arrowCanvas.arrowPoint.y = (_dropEdgeTopPoint.y + radius) - dropDownItem.y
arrowCanvas.arrowPoint.x = 0
arrowCanvas.arrowBase1.x = _arrowPointHeight
arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseWidth / 2)
arrowCanvas.arrowBase1.x = _arrowPointWidth
arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseHeight / 2)
arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseWidth
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseHeight
arrowCanvas.requestPaint()
} // function - _calcPositions
......@@ -117,6 +110,7 @@ Item {
}
}
// This item is sized to hold the entirety of the drop panel including the arrow point
Item {
id: dropDownItem
......@@ -133,29 +127,41 @@ Item {
property point arrowBase2: Qt.point(0, 0)
onPaint: {
var panelX = _arrowPointWidth
var panelY = 0
var panelWidth = parent.width - _arrowPointWidth
var panelHeight = parent.height
var context = getContext("2d")
context.reset()
context.beginPath()
context.moveTo(dropItemHolderRect.x, dropItemHolderRect.y)
context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y)
context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y + dropItemHolderRect.height)
context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y + dropItemHolderRect.height)
context.moveTo(panelX, panelY) // top left
context.lineTo(panelX + panelWidth, panelY) // top right
context.lineTo(panelX + panelWidth, panelX + panelHeight) // bottom right
context.lineTo(panelX, panelY + panelHeight) // bottom left
context.lineTo(arrowBase2.x, arrowBase2.y)
context.lineTo(arrowPoint.x, arrowPoint.y)
context.lineTo(arrowBase1.x, arrowBase1.y)
context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y)
context.lineTo(panelX, panelY) // top left
context.closePath()
context.fillStyle = qgcPal.windowShade
context.fill()
}
} // Canvas - arrowCanvas
Item {
id: dropItemHolderRect
QGCFlickable {
id: panelItemFlickable
anchors.margins: _dropMargin
anchors.leftMargin: _dropMargin + _arrowPointWidth
anchors.fill: parent
flickableDirection: Flickable.VerticalFlick
contentWidth: panelLoader.width
contentHeight: panelLoader.height
Loader {
id: dropDownLoader
id: panelLoader
x: _dropMargin
y: _dropMargin
......@@ -165,6 +171,5 @@ Item {
property var dropPanel: _root
}
}
} // Item - dropDownItem
}
......@@ -23,16 +23,15 @@ import QGroundControl.ScreenTools 1.0
/// Manual - This is simply a check which the user must verify and confirm. It is not based on any system state.
/// Telemetry - This type of check can fail due to some state within the system. A telemetry check failure can be
/// a hard stop in that there is no way to pass the checklist until the system state resolves itself.
/// Or it can also optionall be override by the user.
/// Or it can also optionally be override by the user.
/// If a button uses both manual and telemetry checks, the telemetry check takes precendence and must be passed first.
QGCButton {
property string name: ""
property int group: 0
property string manualText: "" ///< text to show for a manual check, "" signals no manual check
property string telemetryTextOverride: "" ///< text to show if telemetry check failed and override is allowed
property string telemetryTextFailure ///< text to show if telemetry check failed (override not allowed)
property bool telemetryFailure: false ///< true: telemetry check failing, false: telemetry check passing
property bool passed: _manualState === _statePassed && _telemetryState === _statePassed
property string name: ""
property string manualText: "" ///< text to show for a manual check, "" signals no manual check
property string telemetryTextFailure ///< text to show if telemetry check failed (override not allowed)
property bool telemetryFailure: false ///< true: telemetry check failing, false: telemetry check passing
property bool allowTelemetryFailureOverride: false ///< true: user can click past telemetry failure
property bool passed: _manualState === _statePassed && _telemetryState === _statePassed
property int _manualState: manualText === "" ? _statePassed : _statePending
property int _telemetryState: _statePassed
......@@ -40,8 +39,8 @@ QGCButton {
property int _verticalPadding: Math.round(ScreenTools.defaultFontPixelHeight / 2)
property real _stateFlagWidth: ScreenTools.defaultFontPixelWidth * 4
readonly property int _statePending: 0 ///< Telemetry check has failed or manual check not yet verified, user can click to make it pass
readonly property int _stateFailed: 1 ///< Telemetry check has failed, user cannot click to make it pass
readonly property int _statePending: 0 ///< Telemetry check is failing or manual check not yet verified, user can click to make it pass
readonly property int _stateFailed: 1 ///< Telemetry check is failing, user cannot click to make it pass
readonly property int _statePassed: 2 ///< Check has passed
readonly property color _passedColor: Qt.rgba(0.27,0.67,0.42,1)
......@@ -50,8 +49,8 @@ QGCButton {
property string _text: "<b>" + name +"</b>: " +
((_telemetryState !== _statePassed) ?
(_telemetryState === _statePending ? telemetryTextOverride : telemetryTextFailure) :
(_manualState !== _statePassed ? manualText : qsTr("OK")))
telemetryTextFailure :
(_manualState !== _statePassed ? manualText : qsTr("Passed")))
property color _color: _telemetryState === _statePassed && _manualState === _statePassed ?
_passedColor :
(_telemetryState == _stateFailed ?
......@@ -61,7 +60,6 @@ QGCButton {
_failedColor))
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property bool _allowTelemetryFailureOverride: telemetryTextOverride !== ""
width: 40 * ScreenTools.defaultFontPixelWidth
......@@ -94,21 +92,24 @@ QGCButton {
}
}
onTelemetryFailureChanged: {
function _updateTelemetryState() {
if (telemetryFailure) {
// We have a new telemetry failure, reset user pass
_telemetryState = _allowTelemetryFailureOverride ? _statePending : _stateFailed
_telemetryState = allowTelemetryFailureOverride ? _statePending : _stateFailed
} else {
_telemetryState = _statePassed
}
}
onTelemetryFailureChanged: _updateTelemetryState()
onAllowTelemetryFailureOverrideChanged: _updateTelemetryState()
onClicked: {
if (telemetryFailure && !_allowTelemetryFailureOverride) {
if (telemetryFailure && !allowTelemetryFailureOverride) {
// No way to proceed past this failure
return
}
if (telemetryFailure && _allowTelemetryFailureOverride && _telemetryState !== _statePassed) {
if (telemetryFailure && allowTelemetryFailureOverride && _telemetryState !== _statePassed) {
// User is allowed to proceed past this failure
_telemetryState = _statePassed
return
......@@ -131,7 +132,7 @@ QGCButton {
function reset() {
_manualState = manualText === "" ? _statePassed : _statePending
if (telemetryFailure) {
_telemetryState = _allowTelemetryFailureOverride ? _statePending : _stateFailed
_telemetryState = allowTelemetryFailureOverride ? _statePending : _stateFailed
} else {
_telemetryState = _statePassed
}
......
......@@ -22,12 +22,7 @@ Column {
property alias _checked: header.checked
onPassedChanged: {
parent.groupPassedChanged(ObjectModel.index)
if (passed) {
header.checked = false
}
}
onPassedChanged: parent.groupPassedChanged(ObjectModel.index)
Component.onCompleted: {
enabled = _checked
......
......@@ -36,18 +36,18 @@ Rectangle {
Component.onCompleted: reset()
Column {
id: mainColumn
width: 40*ScreenTools.defaultFontPixelWidth
spacing: 0.8*ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 0.6*ScreenTools.defaultFontPixelWidth
anchors.leftMargin: 1.5*ScreenTools.defaultFontPixelWidth
// We delay the updates when a group passes so the user can see all items green for a moment prior to hiding
Timer {
id: delayedGroupPassed
interval: 750
function groupPassedChanged(index) {
property int index
onTriggered: {
var group = checkListRepeater.itemAt(index)
group._checked = false
if (index + 1 < checkListRepeater.count) {
var group = checkListRepeater.itemAt(index + 1)
group = checkListRepeater.itemAt(index + 1)
group.enabled = true
group._checked = true
}
......@@ -59,6 +59,21 @@ Rectangle {
}
_passed = true
}
}
Column {
id: mainColumn
width: 40*ScreenTools.defaultFontPixelWidth
spacing: 0.8*ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 0.6*ScreenTools.defaultFontPixelWidth
anchors.leftMargin: 1.5*ScreenTools.defaultFontPixelWidth
function groupPassedChanged(index) {
delayedGroupPassed.index = index
delayedGroupPassed.restart()
}
// Header/title of checklist
Item {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment