Commit 205138cf authored by Don Gagne's avatar Don Gagne

Fixed Wing landing pattern starting point

Also added ui support for multiple complex item types
parent e4fddb3f
......@@ -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 \
......
......@@ -149,6 +149,7 @@
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
<file alias="SimpleItemEditor.qml">src/MissionEditor/SimpleItemEditor.qml</file>
<file alias="SurveyItemEditor.qml">src/MissionEditor/SurveyItemEditor.qml</file>
<file alias="FWLandingPatternEditor.qml">src/MissionEditor/FWLandingPatternEditor.qml</file>
<file alias="TcpSettings.qml">src/ui/preferences/TcpSettings.qml</file>
<file alias="test.qml">src/test.qml</file>
<file alias="UdpSettings.qml">src/ui/preferences/UdpSettings.qml</file>
......@@ -169,6 +170,7 @@
<file alias="Vehicle/VibrationFact.json">src/Vehicle/VibrationFact.json</file>
<file alias="QGroundControlQmlGlobal.json">src/QmlControls/QGroundControlQmlGlobal.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="Survey.FactMetaData.json">src/MissionManager/Survey.FactMetaData.json</file>
<file alias="USBBoardInfo.json">src/comm/USBBoardInfo.json</file>
</qresource>
......
/****************************************************************************
*
* (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.
*
****************************************************************************/
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" }
}
}
......@@ -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
......@@ -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; })
......
/****************************************************************************
*
* (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.
*
****************************************************************************/
#include "FixedWingLandingComplexItem.h"
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include <QPolygonF>
QGC_LOGGING_CATEGORY(FixedWingLandingComplexItemLog, "FixedWingLandingComplexItemLog")
const char* FixedWingLandingComplexItem::jsonComplexItemTypeValue = "fwLandingPattern";
QMap<QString, FactMetaData*> 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<QGeoCoordinate>();
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<QGeoCoordinate>();
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);
}
/****************************************************************************
*
* (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 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<double>::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<QString, FactMetaData*> _metaDataMap;
};
#endif
......@@ -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);
......
......@@ -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;
......
......@@ -64,6 +64,8 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent)
, _syncingAltitudeRelativeToHomeAndFrame (false)
, _syncingHeadingDegreesAndParam4 (false)
{
_editorQml = "qrc:/qml/SimpleItemEditor.qml";
_altitudeRelativeToHomeFact.setRawValue(true);
_setupMetaData();
......
......@@ -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 */);
}
......
......@@ -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;
......
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