Commit 1dffdbf1 authored by DonLakeFlyer's avatar DonLakeFlyer

Waypoint now supports camera section

parent 2f1e631c
...@@ -449,6 +449,7 @@ HEADERS += \ ...@@ -449,6 +449,7 @@ HEADERS += \
src/JsonHelper.h \ src/JsonHelper.h \
src/LogCompressor.h \ src/LogCompressor.h \
src/MG.h \ src/MG.h \
src/MissionManager/CameraSection.h \
src/MissionManager/ComplexMissionItem.h \ src/MissionManager/ComplexMissionItem.h \
src/MissionManager/FixedWingLandingComplexItem.h \ src/MissionManager/FixedWingLandingComplexItem.h \
src/MissionManager/GeoFenceController.h \ src/MissionManager/GeoFenceController.h \
...@@ -626,6 +627,7 @@ SOURCES += \ ...@@ -626,6 +627,7 @@ SOURCES += \
src/Joystick/JoystickManager.cc \ src/Joystick/JoystickManager.cc \
src/JsonHelper.cc \ src/JsonHelper.cc \
src/LogCompressor.cc \ src/LogCompressor.cc \
src/MissionManager/CameraSection.cc \
src/MissionManager/ComplexMissionItem.cc \ src/MissionManager/ComplexMissionItem.cc \
src/MissionManager/FixedWingLandingComplexItem.cc \ src/MissionManager/FixedWingLandingComplexItem.cc \
src/MissionManager/GeoFenceController.cc \ src/MissionManager/GeoFenceController.cc \
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
<file alias="PX4FlowSensor.qml">src/VehicleSetup/PX4FlowSensor.qml</file> <file alias="PX4FlowSensor.qml">src/VehicleSetup/PX4FlowSensor.qml</file>
<file alias="QGroundControl/Controls/AnalyzePage.qml">src/AnalyzeView/AnalyzePage.qml</file> <file alias="QGroundControl/Controls/AnalyzePage.qml">src/AnalyzeView/AnalyzePage.qml</file>
<file alias="QGroundControl/Controls/AppMessages.qml">src/QmlControls/AppMessages.qml</file> <file alias="QGroundControl/Controls/AppMessages.qml">src/QmlControls/AppMessages.qml</file>
<file alias="QGroundControl/Controls/CameraSection.qml">src/MissionEditor/CameraSection.qml</file>
<file alias="QGroundControl/Controls/ClickableColor.qml">src/QmlControls/ClickableColor.qml</file> <file alias="QGroundControl/Controls/ClickableColor.qml">src/QmlControls/ClickableColor.qml</file>
<file alias="QGroundControl/Controls/DropButton.qml">src/QmlControls/DropButton.qml</file> <file alias="QGroundControl/Controls/DropButton.qml">src/QmlControls/DropButton.qml</file>
<file alias="QGroundControl/Controls/ExclusiveGroupItem.qml">src/QmlControls/ExclusiveGroupItem.qml</file> <file alias="QGroundControl/Controls/ExclusiveGroupItem.qml">src/QmlControls/ExclusiveGroupItem.qml</file>
...@@ -192,6 +193,7 @@ ...@@ -192,6 +193,7 @@
<file alias="RallyPoint.FactMetaData.json">src/MissionManager/RallyPoint.FactMetaData.json</file> <file alias="RallyPoint.FactMetaData.json">src/MissionManager/RallyPoint.FactMetaData.json</file>
<file alias="FWLandingPattern.FactMetaData.json">src/MissionManager/FWLandingPattern.FactMetaData.json</file> <file alias="FWLandingPattern.FactMetaData.json">src/MissionManager/FWLandingPattern.FactMetaData.json</file>
<file alias="USBBoardInfo.json">src/comm/USBBoardInfo.json</file> <file alias="USBBoardInfo.json">src/comm/USBBoardInfo.json</file>
<file alias="CameraSection.FactMetaData.json">src/MissionManager/CameraSection.FactMetaData.json</file>
<file alias="MissionSettings.FactMetaData.json">src/MissionManager/MissionSettings.FactMetaData.json</file> <file alias="MissionSettings.FactMetaData.json">src/MissionManager/MissionSettings.FactMetaData.json</file>
<file alias="Vehicle/VehicleFact.json">src/Vehicle/VehicleFact.json</file> <file alias="Vehicle/VehicleFact.json">src/Vehicle/VehicleFact.json</file>
<file alias="Vehicle/BatteryFact.json">src/Vehicle/BatteryFact.json</file> <file alias="Vehicle/BatteryFact.json">src/Vehicle/BatteryFact.json</file>
......
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
// Camera section for mission item editors
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
property alias exclusiveGroup: cameraSectionHeader.exclusiveGroup
property alias showSpacer: cameraSectionHeader.showSpacer
property alias checked: cameraSectionHeader.checked
property var _camera: missionItem.cameraSection
property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 16
property real _margin: ScreenTools.defaultFontPixelWidth / 2
SectionHeader {
id: cameraSectionHeader
text: qsTr("Camera")
checked: false
}
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
visible: cameraSectionHeader.checked
FactComboBox {
id: cameraActionCombo
anchors.left: parent.left
anchors.right: parent.right
fact: _camera.cameraAction
indexModel: false
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelWidth
visible: cameraActionCombo.currentIndex == 1
QGCLabel {
text: qsTr("Time")
Layout.fillWidth: true
}
FactTextField {
fact: _camera.cameraPhotoIntervalTime
Layout.preferredWidth: _fieldWidth
}
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelWidth
visible: cameraActionCombo.currentIndex == 2
QGCLabel {
text: qsTr("Distance")
Layout.fillWidth: true
}
FactTextField {
fact: _camera.cameraPhotoIntervalDistance
Layout.preferredWidth: _fieldWidth
}
}
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: ScreenTools.defaultFontPixelWidth / 2
rowSpacing: 0
columns: 3
Item { width: 1; height: 1 }
QGCLabel { text: qsTr("Pitch") }
QGCLabel { text: qsTr("Yaw") }
QGCCheckBox {
id: gimbalCheckBox
text: qsTr("Gimbal")
checked: _camera.specifyGimbal
onClicked: _camera.specifyGimbal = checked
Layout.fillWidth: true
}
FactTextField {
fact: _camera.gimbalPitch
implicitWidth: ScreenTools.defaultFontPixelWidth * 9
enabled: gimbalCheckBox.checked
}
FactTextField {
fact: _camera.gimbalYaw
implicitWidth: ScreenTools.defaultFontPixelWidth * 9
enabled: gimbalCheckBox.checked
}
}
}
}
...@@ -579,7 +579,7 @@ QGCView { ...@@ -579,7 +579,7 @@ QGCView {
spacing: _margin / 2 spacing: _margin / 2
orientation: ListView.Vertical orientation: ListView.Vertical
model: missionController.visualItems model: missionController.visualItems
cacheBuffer: height * 2 cacheBuffer: Math.max(height * 2, 0)
clip: true clip: true
currentIndex: _currentMissionIndex currentIndex: _currentMissionIndex
highlightMoveDuration: 250 highlightMoveDuration: 250
......
...@@ -19,12 +19,6 @@ Rectangle { ...@@ -19,12 +19,6 @@ Rectangle {
visible: missionItem.isCurrentItem visible: missionItem.isCurrentItem
radius: _radius radius: _radius
ExclusiveGroup {
id: sectionHeaderExclusiverGroup
}
property ExclusiveGroup sectionHeaderGroup: ScreenTools.isShortScreen ? sectionHeaderExclusiverGroup : null
Loader { Loader {
id: deferedload id: deferedload
active: valuesRect.visible active: valuesRect.visible
...@@ -64,7 +58,6 @@ Rectangle { ...@@ -64,7 +58,6 @@ Rectangle {
id: plannedHomePositionSection id: plannedHomePositionSection
text: qsTr("Planned Home Position") text: qsTr("Planned Home Position")
showSpacer: false showSpacer: false
exclusiveGroup: sectionHeaderGroup
} }
Column { Column {
...@@ -125,7 +118,6 @@ Rectangle { ...@@ -125,7 +118,6 @@ Rectangle {
text: qsTr("Vehicle Info") text: qsTr("Vehicle Info")
visible: _multipleFirmware && _showOfflineEditingCombos visible: _multipleFirmware && _showOfflineEditingCombos
checked: false checked: false
exclusiveGroup: sectionHeaderGroup
} }
GridLayout { GridLayout {
...@@ -183,7 +175,6 @@ Rectangle { ...@@ -183,7 +175,6 @@ Rectangle {
id: missionDefaultsSectionHeader id: missionDefaultsSectionHeader
text: qsTr("Mission Defaults") text: qsTr("Mission Defaults")
checked: false checked: false
exclusiveGroup: sectionHeaderGroup
} }
Column { Column {
...@@ -233,89 +224,8 @@ Rectangle { ...@@ -233,89 +224,8 @@ Rectangle {
*/ */
} }
SectionHeader { CameraSection {
id: cameraSectionHeader checked: missionItem.cameraSection.settingsSpecified
text: qsTr("Camera")
checked: false
exclusiveGroup: sectionHeaderGroup
}
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
visible: cameraSectionHeader.checked
FactComboBox {
id: cameraActionCombo
anchors.left: parent.left
anchors.right: parent.right
fact: missionItem.cameraAction
indexModel: false
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelWidth
visible: cameraActionCombo.currentIndex == 1
QGCLabel {
text: qsTr("Time")
Layout.fillWidth: true
}
FactTextField {
fact: missionItem.cameraPhotoIntervalTime
Layout.preferredWidth: _fieldWidth
}
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelWidth
visible: cameraActionCombo.currentIndex == 2
QGCLabel {
text: qsTr("Distance")
Layout.fillWidth: true
}
FactTextField {
fact: missionItem.cameraPhotoIntervalDistance
Layout.preferredWidth: _fieldWidth
}
}
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: 0
rowSpacing: 0
columns: 3
Item { width: 1; height: 1 }
QGCLabel { text: qsTr("Pitch") }
QGCLabel { text: qsTr("Yaw") }
QGCCheckBox {
id: gimbalCheckBox
text: qsTr("Gimbal")
checked: missionItem.specifyGimbal
onClicked: missionItem.specifyGimbal = checked
Layout.fillWidth: true
}
FactTextField {
fact: missionItem.gimbalPitch
implicitWidth: ScreenTools.defaultFontPixelWidth * 9
enabled: gimbalCheckBox.checked
}
FactTextField {
fact: missionItem.gimbalYaw
implicitWidth: ScreenTools.defaultFontPixelWidth * 9
enabled: gimbalCheckBox.checked
}
}
} }
QGCLabel { QGCLabel {
......
import QtQuick 2.3 import QtQuick 2.3
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Layouts 1.2 import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0 import QGroundControl.Palette 1.0
...@@ -41,10 +42,14 @@ QGCMouseArea { ...@@ -41,10 +42,14 @@ QGCMouseArea {
id: label id: label
Layout.fillWidth: true Layout.fillWidth: true
Image { QGCColoredImage {
id: image
width: label.height / 2
height: width
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
source: "/qmlimages/arrow-down.png" source: "/qmlimages/arrow-down.png"
color: qgcPal.text
visible: !_root.checked visible: !_root.checked
} }
} }
......
...@@ -27,6 +27,7 @@ Rectangle { ...@@ -27,6 +27,7 @@ Rectangle {
anchors.left: valuesRect.left anchors.left: valuesRect.left
anchors.right: valuesRect.right anchors.right: valuesRect.right
anchors.top: valuesRect.top anchors.top: valuesRect.top
sourceComponent: Component { sourceComponent: Component {
Item { Item {
id: valuesItem id: valuesItem
...@@ -114,6 +115,11 @@ Rectangle { ...@@ -114,6 +115,11 @@ Rectangle {
fact: object fact: object
} }
} }
CameraSection {
checked: missionItem.cameraSection.settingsSpecified
visible: missionItem.cameraSection.available
}
} // Column } // Column
} // Item } // Item
} // Component } // Component
......
[
{
"name": "CameraAction",
"shortDescription": "Specify whether the camera should take photos or video",
"type": "uint32",
"enumStrings": "Continue current action,Take photos (time),Take photos (distance),Take video",
"enumValues": "0,1,2,3",
"defaultValue": 0
},
{
"name": "CameraPhotoIntervalDistance",
"shortDescription": "Specify the distance between each photo",
"type": "double",
"units": "m",
"min": 0,
"decimalPlaces": 1,
"defaultValue": 1
},
{
"name": "CameraPhotoIntervalTime",
"shortDescription": "Specify the time between each photo",
"type": "uint32",
"units": "secs",
"min": 1,
"decimalPlaces": 0,
"defaultValue": 10
},
{
"name": "GimbalPitch",
"shortDescription": "Gimbal pitch rotation.",
"type": "double",
"units": "deg",
"min": 0.0,
"max": 360.0,
"decimalPlaces": 0,
"defaultValue": 0
},
{
"name": "GimbalYaw",
"shortDescription": "Gimbal yaw rotation.",
"type": "double",
"units": "deg",
"min": 0.0,
"max": 360.0,
"decimalPlaces": 0,
"defaultValue": 0
}
]
This diff is collapsed.
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#ifndef CameraSection_H
#define CameraSection_H
#include "ComplexMissionItem.h"
#include "MissionItem.h"
#include "Fact.h"
Q_DECLARE_LOGGING_CATEGORY(CameraSectionLog)
class CameraSection : public QObject
{
Q_OBJECT
public:
CameraSection(QObject* parent = NULL);
enum CameraAction {
CameraActionNone,
TakePhotosIntervalTime,
TakePhotoIntervalDistance,
TakeVideo
};
Q_ENUMS(CameraAction)
Q_PROPERTY(bool available READ available WRITE setAvailable NOTIFY availableChanged)
Q_PROPERTY(bool settingsSpecified MEMBER _settingsSpecified NOTIFY settingsSpecifiedChanged)
Q_PROPERTY(bool specifyGimbal READ specifyGimbal WRITE setSpecifyGimbal NOTIFY specifyGimbalChanged)
Q_PROPERTY(Fact* gimbalPitch READ gimbalPitch CONSTANT)
Q_PROPERTY(Fact* gimbalYaw READ gimbalYaw CONSTANT)
Q_PROPERTY(Fact* cameraAction READ cameraAction CONSTANT)
Q_PROPERTY(Fact* cameraPhotoIntervalTime READ cameraPhotoIntervalTime CONSTANT)
Q_PROPERTY(Fact* cameraPhotoIntervalDistance READ cameraPhotoIntervalDistance CONSTANT)
bool available (void) const { return _available; }
void setAvailable (bool available);
bool specifyGimbal (void) const { return _specifyGimbal; }
Fact* gimbalYaw (void) { return &_gimbalYawFact; }
Fact* gimbalPitch (void) { return &_gimbalPitchFact; }
Fact* cameraAction (void) { return &_cameraActionFact; }
Fact* cameraPhotoIntervalTime (void) { return &_cameraPhotoIntervalTimeFact; }
Fact* cameraPhotoIntervalDistance (void) { return &_cameraPhotoIntervalDistanceFact; }
/// Scans the loaded items for the section items
/// @param visualItems Item list
/// @param scanIndex Index to start scanning from
/// @return true: camera section found
bool scanForCameraSection(QmlObjectListModel* visualItems, int scanIndex);
/// Appends the mission items associated with this section
/// @param items List to append to
/// @param missionItemParent QObject parent for created MissionItems
/// @param nextSequenceNumber Sequence number for first item
void appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent, int nextSequenceNumber);
void setSpecifyGimbal (bool specifyGimbal);
bool dirty (void) const { return _dirty; }
void setDirty (bool dirty);
/// Returns the number of mission items represented by this section.
/// Signals: missionItemCountChanged on change
int missionItemCount(void) const;
signals:
void availableChanged (bool available);
void settingsSpecifiedChanged (bool settingsSpecified);
void dirtyChanged (bool dirty);
bool specifyGimbalChanged (bool specifyGimbal);
void missionItemCountChanged (int missionItemCount);
private slots:
void _setDirty(void);
void _setDirtyAndUpdateMissionItemCount(void);
private:
bool _available;
bool _settingsSpecified;
bool _specifyGimbal;
Fact _gimbalYawFact;
Fact _gimbalPitchFact;
Fact _cameraActionFact;
Fact _cameraPhotoIntervalDistanceFact;
Fact _cameraPhotoIntervalTimeFact;
bool _dirty;
static QMap<QString, FactMetaData*> _metaDataMap;
static const char* _gimbalPitchName;
static const char* _gimbalYawName;
static const char* _cameraActionName;
static const char* _cameraPhotoIntervalDistanceName;
static const char* _cameraPhotoIntervalTimeName;
};
#endif
...@@ -21,19 +21,11 @@ public: ...@@ -21,19 +21,11 @@ public:
const ComplexMissionItem& operator=(const ComplexMissionItem& other); const ComplexMissionItem& operator=(const ComplexMissionItem& other);
Q_PROPERTY(int lastSequenceNumber READ lastSequenceNumber NOTIFY lastSequenceNumberChanged)
Q_PROPERTY(double complexDistance READ complexDistance NOTIFY complexDistanceChanged) Q_PROPERTY(double complexDistance READ complexDistance NOTIFY complexDistanceChanged)
/// @return The distance covered the complex mission item in meters. /// @return The distance covered the complex mission item in meters.
virtual double complexDistance(void) const = 0; virtual double complexDistance(void) const = 0;
/// @return The last sequence number used by this item. Takes into account child items of the complex item
virtual int lastSequenceNumber(void) const = 0;
/// Returns the mission items associated with the complex item. Caller is responsible for freeing. Calling
/// delete on returned QmlObjectListModel will free all memory including internal items.
virtual QmlObjectListModel* getMissionItems(void) const = 0;
/// Load the complex mission item from Json /// Load the complex mission item from Json
/// @param complexObject Complex mission item json object /// @param complexObject Complex mission item json object
/// @param sequenceNumber Sequence number for first MISSION_ITEM in survey /// @param sequenceNumber Sequence number for first MISSION_ITEM in survey
...@@ -53,8 +45,7 @@ public: ...@@ -53,8 +45,7 @@ public:
static const char* jsonComplexItemTypeKey; static const char* jsonComplexItemTypeKey;
signals: signals:
void lastSequenceNumberChanged (int lastSequenceNumber); void complexDistanceChanged(double complexDistance);
void complexDistanceChanged (double complexDistance);
}; };
#endif #endif
...@@ -105,7 +105,7 @@ void FixedWingLandingComplexItem::setDirty(bool dirty) ...@@ -105,7 +105,7 @@ void FixedWingLandingComplexItem::setDirty(bool dirty)
} }
} }
void FixedWingLandingComplexItem::save(QJsonArray& missionItems) const void FixedWingLandingComplexItem::save(QJsonArray& missionItems)
{ {
QJsonObject saveObject; QJsonObject saveObject;
...@@ -203,10 +203,8 @@ bool FixedWingLandingComplexItem::specifiesCoordinate(void) const ...@@ -203,10 +203,8 @@ bool FixedWingLandingComplexItem::specifiesCoordinate(void) const
return true; return true;
} }
QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const void FixedWingLandingComplexItem::appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent)
{ {
QmlObjectListModel* pMissionItems = new QmlObjectListModel;
int seqNum = _sequenceNumber; int seqNum = _sequenceNumber;
MissionItem* item = new MissionItem(seqNum++, // sequence number MissionItem* item = new MissionItem(seqNum++, // sequence number
...@@ -215,8 +213,8 @@ QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const ...@@ -215,8 +213,8 @@ QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 1-7 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 1-7
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
pMissionItems); // parent - allow delete on pMissionItems to delete everthing missionItemParent);
pMissionItems->append(item); items.append(item);
float loiterRadius = _loiterRadiusFact.rawValue().toDouble() * (_loiterClockwise ? 1.0 : -1.0); float loiterRadius = _loiterRadiusFact.rawValue().toDouble() * (_loiterClockwise ? 1.0 : -1.0);
item = new MissionItem(seqNum++, item = new MissionItem(seqNum++,
...@@ -231,8 +229,8 @@ QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const ...@@ -231,8 +229,8 @@ QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const
_loiterAltitudeFact.rawValue().toDouble(), _loiterAltitudeFact.rawValue().toDouble(),
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
pMissionItems); // parent - allow delete on pMissionItems to delete everthing missionItemParent);
pMissionItems->append(item); items.append(item);
item = new MissionItem(seqNum++, item = new MissionItem(seqNum++,
MAV_CMD_NAV_LAND, MAV_CMD_NAV_LAND,
...@@ -243,10 +241,8 @@ QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const ...@@ -243,10 +241,8 @@ QmlObjectListModel* FixedWingLandingComplexItem::getMissionItems(void) const
_landingAltitudeFact.rawValue().toDouble(), _landingAltitudeFact.rawValue().toDouble(),
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
pMissionItems); // parent - allow delete on pMissionItems to delete everthing missionItemParent);
pMissionItems->append(item); items.append(item);
return pMissionItems;
} }
double FixedWingLandingComplexItem::complexDistance(void) const double FixedWingLandingComplexItem::complexDistance(void) const
......
...@@ -53,7 +53,6 @@ public: ...@@ -53,7 +53,6 @@ public:
double complexDistance (void) const final; double complexDistance (void) const final;
int lastSequenceNumber (void) const final; int lastSequenceNumber (void) const final;
QmlObjectListModel* getMissionItems (void) const final;
bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final; bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final;
double greatestDistanceTo (const QGeoCoordinate &other) const final; double greatestDistanceTo (const QGeoCoordinate &other) const final;
void setCruiseSpeed (double cruiseSpeed) final; void setCruiseSpeed (double cruiseSpeed) final;
...@@ -72,6 +71,7 @@ public: ...@@ -72,6 +71,7 @@ public:
QGeoCoordinate exitCoordinate (void) const final { return _landingCoordinate; } QGeoCoordinate exitCoordinate (void) const final { return _landingCoordinate; }
int sequenceNumber (void) const final { return _sequenceNumber; } int sequenceNumber (void) const final { return _sequenceNumber; }
double flightSpeed (void) final { return std::numeric_limits<double>::quiet_NaN(); } double flightSpeed (void) final { return std::numeric_limits<double>::quiet_NaN(); }
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
bool coordinateHasRelativeAltitude (void) const final { return true; } bool coordinateHasRelativeAltitude (void) const final { return true; }
bool exitCoordinateHasRelativeAltitude (void) const final { return true; } bool exitCoordinateHasRelativeAltitude (void) const final { return true; }
...@@ -80,7 +80,7 @@ public: ...@@ -80,7 +80,7 @@ public:
void setDirty (bool dirty) final; void setDirty (bool dirty) final;
void setCoordinate (const QGeoCoordinate& coordinate) final { setLoiterCoordinate(coordinate); } void setCoordinate (const QGeoCoordinate& coordinate) final { setLoiterCoordinate(coordinate); }
void setSequenceNumber (int sequenceNumber) final; void setSequenceNumber (int sequenceNumber) final;
void save (QJsonArray& missionItems) const final; void save (QJsonArray& missionItems) final;
static const char* jsonComplexItemTypeValue; static const char* jsonComplexItemTypeValue;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
"specifiesCoordinate": true, "specifiesCoordinate": true,
"friendlyEdit": true, "friendlyEdit": true,
"category": "Basic", "category": "Basic",
"cameraSection": true,
"param1": { "param1": {
"label": "Hold", "label": "Hold",
"units": "secs", "units": "secs",
......
...@@ -35,8 +35,10 @@ const char* MissionCommandUIInfo::_paramRemoveJsonKey = "paramRemove"; ...@@ -35,8 +35,10 @@ const char* MissionCommandUIInfo::_paramRemoveJsonKey = "paramRemove";
const char* MissionCommandUIInfo::_rawNameJsonKey = "rawName"; const char* MissionCommandUIInfo::_rawNameJsonKey = "rawName";
const char* MissionCommandUIInfo::_standaloneCoordinateJsonKey = "standaloneCoordinate"; const char* MissionCommandUIInfo::_standaloneCoordinateJsonKey = "standaloneCoordinate";
const char* MissionCommandUIInfo::_specifiesCoordinateJsonKey = "specifiesCoordinate"; const char* MissionCommandUIInfo::_specifiesCoordinateJsonKey = "specifiesCoordinate";
const char* MissionCommandUIInfo::_specifiesAltitudeOnlyJsonKey = "specifiesAltitudeOnly";
const char* MissionCommandUIInfo::_unitsJsonKey = "units"; const char* MissionCommandUIInfo::_unitsJsonKey = "units";
const char* MissionCommandUIInfo::_commentJsonKey = "comment"; const char* MissionCommandUIInfo::_commentJsonKey = "comment";
const char* MissionCommandUIInfo::_cameraSectionJsonKey = "cameraSection";
const char* MissionCommandUIInfo::_advancedCategory = "Advanced"; const char* MissionCommandUIInfo::_advancedCategory = "Advanced";
MissionCmdParamInfo::MissionCmdParamInfo(QObject* parent) MissionCmdParamInfo::MissionCmdParamInfo(QObject* parent)
...@@ -143,7 +145,7 @@ bool MissionCommandUIInfo::isStandaloneCoordinate(void) const ...@@ -143,7 +145,7 @@ bool MissionCommandUIInfo::isStandaloneCoordinate(void) const
} }
} }
bool MissionCommandUIInfo::specifiesCoordinate (void) const bool MissionCommandUIInfo::specifiesCoordinate(void) const
{ {
if (_infoMap.contains(_specifiesCoordinateJsonKey)) { if (_infoMap.contains(_specifiesCoordinateJsonKey)) {
return _infoMap[_specifiesCoordinateJsonKey].toBool(); return _infoMap[_specifiesCoordinateJsonKey].toBool();
...@@ -152,6 +154,24 @@ bool MissionCommandUIInfo::specifiesCoordinate (void) const ...@@ -152,6 +154,24 @@ bool MissionCommandUIInfo::specifiesCoordinate (void) const
} }
} }
bool MissionCommandUIInfo::specifiesAltitudeOnly(void) const
{
if (_infoMap.contains(_specifiesAltitudeOnlyJsonKey)) {
return _infoMap[_specifiesAltitudeOnlyJsonKey].toBool();
} else {
return false;
}
}
bool MissionCommandUIInfo::cameraSection(void) const
{
if (_infoMap.contains(_cameraSectionJsonKey)) {
return _infoMap[_cameraSectionJsonKey].toBool();
} else {
return false;
}
}
void MissionCommandUIInfo::_overrideInfo(MissionCommandUIInfo* uiInfo) void MissionCommandUIInfo::_overrideInfo(MissionCommandUIInfo* uiInfo)
{ {
// Override info values // Override info values
...@@ -187,7 +207,7 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ ...@@ -187,7 +207,7 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ
QStringList allKeys; QStringList allKeys;
allKeys << _idJsonKey << _rawNameJsonKey << _friendlyNameJsonKey << _descriptionJsonKey << _standaloneCoordinateJsonKey << _specifiesCoordinateJsonKey allKeys << _idJsonKey << _rawNameJsonKey << _friendlyNameJsonKey << _descriptionJsonKey << _standaloneCoordinateJsonKey << _specifiesCoordinateJsonKey
<<_friendlyEditJsonKey << _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _param5JsonKey << _param6JsonKey << _param7JsonKey <<_friendlyEditJsonKey << _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _param5JsonKey << _param6JsonKey << _param7JsonKey
<< _paramRemoveJsonKey << _categoryJsonKey; << _paramRemoveJsonKey << _categoryJsonKey << _cameraSectionJsonKey<< _specifiesAltitudeOnlyJsonKey;
// Look for unknown keys in top level object // Look for unknown keys in top level object
foreach (const QString& key, jsonObject.keys()) { foreach (const QString& key, jsonObject.keys()) {
...@@ -219,7 +239,7 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ ...@@ -219,7 +239,7 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ
QList<QJsonValue::Type> types; QList<QJsonValue::Type> types;
types << QJsonValue::Double << QJsonValue::String << QJsonValue::String<< QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool << QJsonValue::Bool types << QJsonValue::Double << QJsonValue::String << QJsonValue::String<< QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool << QJsonValue::Bool
<< QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object
<< QJsonValue::String << QJsonValue::String; << QJsonValue::String << QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool;
if (!JsonHelper::validateKeyTypes(jsonObject, allKeys, types, internalError)) { if (!JsonHelper::validateKeyTypes(jsonObject, allKeys, types, internalError)) {
errorString = _loadErrorString(internalError); errorString = _loadErrorString(internalError);
return false; return false;
...@@ -247,9 +267,15 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ ...@@ -247,9 +267,15 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ
if (jsonObject.contains(_specifiesCoordinateJsonKey)) { if (jsonObject.contains(_specifiesCoordinateJsonKey)) {
_infoMap[_specifiesCoordinateJsonKey] = jsonObject.value(_specifiesCoordinateJsonKey).toVariant(); _infoMap[_specifiesCoordinateJsonKey] = jsonObject.value(_specifiesCoordinateJsonKey).toVariant();
} }
if (jsonObject.contains(_specifiesAltitudeOnlyJsonKey)) {
_infoMap[_specifiesAltitudeOnlyJsonKey] = jsonObject.value(_specifiesAltitudeOnlyJsonKey).toBool();
}
if (jsonObject.contains(_friendlyEditJsonKey)) { if (jsonObject.contains(_friendlyEditJsonKey)) {
_infoMap[_friendlyEditJsonKey] = jsonObject.value(_friendlyEditJsonKey).toVariant(); _infoMap[_friendlyEditJsonKey] = jsonObject.value(_friendlyEditJsonKey).toVariant();
} }
if (jsonObject.contains(_cameraSectionJsonKey)) {
_infoMap[_cameraSectionJsonKey] = jsonObject.value(_cameraSectionJsonKey).toVariant();
}
if (jsonObject.contains(_paramRemoveJsonKey)) { if (jsonObject.contains(_paramRemoveJsonKey)) {
QStringList indexList = jsonObject.value(_paramRemoveJsonKey).toString().split(QStringLiteral(",")); QStringList indexList = jsonObject.value(_paramRemoveJsonKey).toString().split(QStringLiteral(","));
foreach (const QString& indexString, indexList) { foreach (const QString& indexString, indexList) {
......
...@@ -90,8 +90,10 @@ private: ...@@ -90,8 +90,10 @@ private:
/// friendlyName string rawName Short description of command /// friendlyName string rawName Short description of command
/// description string Long description of command /// description string Long description of command
/// specifiesCoordinate bool false true: Command specifies a lat/lon/alt coordinate /// specifiesCoordinate bool false true: Command specifies a lat/lon/alt coordinate
/// specifiesAltitudeOnly bool false true: Command specifies an altitude only (no coordinate)
/// standaloneCoordinate bool false true: Vehicle does not fly through coordinate associated with command (exampl: ROI) /// standaloneCoordinate bool false true: Vehicle does not fly through coordinate associated with command (exampl: ROI)
/// friendlyEdit bool false true: Command supports friendly editing dialog, false: Command supports 'Show all values" style editing only /// friendlyEdit bool false true: Command supports friendly editing dialog, false: Command supports 'Show all values" style editing only
/// cameraSection bool false true: Camera section of additional settings is added to editor
/// category string Advanced Category which this command belongs to /// category string Advanced Category which this command belongs to
/// paramRemove string Used by an override to remove params, example: "1,3" will remove params 1 and 3 on the override /// paramRemove string Used by an override to remove params, example: "1,3" will remove params 1 and 3 on the override
/// param[1-7] object MissionCommandParamInfo object /// param[1-7] object MissionCommandParamInfo object
...@@ -112,7 +114,9 @@ public: ...@@ -112,7 +114,9 @@ public:
Q_PROPERTY(QString rawName READ rawName CONSTANT) Q_PROPERTY(QString rawName READ rawName CONSTANT)
Q_PROPERTY(bool isStandaloneCoordinate READ isStandaloneCoordinate CONSTANT) Q_PROPERTY(bool isStandaloneCoordinate READ isStandaloneCoordinate CONSTANT)
Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate CONSTANT) Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate CONSTANT)
Q_PROPERTY(bool specifiesAltitudeOnly READ specifiesAltitudeOnly CONSTANT)
Q_PROPERTY(int command READ intCommand CONSTANT) Q_PROPERTY(int command READ intCommand CONSTANT)
Q_PROPERTY(bool cameraSection READ cameraSection CONSTANT)
MAV_CMD command(void) const { return _command; } MAV_CMD command(void) const { return _command; }
int intCommand(void) const { return (int)_command; } int intCommand(void) const { return (int)_command; }
...@@ -124,6 +128,8 @@ public: ...@@ -124,6 +128,8 @@ public:
QString rawName (void) const; QString rawName (void) const;
bool isStandaloneCoordinate (void) const; bool isStandaloneCoordinate (void) const;
bool specifiesCoordinate (void) const; bool specifiesCoordinate (void) const;
bool specifiesAltitudeOnly (void) const;
bool cameraSection (void) const;
/// Load the data in the object from the specified json /// Load the data in the object from the specified json
/// @param jsonObject Json object to load from /// @param jsonObject Json object to load from
...@@ -178,8 +184,10 @@ private: ...@@ -178,8 +184,10 @@ private:
static const char* _rawNameJsonKey; static const char* _rawNameJsonKey;
static const char* _standaloneCoordinateJsonKey; static const char* _standaloneCoordinateJsonKey;
static const char* _specifiesCoordinateJsonKey; static const char* _specifiesCoordinateJsonKey;
static const char* _specifiesAltitudeOnlyJsonKey;
static const char* _unitsJsonKey; static const char* _unitsJsonKey;
static const char* _commentJsonKey; static const char* _commentJsonKey;
static const char* _cameraSectionJsonKey;
static const char* _advancedCategory; static const char* _advancedCategory;
friend class MissionCommandTree; friend class MissionCommandTree;
......
...@@ -126,8 +126,7 @@ void MissionController::_newMissionItemsAvailableFromVehicle(void) ...@@ -126,8 +126,7 @@ void MissionController::_newMissionItemsAvailableFromVehicle(void)
_missionItemsRequested = false; _missionItemsRequested = false;
if (_editMode) { if (_editMode) {
// Scan for mission settings MissionController::_scanForAdditionalSettings(_visualItems, _activeVehicle);
MissionSettingsComplexItem::scanForMissionSettings(_visualItems, _activeVehicle);
} }
_initAllVisualItems(); _initAllVisualItems();
...@@ -159,16 +158,8 @@ void MissionController::sendItemsToVehicle(Vehicle* vehicle, QmlObjectListModel* ...@@ -159,16 +158,8 @@ void MissionController::sendItemsToVehicle(Vehicle* vehicle, QmlObjectListModel*
for (int i=0; i<visualMissionItems->count(); i++) { for (int i=0; i<visualMissionItems->count(); i++) {
VisualMissionItem* visualItem = qobject_cast<VisualMissionItem*>(visualMissionItems->get(i)); VisualMissionItem* visualItem = qobject_cast<VisualMissionItem*>(visualMissionItems->get(i));
if (visualItem->isSimpleItem()) {
missionItems.append(new MissionItem(qobject_cast<SimpleMissionItem*>(visualItem)->missionItem())); visualItem->appendMissionItems(missionItems, NULL);
} else {
ComplexMissionItem* complexItem = qobject_cast<ComplexMissionItem*>(visualItem);
QmlObjectListModel* complexMissionItems = complexItem->getMissionItems();
for (int j=0; j<complexMissionItems->count(); j++) {
missionItems.append(new MissionItem(*qobject_cast<MissionItem*>(complexMissionItems->get(j))));
}
complexMissionItems->deleteLater();
}
} }
vehicle->missionManager()->writeMissionItems(missionItems); vehicle->missionManager()->writeMissionItems(missionItems);
...@@ -185,13 +176,8 @@ int MissionController::_nextSequenceNumber(void) ...@@ -185,13 +176,8 @@ int MissionController::_nextSequenceNumber(void)
qWarning() << "Internal error: Empty visual item list"; qWarning() << "Internal error: Empty visual item list";
return 0; return 0;
} else { } else {
VisualMissionItem* lastItem = qobject_cast<VisualMissionItem*>(_visualItems->get(_visualItems->count() - 1)); VisualMissionItem* lastItem = _visualItems->value<VisualMissionItem*>(_visualItems->count() - 1);
return lastItem->lastSequenceNumber() + 1;
if (lastItem->isSimpleItem()) {
return lastItem->sequenceNumber() + 1;
} else {
return qobject_cast<ComplexMissionItem*>(lastItem)->lastSequenceNumber() + 1;
}
} }
} }
...@@ -374,12 +360,11 @@ bool MissionController::_loadJsonMissionFileV1(Vehicle* vehicle, const QJsonObje ...@@ -374,12 +360,11 @@ bool MissionController::_loadJsonMissionFileV1(Vehicle* vehicle, const QJsonObje
SimpleMissionItem* item = new SimpleMissionItem(vehicle, visualItems); SimpleMissionItem* item = new SimpleMissionItem(vehicle, visualItems);
if (item->load(itemObject, itemObject["id"].toInt(), errorString)) { if (item->load(itemObject, itemObject["id"].toInt(), errorString)) {
qCDebug(MissionControllerLog) << "Json load: adding simple item expectedSequence:actualSequence" << nextSequenceNumber << item->sequenceNumber(); qCDebug(MissionControllerLog) << "Json load: adding simple item expectedSequence:actualSequence" << nextSequenceNumber << item->sequenceNumber();
nextSequenceNumber = item->lastSequenceNumber() + 1;
visualItems->append(item); visualItems->append(item);
} else { } else {
return false; return false;
} }
nextSequenceNumber++;
} }
} while (nextSimpleItemIndex < itemArray.count() || nextComplexItemIndex < surveyItems.count()); } while (nextSimpleItemIndex < itemArray.count() || nextComplexItemIndex < surveyItems.count());
...@@ -465,7 +450,8 @@ bool MissionController::_loadJsonMissionFileV2(Vehicle* vehicle, const QJsonObje ...@@ -465,7 +450,8 @@ bool MissionController::_loadJsonMissionFileV2(Vehicle* vehicle, const QJsonObje
if (itemType == VisualMissionItem::jsonTypeSimpleItemValue) { if (itemType == VisualMissionItem::jsonTypeSimpleItemValue) {
qCDebug(MissionControllerLog) << "Loading MISSION_ITEM: nextSequenceNumber" << nextSequenceNumber; qCDebug(MissionControllerLog) << "Loading MISSION_ITEM: nextSequenceNumber" << nextSequenceNumber;
SimpleMissionItem* simpleItem = new SimpleMissionItem(vehicle, visualItems); SimpleMissionItem* simpleItem = new SimpleMissionItem(vehicle, visualItems);
if (simpleItem->load(itemObject, nextSequenceNumber++, errorString)) { if (simpleItem->load(itemObject, nextSequenceNumber, errorString)) {
nextSequenceNumber = simpleItem->lastSequenceNumber() + 1;
visualItems->append(simpleItem); visualItems->append(simpleItem);
} else { } else {
return false; return false;
...@@ -612,7 +598,7 @@ void MissionController::loadFromFile(const QString& filename) ...@@ -612,7 +598,7 @@ void MissionController::loadFromFile(const QString& filename)
_addMissionSettings(_activeVehicle, _visualItems, true /* addToCenter */); _addMissionSettings(_activeVehicle, _visualItems, true /* addToCenter */);
} }
MissionSettingsComplexItem::scanForMissionSettings(_visualItems, _activeVehicle); MissionController::_scanForAdditionalSettings(_visualItems, _activeVehicle);
_initAllVisualItems(); _initAllVisualItems();
} }
...@@ -1062,16 +1048,8 @@ void MissionController::_recalcSequence(void) ...@@ -1062,16 +1048,8 @@ void MissionController::_recalcSequence(void)
for (int i=0; i<_visualItems->count(); i++) { for (int i=0; i<_visualItems->count(); i++) {
VisualMissionItem* item = qobject_cast<VisualMissionItem*>(_visualItems->get(i)); VisualMissionItem* item = qobject_cast<VisualMissionItem*>(_visualItems->get(i));
item->setSequenceNumber(sequenceNumber++); item->setSequenceNumber(sequenceNumber);
if (!item->isSimpleItem()) { sequenceNumber = item->lastSequenceNumber() + 1;
ComplexMissionItem* complexItem = qobject_cast<ComplexMissionItem*>(item);
if (complexItem) {
sequenceNumber = complexItem->lastSequenceNumber() + 1;
} else {
qWarning() << "isSimpleItem == false, yet not ComplexMissionItem";
}
}
} }
} }
...@@ -1158,6 +1136,7 @@ void MissionController::_initVisualItem(VisualMissionItem* visualItem) ...@@ -1158,6 +1136,7 @@ void MissionController::_initVisualItem(VisualMissionItem* visualItem)
connect(visualItem, &VisualMissionItem::coordinateHasRelativeAltitudeChanged, this, &MissionController::_recalcWaypointLines); connect(visualItem, &VisualMissionItem::coordinateHasRelativeAltitudeChanged, this, &MissionController::_recalcWaypointLines);
connect(visualItem, &VisualMissionItem::exitCoordinateHasRelativeAltitudeChanged, this, &MissionController::_recalcWaypointLines); connect(visualItem, &VisualMissionItem::exitCoordinateHasRelativeAltitudeChanged, this, &MissionController::_recalcWaypointLines);
connect(visualItem, &VisualMissionItem::flightSpeedChanged, this, &MissionController::_recalcAltitudeRangeBearing); connect(visualItem, &VisualMissionItem::flightSpeedChanged, this, &MissionController::_recalcAltitudeRangeBearing);
connect(visualItem, &VisualMissionItem::lastSequenceNumberChanged, this, &MissionController::_recalcSequence);
if (visualItem->isSimpleItem()) { if (visualItem->isSimpleItem()) {
// We need to track commandChanged on simple item since recalc has special handling for takeoff command // We need to track commandChanged on simple item since recalc has special handling for takeoff command
...@@ -1168,10 +1147,12 @@ void MissionController::_initVisualItem(VisualMissionItem* visualItem) ...@@ -1168,10 +1147,12 @@ void MissionController::_initVisualItem(VisualMissionItem* visualItem)
qWarning() << "isSimpleItem == true, yet not SimpleMissionItem"; qWarning() << "isSimpleItem == true, yet not SimpleMissionItem";
} }
} else { } else {
// We need to track changes of lastSequenceNumber so we can recalc sequence numbers for subsequence items
ComplexMissionItem* complexItem = qobject_cast<ComplexMissionItem*>(visualItem); ComplexMissionItem* complexItem = qobject_cast<ComplexMissionItem*>(visualItem);
connect(complexItem, &ComplexMissionItem::lastSequenceNumberChanged, this, &MissionController::_recalcSequence); if (complexItem) {
connect(complexItem, &ComplexMissionItem::complexDistanceChanged, this, &MissionController::_recalcAltitudeRangeBearing); connect(complexItem, &ComplexMissionItem::complexDistanceChanged, this, &MissionController::_recalcAltitudeRangeBearing);
} else {
qWarning() << "ComplexMissionItem not found";
}
} }
} }
...@@ -1472,7 +1453,7 @@ QString MissionController::fileExtension(void) const ...@@ -1472,7 +1453,7 @@ QString MissionController::fileExtension(void) const
return QGCApplication::missionFileExtension; return QGCApplication::missionFileExtension;
} }
double MissionController::cruiseSpeed(void) const double MissionController::cruiseSpeed(void) const
{ {
if (_activeVehicle) { if (_activeVehicle) {
return _activeVehicle->cruiseSpeed(); return _activeVehicle->cruiseSpeed();
...@@ -1481,7 +1462,7 @@ double MissionController::cruiseSpeed(void) const ...@@ -1481,7 +1462,7 @@ double MissionController::cruiseSpeed(void) const
} }
} }
double MissionController::hoverSpeed(void) const double MissionController::hoverSpeed(void) const
{ {
if (_activeVehicle) { if (_activeVehicle) {
return _activeVehicle->hoverSpeed(); return _activeVehicle->hoverSpeed();
...@@ -1489,3 +1470,27 @@ double MissionController::hoverSpeed(void) const ...@@ -1489,3 +1470,27 @@ double MissionController::hoverSpeed(void) const
return 0.0f; return 0.0f;
} }
} }
void MissionController::_scanForAdditionalSettings(QmlObjectListModel* visualItems, Vehicle* vehicle)
{
int scanIndex = 0;
while (scanIndex < visualItems->count()) {
VisualMissionItem* visualItem = visualItems->value<VisualMissionItem*>(scanIndex);
qCDebug(MissionControllerLog) << "MissionController::_scanForAdditionalSettings count:scanIndex" << visualItems->count() << scanIndex;
MissionSettingsComplexItem* settingsItem = qobject_cast<MissionSettingsComplexItem*>(visualItem);
if (settingsItem && settingsItem->scanForMissionSettings(visualItems, scanIndex, vehicle)) {
continue;
}
SimpleMissionItem* simpleItem = qobject_cast<SimpleMissionItem*>(visualItem);
if (simpleItem && simpleItem->cameraSection()->available()) {
scanIndex++;
simpleItem->scanForSections(visualItems, scanIndex, vehicle);
continue;
}
scanIndex++;
}
}
...@@ -160,6 +160,7 @@ private: ...@@ -160,6 +160,7 @@ private:
void _setMissionCruiseDistance(double missionCruiseDistance); void _setMissionCruiseDistance(double missionCruiseDistance);
void _setMissionCruiseTime(double missionCruiseTime); void _setMissionCruiseTime(double missionCruiseTime);
void _setMissionMaxTelemetry(double missionMaxTelemetry); void _setMissionMaxTelemetry(double missionMaxTelemetry);
static void _scanForAdditionalSettings(QmlObjectListModel* visualItems, Vehicle* vehicle);
// Overrides from PlanElementController // Overrides from PlanElementController
void _activeVehicleBeingRemoved(void) final; void _activeVehicleBeingRemoved(void) final;
......
...@@ -29,52 +29,6 @@ ...@@ -29,52 +29,6 @@
"min": 0, "min": 0,
"decimalPlaces": 1 "decimalPlaces": 1
}, },
{
"name": "CameraAction",
"shortDescription": "Specify whether the camera should take photos or video",
"type": "uint32",
"enumStrings": "No camera action,Take photos (time),Take photos (distance),Take video",
"enumValues": "0,1,2,3",
"defaultValue": 0
},
{
"name": "CameraPhotoIntervalDistance",
"shortDescription": "Specify the distance between each photo",
"type": "double",
"units": "m",
"min": 0,
"decimalPlaces": 1,
"defaultValue": 1
},
{
"name": "CameraPhotoIntervalTime",
"shortDescription": "Specify the time between each photo",
"type": "uint32",
"units": "secs",
"min": 1,
"decimalPlaces": 0,
"defaultValue": 10
},
{
"name": "GimbalPitch",
"shortDescription": "Gimbal pitch rotation.",
"type": "double",
"units": "deg",
"min": 0.0,
"max": 360.0,
"decimalPlaces": 0,
"defaultValue": 0
},
{
"name": "GimbalYaw",
"shortDescription": "Gimbal yaw rotation.",
"type": "double",
"units": "deg",
"min": 0.0,
"max": 360.0,
"decimalPlaces": 0,
"defaultValue": 0
},
{ {
"name": "MissionEndAction", "name": "MissionEndAction",
"shortDescription": "The action to take when the mission completed.", "shortDescription": "The action to take when the mission completed.",
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "MissionItem.h" #include "MissionItem.h"
#include "Fact.h" #include "Fact.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "CameraSection.h"
Q_DECLARE_LOGGING_CATEGORY(MissionSettingsComplexItemLog) Q_DECLARE_LOGGING_CATEGORY(MissionSettingsComplexItemLog)
...@@ -32,51 +33,31 @@ public: ...@@ -32,51 +33,31 @@ public:
}; };
Q_ENUMS(MissionEndAction) Q_ENUMS(MissionEndAction)
enum CameraAction {
CameraActionNone,
TakePhotosIntervalTime,
TakePhotoIntervalDistance,
TakeVideo
};
Q_ENUMS(CameraAction)
Q_PROPERTY(bool specifyMissionFlightSpeed READ specifyMissionFlightSpeed WRITE setSpecifyMissionFlightSpeed NOTIFY specifyMissionFlightSpeedChanged) Q_PROPERTY(bool specifyMissionFlightSpeed READ specifyMissionFlightSpeed WRITE setSpecifyMissionFlightSpeed NOTIFY specifyMissionFlightSpeedChanged)
Q_PROPERTY(Fact* missionFlightSpeed READ missionFlightSpeed CONSTANT) Q_PROPERTY(Fact* missionFlightSpeed READ missionFlightSpeed CONSTANT)
Q_PROPERTY(bool specifyGimbal READ specifyGimbal WRITE setSpecifyGimbal NOTIFY specifyGimbalChanged)
Q_PROPERTY(Fact* gimbalPitch READ gimbalPitch CONSTANT)
Q_PROPERTY(Fact* gimbalYaw READ gimbalYaw CONSTANT)
Q_PROPERTY(Fact* cameraAction READ cameraAction CONSTANT)
Q_PROPERTY(Fact* cameraPhotoIntervalTime READ cameraPhotoIntervalTime CONSTANT)
Q_PROPERTY(Fact* cameraPhotoIntervalDistance READ cameraPhotoIntervalDistance CONSTANT)
Q_PROPERTY(Fact* missionEndAction READ missionEndAction CONSTANT) Q_PROPERTY(Fact* missionEndAction READ missionEndAction CONSTANT)
Q_PROPERTY(Fact* plannedHomePositionLatitude READ plannedHomePositionLatitude CONSTANT) Q_PROPERTY(Fact* plannedHomePositionLatitude READ plannedHomePositionLatitude CONSTANT)
Q_PROPERTY(Fact* plannedHomePositionLongitude READ plannedHomePositionLongitude CONSTANT) Q_PROPERTY(Fact* plannedHomePositionLongitude READ plannedHomePositionLongitude CONSTANT)
Q_PROPERTY(Fact* plannedHomePositionAltitude READ plannedHomePositionAltitude CONSTANT) Q_PROPERTY(Fact* plannedHomePositionAltitude READ plannedHomePositionAltitude CONSTANT)
Q_PROPERTY(QObject* cameraSection READ cameraSection CONSTANT)
bool specifyMissionFlightSpeed (void) const { return _specifyMissionFlightSpeed; } bool specifyMissionFlightSpeed (void) const { return _specifyMissionFlightSpeed; }
bool specifyGimbal (void) const { return _specifyGimbal; }
Fact* plannedHomePositionLatitude (void) { return &_plannedHomePositionLatitudeFact; } Fact* plannedHomePositionLatitude (void) { return &_plannedHomePositionLatitudeFact; }
Fact* plannedHomePositionLongitude(void) { return &_plannedHomePositionLongitudeFact; } Fact* plannedHomePositionLongitude(void) { return &_plannedHomePositionLongitudeFact; }
Fact* plannedHomePositionAltitude (void) { return &_plannedHomePositionAltitudeFact; } Fact* plannedHomePositionAltitude (void) { return &_plannedHomePositionAltitudeFact; }
Fact* missionFlightSpeed (void) { return &_missionFlightSpeedFact; } Fact* missionFlightSpeed (void) { return &_missionFlightSpeedFact; }
Fact* gimbalYaw (void) { return &_gimbalYawFact; }
Fact* gimbalPitch (void) { return &_gimbalPitchFact; }
Fact* cameraAction (void) { return &_cameraActionFact; }
Fact* cameraPhotoIntervalTime (void) { return &_cameraPhotoIntervalTimeFact; }
Fact* cameraPhotoIntervalDistance (void) { return &_cameraPhotoIntervalDistanceFact; }
Fact* missionEndAction (void) { return &_missionEndActionFact; } Fact* missionEndAction (void) { return &_missionEndActionFact; }
void setSpecifyMissionFlightSpeed (bool specifyMissionFlightSpeed); void setSpecifyMissionFlightSpeed(bool specifyMissionFlightSpeed);
void setSpecifyGimbal (bool specifyGimbal); QObject* cameraSection(void) { return &_cameraSection; }
/// Scans the loaded items for the settings items /// Scans the loaded items for settings items
static void scanForMissionSettings(QmlObjectListModel* visualItems, Vehicle* vehicle); static bool scanForMissionSettings(QmlObjectListModel* visualItems, int scanIndex, Vehicle* vehicl);
// Overrides from ComplexMissionItem // Overrides from ComplexMissionItem
double complexDistance (void) const final; double complexDistance (void) const final;
int lastSequenceNumber (void) const final; int lastSequenceNumber (void) const final;
QmlObjectListModel* getMissionItems (void) const final;
bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final; bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final;
double greatestDistanceTo (const QGeoCoordinate &other) const final; double greatestDistanceTo (const QGeoCoordinate &other) const final;
void setCruiseSpeed (double cruiseSpeed) final; void setCruiseSpeed (double cruiseSpeed) final;
...@@ -95,6 +76,7 @@ public: ...@@ -95,6 +76,7 @@ public:
QGeoCoordinate exitCoordinate (void) const final { return coordinate(); } QGeoCoordinate exitCoordinate (void) const final { return coordinate(); }
int sequenceNumber (void) const final { return _sequenceNumber; } int sequenceNumber (void) const final { return _sequenceNumber; }
double flightSpeed (void) final { return std::numeric_limits<double>::quiet_NaN(); } double flightSpeed (void) final { return std::numeric_limits<double>::quiet_NaN(); }
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
bool coordinateHasRelativeAltitude (void) const final { return true; } bool coordinateHasRelativeAltitude (void) const final { return true; }
bool exitCoordinateHasRelativeAltitude (void) const final { return true; } bool exitCoordinateHasRelativeAltitude (void) const final { return true; }
...@@ -103,32 +85,27 @@ public: ...@@ -103,32 +85,27 @@ public:
void setDirty (bool dirty) final; void setDirty (bool dirty) final;
void setCoordinate (const QGeoCoordinate& coordinate) final; void setCoordinate (const QGeoCoordinate& coordinate) final;
void setSequenceNumber (int sequenceNumber) final; void setSequenceNumber (int sequenceNumber) final;
void save (QJsonArray& missionItems) const final; void save (QJsonArray& missionItems) final;
static const char* jsonComplexItemTypeValue; static const char* jsonComplexItemTypeValue;
signals: signals:
bool specifyMissionFlightSpeedChanged (bool specifyMissionFlightSpeed); bool specifyMissionFlightSpeedChanged(bool specifyMissionFlightSpeed);
bool specifyGimbalChanged (bool specifyGimbal);
private slots: private slots:
void _setDirtyAndUpdateLastSequenceNumber(void); void _setDirtyAndUpdateLastSequenceNumber(void);
void _setDirtyAndUpdateCoordinate(void); void _setDirtyAndUpdateCoordinate(void);
void _setDirty(void); void _setDirty(void);
void _cameraSectionDirtyChanged(bool dirty);
private: private:
bool _specifyMissionFlightSpeed; bool _specifyMissionFlightSpeed;
bool _specifyGimbal; Fact _plannedHomePositionLatitudeFact;
Fact _plannedHomePositionLatitudeFact; Fact _plannedHomePositionLongitudeFact;
Fact _plannedHomePositionLongitudeFact; Fact _plannedHomePositionAltitudeFact;
Fact _plannedHomePositionAltitudeFact; Fact _missionFlightSpeedFact;
Fact _missionFlightSpeedFact; Fact _missionEndActionFact;
Fact _gimbalYawFact; CameraSection _cameraSection;
Fact _gimbalPitchFact;
Fact _cameraActionFact;
Fact _cameraPhotoIntervalDistanceFact;
Fact _cameraPhotoIntervalTimeFact;
Fact _missionEndActionFact;
int _sequenceNumber; int _sequenceNumber;
bool _dirty; bool _dirty;
...@@ -139,11 +116,6 @@ private: ...@@ -139,11 +116,6 @@ private:
static const char* _plannedHomePositionLongitudeName; static const char* _plannedHomePositionLongitudeName;
static const char* _plannedHomePositionAltitudeName; static const char* _plannedHomePositionAltitudeName;
static const char* _missionFlightSpeedName; static const char* _missionFlightSpeedName;
static const char* _gimbalPitchName;
static const char* _gimbalYawName;
static const char* _cameraActionName;
static const char* _cameraPhotoIntervalDistanceName;
static const char* _cameraPhotoIntervalTimeName;
static const char* _missionEndActionName; static const char* _missionEndActionName;
}; };
......
...@@ -50,6 +50,8 @@ static const struct EnumInfo_s _rgMavFrameInfo[] = { ...@@ -50,6 +50,8 @@ static const struct EnumInfo_s _rgMavFrameInfo[] = {
SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent) SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent)
: VisualMissionItem(vehicle, parent) : VisualMissionItem(vehicle, parent)
, _rawEdit(false) , _rawEdit(false)
, _dirty(false)
, _cameraSection(NULL)
, _commandTree(qgcApp()->toolbox()->missionCommandTree()) , _commandTree(qgcApp()->toolbox()->missionCommandTree())
, _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32) , _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32)
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) , _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32)
...@@ -69,10 +71,15 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent) ...@@ -69,10 +71,15 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent)
_setupMetaData(); _setupMetaData();
_connectSignals(); _connectSignals();
_updateCameraSection();
setDefaultsForCommand(); setDefaultsForCommand();
connect(&_missionItem, &MissionItem::flightSpeedChanged, this, &SimpleMissionItem::flightSpeedChanged); connect(&_missionItem, &MissionItem::flightSpeedChanged, this, &SimpleMissionItem::flightSpeedChanged);
connect(this, &SimpleMissionItem::sequenceNumberChanged, this, &SimpleMissionItem::lastSequenceNumberChanged);
connect(this, &SimpleMissionItem::cameraSectionChanged, this, &SimpleMissionItem::_setDirtyFromSignal);
connect(this, &SimpleMissionItem::cameraSectionChanged, this, &SimpleMissionItem::_updateLastSequenceNumber);
} }
SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, const MissionItem& missionItem, QObject* parent) SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, const MissionItem& missionItem, QObject* parent)
...@@ -80,6 +87,7 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, const MissionItem& missio ...@@ -80,6 +87,7 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, const MissionItem& missio
, _missionItem(missionItem) , _missionItem(missionItem)
, _rawEdit(false) , _rawEdit(false)
, _dirty(false) , _dirty(false)
, _cameraSection(NULL)
, _commandTree(qgcApp()->toolbox()->missionCommandTree()) , _commandTree(qgcApp()->toolbox()->missionCommandTree())
, _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32) , _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32)
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) , _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32)
...@@ -99,6 +107,7 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, const MissionItem& missio ...@@ -99,6 +107,7 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, const MissionItem& missio
_setupMetaData(); _setupMetaData();
_connectSignals(); _connectSignals();
_updateCameraSection();
_syncFrameToAltitudeRelativeToHome(); _syncFrameToAltitudeRelativeToHome();
} }
...@@ -108,6 +117,7 @@ SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, QObject* pa ...@@ -108,6 +117,7 @@ SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, QObject* pa
, _missionItem(other._vehicle) , _missionItem(other._vehicle)
, _rawEdit(false) , _rawEdit(false)
, _dirty(false) , _dirty(false)
, _cameraSection(NULL)
, _commandTree(qgcApp()->toolbox()->missionCommandTree()) , _commandTree(qgcApp()->toolbox()->missionCommandTree())
, _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32) , _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32)
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) , _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32)
...@@ -122,6 +132,7 @@ SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, QObject* pa ...@@ -122,6 +132,7 @@ SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, QObject* pa
_setupMetaData(); _setupMetaData();
_connectSignals(); _connectSignals();
_updateCameraSection();
*this = other; *this = other;
} }
...@@ -240,11 +251,19 @@ SimpleMissionItem::~SimpleMissionItem() ...@@ -240,11 +251,19 @@ SimpleMissionItem::~SimpleMissionItem()
{ {
} }
void SimpleMissionItem::save(QJsonArray& missionItems) const void SimpleMissionItem::save(QJsonArray& missionItems)
{ {
QJsonObject itemObject; QList<MissionItem*> items;
_missionItem.save(itemObject);
missionItems.append(itemObject); appendMissionItems(items, this);
for (int i=0; i<items.count(); i++) {
MissionItem* item = items[i];
QJsonObject saveObject;
item->save(saveObject);
missionItems.append(saveObject);
item->deleteLater();
}
} }
bool SimpleMissionItem::load(QTextStream &loadStream) bool SimpleMissionItem::load(QTextStream &loadStream)
...@@ -489,13 +508,10 @@ void SimpleMissionItem::setRawEdit(bool rawEdit) ...@@ -489,13 +508,10 @@ void SimpleMissionItem::setRawEdit(bool rawEdit)
void SimpleMissionItem::setDirty(bool dirty) void SimpleMissionItem::setDirty(bool dirty)
{ {
if (!_homePositionSpecialCase || !dirty) { if (!_homePositionSpecialCase || (_dirty != dirty)) {
// Home position never affects dirty bit
_dirty = dirty; _dirty = dirty;
// We want to emit dirtyChanged even if _dirty didn't change. This can be handy signal for _cameraSection->setDirty(false);
// any value within the item changing. emit dirtyChanged(dirty);
emit dirtyChanged(_dirty);
} }
} }
...@@ -584,6 +600,7 @@ void SimpleMissionItem::setCommand(MavlinkQmlSingleton::Qml_MAV_CMD command) ...@@ -584,6 +600,7 @@ void SimpleMissionItem::setCommand(MavlinkQmlSingleton::Qml_MAV_CMD command)
{ {
if ((MAV_CMD)command != _missionItem.command()) { if ((MAV_CMD)command != _missionItem.command()) {
_missionItem.setCommand((MAV_CMD)command); _missionItem.setCommand((MAV_CMD)command);
_updateCameraSection();
} }
} }
...@@ -608,3 +625,64 @@ double SimpleMissionItem::flightSpeed(void) ...@@ -608,3 +625,64 @@ double SimpleMissionItem::flightSpeed(void)
{ {
return missionItem().flightSpeed(); return missionItem().flightSpeed();
} }
void SimpleMissionItem::scanForSections(QmlObjectListModel* visualItems, int scanIndex, Vehicle* vehicle)
{
Q_UNUSED(vehicle);
qDebug() << "SimpleMissionItem::scanForSections" << scanIndex << _cameraSection->available();
if (_cameraSection->available()) {
bool sectionFound = _cameraSection->scanForCameraSection(visualItems, scanIndex);
qDebug() << sectionFound;
}
}
void SimpleMissionItem::_updateCameraSection(void)
{
if (_cameraSection) {
// Remove previous section
_cameraSection->deleteLater();
_cameraSection = NULL;
}
// Add new section
_cameraSection = new CameraSection(this);
const MissionCommandUIInfo* uiInfo = _commandTree->getUIInfo(_vehicle, (MAV_CMD)command());
if (uiInfo && uiInfo->cameraSection()) {
_cameraSection->setAvailable(true);
}
connect(_cameraSection, &CameraSection::dirtyChanged, this, &SimpleMissionItem::_cameraSectionDirtyChanged);
connect(_cameraSection, &CameraSection::availableChanged, this, &SimpleMissionItem::_updateLastSequenceNumber);
connect(_cameraSection, &CameraSection::missionItemCountChanged, this, &SimpleMissionItem::_updateLastSequenceNumber);
emit cameraSectionChanged(_cameraSection);
}
int SimpleMissionItem::lastSequenceNumber(void) const
{
return sequenceNumber() + (_cameraSection ? _cameraSection->missionItemCount() : 0);
}
void SimpleMissionItem::_updateLastSequenceNumber(void)
{
emit lastSequenceNumberChanged(lastSequenceNumber());
}
void SimpleMissionItem::_cameraSectionDirtyChanged(bool dirty)
{
if (dirty) {
setDirty(true);
}
}
void SimpleMissionItem::appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent)
{
int seqNum = sequenceNumber();
items.append(new MissionItem(missionItem(), missionItemParent));
seqNum++;
_cameraSection->appendMissionItems(items, missionItemParent, seqNum);
}
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "VisualMissionItem.h" #include "VisualMissionItem.h"
#include "MissionItem.h" #include "MissionItem.h"
#include "MissionCommandTree.h" #include "MissionCommandTree.h"
#include "CameraSection.h"
/// A SimpleMissionItem is used to represent a single MissionItem to the ui. /// A SimpleMissionItem is used to represent a single MissionItem to the ui.
class SimpleMissionItem : public VisualMissionItem class SimpleMissionItem : public VisualMissionItem
...@@ -35,18 +36,27 @@ public: ...@@ -35,18 +36,27 @@ public:
Q_PROPERTY(bool rawEdit READ rawEdit WRITE setRawEdit NOTIFY rawEditChanged) ///< true: raw item editing with all params Q_PROPERTY(bool rawEdit READ rawEdit WRITE setRawEdit NOTIFY rawEditChanged) ///< true: raw item editing with all params
Q_PROPERTY(bool relativeAltitude READ relativeAltitude NOTIFY frameChanged) Q_PROPERTY(bool relativeAltitude READ relativeAltitude NOTIFY frameChanged)
/// Optional sections
Q_PROPERTY(QObject* cameraSection READ cameraSection NOTIFY cameraSectionChanged)
// These properties are used to display the editing ui // These properties are used to display the editing ui
Q_PROPERTY(QmlObjectListModel* checkboxFacts READ checkboxFacts NOTIFY uiModelChanged) Q_PROPERTY(QmlObjectListModel* checkboxFacts READ checkboxFacts NOTIFY uiModelChanged)
Q_PROPERTY(QmlObjectListModel* comboboxFacts READ comboboxFacts NOTIFY uiModelChanged) Q_PROPERTY(QmlObjectListModel* comboboxFacts READ comboboxFacts NOTIFY uiModelChanged)
Q_PROPERTY(QmlObjectListModel* textFieldFacts READ textFieldFacts NOTIFY uiModelChanged) Q_PROPERTY(QmlObjectListModel* textFieldFacts READ textFieldFacts NOTIFY uiModelChanged)
/// Scans the loaded items for additional section settings
/// @param visualItems List of all visual items
/// @param scanIndex Index to start scanning from
/// @param vehicle Vehicle associated with this mission
void scanForSections(QmlObjectListModel* visualItems, int scanIndex, Vehicle* vehicle);
// Property accesors // Property accesors
QString category (void) const; QString category (void) const;
MavlinkQmlSingleton::Qml_MAV_CMD command(void) const { return (MavlinkQmlSingleton::Qml_MAV_CMD)_missionItem._commandFact.cookedValue().toInt(); } MavlinkQmlSingleton::Qml_MAV_CMD command(void) const { return (MavlinkQmlSingleton::Qml_MAV_CMD)_missionItem._commandFact.cookedValue().toInt(); }
bool friendlyEditAllowed (void) const; bool friendlyEditAllowed (void) const;
bool rawEdit (void) const; bool rawEdit (void) const;
CameraSection* cameraSection (void) { return _cameraSection; }
QmlObjectListModel* textFieldFacts (void); QmlObjectListModel* textFieldFacts (void);
QmlObjectListModel* checkboxFacts (void); QmlObjectListModel* checkboxFacts (void);
...@@ -69,6 +79,7 @@ public: ...@@ -69,6 +79,7 @@ public:
bool relativeAltitude(void) { return _missionItem.frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; } bool relativeAltitude(void) { return _missionItem.frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; }
MissionItem& missionItem(void) { return _missionItem; } MissionItem& missionItem(void) { return _missionItem; }
const MissionItem& missionItem(void) const { return _missionItem; }
// Overrides from VisualMissionItem // Overrides from VisualMissionItem
...@@ -84,6 +95,7 @@ public: ...@@ -84,6 +95,7 @@ public:
int sequenceNumber (void) const final { return _missionItem.sequenceNumber(); } int sequenceNumber (void) const final { return _missionItem.sequenceNumber(); }
double flightSpeed (void) final; double flightSpeed (void) final;
QString mapVisualQML (void) const final { return QStringLiteral("SimpleItemMapVisual.qml"); } QString mapVisualQML (void) const final { return QStringLiteral("SimpleItemMapVisual.qml"); }
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
bool coordinateHasRelativeAltitude (void) const final { return _missionItem.relativeAltitude(); } bool coordinateHasRelativeAltitude (void) const final { return _missionItem.relativeAltitude(); }
bool exitCoordinateHasRelativeAltitude (void) const final { return coordinateHasRelativeAltitude(); } bool exitCoordinateHasRelativeAltitude (void) const final { return coordinateHasRelativeAltitude(); }
...@@ -92,7 +104,8 @@ public: ...@@ -92,7 +104,8 @@ public:
void setDirty (bool dirty) final; void setDirty (bool dirty) final;
void setCoordinate (const QGeoCoordinate& coordinate) final; void setCoordinate (const QGeoCoordinate& coordinate) final;
void setSequenceNumber (int sequenceNumber) final; void setSequenceNumber (int sequenceNumber) final;
void save (QJsonArray& missionItems) const final; int lastSequenceNumber (void) const final;
void save (QJsonArray& missionItems) final;
public slots: public slots:
void setDefaultsForCommand(void); void setDefaultsForCommand(void);
...@@ -104,9 +117,11 @@ signals: ...@@ -104,9 +117,11 @@ signals:
void headingDegreesChanged (double heading); void headingDegreesChanged (double heading);
void rawEditChanged (bool rawEdit); void rawEditChanged (bool rawEdit);
void uiModelChanged (void); void uiModelChanged (void);
void cameraSectionChanged (QObject* cameraSection);
private slots: private slots:
void _setDirtyFromSignal(void); void _setDirtyFromSignal(void);
void _cameraSectionDirtyChanged(bool dirty);
void _sendCommandChanged(void); void _sendCommandChanged(void);
void _sendCoordinateChanged(void); void _sendCoordinateChanged(void);
void _sendFrameChanged(void); void _sendFrameChanged(void);
...@@ -114,17 +129,21 @@ private slots: ...@@ -114,17 +129,21 @@ private slots:
void _sendUiModelChanged(void); void _sendUiModelChanged(void);
void _syncAltitudeRelativeToHomeToFrame(const QVariant& value); void _syncAltitudeRelativeToHomeToFrame(const QVariant& value);
void _syncFrameToAltitudeRelativeToHome(void); void _syncFrameToAltitudeRelativeToHome(void);
void _updateLastSequenceNumber(void);
private: private:
void _clearParamMetaData(void); void _clearParamMetaData(void);
void _connectSignals(void); void _connectSignals(void);
void _setupMetaData(void); void _setupMetaData(void);
void _updateCameraSection(void);
private: private:
MissionItem _missionItem; MissionItem _missionItem;
bool _rawEdit; bool _rawEdit;
bool _dirty; bool _dirty;
CameraSection* _cameraSection;
MissionCommandTree* _commandTree; MissionCommandTree* _commandTree;
Fact _altitudeRelativeToHomeFact; Fact _altitudeRelativeToHomeFact;
......
...@@ -294,7 +294,7 @@ void SurveyMissionItem::setDirty(bool dirty) ...@@ -294,7 +294,7 @@ void SurveyMissionItem::setDirty(bool dirty)
} }
} }
void SurveyMissionItem::save(QJsonArray& missionItems) const void SurveyMissionItem::save(QJsonArray& missionItems)
{ {
QJsonObject saveObject; QJsonObject saveObject;
...@@ -822,11 +822,10 @@ void SurveyMissionItem::_gridGenerator(const QList<QPointF>& polygonPoints, QLi ...@@ -822,11 +822,10 @@ void SurveyMissionItem::_gridGenerator(const QList<QPointF>& polygonPoints, QLi
} }
} }
QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const void SurveyMissionItem::appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent)
{ {
QmlObjectListModel* pMissionItems = new QmlObjectListModel;
int seqNum = _sequenceNumber; int seqNum = _sequenceNumber;
for (int i=0; i<_gridPoints.count(); i++) { for (int i=0; i<_gridPoints.count(); i++) {
QGeoCoordinate coord = _gridPoints[i].value<QGeoCoordinate>(); QGeoCoordinate coord = _gridPoints[i].value<QGeoCoordinate>();
double altitude = _gridAltitudeFact.rawValue().toDouble(); double altitude = _gridAltitudeFact.rawValue().toDouble();
...@@ -840,8 +839,8 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const ...@@ -840,8 +839,8 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
altitude, altitude,
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
pMissionItems); // parent - allow delete on pMissionItems to delete everthing missionItemParent);
pMissionItems->append(item); items.append(item);
if (_cameraTriggerFact.rawValue().toBool() && i == 0) { if (_cameraTriggerFact.rawValue().toBool() && i == 0) {
// Turn on camera // Turn on camera
...@@ -852,8 +851,8 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const ...@@ -852,8 +851,8 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 2-7 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 2-7
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
pMissionItems); // parent - allow delete on pMissionItems to delete everthing missionItemParent);
pMissionItems->append(item); items.append(item);
} }
} }
...@@ -866,11 +865,9 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const ...@@ -866,11 +865,9 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 2-7 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // param 2-7
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
pMissionItems); // parent - allow delete on pMissionItems to delete everthing missionItemParent);
pMissionItems->append(item); items.append(item);
} }
return pMissionItems;
} }
void SurveyMissionItem::_cameraTriggerChanged(void) void SurveyMissionItem::_cameraTriggerChanged(void)
......
...@@ -98,7 +98,6 @@ public: ...@@ -98,7 +98,6 @@ public:
double complexDistance (void) const final { return _surveyDistance; } double complexDistance (void) const final { return _surveyDistance; }
int lastSequenceNumber (void) const final; int lastSequenceNumber (void) const final;
QmlObjectListModel* getMissionItems (void) const final;
bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final; bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final;
double greatestDistanceTo (const QGeoCoordinate &other) const final; double greatestDistanceTo (const QGeoCoordinate &other) const final;
void setCruiseSpeed (double cruiseSpeed) final; void setCruiseSpeed (double cruiseSpeed) final;
...@@ -118,6 +117,7 @@ public: ...@@ -118,6 +117,7 @@ public:
QGeoCoordinate exitCoordinate (void) const final { return _exitCoordinate; } QGeoCoordinate exitCoordinate (void) const final { return _exitCoordinate; }
int sequenceNumber (void) const final { return _sequenceNumber; } int sequenceNumber (void) const final { return _sequenceNumber; }
double flightSpeed (void) final { return std::numeric_limits<double>::quiet_NaN(); } double flightSpeed (void) final { return std::numeric_limits<double>::quiet_NaN(); }
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
bool coordinateHasRelativeAltitude (void) const final { return _gridAltitudeRelativeFact.rawValue().toBool(); } bool coordinateHasRelativeAltitude (void) const final { return _gridAltitudeRelativeFact.rawValue().toBool(); }
bool exitCoordinateHasRelativeAltitude (void) const final { return _gridAltitudeRelativeFact.rawValue().toBool(); } bool exitCoordinateHasRelativeAltitude (void) const final { return _gridAltitudeRelativeFact.rawValue().toBool(); }
...@@ -127,7 +127,7 @@ public: ...@@ -127,7 +127,7 @@ public:
void setCoordinate (const QGeoCoordinate& coordinate) final; void setCoordinate (const QGeoCoordinate& coordinate) final;
void setSequenceNumber (int sequenceNumber) final; void setSequenceNumber (int sequenceNumber) final;
void setTurnaroundDist (double dist) { _turnaroundDistFact.setRawValue(dist); } void setTurnaroundDist (double dist) { _turnaroundDistFact.setRawValue(dist); }
void save (QJsonArray& missionItems) const final; void save (QJsonArray& missionItems) final;
static const char* jsonComplexItemTypeValue; static const char* jsonComplexItemTypeValue;
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "QmlObjectListModel.h" #include "QmlObjectListModel.h"
#include "Vehicle.h" #include "Vehicle.h"
class MissionItem;
// Abstract base class for all Simple and Complex visual mission objects. // Abstract base class for all Simple and Complex visual mission objects.
class VisualMissionItem : public QObject class VisualMissionItem : public QObject
{ {
...@@ -132,14 +134,20 @@ public: ...@@ -132,14 +134,20 @@ public:
virtual void setDirty (bool dirty) = 0; virtual void setDirty (bool dirty) = 0;
virtual void setCoordinate (const QGeoCoordinate& coordinate) = 0; virtual void setCoordinate (const QGeoCoordinate& coordinate) = 0;
virtual void setSequenceNumber (int sequenceNumber) = 0; virtual void setSequenceNumber (int sequenceNumber) = 0;
virtual int lastSequenceNumber (void) const = 0;
/// Save the item(s) in Json format /// Save the item(s) in Json format
/// @param missionItems Current set of mission items, new items should be appended to the end /// @param missionItems Current set of mission items, new items should be appended to the end
virtual void save(QJsonArray& missionItems) const = 0; virtual void save(QJsonArray& missionItems) = 0;
/// @return The QML resource file which contains the control which visualizes the item on the map. /// @return The QML resource file which contains the control which visualizes the item on the map.
virtual QString mapVisualQML(void) const = 0; virtual QString mapVisualQML(void) const = 0;
/// Returns the mission items associated with the complex item. Caller is responsible for freeing.
/// @param items List to append to
/// @param missionItemParent Parent object for newly created MissionItems
virtual void appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent) = 0;
static const char* jsonTypeKey; ///< Json file attribute which specifies the item type static const char* jsonTypeKey; ///< Json file attribute which specifies the item type
static const char* jsonTypeSimpleItemValue; ///< Item type is MISSION_ITEM static const char* jsonTypeSimpleItemValue; ///< Item type is MISSION_ITEM
static const char* jsonTypeComplexItemValue; ///< Item type is Complex Item static const char* jsonTypeComplexItemValue; ///< Item type is Complex Item
...@@ -162,6 +170,7 @@ signals: ...@@ -162,6 +170,7 @@ signals:
void specifiesCoordinateChanged (void); void specifiesCoordinateChanged (void);
void isStandaloneCoordinateChanged (void); void isStandaloneCoordinateChanged (void);
void flightSpeedChanged (double flightSpeed); void flightSpeedChanged (double flightSpeed);
void lastSequenceNumberChanged (int sequenceNumber);
void coordinateHasRelativeAltitudeChanged (bool coordinateHasRelativeAltitude); void coordinateHasRelativeAltitudeChanged (bool coordinateHasRelativeAltitude);
void exitCoordinateHasRelativeAltitudeChanged (bool exitCoordinateHasRelativeAltitude); void exitCoordinateHasRelativeAltitudeChanged (bool exitCoordinateHasRelativeAltitude);
......
...@@ -27,13 +27,15 @@ ComboBox { ...@@ -27,13 +27,15 @@ ComboBox {
border.color: control._qgcPal.buttonText border.color: control._qgcPal.buttonText
} }
Image { QGCColoredImage {
id: imageItem id: image
source: "/qmlimages/arrow-down.png" width: ScreenTools.defaultFontPixelHeight / 2
height: width
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: dropDownButtonWidth / 2 anchors.rightMargin: dropDownButtonWidth / 2
opacity: control.enabled ? 0.6 : 0.3 source: "/qmlimages/arrow-down.png"
color: qgcPal.text
} }
} }
} }
......
...@@ -2,6 +2,7 @@ Module QGroundControl.Controls ...@@ -2,6 +2,7 @@ Module QGroundControl.Controls
AnalyzePage 1.0 AnalyzePage.qml AnalyzePage 1.0 AnalyzePage.qml
AppMessages 1.0 AppMessages.qml AppMessages 1.0 AppMessages.qml
CameraSection 1.0 CameraSection.qml
ClickableColor 1.0 ClickableColor.qml ClickableColor 1.0 ClickableColor.qml
DropButton 1.0 DropButton.qml DropButton 1.0 DropButton.qml
DropPanel 1.0 DropPanel.qml DropPanel 1.0 DropPanel.qml
......
src/QmlControls/arrow-down.png

184 Bytes | W: | H:

src/QmlControls/arrow-down.png

169 Bytes | W: | H:

src/QmlControls/arrow-down.png
src/QmlControls/arrow-down.png
src/QmlControls/arrow-down.png
src/QmlControls/arrow-down.png
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment