diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index d032df6f264a212657d7f88d1ac3c15428c88758..b50a6e7fb9beb6c274b1ea8cf492fc773769fe37 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -32,6 +32,7 @@
src/ui/MainWindowNative.qml
src/ui/preferences/MavlinkSettings.qml
src/MissionEditor/MissionEditor.qml
+ src/MissionEditor/MissionSettingsEditor.qml
src/ui/preferences/MockLink.qml
src/ui/preferences/MockLinkSettings.qml
src/MultiVehicle/MultiVehicleView.qml
diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml
index 0b180e91011f50d0d1041e5e29a624221229bdcf..b05d49231c54567d186b7579b9aaf50496d12e1d 100644
--- a/src/MissionEditor/MissionEditor.qml
+++ b/src/MissionEditor/MissionEditor.qml
@@ -944,9 +944,8 @@ QGCView {
missionItems: missionController.visualItems
expandedWidth: missionItemEditor.x - (ScreenTools.defaultFontPixelWidth * 2)
missionDistance: missionController.missionDistance
+ missionTime: missionController.missionTime
missionMaxTelemetry: missionController.missionMaxTelemetry
- cruiseDistance: missionController.cruiseDistance
- hoverDistance: missionController.hoverDistance
visible: _editingLayer == _layerMission && !ScreenTools.isShortScreen
}
} // FlightMap
diff --git a/src/MissionEditor/MissionItemEditor.qml b/src/MissionEditor/MissionItemEditor.qml
index d7be22e884dafc792d58d977b15c9cdd90ecefc0..7761d9660b41d4c760b511ed4e24994d8d8c2877 100644
--- a/src/MissionEditor/MissionItemEditor.qml
+++ b/src/MissionEditor/MissionItemEditor.qml
@@ -26,8 +26,9 @@ Rectangle {
signal insert
signal moveHomeToMapCenter
- property bool _currentItem: missionItem.isCurrentItem
- property color _outerTextColor: _currentItem ? "black" : qgcPal.text
+ property bool _currentItem: missionItem.isCurrentItem
+ property color _outerTextColor: _currentItem ? "black" : qgcPal.text
+ property bool _noMissionItemsAdded: ListView.view.model.count == 1
readonly property real _editFieldWidth: Math.min(width - _margin * 2, ScreenTools.defaultFontPixelWidth * 12)
readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2
@@ -38,7 +39,6 @@ Rectangle {
colorGroupEnabled: enabled
}
-
MouseArea {
anchors.fill: parent
visible: !missionItem.isCurrentItem
@@ -121,7 +121,6 @@ Rectangle {
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
anchors.left: label.right
anchors.top: parent.top
- //anchors.right: hamburger.left
visible: missionItem.sequenceNumber != 0 && missionItem.isCurrentItem && !missionItem.rawEdit && missionItem.isSimpleItem
text: missionItem.commandName
@@ -133,7 +132,7 @@ Rectangle {
}
}
- onClicked: qgcView.showDialog(commandDialog, qsTr("Select Mission Command"), qgcView.showDialogDefaultWidth, StandardButton.Cancel)
+ onClicked: qgcView.showDialog(commandDialog, qsTr("Select Mission Command"), qgcView.showDialogDefaultWidth, StandardButton.Cancel)
}
QGCLabel {
@@ -141,7 +140,7 @@ Rectangle {
visible: missionItem.sequenceNumber == 0 || !missionItem.isCurrentItem || !missionItem.isSimpleItem
verticalAlignment: Text.AlignVCenter
text: missionItem.sequenceNumber == 0 ?
- qsTr("Planned Home Position") :
+ qsTr("Mission Settings") :
(missionItem.isSimpleItem ? missionItem.commandName : qsTr("Survey"))
color: _outerTextColor
}
@@ -153,8 +152,12 @@ Rectangle {
anchors.left: parent.left
anchors.top: commandPicker.bottom
height: item ? item.height : 0
- source: missionItem.isSimpleItem ? "qrc:/qml/SimpleItemEditor.qml" : "qrc:/qml/SurveyItemEditor.qml"
- onLoaded: { item.visible = Qt.binding(function() { return _currentItem; }) }
+ source: missionItem.sequenceNumber == 0 ? "qrc:/qml/MissionSettingsEditor.qml" : (missionItem.isSimpleItem ? "qrc:/qml/SimpleItemEditor.qml" : "qrc:/qml/SurveyItemEditor.qml")
+
+ onLoaded: {
+ item.visible = Qt.binding(function() { return _currentItem; })
+ }
+
property real availableWidth: _root.width - (_margin * 2) ///< How wide the editor should be
property var editorRoot: _root
}
diff --git a/src/MissionEditor/MissionItemStatus.qml b/src/MissionEditor/MissionItemStatus.qml
index 60c8e09f85440a59decb1e7af37df7b7f72aface..2aad79b34b699c69c86626ed4142f4995fa3468b 100644
--- a/src/MissionEditor/MissionItemStatus.qml
+++ b/src/MissionEditor/MissionItemStatus.qml
@@ -20,20 +20,6 @@ import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
Rectangle {
- readonly property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
-
- property Fact _offlineEditingVehicleType: QGroundControl.offlineEditingVehicleType
- property Fact _offlineEditingCruiseSpeed: QGroundControl.offlineEditingCruiseSpeed
- property Fact _offlineEditingHoverSpeed: QGroundControl.offlineEditingHoverSpeed
-
- property var currentMissionItem ///< Mission item to display status for
- property var missionItems ///< List of all available mission items
- property real expandedWidth ///< Width of control when expanded
- property real missionDistance
- property real missionMaxTelemetry
- property real cruiseDistance
- property real hoverDistance
-
width: _expanded ? expandedWidth : _collapsedWidth
height: Math.max(valueGrid.height, valueMissionGrid.height) + (_margins * 2)
radius: ScreenTools.defaultFontPixelWidth * 0.5
@@ -41,42 +27,35 @@ Rectangle {
opacity: 0.80
clip: true
- readonly property real margins: ScreenTools.defaultFontPixelWidth
-
- property real _collapsedWidth: valueGrid.width + (margins * 2)
- property bool _expanded: true
-
- property real _distance: _statusValid ? _currentMissionItem.distance : 0
- property real _altDifference: _statusValid ? _currentMissionItem.altDifference : 0
- property real _gradient: _statusValid && _currentMissionItem.distance > 0 ? Math.atan(_currentMissionItem.altDifference / _currentMissionItem.distance) : 0
- property real _gradientPercent: isNaN(_gradient) ? 0 : _gradient * 100
- property real _azimuth: _statusValid ? _currentMissionItem.azimuth : -1
- property real _missionDistance: _missionValid ? missionDistance : 0
- property real _missionMaxTelemetry: _missionValid ? missionMaxTelemetry : 0
- property real _missionTime: _missionValid && _missionSpeed > 0 ? (_isVTOL ? _hoverTime + _cruiseTime : _missionDistance / _missionSpeed) : 0
- property real _hoverDistance: _missionValid ? hoverDistance : 0
- property real _cruiseDistance: _missionValid ? cruiseDistance : 0
- property real _hoverTime: _missionValid && _offlineEditingHoverSpeed.value > 0 ? _hoverDistance / _offlineEditingHoverSpeed.value : 0
- property real _cruiseTime: _missionValid && _offlineEditingCruiseSpeed.value > 0 ? _cruiseDistance / _offlineEditingCruiseSpeed.value : 0
-
- property bool _statusValid: currentMissionItem != undefined
- property bool _vehicleValid: _activeVehicle != undefined
- property bool _missionValid: missionItems != undefined
- property bool _currentSurvey: _statusValid ? _currentMissionItem.commandName == "Survey" : false
- property bool _isVTOL: _vehicleValid ? _activeVehicle.vtol : _offlineEditingVehicleType.enumStringValue == "VTOL" //hardcoded
- property real _missionSpeed: _offlineEditingVehicleType.enumStringValue == "Fixedwing" ? _offlineEditingCruiseSpeed.value : _offlineEditingHoverSpeed.value
-
- property string _distanceText: _statusValid ? QGroundControl.metersToAppSettingsDistanceUnits(_distance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
- property string _altText: _statusValid ? QGroundControl.metersToAppSettingsDistanceUnits(_altDifference).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
- property string _gradientText: _statusValid ? _gradientPercent.toFixed(0) + "%" : " "
- property string _azimuthText: _statusValid ? Math.round(_azimuth) : " "
- property string _missionDistanceText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_missionDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
- property string _missionTimeText: _missionValid ? Number(_missionTime / 60).toFixed(1) + " min" : " "
- property string _missionMaxTelemetryText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_missionMaxTelemetry).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
- property string _hoverDistanceText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_hoverDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
- property string _cruiseDistanceText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_cruiseDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
- property string _hoverTimeText: _missionValid ? _hoverTime.toFixed(0) + "s" : " "
- property string _cruiseTimeText: _missionValid ? _cruiseTime.toFixed(0) + "s" : " "
+ property var currentMissionItem ///< Mission item to display status for
+ property var missionItems ///< List of all available mission items
+ property real expandedWidth ///< Width of control when expanded
+ property real missionDistance ///< Total mission distance
+ property real missionTime ///< Total mission time
+ property real missionMaxTelemetry
+
+ property real _collapsedWidth: valueGrid.width + (_margins * 2)
+ property bool _expanded: true
+
+ property bool _statusValid: currentMissionItem != undefined
+ property bool _missionValid: missionItems != undefined
+
+ property real _distance: _statusValid ? _currentMissionItem.distance : NaN
+ property real _altDifference: _statusValid ? _currentMissionItem.altDifference : NaN
+ property real _gradient: _statusValid && _currentMissionItem.distance > 0 ? Math.atan(_currentMissionItem.altDifference / _currentMissionItem.distance) : NaN
+ property real _gradientPercent: isNaN(_gradient) ? NaN : _gradient * 100
+ property real _azimuth: _statusValid ? _currentMissionItem.azimuth : NaN
+ property real _missionDistance: _missionValid ? missionDistance : NaN
+ property real _missionMaxTelemetry: _missionValid ? missionMaxTelemetry : NaN
+ property real _missionTime: _missionValid ? missionTime : NaN
+
+ property string _distanceText: isNaN(_distance) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_distance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
+ property string _altDifferenceText: isNaN(_altDifference) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_altDifference).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
+ property string _gradientText: isNaN(_gradient) ? "-.-" : _gradientPercent.toFixed(0) + "%"
+ property string _azimuthText: isNaN(_azimuth) ? "-.-" : Math.round(_azimuth)
+ property string _missionDistanceText: isNaN(_missionDistance) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_missionDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
+ property string _missionTimeText: isNaN(_missionTime) ? "-.-" : Number(_missionTime / 60).toFixed(1) + " min"
+ property string _missionMaxTelemetryText: isNaN(_missionMaxTelemetry) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_missionMaxTelemetry).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
readonly property real _margins: ScreenTools.defaultFontPixelWidth
@@ -103,7 +82,7 @@ Rectangle {
QGCLabel { text: _distanceText }
QGCLabel { text: qsTr("Alt diff:") }
- QGCLabel { text: _altText }
+ QGCLabel { text: _altDifferenceText }
QGCLabel { text: qsTr("Gradient:") }
QGCLabel { text: _gradientText }
@@ -166,42 +145,6 @@ Rectangle {
QGCLabel { text: qsTr("Max telem dist:") }
QGCLabel { text: _missionMaxTelemetryText }
-
- QGCLabel {
- text: qsTr("Hover distance:")
- visible: _isVTOL
- }
- QGCLabel {
- text: _hoverDistanceText
- visible: _isVTOL
- }
-
- QGCLabel {
- text: qsTr("Cruise distance:")
- visible: _isVTOL
- }
- QGCLabel {
- text: _cruiseDistanceText
- visible: _isVTOL
- }
-
- QGCLabel {
- text: qsTr("Hover time:")
- visible: _isVTOL
- }
- QGCLabel {
- text: _hoverTimeText
- visible: _isVTOL
- }
-
- QGCLabel {
- text: qsTr("Cruise time:")
- visible: _isVTOL
- }
- QGCLabel {
- text: _cruiseTimeText
- visible: _isVTOL
- }
}
}
}
diff --git a/src/MissionEditor/MissionSettingsEditor.qml b/src/MissionEditor/MissionSettingsEditor.qml
new file mode 100644
index 0000000000000000000000000000000000000000..b6a0629249cb5ad86fd42215a5c944decb677f91
--- /dev/null
+++ b/src/MissionEditor/MissionSettingsEditor.qml
@@ -0,0 +1,196 @@
+import QtQuick 2.5
+import QtQuick.Controls 1.2
+import QtQuick.Layouts 1.2
+
+import QGroundControl 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.Vehicle 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.FactControls 1.0
+import QGroundControl.Palette 1.0
+
+// Editor for Mission Settings
+Rectangle {
+ id: valuesRect
+ width: availableWidth
+ height: deferedload.status == Loader.Ready ? (visible ? deferedload.item.height : 0) : 0
+ color: qgcPal.windowShadeDark
+ visible: missionItem.isCurrentItem
+ radius: _radius
+
+ Loader {
+ id: deferedload
+ active: valuesRect.visible
+ asynchronous: true
+ anchors.margins: _margin
+ anchors.left: valuesRect.left
+ anchors.right: valuesRect.right
+ anchors.top: valuesRect.top
+
+ sourceComponent: Component {
+ Item {
+ id: valuesItem
+ height: valuesColumn.height + (_margin * 2)
+
+ property var _missionVehicle: missionController.vehicle
+ property bool _offlineEditing: _missionVehicle.isOfflineEditingVehicle
+ property bool _showOfflineEditingCombos: _offlineEditing && _noMissionItemsAdded
+ property bool _showCruiseSpeed: !_missionVehicle.multiRotor
+ property bool _showHoverSpeed: _missionVehicle.multiRotor || missionController.vehicle.vtol
+
+ readonly property string _firmwareLabel: qsTr("Firmware:")
+ readonly property string _vehicleLabel: qsTr("Vehicle:")
+
+ QGCPalette { id: qgcPal }
+
+ Column {
+ id: valuesColumn
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ spacing: _margin
+
+ QGCLabel { text: qsTr("Planned Home Position:") }
+
+ Rectangle {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 1
+ color: qgcPal.text
+ }
+
+ Repeater {
+ model: missionItem.textFieldFacts
+
+ Item {
+ width: valuesColumn.width
+ height: textField.height
+
+ QGCLabel {
+ id: textFieldLabel
+ anchors.baseline: textField.baseline
+ text: object.name
+ }
+
+ FactTextField {
+ id: textField
+ anchors.right: parent.right
+ width: _editFieldWidth
+ showUnits: true
+ fact: object
+ visible: !_root.readOnly
+ }
+
+ FactLabel {
+ anchors.baseline: textFieldLabel.baseline
+ anchors.right: parent.right
+ fact: object
+ visible: _root.readOnly
+ }
+ }
+ }
+
+ QGCButton {
+ text: qsTr("Move Home to map center")
+ visible: missionItem.homePosition
+ onClicked: editorRoot.moveHomeToMapCenter()
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ QGCLabel {
+ width: parent.width
+ wrapMode: Text.WordWrap
+ font.pointSize: ScreenTools.smallFontPointSize
+ text: qsTr("Note: Planned home position for mission display only. Actual home position set by vehicle at flight time.")
+ }
+
+ QGCLabel { text: qsTr("Vehicle Info:") }
+
+ Rectangle {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 1
+ color: qgcPal.text
+ }
+
+ GridLayout {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ columnSpacing: ScreenTools.defaultFontPixelWidth
+ rowSpacing: columnSpacing
+ columns: 2
+
+ QGCLabel {
+ text: _firmwareLabel
+ visible: _showOfflineEditingCombos
+ }
+ FactComboBox {
+ Layout.fillWidth: true
+ fact: QGroundControl.offlineEditingFirmwareType
+ indexModel: false
+ visible: _showOfflineEditingCombos
+ }
+
+ QGCLabel {
+ text: _firmwareLabel
+ visible: !_showOfflineEditingCombos
+ }
+ QGCLabel {
+ text: _missionVehicle.firmwareTypeString
+ visible: !_showOfflineEditingCombos
+ }
+
+ QGCLabel {
+ text: _vehicleLabel
+ visible: _showOfflineEditingCombos
+ }
+ FactComboBox {
+ id: offlineVehicleCombo
+ Layout.fillWidth: true
+ fact: QGroundControl.offlineEditingVehicleType
+ indexModel: false
+ visible: _showOfflineEditingCombos
+ }
+
+ QGCLabel {
+ text: _vehicleLabel
+ visible: !_showOfflineEditingCombos
+ }
+ QGCLabel {
+ text: _missionVehicle.vehicleTypeString
+ visible: !_showOfflineEditingCombos
+ }
+ QGCLabel {
+ Layout.row: 2
+ text: qsTr("Cruise speed:")
+ visible: _showCruiseSpeed
+ }
+ FactTextField {
+ Layout.fillWidth: true
+ fact: QGroundControl.offlineEditingCruiseSpeed
+ visible: _showCruiseSpeed
+ }
+
+ QGCLabel {
+ Layout.row: 3
+ text: qsTr("Hover speed:")
+ visible: _showHoverSpeed
+ }
+ FactTextField {
+ Layout.fillWidth: true
+ fact: QGroundControl.offlineEditingHoverSpeed
+ visible: _showHoverSpeed
+ }
+ } // GridLayout
+
+ QGCLabel {
+ width: parent.width
+ wrapMode: Text.WordWrap
+ font.pointSize: ScreenTools.smallFontPointSize
+ text: qsTr("Note: Speeds are planned speeds only for time calculations. Actual vehicle will not be affected.")
+ }
+ } // Column
+ } // Item
+ } // Component
+ } // Loader
+} // Rectangle
diff --git a/src/MissionEditor/SurveyItemEditor.qml b/src/MissionEditor/SurveyItemEditor.qml
index dca4a2b8fcbba259911d02f0b8c6b9edbc7b0a41..b5fb661e27c44434dd116fbe12669601a17b75be 100644
--- a/src/MissionEditor/SurveyItemEditor.qml
+++ b/src/MissionEditor/SurveyItemEditor.qml
@@ -579,14 +579,17 @@ Rectangle {
}
Grid {
- columns: 2
- spacing: ScreenTools.defaultFontPixelWidth
+ columns: 2
+ columnSpacing: ScreenTools.defaultFontPixelWidth
QGCLabel { text: qsTr("Survey area:") }
QGCLabel { text: QGroundControl.squareMetersToAppSettingsAreaUnits(missionItem.coveredArea).toFixed(2) + " " + QGroundControl.appSettingsAreaUnitsString }
QGCLabel { text: qsTr("# shots:") }
QGCLabel { text: missionItem.cameraShots }
+
+ QGCLabel { text: qsTr("Shot interval:") }
+ QGCLabel { text: missionItem.timeBetweenShots.toFixed(1) + " " + qsTr("secs")}
}
}
}
diff --git a/src/MissionManager/ComplexMissionItem.h b/src/MissionManager/ComplexMissionItem.h
index cb278c6b98db48721e67a375e97550fd2ce61387..ad512e6eed13b4aa119a2f69bd5d76668b35b337 100644
--- a/src/MissionManager/ComplexMissionItem.h
+++ b/src/MissionManager/ComplexMissionItem.h
@@ -46,6 +46,9 @@ public:
/// @return the greatest distance from any point of the complex item to some coordinate
virtual double greatestDistanceTo(const QGeoCoordinate &other) const = 0;
+ /// Informs the complex item of the cruise speed it will fly at
+ virtual void setCruiseSpeed(double cruiseSpeed) = 0;
+
/// This mission item attribute specifies the type of the complex item.
static const char* jsonComplexItemTypeKey;
diff --git a/src/MissionManager/MavCmdInfoCommon.json b/src/MissionManager/MavCmdInfoCommon.json
index e0567057c0f11d87640cf714117dcab30b5df2ea..c831f7e1b1eb47a456fe35d57b3d8ec08e2229d6 100644
--- a/src/MissionManager/MavCmdInfoCommon.json
+++ b/src/MissionManager/MavCmdInfoCommon.json
@@ -5,7 +5,7 @@
"mavCmdInfo": [
{
- "comment": "MAV_CMD_NAV_LAST: Used for fake home position waypoint",
+ "comment": "MAV_CMD_NAV_LAST: Used for mission settings / planned home position waypoint",
"id": 95,
"rawName": "HomeRaw",
"friendlyName": "Home Position",
diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc
index ca16bee56e93230a4e617dcce2f295d384a63d50..791e365b2e8a94278a441128d0ab641b3fb1aef3 100644
--- a/src/MissionManager/MissionController.cc
+++ b/src/MissionManager/MissionController.cc
@@ -33,6 +33,9 @@ const char* MissionController::_jsonFileTypeValue = "Mission";
const char* MissionController::_jsonItemsKey = "items";
const char* MissionController::_jsonPlannedHomePositionKey = "plannedHomePosition";
const char* MissionController::_jsonFirmwareTypeKey = "firmwareType";
+const char* MissionController::_jsonVehicleTypeKey = "vehicleType";
+const char* MissionController::_jsonCruiseSpeedKey = "cruiseSpeed";
+const char* MissionController::_jsonHoverSpeedKey = "hoverSpeed";
const char* MissionController::_jsonParamsKey = "params";
// Deprecated V1 format keys
@@ -49,9 +52,12 @@ MissionController::MissionController(QObject *parent)
, _missionItemsRequested(false)
, _queuedSend(false)
, _missionDistance(0.0)
+ , _missionTime(0.0)
+ , _missionHoverDistance(0.0)
+ , _missionHoverTime(0.0)
+ , _missionCruiseDistance(0.0)
+ , _missionCruiseTime(0.0)
, _missionMaxTelemetry(0.0)
- , _cruiseDistance(0.0)
- , _hoverDistance(0.0)
{
}
@@ -396,6 +402,9 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec
{ _jsonPlannedHomePositionKey, QJsonValue::Array, true },
{ _jsonItemsKey, QJsonValue::Array, true },
{ _jsonFirmwareTypeKey, QJsonValue::Double, true },
+ { _jsonVehicleTypeKey, QJsonValue::Double, false },
+ { _jsonCruiseSpeedKey, QJsonValue::Double, false },
+ { _jsonHoverSpeedKey, QJsonValue::Double, false },
};
if (!JsonHelper::validateKeys(json, rootKeyInfoList, errorString)) {
return false;
@@ -403,11 +412,21 @@ bool MissionController::_loadJsonMissionFileV2(const QJsonObject& json, QmlObjec
qCDebug(MissionControllerLog) << "MissionController::_loadJsonMissionFileV2 itemCount:" << json[_jsonItemsKey].toArray().count();
- // Planned home position
+ // Mission Settings
QGeoCoordinate homeCoordinate;
if (!JsonHelper::loadGeoCoordinate(json[_jsonPlannedHomePositionKey], true /* altitudeRequired */, homeCoordinate, errorString)) {
return false;
}
+ if (json.contains(_jsonVehicleTypeKey) && _activeVehicle->isOfflineEditingVehicle()) {
+ QGroundControlQmlGlobal::offlineEditingVehicleType()->setRawValue(json[_jsonVehicleTypeKey].toDouble());
+ }
+ if (json.contains(_jsonCruiseSpeedKey)) {
+ QGroundControlQmlGlobal::offlineEditingCruiseSpeed()->setRawValue(json[_jsonCruiseSpeedKey].toDouble());
+ }
+ if (json.contains(_jsonHoverSpeedKey)) {
+ QGroundControlQmlGlobal::offlineEditingHoverSpeed()->setRawValue(json[_jsonHoverSpeedKey].toDouble());
+ }
+
SimpleMissionItem* homeItem = new SimpleMissionItem(_activeVehicle, this);
homeItem->setCoordinate(homeCoordinate);
visualItems->insert(0, homeItem);
@@ -645,19 +664,8 @@ void MissionController::saveToFile(const QString& filename)
missionFileObject[JsonHelper::jsonVersionKey] = _missionFileVersion;
missionFileObject[JsonHelper::jsonGroundStationKey] = JsonHelper::jsonGroundStationValue;
- MAV_AUTOPILOT firmwareType = MAV_AUTOPILOT_GENERIC;
- if (_activeVehicle) {
- firmwareType = _activeVehicle->firmwareType();
- } else {
- // FIXME: Hack duplicated code from QGroundControlQmlGlobal. Had to do this for now since
- // QGroundControlQmlGlobal is not available from C++ side.
-
- QSettings settings;
- firmwareType = (MAV_AUTOPILOT)settings.value("OfflineEditingFirmwareType", MAV_AUTOPILOT_ARDUPILOTMEGA).toInt();
- }
- missionFileObject[_jsonFirmwareTypeKey] = firmwareType;
+ // Mission settings
- // Save planned home position
SimpleMissionItem* homeItem = qobject_cast(_visualItems->get(0));
if (!homeItem) {
qgcApp()->showMessage(QStringLiteral("Internal error: VisualMissionItem at index 0 not SimpleMissionItem"));
@@ -666,6 +674,10 @@ void MissionController::saveToFile(const QString& filename)
QJsonValue coordinateValue;
JsonHelper::saveGeoCoordinate(homeItem->coordinate(), true /* writeAltitude */, coordinateValue);
missionFileObject[_jsonPlannedHomePositionKey] = coordinateValue;
+ missionFileObject[_jsonFirmwareTypeKey] = _activeVehicle->firmwareType();
+ missionFileObject[_jsonVehicleTypeKey] = _activeVehicle->vehicleType();
+ missionFileObject[_jsonCruiseSpeedKey] = _activeVehicle->cruiseSpeed();
+ missionFileObject[_jsonHoverSpeedKey] = _activeVehicle->hoverSpeed();
// Save the visual items
QJsonArray rgMissionItems;
@@ -730,7 +742,7 @@ void MissionController::_calcPrevWaypointValues(double homeAlt, VisualMissionIte
}
}
-void MissionController::_calcHomeDist(VisualMissionItem* currentItem, VisualMissionItem* homeItem, double* distance)
+double MissionController::_calcDistanceToHome(VisualMissionItem* currentItem, VisualMissionItem* homeItem)
{
QGeoCoordinate currentCoord = currentItem->coordinate();
QGeoCoordinate homeCoord = homeItem->exitCoordinate();
@@ -740,11 +752,7 @@ void MissionController::_calcHomeDist(VisualMissionItem* currentItem, VisualMiss
qCDebug(MissionControllerLog) << "distanceOk" << distanceOk;
- if (distanceOk) {
- *distance = homeCoord.distanceTo(currentCoord);
- } else {
- *distance = 0.0;
- }
+ return distanceOk ? homeCoord.distanceTo(currentCoord) : 0.0;
}
void MissionController::_recalcWaypointLines(void)
@@ -771,7 +779,7 @@ void MissionController::_recalcWaypointLines(void)
VisualMissionItem* item = qobject_cast(_visualItems->get(i));
- // If we still haven't found the first coordinate item and we hit a a takeoff command link back to home
+ // If we still haven't found the first coordinate item and we hit a takeoff command, link back to home
if (firstCoordinateItem &&
item->isSimpleItem() &&
(qobject_cast(item)->command() == MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF ||
@@ -842,7 +850,7 @@ void MissionController::_recalcAltitudeRangeBearing()
qWarning() << "Home item is not SimpleMissionItem";
}
- bool showHomePosition = homeItem->showHomePosition();
+ bool showHomePosition = homeItem->showHomePosition();
qCDebug(MissionControllerLog) << "_recalcAltitudeRangeBearing";
@@ -862,47 +870,68 @@ void MissionController::_recalcAltitudeRangeBearing()
double missionDistance = 0.0;
double missionMaxTelemetry = 0.0;
+ double missionTime = 0.0;
+ double vtolHoverTime = 0.0;
+ double vtolCruiseTime = 0.0;
+ double vtolHoverDistance = 0.0;
+ double vtolCruiseDistance = 0.0;
+ double currentCruiseSpeed = _activeVehicle->cruiseSpeed();
+ double currentHoverSpeed = _activeVehicle->hoverSpeed();
- bool vtolCalc = (QGroundControlQmlGlobal::offlineEditingVehicleType()->enumStringValue() == "VTOL" || (_activeVehicle && _activeVehicle->vtol())) ? true : false ;
- double cruiseDistance = 0.0;
- double hoverDistance = 0.0;
- bool hoverDistanceCalc = false;
- bool hoverTransition = false;
- bool cruiseTransition = false;
- bool hoverDistanceReset = false;
+ bool vtolVehicle = _activeVehicle->vtol();
+ bool vtolInHover = true;
bool linkBackToHome = false;
-
for (int i=1; i<_visualItems->count(); i++) {
VisualMissionItem* item = qobject_cast(_visualItems->get(i));
+ SimpleMissionItem* simpleItem = qobject_cast(item);
+ ComplexMissionItem* complexItem = qobject_cast(item);
+
// Assume the worst
item->setAzimuth(0.0);
item->setDistance(0.0);
- // If we still haven't found the first coordinate item and we hit a takeoff command link back to home
- if (firstCoordinateItem &&
- item->isSimpleItem() &&
- qobject_cast(item)->command() == MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF) {
- linkBackToHome = true;
- hoverDistanceCalc = true;
+ if (simpleItem && simpleItem->command() == MavlinkQmlSingleton::MAV_CMD_DO_CHANGE_SPEED) {
+ // Adjust cruise speed for time calculations
+ double newSpeed = simpleItem->missionItem().param2();
+ if (newSpeed > 0) {
+ if (_activeVehicle->multiRotor()) {
+ currentHoverSpeed = newSpeed;
+ } else {
+ currentCruiseSpeed = newSpeed;
+ }
+ }
}
- if (item->isSimpleItem() && vtolCalc) {
- SimpleMissionItem* simpleItem = qobject_cast(item);
- if (simpleItem->command() == MavlinkQmlSingleton::MAV_CMD_DO_VTOL_TRANSITION){ //transition waypoint value
- if (simpleItem->missionItem().param1() == 3){ //hover mode value
- hoverDistanceCalc = true;
- hoverTransition = true;
- }
- else if (simpleItem->missionItem().param1() == 4){
- hoverDistanceCalc = false;
- cruiseTransition = true;
+ // Link back to home if first item is takeoff and we have home position
+ if (firstCoordinateItem && simpleItem && simpleItem->command() == MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF) {
+ if (showHomePosition) {
+ linkBackToHome = true;
+ }
+ }
+
+ // Update VTOL state
+ if (simpleItem && vtolVehicle) {
+ switch (simpleItem->command()) {
+ case MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF:
+ vtolInHover = false;
+ break;
+ case MavlinkQmlSingleton::MAV_CMD_NAV_LAND:
+ vtolInHover = false;
+ break;
+ case MavlinkQmlSingleton::MAV_CMD_DO_VTOL_TRANSITION:
+ {
+ int transitionState = simpleItem->missionItem().param1();
+ if (transitionState == MAV_VTOL_STATE_TRANSITION_TO_MC) {
+ vtolInHover = true;
+ } else if (transitionState == MAV_VTOL_STATE_TRANSITION_TO_FW) {
+ vtolInHover = false;
}
}
- if(!hoverTransition && cruiseTransition && !hoverDistanceReset && !linkBackToHome){
- hoverDistance = missionDistance;
- hoverDistanceReset = true;
+ break;
+ default:
+ break;
}
}
@@ -927,62 +956,60 @@ void MissionController::_recalcAltitudeRangeBearing()
if (!item->isStandaloneCoordinate()) {
firstCoordinateItem = false;
- if (lastCoordinateItem != homeItem || (showHomePosition && linkBackToHome)) {
- double azimuth, distance, altDifference, telemetryDistance;
+ if (lastCoordinateItem != homeItem || linkBackToHome) {
+ // This is a subsequent waypoint or we are forcing the first waypoint back to home
+ double azimuth, distance, altDifference;
- // Subsequent coordinate items link to last coordinate item. If the last coordinate item
- // is an invalid home position we skip the line
_calcPrevWaypointValues(homePositionAltitude, item, lastCoordinateItem, &azimuth, &distance, &altDifference);
item->setAltDifference(altDifference);
item->setAzimuth(azimuth);
item->setDistance(distance);
missionDistance += distance;
-
- if (item->isSimpleItem()) {
- _calcHomeDist(item, homeItem, &telemetryDistance);
-
- if (vtolCalc) {
- SimpleMissionItem* simpleItem = qobject_cast(item);
- if (simpleItem->command() == MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF || hoverDistanceCalc){
- hoverDistance += distance;
- }
- cruiseDistance = missionDistance - hoverDistance;
- if(simpleItem->command() == MavlinkQmlSingleton::MAV_CMD_NAV_LAND && !linkBackToHome && !cruiseTransition && !hoverTransition){
- hoverDistance = cruiseDistance;
- cruiseDistance = missionDistance - hoverDistance;
- }
+ missionMaxTelemetry = qMax(missionMaxTelemetry, _calcDistanceToHome(item, homeItem));
+
+ // Calculate mission time
+ if (vtolVehicle) {
+ if (vtolInHover) {
+ double hoverTime = distance / _activeVehicle->hoverSpeed();
+ missionTime += hoverTime;
+ vtolHoverTime += hoverTime;
+ vtolHoverDistance += distance;
+ } else {
+ double cruiseTime = distance / currentCruiseSpeed;
+ missionTime += cruiseTime;
+ vtolCruiseTime += cruiseTime;
+ vtolCruiseDistance += distance;
}
} else {
- missionDistance += qobject_cast(item)->complexDistance();
- telemetryDistance = qobject_cast(item)->greatestDistanceTo(homeItem->exitCoordinate());
-
- if (vtolCalc){
- cruiseDistance += qobject_cast(item)->complexDistance(); //assume all survey missions undertaken in cruise
- }
- }
-
- if (telemetryDistance > missionMaxTelemetry) {
- missionMaxTelemetry = telemetryDistance;
+ missionTime += distance / (_activeVehicle->multiRotor() ? currentHoverSpeed : currentCruiseSpeed);
}
}
- else if (lastCoordinateItem == homeItem && !item->isSimpleItem()){
- missionDistance += qobject_cast(item)->complexDistance();
- missionMaxTelemetry = qobject_cast(item)->greatestDistanceTo(homeItem->exitCoordinate());
-
- if (vtolCalc){
- cruiseDistance += qobject_cast(item)->complexDistance(); //assume all survey missions undertaken in cruise
- }
+ if (complexItem) {
+ // Add in distance/time inside survey as well
+ // This code assumes all surveys are done cruise not hover
+ double complexDistance = complexItem->complexDistance();
+ double cruiseSpeed = _activeVehicle->multiRotor() ? currentHoverSpeed : currentCruiseSpeed;
+ missionDistance += complexDistance;
+ missionTime += complexDistance / cruiseSpeed;
+ missionMaxTelemetry = qMax(missionMaxTelemetry, complexItem->greatestDistanceTo(homeItem->exitCoordinate()));
+
+ // Let the complex item know the current cruise speed
+ complexItem->setCruiseSpeed(cruiseSpeed);
}
- lastCoordinateItem = item;
}
+
+ lastCoordinateItem = item;
}
}
- setMissionDistance(missionDistance);
- setMissionMaxTelemetry(missionMaxTelemetry);
- setCruiseDistance(cruiseDistance);
- setHoverDistance(hoverDistance);
+ _setMissionMaxTelemetry(missionMaxTelemetry);
+ _setMissionDistance(missionDistance);
+ _setMissionTime(missionTime);
+ _setMissionHoverDistance(vtolHoverDistance);
+ _setMissionHoverTime(vtolHoverTime);
+ _setMissionCruiseDistance(vtolCruiseDistance);
+ _setMissionCruiseTime(vtolCruiseTime);
// Walk the list again calculating altitude percentages
double altRange = maxAltSeen - minAltSeen;
@@ -1187,6 +1214,8 @@ void MissionController::_activeVehicleSet(void)
connect(missionManager, &MissionManager::currentItemChanged, this, &MissionController::_currentMissionItemChanged);
connect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionController::_activeVehicleHomePositionAvailableChanged);
connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionController::_activeVehicleHomePositionChanged);
+ connect(_activeVehicle, &Vehicle::cruiseSpeedChanged, this, &MissionController::_recalcAltitudeRangeBearing);
+ connect(_activeVehicle, &Vehicle::hoverSpeedChanged, this, &MissionController::_recalcAltitudeRangeBearing);
if (_activeVehicle->parameterManager()->parametersReady() && !syncInProgress()) {
// We are switching between two previously existing vehicles. We have to manually ask for the items from the Vehicle.
@@ -1230,7 +1259,15 @@ void MissionController::_activeVehicleHomePositionChanged(const QGeoCoordinate&
}
}
-void MissionController::setMissionDistance(double missionDistance)
+void MissionController::_setMissionMaxTelemetry(double missionMaxTelemetry)
+{
+ if (!qFuzzyCompare(_missionMaxTelemetry, missionMaxTelemetry)) {
+ _missionMaxTelemetry = missionMaxTelemetry;
+ emit missionMaxTelemetryChanged(_missionMaxTelemetry);
+ }
+}
+
+void MissionController::_setMissionDistance(double missionDistance)
{
if (!qFuzzyCompare(_missionDistance, missionDistance)) {
_missionDistance = missionDistance;
@@ -1238,27 +1275,43 @@ void MissionController::setMissionDistance(double missionDistance)
}
}
-void MissionController::setMissionMaxTelemetry(double missionMaxTelemetry)
+void MissionController::_setMissionTime(double missionTime)
{
- if (!qFuzzyCompare(_missionMaxTelemetry, missionMaxTelemetry)) {
- _missionMaxTelemetry = missionMaxTelemetry;
- emit missionMaxTelemetryChanged(_missionMaxTelemetry);
+ if (!qFuzzyCompare(_missionTime, missionTime)) {
+ _missionTime = missionTime;
+ emit missionTimeChanged();
+ }
+}
+
+void MissionController::_setMissionHoverTime(double missionHoverTime)
+{
+ if (!qFuzzyCompare(_missionHoverTime, missionHoverTime)) {
+ _missionHoverTime = missionHoverTime;
+ emit missionHoverTimeChanged();
}
}
-void MissionController::setCruiseDistance(double cruiseDistance)
+void MissionController::_setMissionHoverDistance(double missionHoverDistance)
{
- if (!qFuzzyCompare(_cruiseDistance, cruiseDistance)) {
- _cruiseDistance = cruiseDistance;
- emit cruiseDistanceChanged(_cruiseDistance);
+ if (!qFuzzyCompare(_missionHoverDistance, missionHoverDistance)) {
+ _missionHoverDistance = missionHoverDistance;
+ emit missionHoverDistanceChanged(_missionHoverDistance);
}
}
-void MissionController::setHoverDistance(double hoverDistance)
+void MissionController::_setMissionCruiseTime(double missionCruiseTime)
{
- if (!qFuzzyCompare(_hoverDistance, hoverDistance)) {
- _hoverDistance = hoverDistance;
- emit hoverDistanceChanged(_hoverDistance);
+ if (!qFuzzyCompare(_missionCruiseTime, missionCruiseTime)) {
+ _missionCruiseTime = missionCruiseTime;
+ emit missionCruiseTimeChanged();
+ }
+}
+
+void MissionController::_setMissionCruiseDistance(double missionCruiseDistance)
+{
+ if (!qFuzzyCompare(_missionCruiseDistance, missionCruiseDistance)) {
+ _missionCruiseDistance = missionCruiseDistance;
+ emit missionCruiseDistanceChanged(_missionCruiseDistance);
}
}
@@ -1437,3 +1490,21 @@ QString MissionController::fileExtension(void) const
{
return QGCApplication::missionFileExtension;
}
+
+double MissionController::cruiseSpeed(void) const
+{
+ if (_activeVehicle) {
+ return _activeVehicle->cruiseSpeed();
+ } else {
+ return 0.0f;
+ }
+}
+
+double MissionController::hoverSpeed(void) const
+{
+ if (_activeVehicle) {
+ return _activeVehicle->hoverSpeed();
+ } else {
+ return 0.0f;
+ }
+}
diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h
index c03becf26b406270a8a85006be6bb5bdb4eb3e43..bac54c891d8be944a5c8782ac94003624f345237 100644
--- a/src/MissionManager/MissionController.h
+++ b/src/MissionManager/MissionController.h
@@ -34,15 +34,18 @@ public:
MissionController(QObject* parent = NULL);
~MissionController();
- Q_PROPERTY(QGeoCoordinate plannedHomePosition READ plannedHomePosition NOTIFY plannedHomePositionChanged)
- Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged)
- Q_PROPERTY(QmlObjectListModel* complexVisualItems READ complexVisualItems NOTIFY complexVisualItemsChanged)
- Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged)
-
- Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged)
- Q_PROPERTY(double missionMaxTelemetry READ missionMaxTelemetry NOTIFY missionMaxTelemetryChanged)
- Q_PROPERTY(double cruiseDistance READ cruiseDistance NOTIFY cruiseDistanceChanged)
- Q_PROPERTY(double hoverDistance READ hoverDistance NOTIFY hoverDistanceChanged)
+ Q_PROPERTY(QGeoCoordinate plannedHomePosition READ plannedHomePosition NOTIFY plannedHomePositionChanged)
+ Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged)
+ Q_PROPERTY(QmlObjectListModel* complexVisualItems READ complexVisualItems NOTIFY complexVisualItemsChanged)
+ Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged)
+
+ Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged)
+ Q_PROPERTY(double missionTime READ missionTime NOTIFY missionTimeChanged)
+ Q_PROPERTY(double missionHoverDistance READ missionHoverDistance NOTIFY missionHoverDistanceChanged)
+ Q_PROPERTY(double missionCruiseDistance READ missionCruiseDistance NOTIFY missionCruiseDistanceChanged)
+ Q_PROPERTY(double missionHoverTime READ missionHoverTime NOTIFY missionHoverTimeChanged)
+ Q_PROPERTY(double missionCruiseTime READ missionCruiseTime NOTIFY missionCruiseTimeChanged)
+ Q_PROPERTY(double missionMaxTelemetry READ missionMaxTelemetry NOTIFY missionMaxTelemetryChanged)
Q_INVOKABLE void removeMissionItem(int index);
@@ -80,15 +83,14 @@ public:
QmlObjectListModel* waypointLines (void) { return &_waypointLines; }
double missionDistance (void) const { return _missionDistance; }
+ double missionTime (void) const { return _missionTime; }
+ double missionHoverDistance (void) const { return _missionHoverDistance; }
+ double missionHoverTime (void) const { return _missionHoverTime; }
+ double missionCruiseDistance (void) const { return _missionCruiseDistance; }
+ double missionCruiseTime (void) const { return _missionCruiseTime; }
double missionMaxTelemetry (void) const { return _missionMaxTelemetry; }
- double cruiseDistance (void) const { return _cruiseDistance; }
- double hoverDistance (void) const { return _hoverDistance; }
-
- void setMissionDistance (double missionDistance );
- void setMissionMaxTelemetry (double missionMaxTelemetry);
- void setCruiseDistance (double cruiseDistance );
- void setHoverDistance (double hoverDistance );
-
+ double cruiseSpeed (void) const;
+ double hoverSpeed (void) const;
signals:
void plannedHomePositionChanged(QGeoCoordinate plannedHomePosition);
@@ -97,9 +99,16 @@ signals:
void waypointLinesChanged(void);
void newItemsFromVehicle(void);
void missionDistanceChanged(double missionDistance);
+ void missionTimeChanged(void);
+ void missionHoverDistanceChanged(double missionHoverDistance);
+ void missionHoverTimeChanged(void);
+ void missionCruiseDistanceChanged(double missionCruiseDistance);
+ void missionCruiseTimeChanged(void);
void missionMaxTelemetryChanged(double missionMaxTelemetry);
void cruiseDistanceChanged(double cruiseDistance);
void hoverDistanceChanged(double hoverDistance);
+ void cruiseSpeedChanged(double cruiseSpeed);
+ void hoverSpeedChanged(double hoverSpeed);
private slots:
void _newMissionItemsAvailableFromVehicle();
@@ -123,7 +132,7 @@ private:
void _deinitVisualItem(VisualMissionItem* item);
void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle);
static void _calcPrevWaypointValues(double homeAlt, VisualMissionItem* currentItem, VisualMissionItem* prevItem, double* azimuth, double* distance, double* altDifference);
- static void _calcHomeDist(VisualMissionItem* currentItem, VisualMissionItem* homeItem, double* distance);
+ static double _calcDistanceToHome(VisualMissionItem* currentItem, VisualMissionItem* homeItem);
bool _findLastAltitude(double* lastAltitude, MAV_FRAME* frame);
bool _findLastAcceptanceRadius(double* lastAcceptanceRadius);
void _addPlannedHomePosition(QmlObjectListModel* visualItems, bool addToCenter);
@@ -134,6 +143,13 @@ private:
bool _loadJsonMissionFileV2(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString);
int _nextSequenceNumber(void);
+ void _setMissionDistance(double missionDistance);
+ void _setMissionTime(double missionTime);
+ void _setMissionHoverDistance(double missionHoverDistance);
+ void _setMissionHoverTime(double missionHoverTime);
+ void _setMissionCruiseDistance(double missionCruiseDistance);
+ void _setMissionCruiseTime(double missionCruiseTime);
+ void _setMissionMaxTelemetry(double missionMaxTelemetry);
// Overrides from PlanElementController
void _activeVehicleBeingRemoved(void) final;
@@ -148,13 +164,19 @@ private:
bool _missionItemsRequested;
bool _queuedSend;
double _missionDistance;
+ double _missionTime;
+ double _missionHoverDistance;
+ double _missionHoverTime;
+ double _missionCruiseDistance;
+ double _missionCruiseTime;
double _missionMaxTelemetry;
- double _cruiseDistance;
- double _hoverDistance;
static const char* _settingsGroup;
static const char* _jsonFileTypeValue;
static const char* _jsonFirmwareTypeKey;
+ static const char* _jsonVehicleTypeKey;
+ static const char* _jsonCruiseSpeedKey;
+ static const char* _jsonHoverSpeedKey;
static const char* _jsonItemsKey;
static const char* _jsonPlannedHomePositionKey;
static const char* _jsonParamsKey;
diff --git a/src/MissionManager/PlanElementController.cc b/src/MissionManager/PlanElementController.cc
index 1c4d7eba0ddeb2594a57de546fa28d1b41d93ac1..a904796dbd7d5d3eb44ccd2a26c4388ef3b152ed 100644
--- a/src/MissionManager/PlanElementController.cc
+++ b/src/MissionManager/PlanElementController.cc
@@ -54,4 +54,6 @@ void PlanElementController::_activeVehicleChanged(Vehicle* activeVehicle)
// Whenever vehicle changes we need to update syncInProgress
emit syncInProgressChanged(syncInProgress());
+
+ emit vehicleChanged(_activeVehicle);
}
diff --git a/src/MissionManager/PlanElementController.h b/src/MissionManager/PlanElementController.h
index b8ff725d629509b389009ad8df51e7e6909db0a3..a498d07d6c2fe0aaf5320dfae9cde2db70f3a193 100644
--- a/src/MissionManager/PlanElementController.h
+++ b/src/MissionManager/PlanElementController.h
@@ -35,6 +35,8 @@ public:
Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT)
virtual QString fileExtension(void) const = 0;
+ Q_PROPERTY(Vehicle* vehicle READ vehicle NOTIFY vehicleChanged)
+
/// Should be called immediately upon Component.onCompleted.
/// @param editMode true: controller being used in Plan view, false: controller being used in Fly view
Q_INVOKABLE virtual void start(bool editMode);
@@ -55,9 +57,12 @@ public:
virtual bool dirty (void) const = 0;
virtual void setDirty (bool dirty) = 0;
+ Vehicle* vehicle(void) { return _activeVehicle; }
+
signals:
void syncInProgressChanged (bool syncInProgress);
void dirtyChanged (bool dirty);
+ void vehicleChanged (Vehicle* vehicle);
protected:
MultiVehicleManager* _multiVehicleMgr;
diff --git a/src/MissionManager/SurveyMissionItem.cc b/src/MissionManager/SurveyMissionItem.cc
index 0c0a4ff18ad4e2850acd1af04f4218b4a37b0f5d..38ea5f11bcb711bd910d6c754f09694bc1f80a84 100644
--- a/src/MissionManager/SurveyMissionItem.cc
+++ b/src/MissionManager/SurveyMissionItem.cc
@@ -12,6 +12,7 @@
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
+#include "QGroundControlQmlGlobal.h"
#include
@@ -70,6 +71,7 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
, _surveyDistance(0.0)
, _cameraShots(0)
, _coveredArea(0.0)
+ , _timeBetweenShots(0.0)
, _gridAltitudeFact (0, _gridAltitudeFactName, FactMetaData::valueTypeDouble)
, _gridAngleFact (0, _gridAngleFactName, FactMetaData::valueTypeDouble)
, _gridSpacingFact (0, _gridSpacingFactName, FactMetaData::valueTypeDouble)
@@ -132,7 +134,11 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
connect(&_cameraResolutionHeightFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged);
connect(&_cameraFocalLengthFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged);
- connect(this, &SurveyMissionItem::cameraTriggerChanged, this, &SurveyMissionItem::_cameraTriggerChanged);
+ connect(this, &SurveyMissionItem::cameraTriggerChanged, this, &SurveyMissionItem::_cameraTriggerChanged);
+
+ connect(&_cameraTriggerDistanceFact, &Fact::valueChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
+ connect(_vehicle, &Vehicle::cruiseSpeedChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
+ connect(_vehicle, &Vehicle::hoverSpeedChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
}
void SurveyMissionItem::_setSurveyDistance(double surveyDistance)
@@ -780,6 +786,7 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
pMissionItems->append(item);
if (_cameraTrigger && i == 0) {
+ // Turn on camera
MissionItem* item = new MissionItem(seqNum++, // sequence number
MAV_CMD_DO_SET_CAM_TRIGG_DIST, // MAV_CMD
MAV_FRAME_MISSION, // MAV_FRAME
@@ -793,6 +800,7 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
}
if (_cameraTrigger) {
+ // Turn off camera
MissionItem* item = new MissionItem(seqNum++, // sequence number
MAV_CMD_DO_SET_CAM_TRIGG_DIST, // MAV_CMD
MAV_FRAME_MISSION, // MAV_FRAME
@@ -810,10 +818,9 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
void SurveyMissionItem::_cameraTriggerChanged(void)
{
setDirty(true);
- if (_gridPoints.count()) {
- // If we have grid turn on/off camera trigger will add/remove two camera trigger mission items
- emit lastSequenceNumberChanged(lastSequenceNumber());
- }
+ // Camera trigger adds items
+ emit lastSequenceNumberChanged(lastSequenceNumber());
+ // We now have camera shot count
emit cameraShotsChanged(cameraShots());
}
@@ -826,3 +833,16 @@ void SurveyMissionItem::_cameraValueChanged(void)
{
emit cameraValueChanged();
}
+
+double SurveyMissionItem::timeBetweenShots(void) const
+{
+ return _cruiseSpeed == 0 ? 0 : _cameraTriggerDistanceFact.rawValue().toDouble() / _cruiseSpeed;
+}
+
+void SurveyMissionItem::setCruiseSpeed(double cruiseSpeed)
+{
+ if (!qFuzzyCompare(_cruiseSpeed, cruiseSpeed)) {
+ _cruiseSpeed = cruiseSpeed;
+ emit timeBetweenShotsChanged();
+ }
+}
diff --git a/src/MissionManager/SurveyMissionItem.h b/src/MissionManager/SurveyMissionItem.h
index aeb13a15b119d1e909a7e82f12e90d6818ba7035..d00974e77f2786fd428caf8f74fb42cae3620c9f 100644
--- a/src/MissionManager/SurveyMissionItem.h
+++ b/src/MissionManager/SurveyMissionItem.h
@@ -48,6 +48,7 @@ public:
Q_PROPERTY(bool cameraOrientationLandscape MEMBER _cameraOrientationLandscape NOTIFY cameraOrientationLandscapeChanged)
Q_PROPERTY(bool manualGrid MEMBER _manualGrid NOTIFY manualGridChanged)
Q_PROPERTY(QString camera MEMBER _camera NOTIFY cameraChanged)
+ Q_PROPERTY(double timeBetweenShots READ timeBetweenShots NOTIFY timeBetweenShotsChanged)
Q_INVOKABLE void clearPolygon(void);
Q_INVOKABLE void addPolygonCoordinate(const QGeoCoordinate coordinate);
@@ -72,6 +73,7 @@ public:
int cameraShots(void) const;
double coveredArea(void) const { return _coveredArea; }
+ double timeBetweenShots(void) const;
// Overrides from ComplexMissionItem
@@ -80,6 +82,8 @@ public:
QmlObjectListModel* getMissionItems (void) const final;
bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final;
double greatestDistanceTo (const QGeoCoordinate &other) const final;
+ void setCruiseSpeed (double cruiseSpeed) final;
+
// Overrides from VisualMissionItem
@@ -121,6 +125,7 @@ signals:
void cameraOrientationLandscapeChanged (bool cameraOrientationLandscape);
void cameraChanged (QString camera);
void manualGridChanged (bool manualGrid);
+ void timeBetweenShotsChanged (void);
private slots:
void _cameraTriggerChanged(void);
@@ -158,6 +163,8 @@ private:
double _surveyDistance;
int _cameraShots;
double _coveredArea;
+ double _timeBetweenShots;
+ double _cruiseSpeed;
Fact _gridAltitudeFact;
Fact _gridAngleFact;
@@ -198,7 +205,6 @@ private:
static const char* _jsonCameraOrientationLandscapeKey;
static const char* _jsonFixedValueIsAltitudeKey;
-
static const char* _gridAltitudeFactName;
static const char* _gridAngleFactName;
static const char* _gridSpacingFactName;
diff --git a/src/QmlControls/QGroundControlQmlGlobal.json b/src/QmlControls/QGroundControlQmlGlobal.json
index f32ee0b637d55d227731d1a01f5e3dfa4033074e..f48c1b2a1c49586d069a7f8cfc81cfc71ebb0f9f 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.json
+++ b/src/QmlControls/QGroundControlQmlGlobal.json
@@ -3,7 +3,7 @@
"name": "OfflineEditingFirmwareType",
"shortDescription": "Offline editing firmware type",
"type": "uint32",
- "enumStrings": "ArduPilot Firmware,PX4 Pro Firmware,Mavlink Generic Firmware",
+ "enumStrings": "ArduPilot,PX4 Pro,Mavlink Generic",
"enumValues": "3,12,0",
"defaultValue": 3
},
@@ -11,7 +11,7 @@
"name": "OfflineEditingVehicleType",
"shortDescription": "Offline editing vehicle type",
"type": "uint32",
- "enumStrings": "Fixedwing,Multicopter,VTOL,Rover,Sub",
+ "enumStrings": "Fixed Wing,Multi-Rotor,VTOL,Rover,Sub",
"enumValues": "1,2,19,10,12",
"defaultValue": 1
},
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 9b3bc66beeeba5f2d5675082b9f9f27a88e1b403..1ce4132580dac51c3483bae1a240366930ec793d 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -96,6 +96,8 @@ Vehicle::Vehicle(LinkInterface* link,
, _onboardControlSensorsUnhealthy(0)
, _gpsRawIntMessageAvailable(false)
, _globalPositionIntMessageAvailable(false)
+ , _cruiseSpeed(QGroundControlQmlGlobal::offlineEditingCruiseSpeed()->rawValue().toDouble())
+ , _hoverSpeed(QGroundControlQmlGlobal::offlineEditingHoverSpeed()->rawValue().toDouble())
, _connectionLost(false)
, _connectionLostEnabled(true)
, _missionManager(NULL)
@@ -150,7 +152,7 @@ Vehicle::Vehicle(LinkInterface* link,
connect(_uas, &UAS::imageReady, this, &Vehicle::_imageReady);
connect(this, &Vehicle::remoteControlRSSIChanged, this, &Vehicle::_remoteControlRSSIChanged);
- _firmwarePlugin = _firmwarePluginManager->firmwarePluginForAutopilot(_firmwareType, _vehicleType);
+ _commonInit();
_autopilotPlugin = _firmwarePlugin->autopilotPlugin(this);
// connect this vehicle to the follow me handle manager
@@ -183,21 +185,6 @@ Vehicle::Vehicle(LinkInterface* link,
_loadSettings();
- _missionManager = new MissionManager(this);
- connect(_missionManager, &MissionManager::error, this, &Vehicle::_missionManagerError);
- connect(_missionManager, &MissionManager::newMissionItemsAvailable, this, &Vehicle::_newMissionItemsAvailable);
-
- _parameterManager = new ParameterManager(this);
- connect(_parameterManager, &ParameterManager::parametersReadyChanged, this, &Vehicle::_parametersReady);
-
- // GeoFenceManager needs to access ParameterManager so make sure to create after
- _geoFenceManager = _firmwarePlugin->newGeoFenceManager(this);
- connect(_geoFenceManager, &GeoFenceManager::error, this, &Vehicle::_geoFenceManagerError);
- connect(_geoFenceManager, &GeoFenceManager::loadComplete, this, &Vehicle::_newGeoFenceAvailable);
-
- _rallyPointManager = _firmwarePlugin->newRallyPointManager(this);
- connect(_rallyPointManager, &RallyPointManager::error, this, &Vehicle::_rallyPointManagerError);
-
// Ask the vehicle for firmware version info.
sendMavCommand(MAV_COMP_ID_ALL, // Don't know default component id yet.
MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES,
@@ -214,27 +201,6 @@ Vehicle::Vehicle(LinkInterface* link,
// Invalidate the timer to signal first announce
_lowBatteryAnnounceTimer.invalidate();
-
- // Build FactGroup object model
-
- _addFact(&_rollFact, _rollFactName);
- _addFact(&_pitchFact, _pitchFactName);
- _addFact(&_headingFact, _headingFactName);
- _addFact(&_groundSpeedFact, _groundSpeedFactName);
- _addFact(&_airSpeedFact, _airSpeedFactName);
- _addFact(&_climbRateFact, _climbRateFactName);
- _addFact(&_altitudeRelativeFact, _altitudeRelativeFactName);
- _addFact(&_altitudeAMSLFact, _altitudeAMSLFactName);
-
- _addFactGroup(&_gpsFactGroup, _gpsFactGroupName);
- _addFactGroup(&_batteryFactGroup, _batteryFactGroupName);
- _addFactGroup(&_windFactGroup, _windFactGroupName);
- _addFactGroup(&_vibrationFactGroup, _vibrationFactGroupName);
-
- _gpsFactGroup.setVehicle(this);
- _batteryFactGroup.setVehicle(this);
- _windFactGroup.setVehicle(this);
- _vibrationFactGroup.setVehicle(this);
}
// Disconnected Vehicle for offline editing
@@ -275,6 +241,8 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType,
, _onboardControlSensorsUnhealthy(0)
, _gpsRawIntMessageAvailable(false)
, _globalPositionIntMessageAvailable(false)
+ , _cruiseSpeed(QGroundControlQmlGlobal::offlineEditingCruiseSpeed()->rawValue().toDouble())
+ , _hoverSpeed(QGroundControlQmlGlobal::offlineEditingHoverSpeed()->rawValue().toDouble())
, _connectionLost(false)
, _connectionLostEnabled(true)
, _missionManager(NULL)
@@ -314,8 +282,13 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType,
, _windFactGroup(this)
, _vibrationFactGroup(this)
{
- _firmwarePlugin = _firmwarePluginManager->firmwarePluginForAutopilot(_firmwareType, _vehicleType);
+ _commonInit();
_firmwarePlugin->initializeVehicle(this);
+}
+
+void Vehicle::_commonInit(void)
+{
+ _firmwarePlugin = _firmwarePluginManager->firmwarePluginForAutopilot(_firmwareType, _vehicleType);
_missionManager = new MissionManager(this);
connect(_missionManager, &MissionManager::error, this, &Vehicle::_missionManagerError);
@@ -329,6 +302,12 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType,
_rallyPointManager = _firmwarePlugin->newRallyPointManager(this);
connect(_rallyPointManager, &RallyPointManager::error, this, &Vehicle::_rallyPointManagerError);
+ // Offline editing vehicle tracks settings changes for offline editing settings
+ connect(QGroundControlQmlGlobal::offlineEditingFirmwareType(), &Fact::rawValueChanged, this, &Vehicle::_offlineFirmwareTypeSettingChanged);
+ connect(QGroundControlQmlGlobal::offlineEditingVehicleType(), &Fact::rawValueChanged, this, &Vehicle::_offlineVehicleTypeSettingChanged);
+ connect(QGroundControlQmlGlobal::offlineEditingCruiseSpeed(), &Fact::rawValueChanged, this, &Vehicle::_offlineCruiseSpeedSettingChanged);
+ connect(QGroundControlQmlGlobal::offlineEditingHoverSpeed(), &Fact::rawValueChanged, this, &Vehicle::_offlineHoverSpeedSettingChanged);
+
// Build FactGroup object model
_addFact(&_rollFact, _rollFactName);
@@ -344,11 +323,6 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType,
_addFactGroup(&_batteryFactGroup, _batteryFactGroupName);
_addFactGroup(&_windFactGroup, _windFactGroupName);
_addFactGroup(&_vibrationFactGroup, _vibrationFactGroupName);
-
- _gpsFactGroup.setVehicle(NULL);
- _batteryFactGroup.setVehicle(NULL);
- _windFactGroup.setVehicle(NULL);
- _vibrationFactGroup.setVehicle(NULL);
}
Vehicle::~Vehicle()
@@ -366,8 +340,59 @@ Vehicle::~Vehicle()
}
-void
-Vehicle::resetCounters()
+void Vehicle::_offlineFirmwareTypeSettingChanged(QVariant value)
+{
+ _firmwareType = static_cast(value.toInt());
+ emit firmwareTypeChanged();
+}
+
+void Vehicle::_offlineVehicleTypeSettingChanged(QVariant value)
+{
+ _vehicleType = static_cast(value.toInt());
+ emit vehicleTypeChanged();
+}
+
+void Vehicle::_offlineCruiseSpeedSettingChanged(QVariant value)
+{
+ _cruiseSpeed = value.toDouble();
+ emit cruiseSpeedChanged(_cruiseSpeed);
+}
+
+void Vehicle::_offlineHoverSpeedSettingChanged(QVariant value)
+{
+ _hoverSpeed = value.toDouble();
+ emit hoverSpeedChanged(_hoverSpeed);
+}
+
+QString Vehicle::firmwareTypeString(void) const
+{
+ if (px4Firmware()) {
+ return QStringLiteral("PX4 Pro");
+ } else if (apmFirmware()) {
+ return QStringLiteral("ArduPilot");
+ } else {
+ return tr("MAVLink Generic");
+ }
+}
+
+QString Vehicle::vehicleTypeString(void) const
+{
+ if (fixedWing()) {
+ return tr("Fixed Wing");
+ } else if (multiRotor()) {
+ return tr("Multi-Rotor");
+ } else if (vtol()) {
+ return tr("VTOL");
+ } else if (rover()) {
+ return tr("Rover");
+ } else if (sub()) {
+ return tr("Sub");
+ } else {
+ return tr("Unknown");
+ }
+}
+
+void Vehicle::resetCounters()
{
_messagesReceived = 0;
_messagesSent = 0;
@@ -2084,7 +2109,6 @@ const char* VehicleGPSFactGroup::_lockFactName = "lock";
VehicleGPSFactGroup::VehicleGPSFactGroup(QObject* parent)
: FactGroup(1000, ":/json/Vehicle/GPSFact.json", parent)
- , _vehicle(NULL)
, _hdopFact (0, _hdopFactName, FactMetaData::valueTypeDouble)
, _vdopFact (0, _vdopFactName, FactMetaData::valueTypeDouble)
, _courseOverGroundFact (0, _courseOverGroundFactName, FactMetaData::valueTypeDouble)
@@ -2169,11 +2193,6 @@ QString Vehicle::takeControlFlightMode(void) const
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-void VehicleGPSFactGroup::setVehicle(Vehicle* vehicle)
-{
- _vehicle = vehicle;
-}
-
const char* VehicleBatteryFactGroup::_voltageFactName = "voltage";
const char* VehicleBatteryFactGroup::_percentRemainingFactName = "percentRemaining";
const char* VehicleBatteryFactGroup::_mahConsumedFactName = "mahConsumed";
@@ -2192,7 +2211,6 @@ const int VehicleBatteryFactGroup::_cellCountUnavailable = -1.0;
VehicleBatteryFactGroup::VehicleBatteryFactGroup(QObject* parent)
: FactGroup(1000, ":/json/Vehicle/BatteryFact.json", parent)
- , _vehicle(NULL)
, _voltageFact (0, _voltageFactName, FactMetaData::valueTypeDouble)
, _percentRemainingFact (0, _percentRemainingFactName, FactMetaData::valueTypeInt32)
, _mahConsumedFact (0, _mahConsumedFactName, FactMetaData::valueTypeInt32)
@@ -2216,18 +2234,12 @@ VehicleBatteryFactGroup::VehicleBatteryFactGroup(QObject* parent)
_cellCountFact.setRawValue (_cellCountUnavailable);
}
-void VehicleBatteryFactGroup::setVehicle(Vehicle* vehicle)
-{
- _vehicle = vehicle;
-}
-
const char* VehicleWindFactGroup::_directionFactName = "direction";
const char* VehicleWindFactGroup::_speedFactName = "speed";
const char* VehicleWindFactGroup::_verticalSpeedFactName = "verticalSpeed";
VehicleWindFactGroup::VehicleWindFactGroup(QObject* parent)
: FactGroup(1000, ":/json/Vehicle/WindFact.json", parent)
- , _vehicle(NULL)
, _directionFact (0, _directionFactName, FactMetaData::valueTypeDouble)
, _speedFact (0, _speedFactName, FactMetaData::valueTypeDouble)
, _verticalSpeedFact(0, _verticalSpeedFactName, FactMetaData::valueTypeDouble)
@@ -2242,11 +2254,6 @@ VehicleWindFactGroup::VehicleWindFactGroup(QObject* parent)
_verticalSpeedFact.setRawValue (std::numeric_limits::quiet_NaN());
}
-void VehicleWindFactGroup::setVehicle(Vehicle* vehicle)
-{
- _vehicle = vehicle;
-}
-
const char* VehicleVibrationFactGroup::_xAxisFactName = "xAxis";
const char* VehicleVibrationFactGroup::_yAxisFactName = "yAxis";
const char* VehicleVibrationFactGroup::_zAxisFactName = "zAxis";
@@ -2256,7 +2263,6 @@ const char* VehicleVibrationFactGroup::_clipCount3FactName = "clipCount3";
VehicleVibrationFactGroup::VehicleVibrationFactGroup(QObject* parent)
: FactGroup(1000, ":/json/Vehicle/VibrationFact.json", parent)
- , _vehicle(NULL)
, _xAxisFact (0, _xAxisFactName, FactMetaData::valueTypeDouble)
, _yAxisFact (0, _yAxisFactName, FactMetaData::valueTypeDouble)
, _zAxisFact (0, _zAxisFactName, FactMetaData::valueTypeDouble)
@@ -2276,8 +2282,3 @@ VehicleVibrationFactGroup::VehicleVibrationFactGroup(QObject* parent)
_yAxisFact.setRawValue(std::numeric_limits::quiet_NaN());
_zAxisFact.setRawValue(std::numeric_limits::quiet_NaN());
}
-
-void VehicleVibrationFactGroup::setVehicle(Vehicle* vehicle)
-{
- _vehicle = vehicle;
-}
diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h
index ff299e3486580f94310af971039f12b4c87404ce..c9d2c01140dc14871dfec21d9502cc1b375f12d2 100644
--- a/src/Vehicle/Vehicle.h
+++ b/src/Vehicle/Vehicle.h
@@ -63,8 +63,6 @@ public:
Fact* clipCount2 (void) { return &_clipCount2Fact; }
Fact* clipCount3 (void) { return &_clipCount3Fact; }
- void setVehicle(Vehicle* vehicle);
-
static const char* _xAxisFactName;
static const char* _yAxisFactName;
static const char* _zAxisFactName;
@@ -73,7 +71,6 @@ public:
static const char* _clipCount3FactName;
private:
- Vehicle* _vehicle;
Fact _xAxisFact;
Fact _yAxisFact;
Fact _zAxisFact;
@@ -97,14 +94,11 @@ public:
Fact* speed (void) { return &_speedFact; }
Fact* verticalSpeed (void) { return &_verticalSpeedFact; }
- void setVehicle(Vehicle* vehicle);
-
static const char* _directionFactName;
static const char* _speedFactName;
static const char* _verticalSpeedFactName;
private:
- Vehicle* _vehicle;
Fact _directionFact;
Fact _speedFact;
Fact _verticalSpeedFact;
@@ -129,8 +123,6 @@ public:
Fact* count (void) { return &_countFact; }
Fact* lock (void) { return &_lockFact; }
- void setVehicle(Vehicle* vehicle);
-
static const char* _hdopFactName;
static const char* _vdopFactName;
static const char* _courseOverGroundFactName;
@@ -138,7 +130,6 @@ public:
static const char* _lockFactName;
private:
- Vehicle* _vehicle;
Fact _hdopFact;
Fact _vdopFact;
Fact _courseOverGroundFact;
@@ -168,8 +159,6 @@ public:
Fact* cellCount (void) { return &_cellCountFact; }
- void setVehicle(Vehicle* vehicle);
-
static const char* _voltageFactName;
static const char* _percentRemainingFactName;
static const char* _mahConsumedFactName;
@@ -187,7 +176,6 @@ public:
static const int _cellCountUnavailable;
private:
- Vehicle* _vehicle;
Fact _voltageFact;
Fact _percentRemainingFact;
Fact _mahConsumedFact;
@@ -245,8 +233,8 @@ public:
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
Q_PROPERTY(int flowImageIndex READ flowImageIndex NOTIFY flowImageIndexChanged)
Q_PROPERTY(int rcRSSI READ rcRSSI NOTIFY rcRSSIChanged)
- Q_PROPERTY(bool px4Firmware READ px4Firmware CONSTANT)
- Q_PROPERTY(bool apmFirmware READ apmFirmware CONSTANT)
+ Q_PROPERTY(bool px4Firmware READ px4Firmware NOTIFY firmwareTypeChanged)
+ Q_PROPERTY(bool apmFirmware READ apmFirmware NOTIFY firmwareTypeChanged)
Q_PROPERTY(bool soloFirmware READ soloFirmware WRITE setSoloFirmware NOTIFY soloFirmwareChanged)
Q_PROPERTY(bool genericFirmware READ genericFirmware CONSTANT)
Q_PROPERTY(bool connectionLost READ connectionLost NOTIFY connectionLostChanged)
@@ -254,26 +242,28 @@ public:
Q_PROPERTY(uint messagesReceived READ messagesReceived NOTIFY messagesReceivedChanged)
Q_PROPERTY(uint messagesSent READ messagesSent NOTIFY messagesSentChanged)
Q_PROPERTY(uint messagesLost READ messagesLost NOTIFY messagesLostChanged)
- Q_PROPERTY(bool fixedWing READ fixedWing CONSTANT)
- Q_PROPERTY(bool multiRotor READ multiRotor CONSTANT)
- Q_PROPERTY(bool vtol READ vtol CONSTANT)
- Q_PROPERTY(bool rover READ rover CONSTANT)
+ Q_PROPERTY(bool fixedWing READ fixedWing NOTIFY vehicleTypeChanged)
+ Q_PROPERTY(bool multiRotor READ multiRotor NOTIFY vehicleTypeChanged)
+ Q_PROPERTY(bool vtol READ vtol NOTIFY vehicleTypeChanged)
+ Q_PROPERTY(bool rover READ rover NOTIFY vehicleTypeChanged)
+ Q_PROPERTY(bool sub READ sub NOTIFY vehicleTypeChanged)
Q_PROPERTY(bool supportsManualControl READ supportsManualControl CONSTANT)
Q_PROPERTY(bool supportsThrottleModeCenterZero READ supportsThrottleModeCenterZero CONSTANT)
Q_PROPERTY(bool supportsJSButton READ supportsJSButton CONSTANT)
Q_PROPERTY(bool supportsRadio READ supportsRadio CONSTANT)
- Q_PROPERTY(bool sub READ sub CONSTANT)
Q_PROPERTY(bool autoDisconnect MEMBER _autoDisconnect NOTIFY autoDisconnectChanged)
Q_PROPERTY(QString prearmError READ prearmError WRITE setPrearmError NOTIFY prearmErrorChanged)
Q_PROPERTY(int motorCount READ motorCount CONSTANT)
Q_PROPERTY(bool coaxialMotors READ coaxialMotors CONSTANT)
Q_PROPERTY(bool xConfigMotors READ xConfigMotors CONSTANT)
Q_PROPERTY(bool isOfflineEditingVehicle READ isOfflineEditingVehicle CONSTANT)
- Q_PROPERTY(QString brandImage READ brandImage CONSTANT)
+ Q_PROPERTY(QString brandImage READ brandImage NOTIFY firmwareTypeChanged)
Q_PROPERTY(QStringList unhealthySensors READ unhealthySensors NOTIFY unhealthySensorsChanged)
Q_PROPERTY(QString missionFlightMode READ missionFlightMode CONSTANT)
Q_PROPERTY(QString rtlFlightMode READ rtlFlightMode CONSTANT)
Q_PROPERTY(QString takeControlFlightMode READ takeControlFlightMode CONSTANT)
+ Q_PROPERTY(QString firmwareTypeString READ firmwareTypeString NOTIFY firmwareTypeChanged)
+ Q_PROPERTY(QString vehicleTypeString READ vehicleTypeString NOTIFY vehicleTypeChanged)
/// true: Vehicle is flying, false: Vehicle is on ground
Q_PROPERTY(bool flying READ flying WRITE setFlying NOTIFY flyingChanged)
@@ -528,6 +518,10 @@ public:
QString missionFlightMode () const;
QString rtlFlightMode () const;
QString takeControlFlightMode () const;
+ double cruiseSpeed () const { return _cruiseSpeed; }
+ double hoverSpeed () const { return _hoverSpeed; }
+ QString firmwareTypeString () const;
+ QString vehicleTypeString () const;
Fact* roll (void) { return &_rollFact; }
Fact* heading (void) { return &_headingFact; }
@@ -615,6 +609,10 @@ signals:
void prearmErrorChanged(const QString& prearmError);
void soloFirmwareChanged(bool soloFirmware);
void unhealthySensorsChanged(void);
+ void cruiseSpeedChanged(double cruiseSpeed);
+ void hoverSpeedChanged(double hoverSpeed);
+ void firmwareTypeChanged(void);
+ void vehicleTypeChanged(void);
void messagesReceivedChanged ();
void messagesSentChanged ();
@@ -673,6 +671,10 @@ private slots:
void _remoteControlRSSIChanged(uint8_t rssi);
void _handleFlightModeChanged(const QString& flightMode);
void _announceArmedChanged(bool armed);
+ void _offlineFirmwareTypeSettingChanged(QVariant value);
+ void _offlineVehicleTypeSettingChanged(QVariant value);
+ void _offlineCruiseSpeedSettingChanged(QVariant value);
+ void _offlineHoverSpeedSettingChanged(QVariant value);
void _handleTextMessage (int newCount);
void _handletextMessageReceived (UASMessage* message);
@@ -724,8 +726,8 @@ private:
void _ackMavlinkLogData(uint16_t sequence);
void _sendNextQueuedMavCommand(void);
void _updatePriorityLink(void);
+ void _commonInit(void);
-private:
int _id; ///< Mavlink system id
bool _active;
bool _offlineEditingVehicle; ///< This Vehicle is a "disconnected" vehicle for ui use while offline editing
@@ -771,6 +773,8 @@ private:
uint32_t _onboardControlSensorsUnhealthy;
bool _gpsRawIntMessageAvailable;
bool _globalPositionIntMessageAvailable;
+ double _cruiseSpeed;
+ double _hoverSpeed;
typedef struct {
int component;
diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml
index d1975d18954427778779c5d202732c1382d31479..d22c60515f9f0d90a9149d5afaf0bb93d406c505 100644
--- a/src/ui/preferences/GeneralSettings.qml
+++ b/src/ui/preferences/GeneralSettings.qml
@@ -13,6 +13,7 @@ import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.1
import QtMultimedia 5.5
+import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.FactSystem 1.0
@@ -33,6 +34,10 @@ QGCView {
property Fact _percentRemainingAnnounce: QGroundControl.batteryPercentRemainingAnnounce
property real _labelWidth: ScreenTools.defaultFontPixelWidth * 15
property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30
+ property bool _showCruiseSpeed: offlineVehicleCombo.currentText != "Multicopter"
+ property bool _showHoverSpeed: offlineVehicleCombo.currentText != "FixedWing"
+
+ readonly property string _requiresRestart: qsTr("(Requires Restart)")
QGCPalette { id: qgcPal }
@@ -117,90 +122,6 @@ QGCView {
}
}
//-----------------------------------------------------------------
- //-- Offline mission editing
- Item {
- width: qgcView.width * 0.8
- height: offlineLabel.height
- anchors.margins: ScreenTools.defaultFontPixelWidth
- anchors.horizontalCenter: parent.horizontalCenter
- QGCLabel {
- id: offlineLabel
- text: qsTr("Offline Mission Editing (Requires Restart)")
- font.family: ScreenTools.demiboldFontFamily
- }
- }
- Rectangle {
- height: offlineCol.height + (ScreenTools.defaultFontPixelHeight * 2)
- width: qgcView.width * 0.8
- color: qgcPal.windowShade
- anchors.margins: ScreenTools.defaultFontPixelWidth
- anchors.horizontalCenter: parent.horizontalCenter
- Column {
- id: offlineCol
- spacing: ScreenTools.defaultFontPixelWidth
- anchors.centerIn: parent
- Row {
- spacing: ScreenTools.defaultFontPixelWidth
- QGCLabel {
- text: qsTr("Firmware:")
- width: _labelWidth
- anchors.baseline: offlineTypeCombo.baseline
- }
- FactComboBox {
- id: offlineTypeCombo
- width: _editFieldWidth
- fact: QGroundControl.offlineEditingFirmwareType
- indexModel: false
- }
- }
- Row {
- spacing: ScreenTools.defaultFontPixelWidth
- QGCLabel {
- text: qsTr("Vehicle:")
- width: _labelWidth
- anchors.baseline: offlineVehicleCombo.baseline
- }
- FactComboBox {
- id: offlineVehicleCombo
- width: _editFieldWidth
- fact: QGroundControl.offlineEditingVehicleType
- indexModel: false
- }
- }
- Row {
- spacing: ScreenTools.defaultFontPixelWidth
- visible: offlineVehicleCombo.currentText != "Multicopter"
- QGCLabel {
- text: qsTr("Cruise speed:")
- width: _labelWidth
- anchors.baseline: cruiseSpeedField.baseline
- }
- FactTextField {
- id: cruiseSpeedField
- width: _editFieldWidth
- fact: QGroundControl.offlineEditingCruiseSpeed
- enabled: true
- }
- }
- Row {
- spacing: ScreenTools.defaultFontPixelWidth
- visible: offlineVehicleCombo.currentText != "Fixedwing"
- QGCLabel {
- id: hoverSpeedLabel
- text: qsTr("Hover speed:")
- width: _labelWidth
- anchors.baseline: hoverSpeedField.baseline
- }
- FactTextField {
- id: hoverSpeedField
- width: _editFieldWidth
- fact: QGroundControl.offlineEditingHoverSpeed
- enabled: true
- }
- }
- }
- }
- //-----------------------------------------------------------------
//-- Miscelanous
Item {
width: qgcView.width * 0.8
@@ -274,7 +195,7 @@ QGCView {
}
QGCLabel {
anchors.verticalCenter: parent.verticalCenter
- text: qsTr("(Requires Restart)")
+ text: _requiresRestart
}
}
//-----------------------------------------------------------------