diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 3ef7283da447d73ac6dd53e2be04ad99d929f42d..02a09e8e130fc980b5c65635c9c0393df96e43ff 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -429,6 +429,7 @@ HEADERS += \ src/LogCompressor.h \ src/MG.h \ src/MissionManager/ComplexMissionItem.h \ + src/MissionManager/FixedWingLandingComplexItem.h \ src/MissionManager/GeoFenceController.h \ src/MissionManager/GeoFenceManager.h \ src/MissionManager/MissionCommandList.h \ @@ -592,6 +593,7 @@ SOURCES += \ src/JsonHelper.cc \ src/LogCompressor.cc \ src/MissionManager/ComplexMissionItem.cc \ + src/MissionManager/FixedWingLandingComplexItem.cc \ src/MissionManager/GeoFenceController.cc \ src/MissionManager/GeoFenceManager.cc \ src/MissionManager/MissionCommandList.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 9fe698a3fc06e95b985471a41fd3c0f7956a369a..aae4d36b5adefed132d7473dc683062b7a53977c 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -149,6 +149,7 @@ src/VehicleSetup/SetupView.qml src/MissionEditor/SimpleItemEditor.qml src/MissionEditor/SurveyItemEditor.qml + src/MissionEditor/FWLandingPatternEditor.qml src/ui/preferences/TcpSettings.qml src/test.qml src/ui/preferences/UdpSettings.qml @@ -169,6 +170,7 @@ src/Vehicle/VibrationFact.json src/QmlControls/QGroundControlQmlGlobal.json src/MissionManager/RallyPoint.FactMetaData.json + src/MissionManager/FWLandingPattern.FactMetaData.json src/MissionManager/Survey.FactMetaData.json src/comm/USBBoardInfo.json diff --git a/src/MissionEditor/FWLandingPatternEditor.qml b/src/MissionEditor/FWLandingPatternEditor.qml new file mode 100644 index 0000000000000000000000000000000000000000..e30049adef473ceea47a035eb7bcc0a17e2b6326 --- /dev/null +++ b/src/MissionEditor/FWLandingPatternEditor.qml @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 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 Fixed Wing Landing Pattern complex mission item +Rectangle { + id: _root + height: visible ? (editorColumn.height + (_margin * 2)) : 0 + width: availableWidth + color: qgcPal.windowShadeDark + radius: _radius + + // The following properties must be available up the hierarchy chain + //property real availableWidth ///< Width for control + //property var missionItem ///< Mission Item for editor + + property real _margin: ScreenTools.defaultFontPixelWidth * 0.25 + + Column { + id: editorColumn + + QGCLabel { text: "WIP" } + } +} diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml index 1389766e2bbf81082a7e4e6ec57a7522b6b863d3..a71ce19d61265d28eda225c878b7088146056547 100644 --- a/src/MissionEditor/MissionEditor.qml +++ b/src/MissionEditor/MissionEditor.qml @@ -89,15 +89,6 @@ QGCView { } } - function addSurveyItem() { - var coordinate = editorMap.center - coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) - coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces) - coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces) - var sequenceNumber = missionController.insertComplexMissionItem(coordinate, missionController.visualItems.count) - setCurrentItem(sequenceNumber) - } - MapFitFunctions { id: mapFitFunctions map: editorMap @@ -877,8 +868,9 @@ QGCView { toggle: true }, { - name: "Pattern", - iconSource: "/qmlimages/MapDrawShape.svg" + name: "Pattern", + iconSource: "/qmlimages/MapDrawShape.svg", + dropPanelComponent: patternDropPanel }, { name: "Sync", @@ -899,13 +891,8 @@ QGCView { ] onClicked: { - switch (index) { - case 0: + if (index == 0) { _addWaypointOnClick = checked - break - case 1: - addSurveyItem() - break } } } @@ -1084,6 +1071,7 @@ QGCView { checked: QGroundControl.flightMapSettings.mapType === text text: modelData exclusiveGroup: _mapTypeButtonsExclusiveGroup + onClicked: { QGroundControl.flightMapSettings.mapType = text dropPanel.hide() @@ -1093,4 +1081,33 @@ QGCView { } } } + + Component { + id: patternDropPanel + + ColumnLayout { + spacing: ScreenTools.defaultFontPixelWidth * 0.5 + + QGCLabel { text: qsTr("Create complex pattern:") } + + Repeater { + model: missionController.complexMissionItemNames + + QGCButton { + text: modelData + Layout.fillWidth: true + + onClicked: { + var coordinate = editorMap.center + coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) + coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces) + coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces) + var sequenceNumber = missionController.insertComplexMissionItem(modelData, coordinate, missionController.visualItems.count) + setCurrentItem(sequenceNumber) + dropPanel.hide() + } + } + } + } // Column + } } // QGCVIew diff --git a/src/MissionEditor/MissionItemEditor.qml b/src/MissionEditor/MissionItemEditor.qml index e9f4797ff0e58228be5fe57a42f43c7f187b13e1..25b68ffe36b785d7befb7ca140d5616c7823de09 100644 --- a/src/MissionEditor/MissionItemEditor.qml +++ b/src/MissionEditor/MissionItemEditor.qml @@ -141,9 +141,7 @@ Rectangle { anchors.fill: commandPicker visible: missionItem.sequenceNumber == 0 || !missionItem.isCurrentItem || !missionItem.isSimpleItem verticalAlignment: Text.AlignVCenter - text: missionItem.sequenceNumber == 0 ? - qsTr("Mission Settings") : - (missionItem.isSimpleItem ? missionItem.commandName : qsTr("Survey")) + text: missionItem.sequenceNumber == 0 ? qsTr("Mission Settings") : missionItem.commandName color: _outerTextColor } @@ -154,7 +152,7 @@ Rectangle { anchors.left: parent.left anchors.top: commandPicker.bottom height: item ? item.height : 0 - source: missionItem.sequenceNumber == 0 ? "qrc:/qml/MissionSettingsEditor.qml" : (missionItem.isSimpleItem ? "qrc:/qml/SimpleItemEditor.qml" : "qrc:/qml/SurveyItemEditor.qml") + source: missionItem.sequenceNumber == 0 ? "qrc:/qml/MissionSettingsEditor.qml" : missionItem.editorQml onLoaded: { item.visible = Qt.binding(function() { return _currentItem; }) diff --git a/src/MissionManager/FWLandingPattern.FactMetaData.json b/src/MissionManager/FWLandingPattern.FactMetaData.json new file mode 100644 index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380 --- /dev/null +++ b/src/MissionManager/FWLandingPattern.FactMetaData.json @@ -0,0 +1,2 @@ +[ +] diff --git a/src/MissionManager/FixedWingLandingComplexItem.cc b/src/MissionManager/FixedWingLandingComplexItem.cc new file mode 100644 index 0000000000000000000000000000000000000000..55fd5dfb70a958f487fb381a6aeaef61dc356885 --- /dev/null +++ b/src/MissionManager/FixedWingLandingComplexItem.cc @@ -0,0 +1,182 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "FixedWingLandingComplexItem.h" +#include "JsonHelper.h" +#include "MissionController.h" +#include "QGCGeo.h" +#include "QGroundControlQmlGlobal.h" + +#include + +QGC_LOGGING_CATEGORY(FixedWingLandingComplexItemLog, "FixedWingLandingComplexItemLog") + +const char* FixedWingLandingComplexItem::jsonComplexItemTypeValue = "fwLandingPattern"; + +QMap FixedWingLandingComplexItem::_metaDataMap; + +FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, QObject* parent) + : ComplexMissionItem(vehicle, parent) + , _sequenceNumber(0) + , _dirty(false) +{ + _editorQml = "qrc:/qml/FWLandingPatternEditor.qml"; + + if (_metaDataMap.isEmpty()) { + _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/FWLandingPattern.FactMetaData.json"), NULL /* metaDataParent */); + } +} + +int FixedWingLandingComplexItem::lastSequenceNumber(void) const +{ + return _sequenceNumber; +} + +void FixedWingLandingComplexItem::setCoordinate(const QGeoCoordinate& coordinate) +{ + if (_coordinate != coordinate) { + _coordinate = coordinate; + emit coordinateChanged(_coordinate); + } +} + +void FixedWingLandingComplexItem::setDirty(bool dirty) +{ + if (_dirty != dirty) { + _dirty = dirty; + emit dirtyChanged(_dirty); + } +} + +void FixedWingLandingComplexItem::save(QJsonObject& saveObject) const +{ + saveObject[JsonHelper::jsonVersionKey] = 1; + saveObject[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeComplexItemValue; + saveObject[ComplexMissionItem::jsonComplexItemTypeKey] = jsonComplexItemTypeValue; + + // FIXME: Need real implementation +} + +void FixedWingLandingComplexItem::setSequenceNumber(int sequenceNumber) +{ + if (_sequenceNumber != sequenceNumber) { + _sequenceNumber = sequenceNumber; + emit sequenceNumberChanged(sequenceNumber); + emit lastSequenceNumberChanged(lastSequenceNumber()); + } +} + +bool FixedWingLandingComplexItem::load(const QJsonObject& complexObject, int sequenceNumber, QString& errorString) +{ + // FIXME: Need real implementation + Q_UNUSED(complexObject); + Q_UNUSED(sequenceNumber); + + errorString = "NYI"; + return false; +} + +double FixedWingLandingComplexItem::greatestDistanceTo(const QGeoCoordinate &other) const +{ + // FIXME: Need real implementation + Q_UNUSED(other); + + double greatestDistance = 0.0; + +#if 0 + for (int i=0; i<_gridPoints.count(); i++) { + QGeoCoordinate currentCoord = _gridPoints[i].value(); + double distance = currentCoord.distanceTo(other); + if (distance > greatestDistance) { + greatestDistance = distance; + } + } +#endif + + return greatestDistance; +} + +void FixedWingLandingComplexItem::_setExitCoordinate(const QGeoCoordinate& coordinate) +{ + if (_exitCoordinate != coordinate) { + _exitCoordinate = coordinate; + emit exitCoordinateChanged(coordinate); + } +} + +bool FixedWingLandingComplexItem::specifiesCoordinate(void) const +{ + return true; +} + +QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const +{ + // FIXME: Need real implementation + QmlObjectListModel* pMissionItems = new QmlObjectListModel; + +#if 0 + int seqNum = _sequenceNumber; + for (int i=0; i<_gridPoints.count(); i++) { + QGeoCoordinate coord = _gridPoints[i].value(); + double altitude = _gridAltitudeFact.rawValue().toDouble(); + + MissionItem* item = new MissionItem(seqNum++, // sequence number + MAV_CMD_NAV_WAYPOINT, // MAV_CMD + _gridAltitudeRelative ? MAV_FRAME_GLOBAL_RELATIVE_ALT : MAV_FRAME_GLOBAL, // MAV_FRAME + 0.0, 0.0, 0.0, 0.0, // param 1-4 + coord.latitude(), + coord.longitude(), + altitude, + true, // autoContinue + false, // isCurrentItem + pMissionItems); // parent - allow delete on pMissionItems to delete everthing + 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 + _cameraTriggerDistanceFact.rawValue().toDouble(), // trigger distance + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 2-7 + true, // autoContinue + false, // isCurrentItem + pMissionItems); // parent - allow delete on pMissionItems to delete everthing + pMissionItems->append(item); + } + } + + 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 + 0.0, // trigger distance + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 2-7 + true, // autoContinue + false, // isCurrentItem + pMissionItems); // parent - allow delete on pMissionItems to delete everthing + pMissionItems->append(item); + } +#endif + + return pMissionItems; +} + +double FixedWingLandingComplexItem::complexDistance(void) const +{ + // FIXME: Need real implementation + return 0; +} + +void FixedWingLandingComplexItem::setCruiseSpeed(double cruiseSpeed) +{ + // FIXME: Need real implementation + Q_UNUSED(cruiseSpeed); +} diff --git a/src/MissionManager/FixedWingLandingComplexItem.h b/src/MissionManager/FixedWingLandingComplexItem.h new file mode 100644 index 0000000000000000000000000000000000000000..0c9f76b43ccbf61004f31eb3989696062b151add --- /dev/null +++ b/src/MissionManager/FixedWingLandingComplexItem.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#ifndef FixedWingLandingComplexItem_H +#define FixedWingLandingComplexItem_H + +#include "ComplexMissionItem.h" +#include "MissionItem.h" +#include "Fact.h" +#include "QGCLoggingCategory.h" + +Q_DECLARE_LOGGING_CATEGORY(FixedWingLandingComplexItemLog) + +class FixedWingLandingComplexItem : public ComplexMissionItem +{ + Q_OBJECT + +public: + FixedWingLandingComplexItem(Vehicle* vehicle, QObject* parent = NULL); + + // Overrides from ComplexMissionItem + + double complexDistance (void) const final; + int lastSequenceNumber (void) const final; + 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 + + bool dirty (void) const final { return _dirty; } + bool isSimpleItem (void) const final { return false; } + bool isStandaloneCoordinate (void) const final { return false; } + bool specifiesCoordinate (void) const final; + QString commandDescription (void) const final { return "Landing Pattern"; } + QString commandName (void) const final { return "Landing Pattern"; } + QString abbreviation (void) const final { return "L"; } + QGeoCoordinate coordinate (void) const final { return _coordinate; } + QGeoCoordinate exitCoordinate (void) const final { return _exitCoordinate; } + int sequenceNumber (void) const final { return _sequenceNumber; } + double flightSpeed (void) final { return std::numeric_limits::quiet_NaN(); } + + bool coordinateHasRelativeAltitude (void) const final { return true; } + bool exitCoordinateHasRelativeAltitude (void) const final { return true; } + bool exitCoordinateSameAsEntry (void) const final { return true; } + + void setDirty (bool dirty) final; + void setCoordinate (const QGeoCoordinate& coordinate) final; + void setSequenceNumber (int sequenceNumber) final; + void save (QJsonObject& saveObject) const final; + + static const char* jsonComplexItemTypeValue; + +signals: + +private slots: + +private: + void _setExitCoordinate(const QGeoCoordinate& coordinate); + + int _sequenceNumber; + bool _dirty; + QGeoCoordinate _coordinate; + QGeoCoordinate _exitCoordinate; + + static QMap _metaDataMap; +}; + +#endif diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index 71d2b6fff54c7557bcd2890e85f8b1f4d8fbba5c..70011b715ddbf620287c76875d87f5c0fb75713d 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -16,6 +16,7 @@ #include "QGCApplication.h" #include "SimpleMissionItem.h" #include "SurveyMissionItem.h" +#include "FixedWingLandingComplexItem.h" #include "JsonHelper.h" #include "ParameterManager.h" #include "QGroundControlQmlGlobal.h" @@ -59,7 +60,9 @@ MissionController::MissionController(QObject *parent) , _missionCruiseTime(0.0) , _missionMaxTelemetry(0.0) { - + _surveyMissionItemName = tr("Survey"); + _fwLandingMissionItemName = tr("Fixed Wing Landing"); + _complexMissionItemNames << _surveyMissionItemName << _fwLandingMissionItemName; } MissionController::~MissionController() @@ -218,12 +221,21 @@ int MissionController::insertSimpleMissionItem(QGeoCoordinate coordinate, int i) return newItem->sequenceNumber(); } -int MissionController::insertComplexMissionItem(QGeoCoordinate coordinate, int i) +int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate mapCenterCoordinate, int i) { + ComplexMissionItem* newItem; + int sequenceNumber = _nextSequenceNumber(); - SurveyMissionItem* newItem = new SurveyMissionItem(_activeVehicle, _visualItems); + if (itemName == _surveyMissionItemName) { + newItem = new SurveyMissionItem(_activeVehicle, _visualItems); + } else if (itemName == _fwLandingMissionItemName) { + newItem = new FixedWingLandingComplexItem(_activeVehicle, _visualItems); + } else { + qWarning() << "Internal error: Unknown complex item:" << itemName; + return sequenceNumber; + } newItem->setSequenceNumber(sequenceNumber); - newItem->setCoordinate(coordinate); + newItem->setCoordinate(mapCenterCoordinate); _initVisualItem(newItem); _visualItems->insert(i, newItem); diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 5a341ad197b79dfc7346b426b015b65eec3ebf9e..f1b45fb34c5b0abe2bf87c8ef9eccfd9e3c50ad3 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -39,6 +39,8 @@ public: Q_PROPERTY(QmlObjectListModel* complexVisualItems READ complexVisualItems NOTIFY complexVisualItemsChanged) Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged) + Q_PROPERTY(QStringList complexMissionItemNames MEMBER _complexMissionItemNames CONSTANT) + Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged) Q_PROPERTY(double missionTime READ missionTime NOTIFY missionTimeChanged) Q_PROPERTY(double missionHoverDistance READ missionHoverDistance NOTIFY missionHoverDistanceChanged) @@ -55,9 +57,11 @@ public: Q_INVOKABLE int insertSimpleMissionItem(QGeoCoordinate coordinate, int i); /// Add a new complex mission item to the list + /// @param itemName: Name of complex item to create (from complexMissionItemNames) + /// @param mapCenterCoordinate: coordinate for current center of map /// @param i: index to insert at /// @return Sequence number for new item - Q_INVOKABLE int insertComplexMissionItem(QGeoCoordinate coordinate, int i); + Q_INVOKABLE int insertComplexMissionItem(QString itemName, QGeoCoordinate mapCenterCoordinate, int i); /// Loads the mission items from the specified file /// @param[in] vehicle Vehicle we are loading items for @@ -180,7 +184,10 @@ private: double _missionHoverTime; double _missionCruiseDistance; double _missionCruiseTime; - double _missionMaxTelemetry; + double _missionMaxTelemetry; + QString _surveyMissionItemName; + QString _fwLandingMissionItemName; + QStringList _complexMissionItemNames; static const char* _settingsGroup; static const char* _jsonFileTypeValue; diff --git a/src/MissionManager/SimpleMissionItem.cc b/src/MissionManager/SimpleMissionItem.cc index 355a59c0ac448ee1b167a96e8f445ca06c8a5735..5464ddfd3e5326ba6c33619afba2440330cfa4dd 100644 --- a/src/MissionManager/SimpleMissionItem.cc +++ b/src/MissionManager/SimpleMissionItem.cc @@ -64,6 +64,8 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent) , _syncingAltitudeRelativeToHomeAndFrame (false) , _syncingHeadingDegreesAndParam4 (false) { + _editorQml = "qrc:/qml/SimpleItemEditor.qml"; + _altitudeRelativeToHomeFact.setRawValue(true); _setupMetaData(); diff --git a/src/MissionManager/SurveyMissionItem.cc b/src/MissionManager/SurveyMissionItem.cc index 03a8f4356cd660efd2e9edb66c1a7db8855a1820..954fc3cf2ac97451df1b5f5185f6e3a46ba5c960 100644 --- a/src/MissionManager/SurveyMissionItem.cc +++ b/src/MissionManager/SurveyMissionItem.cc @@ -86,6 +86,8 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent) , _cameraResolutionHeightFact (0, _cameraResolutionHeightFactName, FactMetaData::valueTypeUint32) , _cameraFocalLengthFact (0, _cameraFocalLengthFactName, FactMetaData::valueTypeDouble) { + _editorQml = "qrc:/qml/SurveyItemEditor.qml"; + if (_metaDataMap.isEmpty()) { _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/Survey.FactMetaData.json"), NULL /* metaDataParent */); } diff --git a/src/MissionManager/VisualMissionItem.h b/src/MissionManager/VisualMissionItem.h index ab2612b7879d97ad3673677f91a63c5032d48a13..a4ad9419d12f2ea5bb48cb5ad0e476419cc36b60 100644 --- a/src/MissionManager/VisualMissionItem.h +++ b/src/MissionManager/VisualMissionItem.h @@ -78,6 +78,7 @@ public: Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate NOTIFY specifiesCoordinateChanged) ///< Item is associated with a coordinate position Q_PROPERTY(bool isStandaloneCoordinate READ isStandaloneCoordinate NOTIFY isStandaloneCoordinateChanged) ///< Waypoint line does not go through item Q_PROPERTY(bool isSimpleItem READ isSimpleItem NOTIFY isSimpleItemChanged) ///< Simple or Complex MissionItem + Q_PROPERTY(QString editorQml MEMBER _editorQml CONSTANT) ///< Qml code for editing this item /// List of child mission items. Child mission item are subsequent mision items which do not specify a coordinate. They /// are shown next to the exitCoordinate indidcator in the ui. @@ -161,6 +162,7 @@ protected: double _altPercent; ///< Percent of total altitude change in mission double _azimuth; ///< Azimuth to previous waypoint double _distance; ///< Distance to previous waypoint + QString _editorQml; ///< Qml resource for editing item /// This is used to reference any subsequent mission items which do not specify a coordinate. QmlObjectListModel _childItems;