Unverified Commit 4dec1b4c authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #8993 from DonLakeFlyer/ForceArm

Force arm support
parents 9b9d8130 50acd9a9
...@@ -4,6 +4,7 @@ Note: This file only contains high level features or important fixes. ...@@ -4,6 +4,7 @@ Note: This file only contains high level features or important fixes.
## 4.1 - Daily build ## 4.1 - Daily build
* Fly: Press and hold on arm button will change it to Force Arm. Click again to force arm.
* VTOL: General setting for transition distance which affects Plan takeoff, landing pattern creation * VTOL: General setting for transition distance which affects Plan takeoff, landing pattern creation
* VTOL: Much better VTOL support throughout QGC * VTOL: Much better VTOL support throughout QGC
* Maps: Support zoom up to level 23 even if map provider doesn't provide tiles that high * Maps: Support zoom up to level 23 even if map provider doesn't provide tiles that high
......
...@@ -61,8 +61,6 @@ SetupPage { ...@@ -61,8 +61,6 @@ SetupPage {
property real _margins: ScreenTools.defaultFontPixelHeight property real _margins: ScreenTools.defaultFontPixelHeight
property bool _showIcon: !ScreenTools.isTinyScreen property bool _showIcon: !ScreenTools.isTinyScreen
ExclusiveGroup { id: fenceActionRadioGroup }
Column { Column {
spacing: _margins / 2 spacing: _margins / 2
......
...@@ -59,10 +59,6 @@ SetupPage { ...@@ -59,10 +59,6 @@ SetupPage {
property bool _loadComplete: false property bool _loadComplete: false
ExclusiveGroup { id: fenceActionRadioGroup }
ExclusiveGroup { id: landLoiterRadioGroup }
ExclusiveGroup { id: returnAltRadioGroup }
Component.onCompleted: { Component.onCompleted: {
// We use QtCharts only on Desktop platforms // We use QtCharts only on Desktop platforms
showAdvanced = !ScreenTools.isMobile showAdvanced = !ScreenTools.isMobile
......
...@@ -34,14 +34,12 @@ SetupPage { ...@@ -34,14 +34,12 @@ SetupPage {
property real _margins: ScreenTools.defaultFontPixelHeight property real _margins: ScreenTools.defaultFontPixelHeight
ExclusiveGroup { id: buttonGroup }
Row { Row {
spacing: _margins spacing: _margins
QGCButton { QGCButton {
id: atcButton id: atcButton
text: qsTr("Attitude Controller Parameters") text: qsTr("Attitude Controller Parameters")
exclusiveGroup: buttonGroup autoExclusive: true
checked: true checked: true
onClicked: checked = true onClicked: checked = true
} }
...@@ -49,14 +47,14 @@ SetupPage { ...@@ -49,14 +47,14 @@ SetupPage {
QGCButton { QGCButton {
id: posButton id: posButton
text: qsTr("Position Controller Parameters") text: qsTr("Position Controller Parameters")
exclusiveGroup: buttonGroup autoExclusive: true
onClicked: checked = true onClicked: checked = true
} }
QGCButton { QGCButton {
id: navButton id: navButton
text: qsTr("Waypoint navigation parameters") text: qsTr("Waypoint navigation parameters")
exclusiveGroup: buttonGroup autoExclusive: true
onClicked: checked = true onClicked: checked = true
} }
} }
......
...@@ -35,6 +35,7 @@ Item { ...@@ -35,6 +35,7 @@ Item {
readonly property string emergencyStopTitle: qsTr("EMERGENCY STOP") readonly property string emergencyStopTitle: qsTr("EMERGENCY STOP")
readonly property string armTitle: qsTr("Arm") readonly property string armTitle: qsTr("Arm")
readonly property string forceArmTitle: qsTr("Force Arm")
readonly property string disarmTitle: qsTr("Disarm") readonly property string disarmTitle: qsTr("Disarm")
readonly property string rtlTitle: qsTr("Return") readonly property string rtlTitle: qsTr("Return")
readonly property string takeoffTitle: qsTr("Takeoff") readonly property string takeoffTitle: qsTr("Takeoff")
...@@ -55,6 +56,7 @@ Item { ...@@ -55,6 +56,7 @@ Item {
readonly property string actionListTitle: qsTr("Action") readonly property string actionListTitle: qsTr("Action")
readonly property string armMessage: qsTr("Arm the vehicle.") readonly property string armMessage: qsTr("Arm the vehicle.")
readonly property string forceArmMessage: qsTr("WARNING: This will force arming of the vehicle bypassing any safety checks.")
readonly property string disarmMessage: qsTr("Disarm 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 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 takeoffMessage: qsTr("Takeoff from ground and hold position.")
...@@ -97,6 +99,7 @@ Item { ...@@ -97,6 +99,7 @@ Item {
readonly property int actionVtolTransitionToMRFlight: 21 readonly property int actionVtolTransitionToMRFlight: 21
readonly property int actionROI: 22 readonly property int actionROI: 22
readonly property int actionActionList: 23 readonly property int actionActionList: 23
readonly property int actionForceArm: 24
property bool _useChecklist: QGroundControl.settingsManager.appSettings.useChecklist.rawValue && QGroundControl.corePlugin.options.preFlightChecklistUrl.toString().length property bool _useChecklist: QGroundControl.settingsManager.appSettings.useChecklist.rawValue && QGroundControl.corePlugin.options.preFlightChecklistUrl.toString().length
property bool _enforceChecklist: _useChecklist && QGroundControl.settingsManager.appSettings.enforceChecklist.rawValue property bool _enforceChecklist: _useChecklist && QGroundControl.settingsManager.appSettings.enforceChecklist.rawValue
...@@ -104,6 +107,7 @@ Item { ...@@ -104,6 +107,7 @@ Item {
property bool showEmergenyStop: _guidedActionsEnabled && !_hideEmergenyStop && _vehicleArmed && _vehicleFlying property bool showEmergenyStop: _guidedActionsEnabled && !_hideEmergenyStop && _vehicleArmed && _vehicleFlying
property bool showArm: _guidedActionsEnabled && !_vehicleArmed && _canArm property bool showArm: _guidedActionsEnabled && !_vehicleArmed && _canArm
property bool showForceArm: _guidedActionsEnabled && !_vehicleArmed
property bool showDisarm: _guidedActionsEnabled && _vehicleArmed && !_vehicleFlying property bool showDisarm: _guidedActionsEnabled && _vehicleArmed && !_vehicleFlying
property bool showRTL: _guidedActionsEnabled && _vehicleArmed && activeVehicle.guidedModeSupported && _vehicleFlying && !_vehicleInRTLMode property bool showRTL: _guidedActionsEnabled && _vehicleArmed && activeVehicle.guidedModeSupported && _vehicleFlying && !_vehicleInRTLMode
property bool showTakeoff: _guidedActionsEnabled && activeVehicle.takeoffVehicleSupported && !_vehicleFlying && _canArm property bool showTakeoff: _guidedActionsEnabled && activeVehicle.takeoffVehicleSupported && !_vehicleFlying && _canArm
...@@ -274,6 +278,7 @@ Item { ...@@ -274,6 +278,7 @@ Item {
Connections { Connections {
target: mainWindow target: mainWindow
onArmVehicleRequest: armVehicleRequest() onArmVehicleRequest: armVehicleRequest()
onForceArmVehicleRequest: forceArmVehicleRequest()
onDisarmVehicleRequest: disarmVehicleRequest() onDisarmVehicleRequest: disarmVehicleRequest()
onVtolTransitionToFwdFlightRequest: vtolTransitionToFwdFlightRequest() onVtolTransitionToFwdFlightRequest: vtolTransitionToFwdFlightRequest()
onVtolTransitionToMRFlightRequest: vtolTransitionToMRFlightRequest() onVtolTransitionToMRFlightRequest: vtolTransitionToMRFlightRequest()
...@@ -283,6 +288,10 @@ Item { ...@@ -283,6 +288,10 @@ Item {
confirmAction(actionArm) confirmAction(actionArm)
} }
function forceArmVehicleRequest() {
confirmAction(actionForceArm)
}
function disarmVehicleRequest() { function disarmVehicleRequest() {
if (showEmergenyStop) { if (showEmergenyStop) {
confirmAction(actionEmergencyStop) confirmAction(actionEmergencyStop)
...@@ -325,6 +334,11 @@ Item { ...@@ -325,6 +334,11 @@ Item {
confirmDialog.message = armMessage confirmDialog.message = armMessage
confirmDialog.hideTrigger = Qt.binding(function() { return !showArm }) confirmDialog.hideTrigger = Qt.binding(function() { return !showArm })
break; break;
case actionForceArm:
confirmDialog.title = forceArmTitle
confirmDialog.message = forceArmMessage
confirmDialog.hideTrigger = Qt.binding(function() { return !showForceArm })
break;
case actionDisarm: case actionDisarm:
if (_vehicleFlying) { if (_vehicleFlying) {
return return
...@@ -480,6 +494,9 @@ Item { ...@@ -480,6 +494,9 @@ Item {
case actionArm: case actionArm:
activeVehicle.armed = true activeVehicle.armed = true
break break
case actionForceArm:
activeVehicle.forceArm()
break
case actionDisarm: case actionDisarm:
activeVehicle.armed = false activeVehicle.armed = false
break break
......
...@@ -28,10 +28,6 @@ Column { ...@@ -28,10 +28,6 @@ Column {
QGCPalette { id: qgcPal; colorGroupEnabled: true } QGCPalette { id: qgcPal; colorGroupEnabled: true }
ExclusiveGroup {
id: cameraOrientationGroup
}
Column { Column {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
......
...@@ -188,8 +188,6 @@ Item { ...@@ -188,8 +188,6 @@ Item {
} }
} }
ExclusiveGroup { id: buttonGroup }
Repeater { Repeater {
model: categoryHeader.checked ? controller.getGroupsForCategory(category) : 0 model: categoryHeader.checked ? controller.getGroupsForCategory(category) : 0
...@@ -198,7 +196,7 @@ Item { ...@@ -198,7 +196,7 @@ Item {
text: groupName text: groupName
height: _rowHeight height: _rowHeight
checked: controller.currentGroup === text checked: controller.currentGroup === text
exclusiveGroup: buttonGroup autoExclusive: true
readonly property string groupName: modelData readonly property string groupName: modelData
......
import QtQuick 2.3 import QtQuick 2.3
import QtQuick.Controls 1.2 import QtQuick.Controls 2.12
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import QGroundControl.Palette 1.0 import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
Button { Button {
activeFocusOnPress: true id: control
hoverEnabled: true
topPadding: _verticalPadding
bottomPadding: _verticalPadding
leftPadding: _horizontalPadding
rightPadding: _horizontalPadding
focusPolicy: Qt.ClickFocus
property bool primary: false ///< primary button for a group of buttons property bool primary: false ///< primary button for a group of buttons
property real pointSize: ScreenTools.defaultFontPointSize ///< Point size for button text property real pointSize: ScreenTools.defaultFontPointSize ///< Point size for button text
property bool showBorder: _qgcPal.globalTheme === QGCPalette.Light property bool showBorder: qgcPal.globalTheme === QGCPalette.Light
property bool iconLeft: false property bool iconLeft: false
property real backRadius: 0 property real backRadius: 0
property real heightFactor: 0.5 property real heightFactor: 0.5
property string iconSource
property var _qgcPal: QGCPalette { colorGroupEnabled: enabled } property bool _showHighlight: pressed | hovered | checked
property bool _showHighlight: (pressed | hovered | checked) && !__forceHoverOff
// This fixes the issue with button hover where if a Button is near the edge oa QQuickWidget you can
// move the mouse fast enough such that the MouseArea does not trigger an onExited. This is turn
// cause the hover property to not be cleared correctly.
property bool __forceHoverOff: false
property int __lastGlobalMouseX: 0
property int __lastGlobalMouseY: 0
property int _horizontalPadding: ScreenTools.defaultFontPixelWidth property int _horizontalPadding: ScreenTools.defaultFontPixelWidth
property int _verticalPadding: Math.round(ScreenTools.defaultFontPixelHeight * heightFactor) property int _verticalPadding: Math.round(ScreenTools.defaultFontPixelHeight * heightFactor)
Connections { QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
target: __behavior
onMouseXChanged: {
__lastGlobalMouseX = ScreenTools.mouseX()
__lastGlobalMouseY = ScreenTools.mouseY()
}
onMouseYChanged: {
__lastGlobalMouseX = ScreenTools.mouseX()
__lastGlobalMouseY = ScreenTools.mouseY()
}
onEntered: { __forceHoverOff = false; hoverTimer.start() }
onExited: { __forceHoverOff = false; hoverTimer.stop() }
}
Timer { background: Rectangle {
id: hoverTimer id: backRect
interval: 250 implicitWidth: ScreenTools.implicitButtonWidth
repeat: true implicitHeight: ScreenTools.implicitButtonHeight
onTriggered: { radius: backRadius
__forceHoverOff = (__lastGlobalMouseX !== ScreenTools.mouseX() || __lastGlobalMouseY !== ScreenTools.mouseY()); border.width: showBorder ? 1 : 0
} border.color: qgcPal.buttonText
color: _showHighlight ?
qgcPal.buttonHighlight :
(primary ? qgcPal.primaryButton : qgcPal.button)
} }
style: ButtonStyle { contentItem: Item {
/*! The padding between the background and the label components. */ implicitWidth: text.implicitWidth + icon.width
padding { implicitHeight: text.implicitHeight
top: _verticalPadding baselineOffset: text.y + text.baselineOffset
bottom: _verticalPadding
left: _horizontalPadding
right: _horizontalPadding
}
/*! This defines the background of the button. */
background: Rectangle {
id: backRect
implicitWidth: ScreenTools.implicitButtonWidth
implicitHeight: ScreenTools.implicitButtonHeight
radius: backRadius
border.width: showBorder ? 1 : 0
border.color: _qgcPal.buttonText
color: _showHighlight ?
control._qgcPal.buttonHighlight :
(primary ? control._qgcPal.primaryButton : control._qgcPal.button)
}
/*! This defines the label of the button. */
label: Item {
implicitWidth: text.implicitWidth + icon.width
implicitHeight: text.implicitHeight
baselineOffset: text.y + text.baselineOffset
QGCColoredImage { QGCColoredImage {
id: icon id: icon
source: control.iconSource source: control.iconSource
height: source === "" ? 0 : text.height height: source === "" ? 0 : text.height
width: height width: height
color: text.color color: text.color
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
sourceSize.height: height sourceSize.height: height
anchors.left: control.iconLeft ? parent.left : undefined anchors.left: control.iconLeft ? parent.left : undefined
anchors.leftMargin: control.iconLeft ? ScreenTools.defaultFontPixelWidth : undefined anchors.leftMargin: control.iconLeft ? ScreenTools.defaultFontPixelWidth : undefined
anchors.right: !control.iconLeft ? parent.right : undefined anchors.right: !control.iconLeft ? parent.right : undefined
anchors.rightMargin: !control.iconLeft ? ScreenTools.defaultFontPixelWidth : undefined anchors.rightMargin: !control.iconLeft ? ScreenTools.defaultFontPixelWidth : undefined
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { Text {
id: text id: text
anchors.centerIn: parent anchors.centerIn: parent
antialiasing: true antialiasing: true
text: control.text text: control.text
font.pointSize: pointSize font.pointSize: pointSize
font.family: ScreenTools.normalFontFamily font.family: ScreenTools.normalFontFamily
color: _showHighlight ? color: _showHighlight ?
control._qgcPal.buttonHighlightText : qgcPal.buttonHighlightText :
(primary ? control._qgcPal.primaryButtonText : control._qgcPal.buttonText) (primary ? qgcPal.primaryButtonText : qgcPal.buttonText)
}
}
} }
}
} }
...@@ -2397,6 +2397,15 @@ void Vehicle::setArmed(bool armed) ...@@ -2397,6 +2397,15 @@ void Vehicle::setArmed(bool armed)
armed ? 1.0f : 0.0f); armed ? 1.0f : 0.0f);
} }
void Vehicle::forceArm(void)
{
sendMavCommand(_defaultComponentId,
MAV_CMD_COMPONENT_ARM_DISARM,
true, // show error if fails
1.0f, // arm
2989); // force arm
}
bool Vehicle::flightModeSetAvailable() bool Vehicle::flightModeSetAvailable()
{ {
return _firmwarePlugin->isCapable(this, FirmwarePlugin::SetFlightModeCapability); return _firmwarePlugin->isCapable(this, FirmwarePlugin::SetFlightModeCapability);
......
...@@ -791,6 +791,7 @@ public: ...@@ -791,6 +791,7 @@ public:
Q_INVOKABLE void gimbalPitchStep (int direction); Q_INVOKABLE void gimbalPitchStep (int direction);
Q_INVOKABLE void gimbalYawStep (int direction); Q_INVOKABLE void gimbalYawStep (int direction);
Q_INVOKABLE void centerGimbal (); Q_INVOKABLE void centerGimbal ();
Q_INVOKABLE void forceArm ();
/// Sends PARAM_MAP_RC message to vehicle /// Sends PARAM_MAP_RC message to vehicle
Q_INVOKABLE void sendParamMapRC(const QString& paramName, double scale, double centerValue, int tuningID, double minValue, double maxValue); Q_INVOKABLE void sendParamMapRC(const QString& paramName, double scale, double centerValue, int tuningID, double minValue, double maxValue);
......
...@@ -49,8 +49,6 @@ Rectangle { ...@@ -49,8 +49,6 @@ Rectangle {
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick
clip: true clip: true
ExclusiveGroup { id: panelActionGroup }
ColumnLayout { ColumnLayout {
id: buttonColumn id: buttonColumn
spacing: _verticalMargin spacing: _verticalMargin
...@@ -62,7 +60,7 @@ Rectangle { ...@@ -62,7 +60,7 @@ Rectangle {
QGCButton { QGCButton {
height: _buttonHeight height: _buttonHeight
text: modelData.title text: modelData.title
exclusiveGroup: panelActionGroup autoExclusive: true
Layout.fillWidth: true Layout.fillWidth: true
onClicked: { onClicked: {
......
...@@ -96,6 +96,7 @@ ApplicationWindow { ...@@ -96,6 +96,7 @@ ApplicationWindow {
//-- Actions //-- Actions
signal armVehicleRequest signal armVehicleRequest
signal forceArmVehicleRequest
signal disarmVehicleRequest signal disarmVehicleRequest
signal vtolTransitionToFwdFlightRequest signal vtolTransitionToFwdFlightRequest
signal vtolTransitionToMRFlightRequest signal vtolTransitionToMRFlightRequest
......
...@@ -25,7 +25,6 @@ Column { ...@@ -25,7 +25,6 @@ Column {
function saveSettings() { function saveSettings() {
// No need // No need
} }
ExclusiveGroup { id: linkGroup }
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
QGCLabel { QGCLabel {
...@@ -79,10 +78,10 @@ Column { ...@@ -79,10 +78,10 @@ Column {
model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth ? subEditConfig.nameList : "" model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth ? subEditConfig.nameList : ""
delegate: delegate:
QGCButton { QGCButton {
text: modelData text: modelData
width: _secondColumn width: _secondColumn
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2 anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
exclusiveGroup: linkGroup autoExclusive: true
onClicked: { onClicked: {
checked = true checked = true
if(subEditConfig && modelData !== "") if(subEditConfig && modelData !== "")
......
...@@ -27,8 +27,6 @@ Rectangle { ...@@ -27,8 +27,6 @@ Rectangle {
property int _firstColumn: ScreenTools.defaultFontPixelWidth * 12 property int _firstColumn: ScreenTools.defaultFontPixelWidth * 12
property int _secondColumn: ScreenTools.defaultFontPixelWidth * 30 property int _secondColumn: ScreenTools.defaultFontPixelWidth * 30
ExclusiveGroup { id: linkGroup }
QGCPalette { QGCPalette {
id: qgcPal id: qgcPal
colorGroupEnabled: enabled colorGroupEnabled: enabled
...@@ -65,7 +63,7 @@ Rectangle { ...@@ -65,7 +63,7 @@ Rectangle {
anchors.horizontalCenter: settingsColumn.horizontalCenter anchors.horizontalCenter: settingsColumn.horizontalCenter
width: _linkRoot.width * 0.5 width: _linkRoot.width * 0.5
text: object.name text: object.name
exclusiveGroup: linkGroup autoExclusive: true
visible: !object.dynamic visible: !object.dynamic
onClicked: { onClicked: {
checked = true checked = true
......
...@@ -28,8 +28,6 @@ Column { ...@@ -28,8 +28,6 @@ Column {
property string _currentHost: "" property string _currentHost: ""
ExclusiveGroup { id: linkGroup }
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
QGCLabel { QGCLabel {
...@@ -81,10 +79,10 @@ Column { ...@@ -81,10 +79,10 @@ Column {
model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeUdp ? subEditConfig.hostList : "" model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeUdp ? subEditConfig.hostList : ""
delegate: delegate:
QGCButton { QGCButton {
text: modelData text: modelData
width: _secondColumn width: _secondColumn
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2 anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
exclusiveGroup: linkGroup autoExclusive: true
onClicked: { onClicked: {
checked = true checked = true
_udpSetting._currentHost = modelData _udpSetting._currentHost = modelData
......
...@@ -190,13 +190,23 @@ RowLayout { ...@@ -190,13 +190,23 @@ RowLayout {
QGCButton { QGCButton {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: _armed ? qsTr("Disarm") : qsTr("Arm") text: _armed ? qsTr("Disarm") : (forceArm ? qsTr("Force Arm") : qsTr("Arm"))
property bool forceArm: false
onPressAndHold: forceArm = true
onClicked: { onClicked: {
if (_armed) { if (_armed) {
mainWindow.disarmVehicleRequest() mainWindow.disarmVehicleRequest()
} else { } else {
mainWindow.armVehicleRequest() if (forceArm) {
mainWindow.forceArmVehicleRequest()
} else {
mainWindow.armVehicleRequest()
}
} }
forceArm = false
mainWindow.hideIndicatorPopup() mainWindow.hideIndicatorPopup()
} }
} }
......
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