diff --git a/ChangeLog.md b/ChangeLog.md
index 56581887f6ea3be18291a10c098be7ac75566a4b..040f1bcf0b2771750f0b65ebd2a93fb0622b8d05 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -6,6 +6,7 @@ Note: This file only contains high level features or important fixes.
### 4.0.0 - Daily Build
+* Added ROI option during manual flight.
* Windows: Move builds to 64 bit, Qt 5.12.5
* Plan: ROI button will switch to Cancel ROI at appropriate times
* Plan: When ROI is selected the flight path lines which are affected by the ROI will change color
diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri
index 890f514142e4e97589d9d77acc2fdd0c62f278a5..0cf4f15176fe4424efb84ee02c9cad7ec45f6518 100644
--- a/QGCExternalLibs.pri
+++ b/QGCExternalLibs.pri
@@ -131,9 +131,9 @@ AndroidBuild {
contains(DEFINES, QGC_ENABLE_PAIRING) {
MacBuild {
#- Pairing is generally not supported on macOS. This is here solely for development.
- exists(/usr/local/Cellar/openssl/1.0.2s/include) {
- INCLUDEPATH += /usr/local/Cellar/openssl/1.0.2s/include
- LIBS += -L/usr/local/Cellar/openssl/1.0.2s/lib
+ exists(/usr/local/Cellar/openssl/1.0.2t/include) {
+ INCLUDEPATH += /usr/local/Cellar/openssl/1.0.2t/include
+ LIBS += -L/usr/local/Cellar/openssl/1.0.2t/lib
LIBS += -lcrypto -lz
} else {
# There is some circular reference settings going on between QGCExternalLibs.pri and gqgroundcontrol.pro.
diff --git a/qgcimages.qrc b/qgcimages.qrc
index 4c0d059bbc989a745ce802b63f614f17dfc82c34..a363127a36804499f916282ea9a5fb7ce12e6eb1 100644
--- a/qgcimages.qrc
+++ b/qgcimages.qrc
@@ -147,6 +147,7 @@
src/AutoPilotPlugins/PX4/Images/RCLossLight.svg
src/AutoPilotPlugins/PX4/Images/ReturnToHomeAltitude.svg
src/AutoPilotPlugins/PX4/Images/ReturnToHomeAltitudeCopter.svg
+ src/ui/toolbar/Images/roi.svg
src/FlightMap/Images/rollDialWhite.svg
src/FlightMap/Images/rollPointerWhite.svg
src/ui/toolbar/Images/RTK.svg
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index e82ba2e3872e81f202665e9de387a285fabba9ea..542cba60e2344caecfb98c3319c0dee5fb0d8c46 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -15,6 +15,7 @@
src/ui/toolbar/ModeIndicator.qml
src/ui/toolbar/MultiVehicleSelector.qml
src/ui/toolbar/RCRSSIIndicator.qml
+ src/ui/toolbar/ROIIndicator.qml
src/ui/toolbar/TelemetryRSSIIndicator.qml
src/ui/toolbar/VTOLModeIndicator.qml
diff --git a/src/FirmwarePlugin/FirmwarePlugin.cc b/src/FirmwarePlugin/FirmwarePlugin.cc
index 22d5f3d6399d8501e17c3db35cdf18be340925ce..f4150acb5b335d69491e9176efecd7d86b75de4e 100644
--- a/src/FirmwarePlugin/FirmwarePlugin.cc
+++ b/src/FirmwarePlugin/FirmwarePlugin.cc
@@ -271,18 +271,15 @@ void FirmwarePlugin::guidedModeGotoLocation(Vehicle* vehicle, const QGeoCoordina
qgcApp()->showMessage(guided_mode_not_supported_by_vehicle);
}
-void FirmwarePlugin::guidedModeChangeAltitude(Vehicle* vehicle, double altitudeRel)
+void FirmwarePlugin::guidedModeChangeAltitude(Vehicle*, double)
{
// Not supported by generic vehicle
- Q_UNUSED(vehicle);
- Q_UNUSED(altitudeRel);
qgcApp()->showMessage(guided_mode_not_supported_by_vehicle);
}
-void FirmwarePlugin::startMission(Vehicle* vehicle)
+void FirmwarePlugin::startMission(Vehicle*)
{
// Not supported by generic vehicle
- Q_UNUSED(vehicle);
qgcApp()->showMessage(guided_mode_not_supported_by_vehicle);
}
@@ -293,33 +290,28 @@ const FirmwarePlugin::remapParamNameMajorVersionMap_t& FirmwarePlugin::paramName
return remap;
}
-int FirmwarePlugin::remapParamNameHigestMinorVersionNumber(int majorVersionNumber) const
+int FirmwarePlugin::remapParamNameHigestMinorVersionNumber(int) const
{
- Q_UNUSED(majorVersionNumber);
return 0;
}
-QString FirmwarePlugin::vehicleImageOpaque(const Vehicle* vehicle) const
+QString FirmwarePlugin::vehicleImageOpaque(const Vehicle*) const
{
- Q_UNUSED(vehicle);
return QStringLiteral("/qmlimages/vehicleArrowOpaque.svg");
}
-QString FirmwarePlugin::vehicleImageOutline(const Vehicle* vehicle) const
+QString FirmwarePlugin::vehicleImageOutline(const Vehicle*) const
{
- Q_UNUSED(vehicle);
return QStringLiteral("/qmlimages/vehicleArrowOutline.svg");
}
-QString FirmwarePlugin::vehicleImageCompass(const Vehicle* vehicle) const
+QString FirmwarePlugin::vehicleImageCompass(const Vehicle*) const
{
- Q_UNUSED(vehicle);
return QStringLiteral("/qmlimages/compassInstrumentArrow.svg");
}
-const QVariantList &FirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
+const QVariantList &FirmwarePlugin::toolBarIndicators(const Vehicle*)
{
- Q_UNUSED(vehicle);
//-- Default list of indicators for all vehicles.
if(_toolBarIndicatorList.size() == 0) {
_toolBarIndicatorList = QVariantList({
@@ -329,6 +321,7 @@ const QVariantList &FirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/BatteryIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSRTKIndicator.qml")),
+ QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/ROIIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/ArmedIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/ModeIndicator.qml")),
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/VTOLModeIndicator.qml")),
@@ -339,10 +332,8 @@ const QVariantList &FirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
return _toolBarIndicatorList;
}
-const QVariantList& FirmwarePlugin::cameraList(const Vehicle* vehicle)
+const QVariantList& FirmwarePlugin::cameraList(const Vehicle*)
{
- Q_UNUSED(vehicle);
-
if (_cameraList.size() == 0) {
CameraMetaData* metaData;
diff --git a/src/FirmwarePlugin/FirmwarePlugin.h b/src/FirmwarePlugin/FirmwarePlugin.h
index a6627e61f07504763cd4464a867578eaa6241244..888ac2e0941d09685951f8e5d9848744652e9f64 100644
--- a/src/FirmwarePlugin/FirmwarePlugin.h
+++ b/src/FirmwarePlugin/FirmwarePlugin.h
@@ -48,6 +48,7 @@ public:
GuidedModeCapability = 1 << 2, ///< Vehicle supports guided mode commands
OrbitModeCapability = 1 << 3, ///< Vehicle supports orbit mode
TakeoffVehicleCapability = 1 << 4, ///< Vehicle supports guided takeoff
+ ROIModeCapability = 1 << 5, ///< Vehicle supports ROI
} FirmwareCapabilities;
/// Maps from on parameter name to another
diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc
index bd6efcbe49742dc1be197ca9866f180942cf25b0..426df8e7917ca27ada8751369bba332628367e19 100644
--- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc
+++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc
@@ -226,10 +226,13 @@ bool PX4FirmwarePlugin::setFlightMode(const QString& flightMode, uint8_t* base_m
bool PX4FirmwarePlugin::isCapable(const Vehicle *vehicle, FirmwareCapabilities capabilities)
{
int available = SetFlightModeCapability | PauseVehicleCapability | GuidedModeCapability;
+ //-- This is arbitrary until I find how to really tell if ROI is avaiable
+ if (vehicle->multiRotor()) {
+ available |= ROIModeCapability;
+ }
if (vehicle->multiRotor() || vehicle->vtol()) {
available |= TakeoffVehicleCapability | OrbitModeCapability;
}
-
return (capabilities & available) == capabilities;
}
diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlightDisplayViewMap.qml
index 92bf418a1ab93a2ee8e75d3dcfe78d3fedcf486e..0cb2a3194cbd3cac0a06bfe4fc985611a8180287 100644
--- a/src/FlightDisplay/FlightDisplayViewMap.qml
+++ b/src/FlightDisplay/FlightDisplayViewMap.qml
@@ -44,7 +44,6 @@ FlightMap {
property var _geoFenceController: missionController.geoFenceController
property var _rallyPointController: missionController.rallyPointController
- property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property var _activeVehicleCoordinate: activeVehicle ? activeVehicle.coordinate : QtPositioning.coordinate()
property real _toolButtonTopMargin: parent.height - mainWindow.height + (ScreenTools.defaultFontPixelHeight / 2)
property bool _airspaceEnabled: QGroundControl.airmapSupported ? (QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue && QGroundControl.airspaceManager.connected): false
@@ -409,6 +408,34 @@ FlightMap {
}
}
+ // ROI Location visuals
+ MapQuickItem {
+ id: roiLocationItem
+ visible: activeVehicle && activeVehicle.isROIEnabled
+ z: QGroundControl.zOrderMapItems
+ anchorPoint.x: sourceItem.anchorPointX
+ anchorPoint.y: sourceItem.anchorPointY
+ sourceItem: MissionItemIndexLabel {
+ checked: true
+ index: -1
+ label: qsTr("ROI here", "Make this a Region Of Interest")
+ }
+
+ //-- Visibilty controlled by actual state
+ function show(coord) {
+ roiLocationItem.coordinate = coord
+ }
+
+ function hide() {
+ }
+
+ function actionConfirmed() {
+ }
+
+ function actionCancelled() {
+ }
+ }
+
// Orbit telemetry visuals
QGCMapCircleVisuals {
id: orbitTelemetryCircle
@@ -437,9 +464,7 @@ FlightMap {
QGCMenu {
id: clickMenu
-
property var coord
-
QGCMenuItem {
text: qsTr("Go to location")
visible: guidedActionsController.showGotoLocation
@@ -450,7 +475,6 @@ FlightMap {
guidedActionsController.confirmAction(guidedActionsController.actionGoto, clickMenu.coord, gotoLocationItem)
}
}
-
QGCMenuItem {
text: qsTr("Orbit at location")
visible: guidedActionsController.showOrbit
@@ -461,6 +485,15 @@ FlightMap {
guidedActionsController.confirmAction(guidedActionsController.actionOrbit, clickMenu.coord, orbitMapCircle)
}
}
+ QGCMenuItem {
+ text: qsTr("ROI at location")
+ visible: guidedActionsController.showROI
+
+ onTriggered: {
+ roiLocationItem.show(clickMenu.coord)
+ guidedActionsController.confirmAction(guidedActionsController.actionROI, clickMenu.coord, orbitMapCircle)
+ }
+ }
}
onClicked: {
diff --git a/src/FlightDisplay/GuidedActionsController.qml b/src/FlightDisplay/GuidedActionsController.qml
index bb5831b961f4b4d63d36507fae99a827e5fb089b..9df7acc0f4887e9327046568393bd81623b38a4f 100644
--- a/src/FlightDisplay/GuidedActionsController.qml
+++ b/src/FlightDisplay/GuidedActionsController.qml
@@ -51,6 +51,7 @@ Item {
readonly property string setWaypointTitle: qsTr("Set Waypoint")
readonly property string gotoTitle: qsTr("Go To Location")
readonly property string vtolTransitionTitle: qsTr("VTOL Transition")
+ readonly property string roiTitle: qsTr("ROI")
readonly property string armMessage: qsTr("Arm the vehicle.")
readonly property string disarmMessage: qsTr("Disarm the vehicle")
@@ -70,6 +71,7 @@ Item {
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 string roiMessage: qsTr("Make the specified location a Region Of Interest.")
readonly property int actionRTL: 1
readonly property int actionLand: 2
@@ -92,35 +94,36 @@ Item {
readonly property int actionMVStartMission: 19
readonly property int actionVtolTransitionToFwdFlight: 20
readonly property int actionVtolTransitionToMRFlight: 21
+ readonly property int actionROI: 22
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 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 && _vehicleArmed && _vehicleFlying && (_currentMissionIndex < _missionItemCount - 1)
- property bool showPause: _guidedActionsEnabled && _vehicleArmed && _activeVehicle.pauseVehicleSupported && _vehicleFlying && !_vehiclePaused && !_fixedWingOnApproach
- property bool showChangeAlt: _guidedActionsEnabled && _vehicleFlying && _activeVehicle.guidedModeSupported && _vehicleArmed && !_missionActive
- property bool showOrbit: _guidedActionsEnabled && !_hideOrbit && _vehicleFlying && _activeVehicle.orbitModeSupported && !_missionActive
+ property bool showPause: _guidedActionsEnabled && _vehicleArmed && activeVehicle.pauseVehicleSupported && _vehicleFlying && !_vehiclePaused && !_fixedWingOnApproach
+ property bool showChangeAlt: _guidedActionsEnabled && _vehicleFlying && activeVehicle.guidedModeSupported && _vehicleArmed && !_missionActive
+ property bool showOrbit: _guidedActionsEnabled && !_hideOrbit && _vehicleFlying && activeVehicle.orbitModeSupported && !_missionActive
+ property bool showROI: _guidedActionsEnabled && !_hideROI && _vehicleFlying && activeVehicle.roiModeSupported && !_missionActive
property bool showLandAbort: _guidedActionsEnabled && _vehicleFlying && _fixedWingOnApproach
property bool showGotoLocation: _guidedActionsEnabled && _vehicleFlying
// Note: The '_missionItemCount - 2' 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 < _missionItemCount - 2)
+ property bool showResumeMission: activeVehicle && !_vehicleArmed && _vehicleWasFlying && _missionAvailable && _resumeMissionIndex > 0 && (_resumeMissionIndex < _missionItemCount - 2)
property bool guidedUIVisible: guidedActionConfirm.visible || guidedActionList.visible
property var _corePlugin: QGroundControl.corePlugin
- property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
- property bool _guidedActionsEnabled: (!ScreenTools.isDebug && QGroundControl.corePlugin.options.guidedActionsRequireRCRSSI && _activeVehicle) ? _rcRSSIAvailable : _activeVehicle
- property string _flightMode: _activeVehicle ? _activeVehicle.flightMode : ""
+ property bool _guidedActionsEnabled: (!ScreenTools.isDebug && QGroundControl.corePlugin.options.guidedActionsRequireRCRSSI && activeVehicle) ? _rcRSSIAvailable : 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 _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
@@ -130,18 +133,19 @@ Item {
property int _resumeMissionIndex: missionController.resumeMissionIndex
property bool _hideEmergenyStop: !QGroundControl.corePlugin.options.guidedBarShowEmergencyStop
property bool _hideOrbit: !QGroundControl.corePlugin.options.guidedBarShowOrbit
+ property bool _hideROI: !QGroundControl.corePlugin.options.guidedBarShowOrbit
property bool _vehicleWasFlying: false
- property bool _rcRSSIAvailable: _activeVehicle ? _activeVehicle.rcRSSI > 0 && _activeVehicle.rcRSSI <= 100 : false
- property bool _fixedWingOnApproach: _activeVehicle ? _activeVehicle.fixedWing && _vehicleLanding : false
+ property bool _rcRSSIAvailable: activeVehicle ? activeVehicle.rcRSSI > 0 && activeVehicle.rcRSSI <= 100 : false
+ property bool _fixedWingOnApproach: activeVehicle ? activeVehicle.fixedWing && _vehicleLanding : false
// You can turn on log output for GuidedActionsController by turning on GuidedActionsControllerLog category
- property bool __guidedModeSupported: _activeVehicle ? _activeVehicle.guidedModeSupported : false
- property bool __pauseVehicleSupported: _activeVehicle ? _activeVehicle.pauseVehicleSupported : false
+ property bool __guidedModeSupported: activeVehicle ? activeVehicle.guidedModeSupported : false
+ property bool __pauseVehicleSupported: activeVehicle ? activeVehicle.pauseVehicleSupported : false
property bool __flightMode: _flightMode
function _outputState() {
if (_corePlugin.guidedActionsControllerLogging()) {
- console.log(qsTr("_activeVehicle(%1) _vehicleArmed(%2) guidedModeSupported(%3) _vehicleFlying(%4) _vehicleWasFlying(%5) _vehicleInRTLMode(%6) pauseVehicleSupported(%7) _vehiclePaused(%8) _flightMode(%9) _missionItemCount(%10)").arg(_activeVehicle ? 1 : 0).arg(_vehicleArmed ? 1 : 0).arg(__guidedModeSupported ? 1 : 0).arg(_vehicleFlying ? 1 : 0).arg(_vehicleWasFlying ? 1 : 0).arg(_vehicleInRTLMode ? 1 : 0).arg(__pauseVehicleSupported ? 1 : 0).arg(_vehiclePaused ? 1 : 0).arg(_flightMode).arg(_missionItemCount))
+ console.log(qsTr("activeVehicle(%1) _vehicleArmed(%2) guidedModeSupported(%3) _vehicleFlying(%4) _vehicleWasFlying(%5) _vehicleInRTLMode(%6) pauseVehicleSupported(%7) _vehiclePaused(%8) _flightMode(%9) _missionItemCount(%10)").arg(activeVehicle ? 1 : 0).arg(_vehicleArmed ? 1 : 0).arg(__guidedModeSupported ? 1 : 0).arg(_vehicleFlying ? 1 : 0).arg(_vehicleWasFlying ? 1 : 0).arg(_vehicleInRTLMode ? 1 : 0).arg(__pauseVehicleSupported ? 1 : 0).arg(_vehiclePaused ? 1 : 0).arg(_flightMode).arg(_missionItemCount))
}
}
@@ -209,10 +213,10 @@ Item {
property var _actionData
on_FlightModeChanged: {
- _vehiclePaused = _activeVehicle ? _flightMode === _activeVehicle.pauseFlightMode : false
- _vehicleInRTLMode = _activeVehicle ? _flightMode === _activeVehicle.rtlFlightMode || _flightMode === _activeVehicle.smartRTLFlightMode : false
- _vehicleInLandMode = _activeVehicle ? _flightMode === _activeVehicle.landFlightMode : false
- _vehicleInMissionMode = _activeVehicle ? _flightMode === _activeVehicle.missionFlightMode : false // Must be last to get correct signalling for showStartMission popups
+ _vehiclePaused = activeVehicle ? _flightMode === activeVehicle.pauseFlightMode : false
+ _vehicleInRTLMode = activeVehicle ? _flightMode === activeVehicle.rtlFlightMode || _flightMode === activeVehicle.smartRTLFlightMode : 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
@@ -287,7 +291,7 @@ Item {
case actionRTL:
confirmDialog.title = rtlTitle
confirmDialog.message = rtlMessage
- if (_activeVehicle.supportsSmartRTL) {
+ if (activeVehicle.supportsSmartRTL) {
confirmDialog.optionText = qsTr("Smart RTL")
confirmDialog.optionChecked = false
}
@@ -343,6 +347,11 @@ Item {
confirmDialog.message = vtolTransitionMRMessage
confirmDialog.hideTrigger = true
break
+ case actionROI:
+ confirmDialog.title = roiTitle
+ confirmDialog.message = roiMessage
+ confirmDialog.hideTrigger = Qt.binding(function() { return !showROI })
+ break;
default:
console.warn("Unknown actionCode", actionCode)
return
@@ -356,13 +365,13 @@ Item {
var rgVehicle;
switch (actionCode) {
case actionRTL:
- _activeVehicle.guidedModeRTL(optionChecked)
+ activeVehicle.guidedModeRTL(optionChecked)
break
case actionLand:
- _activeVehicle.guidedModeLand()
+ activeVehicle.guidedModeLand()
break
case actionTakeoff:
- _activeVehicle.guidedModeTakeoff(actionAltitudeChange)
+ activeVehicle.guidedModeTakeoff(actionAltitudeChange)
break
case actionResumeMission:
case actionResumeMissionUploadFail:
@@ -370,7 +379,7 @@ Item {
break
case actionStartMission:
case actionContinueMission:
- _activeVehicle.startMission()
+ activeVehicle.startMission()
break
case actionMVStartMission:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
@@ -379,32 +388,32 @@ Item {
}
break
case actionArm:
- _activeVehicle.armed = true
+ activeVehicle.armed = true
break
case actionDisarm:
- _activeVehicle.armed = false
+ activeVehicle.armed = false
break
case actionEmergencyStop:
- _activeVehicle.emergencyStop()
+ activeVehicle.emergencyStop()
break
case actionChangeAlt:
- _activeVehicle.guidedModeChangeAltitude(actionAltitudeChange)
+ activeVehicle.guidedModeChangeAltitude(actionAltitudeChange)
break
case actionGoto:
- _activeVehicle.guidedModeGotoLocation(actionData)
+ activeVehicle.guidedModeGotoLocation(actionData)
break
case actionSetWaypoint:
- _activeVehicle.setCurrentMissionSequence(actionData)
+ activeVehicle.setCurrentMissionSequence(actionData)
break
case actionOrbit:
- _activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius() * (orbitMapCircle.clockwiseRotation ? 1 : -1), _activeVehicle.altitudeAMSL.rawValue + actionAltitudeChange)
+ activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius() * (orbitMapCircle.clockwiseRotation ? 1 : -1), activeVehicle.altitudeAMSL.rawValue + actionAltitudeChange)
break
case actionLandAbort:
- _activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored
+ activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored
break
case actionPause:
- _activeVehicle.pauseVehicle()
- _activeVehicle.guidedModeChangeAltitude(actionAltitudeChange)
+ activeVehicle.pauseVehicle()
+ activeVehicle.guidedModeChangeAltitude(actionAltitudeChange)
break
case actionMVPause:
rgVehicle = QGroundControl.multiVehicleManager.vehicles
@@ -413,10 +422,13 @@ Item {
}
break
case actionVtolTransitionToFwdFlight:
- _activeVehicle.vtolInFwdFlight = true
+ activeVehicle.vtolInFwdFlight = true
break
case actionVtolTransitionToMRFlight:
- _activeVehicle.vtolInFwdFlight = false
+ activeVehicle.vtolInFwdFlight = false
+ break
+ case actionROI:
+ activeVehicle.guidedModeROI(actionData)
break
default:
console.warn(qsTr("Internal error: unknown actionCode"), actionCode)
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 1757cdc7b5822d68f230d131fc8f3ea8a5c1c2f0..0a8a6db831300fd3d5c997dcf12804bebb31d7d7 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -2979,6 +2979,11 @@ bool Vehicle::orbitModeSupported() const
return _firmwarePlugin->isCapable(this, FirmwarePlugin::OrbitModeCapability);
}
+bool Vehicle::roiModeSupported() const
+{
+ return _firmwarePlugin->isCapable(this, FirmwarePlugin::ROIModeCapability);
+}
+
bool Vehicle::takeoffVehicleSupported() const
{
return _firmwarePlugin->isCapable(this, FirmwarePlugin::TakeoffVehicleCapability);
@@ -3084,6 +3089,74 @@ void Vehicle::guidedModeOrbit(const QGeoCoordinate& centerCoord, double radius,
}
}
+void Vehicle::guidedModeROI(const QGeoCoordinate& centerCoord)
+{
+ if (!roiModeSupported()) {
+ qgcApp()->showMessage(QStringLiteral("ROI mode not supported by Vehicle."));
+ return;
+ }
+ if (capabilityBits() & MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
+ sendMavCommandInt(
+ defaultComponentId(),
+ MAV_CMD_DO_SET_ROI_LOCATION,
+ MAV_FRAME_GLOBAL,
+ true, // show error if fails
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ centerCoord.latitude(),
+ centerCoord.longitude(),
+ static_cast(centerCoord.altitude()));
+ } else {
+ sendMavCommand(
+ defaultComponentId(),
+ MAV_CMD_DO_SET_ROI_LOCATION,
+ true, // show error if fails
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(centerCoord.latitude()),
+ static_cast(centerCoord.longitude()),
+ static_cast(centerCoord.altitude()));
+ }
+}
+
+void Vehicle::stopGuidedModeROI()
+{
+ if (!roiModeSupported()) {
+ qgcApp()->showMessage(QStringLiteral("ROI mode not supported by Vehicle."));
+ return;
+ }
+ if (capabilityBits() & MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
+ sendMavCommandInt(
+ defaultComponentId(),
+ MAV_CMD_DO_SET_ROI_NONE,
+ MAV_FRAME_GLOBAL,
+ true, // show error if fails
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN())); // Empty
+ } else {
+ sendMavCommand(
+ defaultComponentId(),
+ MAV_CMD_DO_SET_ROI_NONE,
+ true, // show error if fails
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN()), // Empty
+ static_cast(qQNaN())); // Empty
+ }
+}
+
void Vehicle::pauseVehicle(void)
{
if (!pauseVehicleSupported()) {
@@ -3352,6 +3425,20 @@ void Vehicle::_handleCommandAck(mavlink_message_t& message)
}
}
+ if (ack.command == MAV_CMD_DO_SET_ROI_LOCATION) {
+ if (ack.result == MAV_RESULT_ACCEPTED) {
+ _isROIEnabled = true;
+ emit isROIEnabledChanged();
+ }
+ }
+
+ if (ack.command == MAV_CMD_DO_SET_ROI_NONE) {
+ if (ack.result == MAV_RESULT_ACCEPTED) {
+ _isROIEnabled = false;
+ emit isROIEnabledChanged();
+ }
+ }
+
#if !defined(NO_ARDUPILOT_DIALECT)
if (ack.command == MAV_CMD_FLASH_BOOTLOADER && ack.result == MAV_RESULT_ACCEPTED) {
qgcApp()->showMessage(tr("Bootloader flash succeeded"));
diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h
index 9368bf8e4667b16fc141da0d4dd363db25229c64..ed395f1bbd17d5fa879d35aafcfa24dba9e6c3ba 100644
--- a/src/Vehicle/Vehicle.h
+++ b/src/Vehicle/Vehicle.h
@@ -634,6 +634,7 @@ public:
Q_PROPERTY(qreal gimbalPitch READ gimbalPitch NOTIFY gimbalPitchChanged)
Q_PROPERTY(qreal gimbalYaw READ gimbalYaw NOTIFY gimbalYawChanged)
Q_PROPERTY(bool gimbalData READ gimbalData NOTIFY gimbalDataChanged)
+ Q_PROPERTY(bool isROIEnabled READ isROIEnabled NOTIFY isROIEnabledChanged)
// The following properties relate to Orbit status
Q_PROPERTY(bool orbitActive READ orbitActive NOTIFY orbitActiveChanged)
@@ -646,6 +647,7 @@ public:
Q_PROPERTY(bool guidedModeSupported READ guidedModeSupported CONSTANT) ///< Guided mode commands are supported by this vehicle
Q_PROPERTY(bool pauseVehicleSupported READ pauseVehicleSupported CONSTANT) ///< Pause vehicle command is supported
Q_PROPERTY(bool orbitModeSupported READ orbitModeSupported CONSTANT) ///< Orbit mode is supported by this vehicle
+ Q_PROPERTY(bool roiModeSupported READ roiModeSupported CONSTANT) ///< Orbit mode is supported by this vehicle
Q_PROPERTY(bool takeoffVehicleSupported READ takeoffVehicleSupported CONSTANT) ///< Guided takeoff supported
Q_PROPERTY(QString gotoFlightMode READ gotoFlightMode CONSTANT) ///< Flight mode vehicle is in while performing goto
@@ -729,6 +731,11 @@ public:
/// @param amslAltitude Desired vehicle altitude
Q_INVOKABLE void guidedModeOrbit(const QGeoCoordinate& centerCoord, double radius, double amslAltitude);
+ /// Command vehicle to keep given point as ROI
+ /// @param centerCoord ROI coordinates
+ Q_INVOKABLE void guidedModeROI(const QGeoCoordinate& centerCoord);
+ Q_INVOKABLE void stopGuidedModeROI();
+
/// Command vehicle to pause at current location. If vehicle supports guide mode, vehicle will be left
/// in guided mode after pause.
Q_INVOKABLE void pauseVehicle(void);
@@ -778,6 +785,7 @@ public:
bool guidedModeSupported (void) const;
bool pauseVehicleSupported (void) const;
bool orbitModeSupported (void) const;
+ bool roiModeSupported (void) const;
bool takeoffVehicleSupported (void) const;
QString gotoFlightMode (void) const;
@@ -1100,6 +1108,7 @@ public:
qreal gimbalPitch () { return static_cast(_curGimbalPitch); }
qreal gimbalYaw () { return static_cast(_curGinmbalYaw); }
bool gimbalData () { return _haveGimbalData; }
+ bool isROIEnabled () { return _isROIEnabled; }
public slots:
void setVtolInFwdFlight (bool vtolInFwdFlight);
@@ -1215,6 +1224,7 @@ signals:
void gimbalPitchChanged ();
void gimbalYawChanged ();
void gimbalDataChanged ();
+ void isROIEnabledChanged ();
private slots:
void _mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message);
@@ -1481,6 +1491,7 @@ private:
float _curGimbalPitch = 0.0f;
float _curGinmbalYaw = 0.0f;
bool _haveGimbalData = false;
+ bool _isROIEnabled = false;
Joystick* _activeJoystick = nullptr;
int _firmwareMajorVersion;
diff --git a/src/api/QGCOptions.h b/src/api/QGCOptions.h
index ac660fa92cb2246c62776878b0e03fe0c6002f9d..a290f93d1fc8f7be0e59e12b419be6199e5a0659 100644
--- a/src/api/QGCOptions.h
+++ b/src/api/QGCOptions.h
@@ -49,6 +49,7 @@ public:
Q_PROPERTY(QString firmwareUpgradeSingleURL READ firmwareUpgradeSingleURL CONSTANT)
Q_PROPERTY(bool guidedBarShowEmergencyStop READ guidedBarShowEmergencyStop NOTIFY guidedBarShowEmergencyStopChanged)
Q_PROPERTY(bool guidedBarShowOrbit READ guidedBarShowOrbit NOTIFY guidedBarShowOrbitChanged)
+ Q_PROPERTY(bool guidedBarShowROI READ guidedBarShowROI NOTIFY guidedBarShowROIChanged)
Q_PROPERTY(bool missionWaypointsOnly READ missionWaypointsOnly NOTIFY missionWaypointsOnlyChanged)
Q_PROPERTY(bool multiVehicleEnabled READ multiVehicleEnabled NOTIFY multiVehicleEnabledChanged)
Q_PROPERTY(bool showOfflineMapExport READ showOfflineMapExport NOTIFY showOfflineMapExportChanged)
@@ -110,6 +111,7 @@ public:
virtual bool showFirmwareUpgrade () const { return true; }
virtual bool guidedBarShowEmergencyStop () const { return true; }
virtual bool guidedBarShowOrbit () const { return true; }
+ virtual bool guidedBarShowROI () const { return true; }
virtual bool missionWaypointsOnly () const { return false; } ///< true: Only allow waypoints and complex items in Plan
virtual bool multiVehicleEnabled () const { return true; } ///< false: multi vehicle support is disabled
virtual bool guidedActionsRequireRCRSSI () const { return false; } ///< true: Guided actions will be disabled is there is no RC RSSI
@@ -147,6 +149,7 @@ signals:
void showFirmwareUpgradeChanged (bool show);
void guidedBarShowEmergencyStopChanged (bool show);
void guidedBarShowOrbitChanged (bool show);
+ void guidedBarShowROIChanged (bool show);
void missionWaypointsOnlyChanged (bool missionWaypointsOnly);
void multiVehicleEnabledChanged (bool multiVehicleEnabled);
void showOfflineMapExportChanged ();
diff --git a/src/ui/MainRootWindow.qml b/src/ui/MainRootWindow.qml
index 21b3c87403922322eed5597022ba0808f3f8e476..656395ebfc6b148c3b38e00c4e0753d5a62b8f2c 100644
--- a/src/ui/MainRootWindow.qml
+++ b/src/ui/MainRootWindow.qml
@@ -629,6 +629,12 @@ ApplicationWindow {
indicatorDropdown.open()
}
+ function hidePopUp() {
+ indicatorDropdown.close()
+ indicatorDropdown.currentItem = null
+ indicatorDropdown.currentIndicator = null
+ }
+
Popup {
id: indicatorDropdown
y: ScreenTools.defaultFontPixelHeight
diff --git a/src/ui/toolbar/Images/roi.svg b/src/ui/toolbar/Images/roi.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6983926e0ec7167fe2209eddb5cefaf712374719
--- /dev/null
+++ b/src/ui/toolbar/Images/roi.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/ui/toolbar/ROIIndicator.qml b/src/ui/toolbar/ROIIndicator.qml
new file mode 100644
index 0000000000000000000000000000000000000000..c6f52b97e2dbef95dcbfcc1f5855d10acd242ba8
--- /dev/null
+++ b/src/ui/toolbar/ROIIndicator.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+ *
+ * (c) 2009-2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ * @file
+ * @author Gus Grubba
+ */
+
+import QtQuick 2.11
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.11
+
+import QGroundControl 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.MultiVehicleManager 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.Palette 1.0
+
+//-------------------------------------------------------------------------
+//-- ROI Indicator
+Item {
+ id: _root
+ width: showIndicator ? roiIcon.width : 0
+ visible: showIndicator
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+
+ property bool showIndicator: activeVehicle && activeVehicle.roiModeSupported
+
+ Component {
+ id: roiInfo
+
+ Rectangle {
+ width: roiCol.width + ScreenTools.defaultFontPixelWidth * 6
+ height: roiCol.height + ScreenTools.defaultFontPixelHeight * 2
+ radius: ScreenTools.defaultFontPixelHeight * 0.5
+ color: qgcPal.window
+
+ Column {
+ id: roiCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: Math.max(roiButton.width, roiLabel.width)
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ anchors.centerIn: parent
+
+ QGCLabel {
+ id: roiLabel
+ text: qsTr("ROI Disabled")
+ font.family: ScreenTools.demiboldFontFamily
+ visible: !roiButton.visible
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ QGCButton {
+ id: roiButton
+ visible: activeVehicle && activeVehicle.isROIEnabled
+ text: qsTr("Disable ROI")
+ onClicked: {
+ if(activeVehicle)
+ activeVehicle.stopGuidedModeROI()
+ mainWindow.hidePopUp()
+ }
+ }
+ }
+ }
+ }
+
+ QGCColoredImage {
+ id: roiIcon
+ width: height
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ sourceSize.height: height
+ source: "/qmlimages/roi.svg"
+ color: activeVehicle && activeVehicle.isROIEnabled ? qgcPal.colorGreen : qgcPal.text
+ fillMode: Image.PreserveAspectFit
+ opacity: activeVehicle && activeVehicle.isROIEnabled ? 1 : 0.5
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ mainWindow.showPopUp(_root, roiInfo)
+ }
+ }
+}