diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponent.qml b/src/AutoPilotPlugins/PX4/FlightModesComponent.qml index d809205e18be67a776eeb75ab9893eb679730348..a241a4f90e9a3cdf0ccae29c39a2e9f4beaa39ff 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponent.qml +++ b/src/AutoPilotPlugins/PX4/FlightModesComponent.qml @@ -60,6 +60,7 @@ Item { Fact { id: rc_map_mode_sw; name: "RC_MAP_MODE_SW" } Fact { id: rc_map_posctl_sw; name: "RC_MAP_POSCTL_SW" } Fact { id: rc_map_return_sw; name: "RC_MAP_RETURN_SW" } + Fact { id: rc_map_offboard_sw; name: "RC_MAP_OFFB_SW" } Fact { id: rc_map_loiter_sw; name: "RC_MAP_LOITER_SW" } Fact { id: rc_assist_th; name: "RC_ASSIST_TH" } @@ -67,6 +68,7 @@ Item { Fact { id: rc_auto_th; name: "RC_AUTO_TH" } Fact { id: rc_loiter_th; name: "RC_LOITER_TH" } Fact { id: rc_return_th; name: "RC_RETURN_TH" } + Fact { id: rc_offboard_th; name: "RC_OFFB_TH" } Fact { id: rc_th_user; name: "RC_TH_USER" } @@ -81,6 +83,7 @@ Item { property int modeChannel: rc_map_mode_sw.value property int posCtlChannel: rc_map_posctl_sw.value property int returnChannel: rc_map_return_sw.value + property int offboardChannel: rc_map_offboard_sw.value property int loiterChannel: rc_map_loiter_sw.value property real rcThUserValue: rc_th_user.value @@ -187,15 +190,19 @@ Item { // If dropped over a channel target remap switch if (parent.Drag.target && parent.Drag.target.dropAllowed) { - fact.value = parent.Drag.target.channel + if (!singleSwitchRequired || parent.Drag.target.unassignedChannel) { + fact.value = parent.Drag.target.channel + } } } } DropArea { // This will cause to tile to go back to unassigned if dropped here - readonly property int channel: 0 - property bool dropAllowed: true + readonly property int channel: 0 + property bool dropAllowed: true + property bool unassignedChannel: true + id: dropArea width: parent.width @@ -258,7 +265,9 @@ Item { // If dropped over a channel target remap switch if (parent.Drag.target && parent.Drag.target.dropAllowed) { - fact.value = parent.Drag.target.channel + if (!singleSwitchRequired || parent.Drag.target.unassignedChannel) { + fact.value = parent.Drag.target.channel + } } } } @@ -267,6 +276,7 @@ Item { onModeChannelChanged: if (!inRedistribution) redistributeThresholds() onReturnChannelChanged: if (!inRedistribution) redistributeThresholds() + onOffboardChannelChanged: if (!inRedistribution) redistributeThresholds() onLoiterChannelChanged: if (!inRedistribution) redistributeThresholds() onPosCtlChannelChanged: if (!inRedistribution) redistributeThresholds() onRcThUserValue: if (!inRedistribution) redistributeThresholds() @@ -280,11 +290,9 @@ Item { if (modeChannel != 0) { var positions = 3 // Manual/Assist/Auto always exist - var returnOnModeSwitch = modeChannel == returnChannel var loiterOnModeSwitch = modeChannel == loiterChannel var posCtlOnModeSwitch = modeChannel == posCtlChannel - positions += returnOnModeSwitch ? 1 : 0 positions += loiterOnModeSwitch ? 1 : 0 positions += posCtlOnModeSwitch ? 1 : 0 @@ -306,75 +314,49 @@ Item { currentThreshold += increment rc_loiter_th.value = currentThreshold } - if (returnOnModeSwitch) { - currentThreshold += increment - rc_return_th.value = currentThreshold - } inRedistribution = false } - if (returnChannel != 0 && returnChannel != modeChannel) { - var positions = 2 // On/off always exist - - var loiterOnReturnSwitch = returnChannel == loiterChannel - - positions += loiterOnReturnSwitch ? 1 : 0 - - var increment = 1.0 / positions - var currentThreshold = 0.0 - - if (positions == 2) { - // If only two positions don't set threshold at midrange. Setting to 0.25 - // allows for this channel to work with either two or three position switch - increment = 0.25 - } - - // Make sure we don't re-enter + if (returnChannel != 0) { inRedistribution = true - if (loiterOnReturnSwitch) { - currentThreshold += increment - rc_loiter_th.value = currentThreshold - } - currentThreshold += increment - rc_return_th.value = currentThreshold + // If only two positions don't set threshold at midrange. Setting to 0.25 + // allows for this channel to work with either two or three position switch + rc_return_th.value = 0.25 inRedistribution = false } - if (loiterChannel != 0 && loiterChannel != modeChannel && loiterChannel != returnChannel) { + if (offboardChannel != 0) { + inRedistribution = true + // If only two positions don't set threshold at midrange. Setting to 0.25 // allows for this channel to work with either two or three position switch - var increment = 0.25 + rc_offboard_th.value = 0.25 - var currentThreshold = 0.0 + inRedistribution = false + } - // Make sure we don't re-enter + if (loiterChannel != 0 && loiterChannel != modeChannel) { inRedistribution = true - currentThreshold += increment - rc_loiter_th.value = currentThreshold + // If only two positions don't set threshold at midrange. Setting to 0.25 + // allows for this channel to work with either two or three position switch + rc_loiter_th.value = 0.25 inRedistribution = false } if (posCtlChannel != 0 & posCtlChannel != modeChannel) { - // If only two positions don't set threshold at midrange. Setting to 0.25 - // allows for this channel to work with either two or three position switch - var increment = 0.25 - - var currentThreshold = 0.0 - - // Make sure we don't re-enter inRedistribution = true - currentThreshold += increment - rc_posctl_th.value = currentThreshold + // If only two positions don't set threshold at midrange. Setting to 0.25 + // allows for this channel to work with either two or three position switch + rc_posctl_th.value = 0.25 inRedistribution = false } - } Column { @@ -389,9 +371,10 @@ Item { QGCLabel { width: parent.width - text: "Flight Mode switches can be assigned to any channel which is not currently being used for attitude control. All channels are displayed below. " + - "You can drag Flight Modes from the Flight Modes section below to a channel and drop it there. You can also drag switches assigned to a channel " + - "to another channel or back to the Unassigned Switches section. The Switch Display section at the very bottom will show you the results of your Flight Mode setup." + text: "The Main Mode, Loiter and PostCtl switches can be assigned to any channel which is not currently being used for attitude control. The Return and Offboard switches must be assigned to their seperate channel. " + + "All channels are displayed below. " + + "You can drag Flight Modes from the Flight Modes section below to a channel and drop it there. You can also drag switches assigned to a channel " + + "to another channel or back to the Unassigned Switches section. The Switch Display section at the very bottom will show you the results of your Flight Mode setup." wrapMode: Text.WordWrap } @@ -420,10 +403,12 @@ Item { property bool modeMapped: channel == modeChannel property bool posCtlMapped: channel == posCtlChannel property bool returnMapped: channel == returnChannel + property bool offboardMapped: channel == offboardChannel property bool loiterMapped: channel == loiterChannel property bool nonFlightModeMapping: throttleMapped | yawMapped | pitchMapped | rollMapped | flapsMapped | aux1Mapped | aux2Mapped - property bool unassignedMapping: !(nonFlightModeMapping | modeMapped | posCtlMapped | returnMapped | loiterMapped) + property bool unassignedMapping: !(nonFlightModeMapping | modeMapped | posCtlMapped | returnMapped | offboardMapped | loiterMapped) + property bool singleSwitchMapping: returnMapped | offboardMapped id: channelTarget width: tileWidth @@ -433,7 +418,7 @@ Item { states: [ State { - when: dropArea.containsDrag && dropArea.dropAllowed + when: dropArea.containsDrag && dropArea.dropAllowed && (!dropArea.drag.source.singleSwitchRequired || dropArea.unassignedChannel) PropertyChanges { target: channelHeader color: "red" @@ -522,37 +507,51 @@ Item { sourceComponent: assignedModeTileComponent } Loader { - property string tileLabel: "Main Mode" - property bool tileVisible: visible - property bool tileDragEnabled: true - property string tileParam: "RC_MAP_MODE_SW" + property string tileLabel: "Main Mode" + property bool tileVisible: visible + property bool tileDragEnabled: true + property string tileParam: "RC_MAP_MODE_SW" + property bool singleSwitchRequired: false visible: modeMapped sourceComponent: assignedModeTileComponent } Loader { - property string tileLabel: "Return" - property bool tileVisible: visible - property bool tileDragEnabled: true - property string tileParam: "RC_MAP_RETURN_SW" + property string tileLabel: "Return" + property bool tileVisible: visible + property bool tileDragEnabled: true + property string tileParam: "RC_MAP_RETURN_SW" + property bool singleSwitchRequired: true visible: returnMapped sourceComponent: assignedModeTileComponent } Loader { - property string tileLabel: "Loiter" - property bool tileVisible: visible - property bool tileDragEnabled: true - property string tileParam: "RC_MAP_LOITER_SW" + property string tileLabel: "Offboard" + property bool tileVisible: visible + property bool tileDragEnabled: true + property string tileParam: "RC_MAP_OFFB_SW" + property bool singleSwitchRequired: true + + visible: offboardMapped + sourceComponent: assignedModeTileComponent + } + Loader { + property string tileLabel: "Loiter" + property bool tileVisible: visible + property bool tileDragEnabled: true + property string tileParam: "RC_MAP_LOITER_SW" + property bool singleSwitchRequired: false visible: loiterMapped sourceComponent: assignedModeTileComponent } Loader { - property string tileLabel: "PosCtl" - property bool tileVisible: visible - property bool tileDragEnabled: true - property string tileParam: "RC_MAP_POSCTL_SW" + property string tileLabel: "PosCtl" + property bool tileVisible: visible + property bool tileDragEnabled: true + property string tileParam: "RC_MAP_POSCTL_SW" + property bool singleSwitchRequired: false visible: posCtlMapped sourceComponent: assignedModeTileComponent @@ -561,7 +560,8 @@ Item { DropArea { // Drops are not allowed on channels which are mapped to non-flight mode switches - property bool dropAllowed: !nonFlightModeMapping + property bool dropAllowed: !nonFlightModeMapping && !singleSwitchMapping + property bool unassignedChannel: unassignedMapping property int channel: parent.channel id: dropArea @@ -592,24 +592,34 @@ Item { spacing: 5 Loader { - property string tileLabel: "Main Mode" - property string tileParam: "RC_MAP_MODE_SW" - sourceComponent: unassignedModeTileComponent + property string tileLabel: "Main Mode" + property string tileParam: "RC_MAP_MODE_SW" + property bool singleSwitchRequired: false + sourceComponent: unassignedModeTileComponent + } + Loader { + property string tileLabel: "Loiter" + property string tileParam: "RC_MAP_LOITER_SW" + property bool singleSwitchRequired: false + sourceComponent: unassignedModeTileComponent } Loader { - property string tileLabel: "Return" - property string tileParam: "RC_MAP_RETURN_SW" - sourceComponent: unassignedModeTileComponent + property string tileLabel: "PosCtl" + property string tileParam: "RC_MAP_POSCTL_SW" + property bool singleSwitchRequired: false + sourceComponent: unassignedModeTileComponent } Loader { - property string tileLabel: "Loiter" - property string tileParam: "RC_MAP_LOITER_SW" - sourceComponent: unassignedModeTileComponent + property string tileLabel: "Return" + property string tileParam: "RC_MAP_RETURN_SW" + property bool singleSwitchRequired: true + sourceComponent: unassignedModeTileComponent } Loader { - property string tileLabel: "PosCtl" - property string tileParam: "RC_MAP_POSCTL_SW" - sourceComponent: unassignedModeTileComponent + property string tileLabel: "Offboard" + property string tileParam: "RC_MAP_OFFB_SW" + property bool singleSwitchRequired: true + sourceComponent: unassignedModeTileComponent } } @@ -643,9 +653,10 @@ Item { Row { property bool modeSwitchVisible: modeChannel != 0 - property bool returnSwitchVisible: returnChannel != 0 && returnChannel != modeChannel property bool loiterSwitchVisible: loiterChannel != 0 && loiterChannel != modeChannel && loiterChannel != returnChannel property bool posCtlSwitchVisible: posCtlChannel != 0 && posCtlChannel != modeChannel + property bool returnSwitchVisible: returnChannel != 0 + property bool offboardSwitchVisible: offboardChannel != 0 width: parent.width spacing: 20 @@ -668,14 +679,6 @@ Item { text: "Auto" } - QGCLabel { - width: parent.width - y: (parent.height * (1.0 - rc_return_th.value)) - (implicitHeight / 2) - visible: modeChannel == returnChannel - horizontalAlignment: Text.AlignRight - text: "Auto: Return" - } - QGCLabel { width: parent.width y: (parent.height * (1.0 - rc_loiter_th.value)) - (implicitHeight / 2) @@ -741,9 +744,9 @@ Item { } Column { - visible: parent.returnSwitchVisible + visible: parent.loiterSwitchVisible - QGCLabel { text: "Return Switch" } + QGCLabel { text: "Loiter Switch" } Row { Item { @@ -752,48 +755,64 @@ Item { QGCLabel { width: parent.width - y: (parent.height * (1.0 - rc_return_th.value)) - (implicitHeight / 2) + y: (parent.height * (1.0 - rc_loiter_th.value)) - (implicitHeight / 2) horizontalAlignment: Text.AlignRight - text: "Auto: Return" + text: "Auto: Loiter" } QGCLabel { width: parent.width - y: (parent.height * (1.0 - rc_loiter_th.value)) - (implicitHeight / 2) - visible: returnChannel == loiterChannel + y: parent.height - (implicitHeight / 2) horizontalAlignment: Text.AlignRight - text: "Auto: Loiter" + text: "Auto: Mission" } + } + + ProgressBar { + height: progressBarHeight + orientation: Qt.Vertical + value: controller.loiterSwitchLiveRange + } + } + } + + Column { + visible: parent.posCtlSwitchVisible + + QGCLabel { text: "PosCtl Switch" } + + Row { + Item { + height: progressBarHeight + width: 150 QGCLabel { width: parent.width - y: parent.height - (implicitHeight / 2) - visible: returnChannel == loiterChannel + y: (parent.height * (1.0 - rc_posctl_th.value)) - (implicitHeight / 2) horizontalAlignment: Text.AlignRight - text: "Auto: Mission" + text: "Assist: PosCtl" } QGCLabel { width: parent.width y: parent.height - (implicitHeight / 2) - visible: returnChannel != loiterChannel horizontalAlignment: Text.AlignRight - text: "Auto: Return Off" + text: "Assist: AltCtl" } } ProgressBar { height: progressBarHeight orientation: Qt.Vertical - value: controller.returnSwitchLiveRange + value: controller.posCtlSwitchLiveRange } } } Column { - visible: parent.loiterSwitchVisible + visible: parent.returnSwitchVisible - QGCLabel { text: "Loiter Switch" } + QGCLabel { text: "Return Switch" } Row { Item { @@ -802,31 +821,32 @@ Item { QGCLabel { width: parent.width - y: (parent.height * (1.0 - rc_loiter_th.value)) - (implicitHeight / 2) + y: (parent.height * (1.0 - rc_return_th.value)) - (implicitHeight / 2) horizontalAlignment: Text.AlignRight - text: "Auto: Loiter" + text: "Return" } QGCLabel { width: parent.width y: parent.height - (implicitHeight / 2) + visible: returnChannel != loiterChannel horizontalAlignment: Text.AlignRight - text: "Auto: Mission" + text: "Return Off" } } ProgressBar { height: progressBarHeight orientation: Qt.Vertical - value: controller.loiterSwitchLiveRange + value: controller.returnSwitchLiveRange } } } Column { - visible: parent.posCtlSwitchVisible + visible: parent.offboardSwitchVisible - QGCLabel { text: "PosCtl Switch" } + QGCLabel { text: "Offboard Switch" } Row { Item { @@ -835,23 +855,24 @@ Item { QGCLabel { width: parent.width - y: (parent.height * (1.0 - rc_posctl_th.value)) - (implicitHeight / 2) + y: (parent.height * (1.0 - rc_return_th.value)) - (implicitHeight / 2) horizontalAlignment: Text.AlignRight - text: "Assist: PosCtl" + text: "Offboad" } QGCLabel { width: parent.width y: parent.height - (implicitHeight / 2) + visible: returnChannel != loiterChannel horizontalAlignment: Text.AlignRight - text: "Assist: AltCtl" + text: "Offboard Off" } } ProgressBar { height: progressBarHeight orientation: Qt.Vertical - value: controller.posCtlSwitchLiveRange + value: controller.offboardSwitchLiveRange } } } diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponentController.cc b/src/AutoPilotPlugins/PX4/FlightModesComponentController.cc index 018457d26704c219917ba1d44a4c96845c744096..5b523e983c42fa7f71876745e27ffedb25c005f9 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponentController.cc +++ b/src/AutoPilotPlugins/PX4/FlightModesComponentController.cc @@ -82,8 +82,8 @@ void FlightModesComponentController::_validateConfiguration(void) QStringList switchParams, switchNames; QList switchMappings; - switchParams << "RC_MAP_MODE_SW" << "RC_MAP_RETURN_SW" << "RC_MAP_LOITER_SW" << "RC_MAP_POSCTL_SW"; - switchNames << "Mode Switch" << "Return Switch" << "Loiter Switch" << "PosCtl Switch"; + switchParams << "RC_MAP_MODE_SW" << "RC_MAP_RETURN_SW" << "RC_MAP_LOITER_SW" << "RC_MAP_POSCTL_SW" << "RC_MAP_OFFB_SW"; + switchNames << "Mode Switch" << "Return Switch" << "Loiter Switch" << "PosCtl Switch" << "Offboard Switch"; for(int i=0; igetParameterFact(switchParams[i])->value().toInt(); @@ -95,12 +95,12 @@ void FlightModesComponentController::_validateConfiguration(void) } } - // Make sure switches are not mapped to attitude control channels + // Make sure switches are not double-mapped QStringList attitudeParams, attitudeNames; - attitudeParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2"; - attitudeNames << "Throttle" << "Yaw" << "Pitch" << "Roll" << "Flaps" << "Aux1" << "Aux2"; + attitudeParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2" << "RC_MAP_ACRO_SW"; + attitudeNames << "Throttle" << "Yaw" << "Pitch" << "Roll" << "Flaps" << "Aux1" << "Aux2" << "Acro"; for (int i=0; igetParameterFact(attitudeParams[i])->value().toInt(); @@ -112,6 +112,24 @@ void FlightModesComponentController::_validateConfiguration(void) } } } + + // Check for switches that must be on their own channel + + QStringList singleSwitchParams, singleSwitchNames; + + singleSwitchParams << "RC_MAP_RETURN_SW" << "RC_MAP_OFFB_SW"; + singleSwitchNames << "Return Switch" << "Offboard Switch"; + + for (int i=0; igetParameterFact(singleSwitchParams[i])->value().toInt(); + + for (int j=0; j