diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h index dad179ac675459df5a6bae4b1de37850c90e9458..b12647ad7232749ea8372abf0516732f901c9a88 100644 --- a/src/FactSystem/Fact.h +++ b/src/FactSystem/Fact.h @@ -92,6 +92,9 @@ public: void _containerSetValue(const QVariant& value); + /// Generally you should not change the name of a fact. But if you know what you are doing, you can. + void _setName(const QString& name) { _name = name; } + signals: /// QObject Property System signal for value property changes /// diff --git a/src/MissionItem.cc b/src/MissionItem.cc index 1be08bb9257ef2932db7484d9a96d16f7589dfe2..d592a5ea126110075c131434fd5b433a8d5e6d70 100644 --- a/src/MissionItem.cc +++ b/src/MissionItem.cc @@ -38,7 +38,7 @@ const MissionItem::MavCmd2Name_t MissionItem::_rgMavCmd2Name[_cMavCmd2Name] = { { MAV_CMD_NAV_WAYPOINT, "Waypoint" }, { MAV_CMD_NAV_LOITER_UNLIM, "Loiter" }, { MAV_CMD_NAV_LOITER_TURNS, "Loiter (turns)" }, - { MAV_CMD_NAV_LOITER_TIME, "Loiter (unlimited)" }, + { MAV_CMD_NAV_LOITER_TIME, "Loiter (seconds)" }, { MAV_CMD_NAV_RETURN_TO_LAUNCH, "Return Home" }, { MAV_CMD_NAV_LAND, "Land" }, { MAV_CMD_NAV_TAKEOFF, "Takeoff" }, @@ -60,7 +60,7 @@ MissionItem::MissionItem(QObject* parent, : QObject(parent) , _sequenceNumber(sequenceNumber) , _coordinate(coordinate) - , _yaw(param4) + , _yawRadians(param4) , _frame(frame) , _action(action) , _autocontinue(autocontinue) @@ -69,8 +69,50 @@ MissionItem::MissionItem(QObject* parent, , _param1(param1) , _param2(param2) , _reachedTime(0) + , _yawFact(NULL) { + _yawFact = new Fact(0, "Heading:", FactMetaData::valueTypeDouble, this); + _pitchFact = new Fact(0, "Pitch:", FactMetaData::valueTypeDouble, this); + _loiterRadiusFact = new Fact(0, "Radius:", FactMetaData::valueTypeDouble, this); + _param1Fact = new Fact(0, QString(), FactMetaData::valueTypeDouble, this); + _param2Fact = new Fact(0, QString(), FactMetaData::valueTypeDouble, this); + + // FIXME: Need to fill out more meta data + + _yawMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _yawMetaData->setUnits("degrees"); + + _pitchMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _pitchMetaData->setUnits("degrees"); + + _acceptanceRadiusMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _acceptanceRadiusMetaData->setUnits("meters"); + + _holdTimeMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _holdTimeMetaData->setUnits("seconds"); + + _loiterRadiusMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _loiterRadiusMetaData->setUnits("meters"); + + _loiterTurnsMetaData = new FactMetaData(FactMetaData::valueTypeInt32, this); + _loiterTurnsMetaData->setUnits("count"); + + _loiterSecondsMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _loiterSecondsMetaData->setUnits("seconds"); + + _delaySecondsMetaData = new FactMetaData(FactMetaData::valueTypeDouble, this); + _delaySecondsMetaData->setUnits("seconds"); + + _jumpSequenceMetaData = new FactMetaData(FactMetaData::valueTypeInt32, this); + _jumpSequenceMetaData->setUnits("#"); + + _jumpRepeatMetaData = new FactMetaData(FactMetaData::valueTypeInt32, this); + _jumpRepeatMetaData->setUnits("count"); + + _yawFact->setMetaData(_yawMetaData); + _pitchFact->setMetaData(_pitchMetaData); + _loiterRadiusFact->setMetaData(_loiterRadiusMetaData); } MissionItem::MissionItem(const MissionItem& other) @@ -88,7 +130,7 @@ const MissionItem& MissionItem::operator=(const MissionItem& other) _sequenceNumber = other._sequenceNumber; _isCurrentItem = other._isCurrentItem; _coordinate = other._coordinate; - _yaw = other._yaw; + _yawRadians = other._yawRadians; _frame = other._frame; _action = other._action; _autocontinue = other._autocontinue; @@ -112,7 +154,7 @@ void MissionItem::save(QTextStream &saveStream) position = position.arg(y(), 0, 'g', 18); position = position.arg(z(), 0, 'g', 18); QString parameters("%1\t%2\t%3\t%4"); - parameters = parameters.arg(_param1, 0, 'g', 18).arg(_param2, 0, 'g', 18).arg(_orbit, 0, 'g', 18).arg(_yaw, 0, 'g', 18); + parameters = parameters.arg(_param1, 0, 'g', 18).arg(_param2, 0, 'g', 18).arg(_orbit, 0, 'g', 18).arg(_yawRadians, 0, 'g', 18); // FORMAT: // as documented here: http://qgroundcontrol.org/waypoint_protocol saveStream << this->sequenceNumber() << "\t" << this->isCurrentItem() << "\t" << this->getFrame() << "\t" << this->getAction() << "\t" << parameters << "\t" << position << "\t" << this->getAutoContinue() << "\r\n"; //"\t" << this->getDescription() << "\r\n"; @@ -129,7 +171,7 @@ bool MissionItem::load(QTextStream &loadStream) _param1 = wpParams[4].toDouble(); _param2 = wpParams[5].toDouble(); _orbit = wpParams[6].toDouble(); - setYaw(wpParams[7].toDouble()); + setYawRadians(wpParams[7].toDouble()); setLatitude(wpParams[8].toDouble()); setLongitude(wpParams[9].toDouble()); setAltitude(wpParams[10].toDouble()); @@ -202,17 +244,6 @@ void MissionItem::setAltitude(double altitude) } } -void MissionItem::setYaw(double yaw) -{ - if (_yaw != yaw) - { - _yaw = yaw; - emit yawChanged(yaw); - emit changed(this); - emit valueStringsChanged(valueStrings()); - } -} - void MissionItem::setAction(int /*MAV_CMD*/ action) { if (_action != action) { @@ -301,8 +332,8 @@ void MissionItem::setParam3(double param3) void MissionItem::setParam4(double param4) { - if (_yaw != param4) { - _yaw = param4; + if (_yawRadians != param4) { + _yawRadians = param4; emit changed(this); emit valueStringsChanged(valueStrings()); } @@ -362,15 +393,6 @@ void MissionItem::setHoldTime(double holdTime) } } -void MissionItem::setTurns(int turns) -{ - if (_param1 != turns) { - _param1 = turns; - emit changed(this); - emit valueStringsChanged(valueStrings()); - } -} - bool MissionItem::specifiesCoordinate(void) const { switch (_action) { @@ -486,24 +508,24 @@ QStringList MissionItem::valueStrings(void) switch (_action) { case MAV_CMD_NAV_WAYPOINT: - list << _oneDecimalString(_coordinate.altitude()) << _oneDecimalString(_yaw * (180.0 / M_PI)) << _oneDecimalString(_param2) << _oneDecimalString(_param1); + list << _oneDecimalString(_coordinate.altitude()) << _oneDecimalString(_yawRadians * (180.0 / M_PI)) << _oneDecimalString(_param2) << _oneDecimalString(_param1); break; case MAV_CMD_NAV_LOITER_UNLIM: - list << _oneDecimalString(_yaw * (180.0 / M_PI)) << _oneDecimalString(_orbit); + list << _oneDecimalString(_yawRadians * (180.0 / M_PI)) << _oneDecimalString(_orbit); break; case MAV_CMD_NAV_LOITER_TURNS: - list << _oneDecimalString(_yaw * (180.0 / M_PI)) << _oneDecimalString(_orbit) << _oneDecimalString(_turns); + list << _oneDecimalString(_yawRadians * (180.0 / M_PI)) << _oneDecimalString(_orbit) << _oneDecimalString(_param1); break; case MAV_CMD_NAV_LOITER_TIME: - list << _oneDecimalString(_yaw * (180.0 / M_PI)) << _oneDecimalString(_orbit) << _oneDecimalString(_param1); + list << _oneDecimalString(_yawRadians * (180.0 / M_PI)) << _oneDecimalString(_orbit) << _oneDecimalString(_param1); break; case MAV_CMD_NAV_RETURN_TO_LAUNCH: break; case MAV_CMD_NAV_LAND: - list << _oneDecimalString(_coordinate.altitude()) << _oneDecimalString(_yaw * (180.0 / M_PI)); + list << _oneDecimalString(_coordinate.altitude()) << _oneDecimalString(_yawRadians * (180.0 / M_PI)); break; case MAV_CMD_NAV_TAKEOFF: - list << _oneDecimalString(_coordinate.altitude()) << _oneDecimalString(_yaw * (180.0 / M_PI)) << _oneDecimalString(_param1); + list << _oneDecimalString(_coordinate.altitude()) << _oneDecimalString(_yawRadians * (180.0 / M_PI)) << _oneDecimalString(_param1); break; case MAV_CMD_CONDITION_DELAY: list << _oneDecimalString(_param1); @@ -555,3 +577,90 @@ void MissionItem::setCommandByIndex(int index) setCommand((MavlinkQmlSingleton::Qml_MAV_CMD)_rgMavCmd2Name[index].command); } + +QmlObjectListModel* MissionItem::facts(void) +{ + QmlObjectListModel* model = new QmlObjectListModel(this); + + switch (_action) { + case MAV_CMD_NAV_WAYPOINT: + _param2Fact->_setName("Radius:"); + _param2Fact->setMetaData(_acceptanceRadiusMetaData); + _param1Fact->_setName("Hold:"); + _param1Fact->setMetaData(_holdTimeMetaData); + model->append(_yawFact); + model->append(_param2Fact); + model->append(_param1Fact); + break; + case MAV_CMD_NAV_LOITER_UNLIM: + model->append(_yawFact); + model->append(_loiterRadiusFact); + break; + case MAV_CMD_NAV_LOITER_TURNS: + _param1Fact->_setName("Turns:"); + _param1Fact->setMetaData(_loiterTurnsMetaData); + model->append(_yawFact); + model->append(_loiterRadiusFact); + model->append(_param1Fact); + break; + case MAV_CMD_NAV_LOITER_TIME: + _param1Fact->_setName("Seconds:"); + _param1Fact->setMetaData(_loiterSecondsMetaData); + model->append(_yawFact); + model->append(_loiterRadiusFact); + model->append(_param1Fact); + break; + case MAV_CMD_NAV_RETURN_TO_LAUNCH: + break; + case MAV_CMD_NAV_LAND: + model->append(_yawFact); + break; + case MAV_CMD_NAV_TAKEOFF: + model->append(_yawFact); + model->append(_pitchFact); + break; + case MAV_CMD_CONDITION_DELAY: + _param1Fact->_setName("Seconds:"); + _param1Fact->setMetaData(_delaySecondsMetaData); + model->append(_param1Fact); + break; + case MAV_CMD_DO_JUMP: + _param1Fact->_setName("Seq #:"); + _param1Fact->setMetaData(_jumpSequenceMetaData); + _param2Fact->_setName("Repeat:"); + _param2Fact->setMetaData(_jumpRepeatMetaData); + model->append(_param1Fact); + model->append(_param2Fact); + break; + } + + return model; +} + +double MissionItem::yawRadians(void) const +{ + return _yawRadians; +} + +void MissionItem::setYawRadians(double yaw) +{ + if (_yawRadians != yaw) + { + _yawRadians = yaw; + emit yawChanged(yaw); + emit changed(this); + emit valueStringsChanged(valueStrings()); + } +} + + +double MissionItem::yawDegrees(void) const +{ + return _yawRadians * (180.0 / M_PI); +} + +void MissionItem::setYawDegrees(double yaw) +{ + setYawRadians(yaw * (M_PI / 180.0)); +} + diff --git a/src/MissionItem.h b/src/MissionItem.h index 300ac3d7f4da38268e3daddfc7e4e681f8e2b9d4..b561e3beeec840f942c6b133064cb30030f92947 100644 --- a/src/MissionItem.h +++ b/src/MissionItem.h @@ -33,6 +33,8 @@ #include "QGCMAVLink.h" #include "QGC.h" #include "MavlinkQmlSingleton.h" +#include "QmlObjectListModel.h" +#include "Fact.h" class MissionItem : public QObject { @@ -56,17 +58,18 @@ public: const MissionItem& operator=(const MissionItem& other); - Q_PROPERTY(int sequenceNumber READ sequenceNumber WRITE setSequenceNumber NOTIFY sequenceNumberChanged) - Q_PROPERTY(bool isCurrentItem READ isCurrentItem WRITE setIsCurrentItem NOTIFY isCurrentItemChanged) - Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate NOTIFY specifiesCoordinateChanged) - Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged) - Q_PROPERTY(double yaw READ yaw WRITE setYaw NOTIFY yawChanged) - Q_PROPERTY(QStringList commandNames READ commandNames CONSTANT) - Q_PROPERTY(QString commandName READ commandName NOTIFY commandChanged) - Q_PROPERTY(QStringList valueLabels READ valueLabels NOTIFY commandChanged) - Q_PROPERTY(QStringList valueStrings READ valueStrings NOTIFY valueStringsChanged) - Q_PROPERTY(int commandByIndex READ commandByIndex WRITE setCommandByIndex NOTIFY commandChanged) - Q_PROPERTY(MavlinkQmlSingleton::Qml_MAV_CMD command READ command WRITE setCommand NOTIFY commandChanged) + Q_PROPERTY(int sequenceNumber READ sequenceNumber WRITE setSequenceNumber NOTIFY sequenceNumberChanged) + Q_PROPERTY(bool isCurrentItem READ isCurrentItem WRITE setIsCurrentItem NOTIFY isCurrentItemChanged) + Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate NOTIFY specifiesCoordinateChanged) + Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged) + Q_PROPERTY(double yaw READ yawDegrees WRITE setYawDegrees NOTIFY yawChanged) + Q_PROPERTY(QStringList commandNames READ commandNames CONSTANT) + Q_PROPERTY(QString commandName READ commandName NOTIFY commandChanged) + Q_PROPERTY(QStringList valueLabels READ valueLabels NOTIFY commandChanged) + Q_PROPERTY(QStringList valueStrings READ valueStrings NOTIFY valueStringsChanged) + Q_PROPERTY(int commandByIndex READ commandByIndex WRITE setCommandByIndex NOTIFY commandChanged) + Q_PROPERTY(QmlObjectListModel* facts READ facts NOTIFY commandChanged) + Q_PROPERTY(MavlinkQmlSingleton::Qml_MAV_CMD command READ command WRITE setCommand NOTIFY commandChanged) // Property accesors @@ -93,6 +96,11 @@ public: QStringList valueLabels(void); QStringList valueStrings(void); + QmlObjectListModel* facts(void); + + double yawDegrees(void) const; + void setYawDegrees(double yaw); + // C++ only methods double latitude(void) const { return _coordinate.latitude(); } @@ -111,8 +119,8 @@ public: void setY(double y); void setZ(double z); - double yaw(void) const { return _yaw; } - void setYaw(double yaw); + double yawRadians(void) const; + void setYawRadians(double yaw); bool getAutoContinue() const { return _autocontinue; @@ -136,7 +144,7 @@ public: return _orbit; } double getParam4() const { - return yaw(); + return yawRadians(); } double getParam5() const { return latitude(); @@ -147,9 +155,6 @@ public: double getParam7() const { return altitude(); } - int getTurns() const { - return _param1; - } // MAV_FRAME int getFrame() const { return _frame; @@ -201,8 +206,6 @@ public: void setAcceptanceRadius(double radius); void setHoldTime (int holdTime); void setHoldTime (double holdTime); - /** @brief Number of turns for loiter waypoints */ - void setTurns (int _turns); /** @brief Set waypoint as reached */ void setReached () { _reachedTime = QGC::groundTimeMilliseconds(); } /** @brief Wether this waypoint has been reached yet */ @@ -223,7 +226,7 @@ private: int _sequenceNumber; QGeoCoordinate _coordinate; - double _yaw; + double _yawRadians; int _frame; int _action; bool _autocontinue; @@ -231,9 +234,25 @@ private: double _orbit; double _param1; double _param2; - int _turns; quint64 _reachedTime; + Fact* _yawFact; + Fact* _pitchFact; + Fact* _loiterRadiusFact; + Fact* _param1Fact; + Fact* _param2Fact; + + FactMetaData* _yawMetaData; + FactMetaData* _pitchMetaData; + FactMetaData* _acceptanceRadiusMetaData; + FactMetaData* _holdTimeMetaData; + FactMetaData* _loiterRadiusMetaData; + FactMetaData* _loiterTurnsMetaData; + FactMetaData* _loiterSecondsMetaData; + FactMetaData* _delaySecondsMetaData; + FactMetaData* _jumpSequenceMetaData; + FactMetaData* _jumpRepeatMetaData; + static const int _cMavCmd2Name = 9; static const MavCmd2Name_t _rgMavCmd2Name[_cMavCmd2Name]; }; diff --git a/src/QmlControls/MissionItemEditor.qml b/src/QmlControls/MissionItemEditor.qml index b6f32e61195e1fd7236f0ac96e9af5a31b22faf8..8105c05c5b9e2f7a6a002eaff15de37996be1fde 100644 --- a/src/QmlControls/MissionItemEditor.qml +++ b/src/QmlControls/MissionItemEditor.qml @@ -4,6 +4,8 @@ import QtQuick.Controls.Styles 1.2 import QGroundControl.ScreenTools 1.0 import QGroundControl.Vehicle 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FactControls 1.0 /// Mission item edit control Rectangle { @@ -117,32 +119,29 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.top: missionItem.specifiesCoordinate ? _altitudeField.bottom : _commandCombo.bottom + spacing: parent.radius / 2 Repeater { - model: missionItem.valueLabels - - QGCLabel { - color: "black" - text: modelData + model: missionItem.facts + + Item { + width: _valueColumn.width + height: textField.height + + QGCLabel { + anchors.baseline: textField.baseline + color: "black" + text: object.name + } + + FactTextField { + id: textField + anchors.right: parent.right + width: _editFieldWidth + showUnits: true + fact: object + } } } - } - - Column { - anchors.margins: parent.radius / 2 - anchors.left: parent.left - anchors.right: parent.right - anchors.top: _valueColumn.top - - Repeater { - model: missionItem.valueStrings - - QGCLabel { - width: _valueColumn.width - color: "black" - text: modelData - horizontalAlignment: Text.AlignRight - } - } - } -} + } // Column - Values column +} // Rectangle