diff --git a/qgcresources.qrc b/qgcresources.qrc
index c6c6cf321bf249f9a4d74fb9a8a25ef7395bdb89..dda957c4ec49f16b5f271c02b7f1ff12cfc53c99 100644
--- a/qgcresources.qrc
+++ b/qgcresources.qrc
@@ -18,7 +18,7 @@
resources/counter-clockwise-arrow.svg
resources/chevron-down.svg
resources/chevron-up.svg
- resources/DropArrow.svg
+ resources/DropArrow.svg
resources/gear-black.svg
resources/gear-white.svg
resources/helicoptericon.svg
@@ -34,7 +34,7 @@
resources/Play.svg
resources/PowerButton.svg
resources/QGCLogoBlack.svg
- resources/QGCLogoFull.svg
+ resources/QGCLogoFull.svg
resources/QGCLogoWhite.svg
resources/QGCLogoArrow.svg
resources/QGroundControlConnect.svg
@@ -56,6 +56,7 @@
resources/street.png
resources/measurement.png
resources/calculator.png
+ resources/fish.svg
resources/firmware/3drradio.png
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index b2dc3e37e65e38d04f477e4d26b0b2b361df3da2..6774f22a8b9bfb67659de2c4c8c052f554a55807 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -293,6 +293,7 @@
src/MeasurementComplexItem/qml/AreaDataEditor.qml
src/MeasurementComplexItem/qml/ParameterEditor.qml
src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir
+ src/MeasurementComplexItem/qml/NemoEditor.qml
src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml
diff --git a/resources/InstrumentValueIcons/.directory b/resources/InstrumentValueIcons/.directory
new file mode 100644
index 0000000000000000000000000000000000000000..deeb4ca199fd64c4dc8beb4d956030d9ca0ba6bf
--- /dev/null
+++ b/resources/InstrumentValueIcons/.directory
@@ -0,0 +1,4 @@
+[Dolphin]
+PreviewsShown=true
+Timestamp=2020,12,19,15,18,21
+Version=4
diff --git a/resources/credits.txt b/resources/credits.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f645d7379802e0e1938b6f9d64f1409f07807cae
--- /dev/null
+++ b/resources/credits.txt
@@ -0,0 +1 @@
+fish.svg: from https://commons.wikimedia.org/wiki/File:Font_Awesome_5_solid_fish.svg
diff --git a/resources/fish.svg b/resources/fish.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b5e0bf2a719dadcd790006b43ed15cd264713e09
--- /dev/null
+++ b/resources/fish.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/src/MeasurementComplexItem/AreaData.cc b/src/MeasurementComplexItem/AreaData.cc
index a8579e7f1b9267ad866b39781603de1febdc13a8..165e531a5de0069d9f267fe4e9f49b532f1f6e74 100644
--- a/src/MeasurementComplexItem/AreaData.cc
+++ b/src/MeasurementComplexItem/AreaData.cc
@@ -126,8 +126,9 @@ bool AreaData::isCorrect(bool showError) {
// ss << "safeAreaENU: " << bg::wkt(safeAreaENU) << std::endl;
// qDebug() << ss.str().c_str();
if (!bg::covered_by(measurementAreaENU, safeAreaENU)) {
- _processError(tr("Measurement Area not inside Safe Area. Please adjust "
- "the Measurement Area.\n"),
+ _processError(tr("Measurement Area is not covered by Safe "
+ "Area. Please adjust "
+ "the areas accordingly.\n"),
showError);
return false;
}
@@ -228,10 +229,10 @@ void AreaData::intersection(bool showError) {
boost::geometry::intersection(measurementAreaENU, safeAreaENU, outputENU);
if (outputENU.size() < 1 || outputENU[0].outer().size() < 4) {
- _processError(
- "Intersection did't deliver any result. Measurement Area and "
- "Safe Area must touch each other.",
- showError);
+ _processError("Intersection did't deliver any result. The Measurement "
+ "Area(s) and "
+ "The Safe Area must touch each other.",
+ showError);
return;
}
@@ -266,11 +267,29 @@ void AreaData::intersection(bool showError) {
}
}
-MeasurementArea *AreaData::measurementArea() {
- return getGeoArea(_areaList);
+QVector AreaData::measurementAreaArray() {
+ return getGeoAreaList(_areaList);
+}
+
+QVector AreaData::safeAreaArray() {
+ return getGeoAreaList(_areaList);
}
-SafeArea *AreaData::safeArea() { return getGeoArea(_areaList); }
+QmlObjectListModel *AreaData::measurementAreaList() {
+ _measurementAreaList.clear();
+ auto array = getGeoAreaList(_areaList);
+ for (auto area : array)
+ _measurementAreaList.append(area);
+ return &_measurementAreaList;
+}
+
+QmlObjectListModel *AreaData::safeAreaList() {
+ _safeAreaList.clear();
+ auto array = getGeoAreaList(_areaList);
+ for (auto &area : array)
+ _safeAreaList.append(area);
+ return &_safeAreaList;
+}
bool AreaData::operator==(const AreaData &other) const {
if (_areaList.count() == other._areaList.count()) {
@@ -442,13 +461,13 @@ bool AreaData::_getAreas(MeasurementArea **measurementArea, SafeArea **safeArea,
*measurementArea = getGeoArea(_areaList);
if (*measurementArea == nullptr) {
_processError(
- tr("Measurement Area missing. Please define a measurement area."),
+ tr("Measurement Area is missing. Please define a Measurement Area."),
showError);
return false;
}
*safeArea = getGeoArea(_areaList);
if (*safeArea == nullptr) {
- _processError(tr("Safe Area missing. Please define a safe area."),
+ _processError(tr("Safe Area is missing. Please define a Safe Area."),
showError);
return false;
}
diff --git a/src/MeasurementComplexItem/AreaData.h b/src/MeasurementComplexItem/AreaData.h
index f2f3ac2c2f1d3cd31b2fed4638ec5d9c97369468..3f87865f6a126c2f58ce06a0eb8c081bcdb428cc 100644
--- a/src/MeasurementComplexItem/AreaData.h
+++ b/src/MeasurementComplexItem/AreaData.h
@@ -20,6 +20,10 @@ public:
AreaData &operator=(const AreaData &other);
Q_PROPERTY(QmlObjectListModel *areaList READ areaList NOTIFY areaListChanged)
+ Q_PROPERTY(QmlObjectListModel *measurementAreaList READ measurementAreaList
+ NOTIFY areaListChanged)
+ Q_PROPERTY(
+ QmlObjectListModel *safeAreaList READ safeAreaList NOTIFY areaListChanged)
Q_PROPERTY(QString errorString READ errorString NOTIFY error)
// Member Methodes
@@ -70,8 +74,10 @@ public:
Q_INVOKABLE bool initialized();
Q_INVOKABLE void intersection(bool showError = true);
- Q_INVOKABLE MeasurementArea *measurementArea();
- Q_INVOKABLE SafeArea *safeArea();
+ QVector measurementAreaArray();
+ QVector safeAreaArray();
+ QmlObjectListModel *measurementAreaList();
+ QmlObjectListModel *safeAreaList();
bool operator==(const AreaData &other) const;
bool operator!=(const AreaData &other) const;
@@ -97,5 +103,7 @@ private:
QGeoCoordinate _origin;
QmlObjectListModel _areaList;
+ QmlObjectListModel _measurementAreaList;
+ QmlObjectListModel _safeAreaList;
QString _errorString;
};
diff --git a/src/MeasurementComplexItem/GeneratorBase.h b/src/MeasurementComplexItem/GeneratorBase.h
index b0ce44f455495ca5e87c3525880c66f5c9cda01c..4d1f6daf45cbe8dd012d167454f3be6692a7a2ff 100644
--- a/src/MeasurementComplexItem/GeneratorBase.h
+++ b/src/MeasurementComplexItem/GeneratorBase.h
@@ -83,9 +83,9 @@ private:
std::map _creatorMap;
};
+#define pGeneratorFactory ::routing::GeneratorFactory::instance()
#define REGISTER_GENERATOR(type, creator) \
namespace { \
- auto registered = \
- GeneratorFactory::instance() -> registerGenerator(type, creator); \
+ auto registered = pGeneratorFactory -> registerGenerator(type, creator); \
}
} // namespace routing
diff --git a/src/MeasurementComplexItem/GenericSingelton.h b/src/MeasurementComplexItem/GenericSingelton.h
index 93e1ec0d5b684d8059b896f607a4851018b611ae..940d07c05853f6e5bcc4bc55df8a703ac0b1f6c8 100644
--- a/src/MeasurementComplexItem/GenericSingelton.h
+++ b/src/MeasurementComplexItem/GenericSingelton.h
@@ -3,6 +3,8 @@
#include
#include
+// from https://stackoverflow.com/questions/46172607/qt-singleton-implementation
+
template class GenericSingelton {
private:
typedef T *(*CreateInstanceFunction)();
diff --git a/src/MeasurementComplexItem/MeasurementComplexItem.cc b/src/MeasurementComplexItem/MeasurementComplexItem.cc
index 723ccbf4b62845abb6da8861b8642f2f906d01af..d287a3032a2a56df9cf4c698c545225565af7ccf 100644
--- a/src/MeasurementComplexItem/MeasurementComplexItem.cc
+++ b/src/MeasurementComplexItem/MeasurementComplexItem.cc
@@ -247,8 +247,7 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject,
QString e;
// create generator
- auto gen = routing::GeneratorFactory::instance()->create(
- jsonGen, e, &parent /*parent*/);
+ auto gen = pGeneratorFactory->create(jsonGen, e, &parent /*parent*/);
if (gen != nullptr) {
// remove generators of same type and insert this generator.
@@ -267,7 +266,7 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject,
errorString.append(
tr("Error loading generator of type ") +
jsonGen[routing::GeneratorBase::typeKey].toString() + ".\n");
- if (!routing::GeneratorFactory::instance()->registered(
+ if (!pGeneratorFactory->registered(
jsonGen[routing::GeneratorBase::typeKey].toString())) {
errorString.append(tr("This type is unknown.\n"));
qCritical()
@@ -360,8 +359,10 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject,
// Check if variants are covered by safe area.
if (variantsSuccess) {
- auto safeArea = _pCurrentData->safeArea();
- if (safeArea != nullptr) {
+ auto safeAreaArray = _pCurrentData->safeAreaArray();
+
+ if (safeAreaArray.size() > 0 && safeAreaArray.at(0) != nullptr) {
+ auto safeArea = safeAreaArray[0];
QGeoCoordinate origin =
safeArea->pathModel().value(0)->coordinate();
snake::FPolygon safeAreaENU;
@@ -733,8 +734,11 @@ void MeasurementComplexItem::_updateFlightpathSegments() {
if (hasCollisionOld != hasCollision) {
emit terrainCollisionChanged(hasCollision);
}
- if (_pAreaData->measurementArea() != nullptr) {
- _pAreaData->measurementArea()->setShowAltColor(hasCollision);
+ auto measurementAreaArray = _pAreaData->measurementAreaArray();
+ for (auto area : measurementAreaArray) {
+ if (area != nullptr) {
+ area->setShowAltColor(hasCollision);
+ }
}
_masterController->missionController()->recalcTerrainProfile();
@@ -782,6 +786,20 @@ void MeasurementComplexItem::_updateRoute() {
if (this->_pAreaData->isCorrect()) {
+ auto measurmentAreaArray = _pAreaData->measurementAreaArray();
+ bool measurementComplete = true;
+ for (const auto &area : measurmentAreaArray) {
+ if (!area->measurementCompleted()) {
+ measurementComplete = false;
+ }
+ }
+
+ if (measurementComplete) {
+ qCDebug(MeasurementComplexItemLog)
+ << "_updateWorker(): measurement complete!";
+ return;
+ }
+
// Prepare data.
auto origin = this->_pAreaData->origin();
origin.setAltitude(0);
@@ -1039,13 +1057,13 @@ void MeasurementComplexItem::resetGenerators() {
removeGenerator(0);
}
- auto lg = routing::GeneratorFactory::instance()->create(
- routing::LinearGenerator::typeString, this);
+ auto lg =
+ pGeneratorFactory->create(routing::LinearGenerator::typeString, this);
lg->setData(this->_pAreaData);
addGenerator(lg);
- auto cg = routing::GeneratorFactory::instance()->create(
- routing::CircularGenerator::typeString, this);
+ auto cg =
+ pGeneratorFactory->create(routing::CircularGenerator::typeString, this);
cg->setData(this->_pAreaData);
addGenerator(cg);
}
@@ -1139,6 +1157,24 @@ void MeasurementComplexItem::abortEditing() {
}
}
+void MeasurementComplexItem::reset() {
+ if (editing()) {
+ *_pEditorData = *_pAreaData;
+ }
+}
+
+bool MeasurementComplexItem::initialize(const QGeoCoordinate &bottomLeft,
+ const QGeoCoordinate &topRight) {
+ bool r1 = _pAreaData->initialize(bottomLeft, topRight);
+ bool r2 = _pEditorData->initialize(bottomLeft, topRight);
+
+ return r1 && r2;
+}
+
+bool MeasurementComplexItem::initialized() {
+ return _pCurrentData->initialized();
+}
+
void MeasurementComplexItem::_storeRoutingData(
MeasurementComplexItem::PtrRoutingData pRoute) {
if (this->_state == STATE::ROUTING) {
diff --git a/src/MeasurementComplexItem/MeasurementComplexItem.h b/src/MeasurementComplexItem/MeasurementComplexItem.h
index 0c20fd1e6dcc3e2aa42a74fe8e675b9b97d6fc3f..f87224987f65305b8737deefb4f61cfc1830c127 100644
--- a/src/MeasurementComplexItem/MeasurementComplexItem.h
+++ b/src/MeasurementComplexItem/MeasurementComplexItem.h
@@ -174,6 +174,31 @@ public:
//! editingStart().
//!
Q_INVOKABLE void abortEditing();
+ //!
+ //! \brief reset Resets the areas to the state before startEditing().
+ //!
+ //! Resets the areas to the state before startEditing(). Does nothing if
+ //! editinge() == false.
+ //!
+ Q_INVOKABLE void reset();
+
+ //!
+ //! \brief initialize Initializes the areas in a valid way, such that they
+ //! area inside the bounding box. \param bottomLeft bottom left corner of the
+ //! bounding box. \param topRight top right corner of the bounding box. \note
+ //! Behavior is undefined, if \p bottomLeft and \p topRight are not the bottom
+ //! left and the top right corner of the bounding box. \return Returns true on
+ //! succes, false either.
+ //!
+ Q_INVOKABLE bool initialize(const QGeoCoordinate &bottomLeft,
+ const QGeoCoordinate &topRight);
+ //!
+ //! \brief initialized Checks if area data is initialized
+ //! \return Returns true if area list contains a SafeArea and a
+ //! MeasurementArea and both areas have at least three vertices, returns false
+ //! either.
+ //!
+ Q_INVOKABLE bool initialized();
// Property getters
const AreaData *areaData() const;
diff --git a/src/MeasurementComplexItem/NemoInterface.cpp b/src/MeasurementComplexItem/NemoInterface.cpp
index 94a61efa883a5d5526c0362dce2fe32eef9d018c..afd765cf4a3d0f40eb8fc03156fc13eea80c0fd3 100644
--- a/src/MeasurementComplexItem/NemoInterface.cpp
+++ b/src/MeasurementComplexItem/NemoInterface.cpp
@@ -12,6 +12,7 @@
#include
+#include "GenericSingelton.h"
#include "geometry/MeasurementArea.h"
#include "geometry/snake.h"
#include "nemo_interface/QNemoHeartbeat.h"
@@ -426,8 +427,15 @@ bool NemoInterface::Impl::setStatus(NemoInterface::STATUS s) {
// ===============================================================
// NemoInterface
-NemoInterface::NemoInterface(QObject *parent)
- : QObject(parent), pImpl(std::make_unique(this)) {}
+NemoInterface::NemoInterface()
+ : QObject(), pImpl(std::make_unique(this)) {}
+
+NemoInterface *NemoInterface::createInstance() { return new NemoInterface(); }
+
+NemoInterface *NemoInterface::instance() {
+ return GenericSingelton::instance(
+ NemoInterface::createInstance);
+}
NemoInterface::~NemoInterface() {}
@@ -449,9 +457,7 @@ bool NemoInterface::hasTileData(const TileData &tileData) const {
return this->pImpl->hasTileData(tileData);
}
-int NemoInterface::status() const { return integral(this->pImpl->status()); }
-
-NemoInterface::STATUS NemoInterface::statusEnum() const {
+NemoInterface::STATUS NemoInterface::status() const {
return this->pImpl->status();
}
diff --git a/src/MeasurementComplexItem/NemoInterface.h b/src/MeasurementComplexItem/NemoInterface.h
index 459f02917dae3f177ef96e5579db979054c80c31..681d3251ca8543d3928d13d5756601d184bc028a 100644
--- a/src/MeasurementComplexItem/NemoInterface.h
+++ b/src/MeasurementComplexItem/NemoInterface.h
@@ -12,7 +12,14 @@ class NemoInterface : public QObject {
class Impl;
using PImpl = std::unique_ptr;
+ NemoInterface();
+ NemoInterface(NemoInterface &other) = delete;
+ static NemoInterface *createInstance();
+
public:
+ ~NemoInterface() override;
+ static NemoInterface *instance();
+
enum class STATUS {
NOT_CONNECTED = 0,
HEARTBEAT_DETECTED = 1,
@@ -20,11 +27,9 @@ public:
TIMEOUT = -1,
INVALID_HEARTBEAT = -2
};
+ Q_ENUM(STATUS)
- explicit NemoInterface(QObject *parent = nullptr);
- ~NemoInterface() override;
-
- Q_PROPERTY(int status READ status NOTIFY statusChanged)
+ Q_PROPERTY(STATUS status READ status NOTIFY statusChanged)
Q_PROPERTY(QString statusString READ statusString NOTIFY statusChanged)
Q_PROPERTY(QVector progress READ progress NOTIFY progressChanged)
Q_PROPERTY(QString editorQml READ editorQml CONSTANT)
@@ -40,8 +45,7 @@ public:
void setAutoPublish(bool ap);
void setHoldProgress(bool hp);
- int status() const;
- STATUS statusEnum() const;
+ STATUS status() const;
QString statusString() const;
QVector progress() const;
QString editorQml();
@@ -55,3 +59,5 @@ signals:
private:
PImpl pImpl;
};
+
+#define pNemoInterface NemoInterface::instance()
diff --git a/src/MeasurementComplexItem/geometry/GeoArea.h b/src/MeasurementComplexItem/geometry/GeoArea.h
index 0bd637ad8ff007de4517494b8ce8ebc24ca87159..9dff92211fb42e5982f3d238e4a7ee8fffa89bf9 100644
--- a/src/MeasurementComplexItem/geometry/GeoArea.h
+++ b/src/MeasurementComplexItem/geometry/GeoArea.h
@@ -56,8 +56,14 @@ private:
// Example usage:
// QmlObjecListModel list;
// .... add areas ....
-// auto area = getArea(list); // returns the first
-// WimaMeasurementArea or nullptr
+// auto area = getGeoArea(list); // returns the first
+// MeasurementArea or nullptr
+//! \example
+//!
+//! QmlObjecListModel list;
+//! // .... add areas ....
+//! auto area = getGeoArea(list); // returns the first
+//! MeasurementArea or nullptr
template
inline AreaPtr getGeoArea(QObjectList &list) {
static_assert(std::is_pointer::value,
@@ -72,5 +78,28 @@ inline AreaPtr getGeoArea(QObjectList &list) {
return nullptr;
}
+//! \example
+//!
+//! QmlObjecListModel list;
+//! // .... add areas ....
+//! auto areaArray = getGeoAreaArray(list); // returns a
+//! QList
+//! // containing all MeasurementArea's inside list
+template class Container = QList,
+ class QObjectList>
+inline Container getGeoAreaList(QObjectList &list) {
+ static_assert(std::is_pointer::value,
+ "AreaPtr must be a pointer type.");
+ Container out;
+ for (int i = 0; i < list.count(); ++i) {
+ auto obj = list[i];
+ auto area = qobject_cast(obj);
+ if (area != nullptr) {
+ out.append(area);
+ }
+ }
+ return out;
+}
+
bool copyAreaList(const QmlObjectListModel &from, QmlObjectListModel &to,
QObject *parent);
diff --git a/src/MeasurementComplexItem/geometry/MeasurementArea.cc b/src/MeasurementComplexItem/geometry/MeasurementArea.cc
index af45d7a10f01871e41e61fae198efc61e8400d83..84080c576536720422f5dda30daa49f0f3256057 100644
--- a/src/MeasurementComplexItem/geometry/MeasurementArea.cc
+++ b/src/MeasurementComplexItem/geometry/MeasurementArea.cc
@@ -2,6 +2,7 @@
#include "QtConcurrentRun"
#include "nemo_interface/SnakeTile.h"
#include "snake.h"
+#include
#include
@@ -170,7 +171,7 @@ MeasurementArea::MeasurementArea(QObject *parent)
this /* QObject parent */)),
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesKey],
this /* QObject parent */)),
- _state(STATE::IDLE) {
+ _holdProgress(false), _state(STATE::IDLE) {
init();
}
@@ -188,7 +189,7 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent)
this /* QObject parent */)),
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesKey],
this /* QObject parent */)),
- _state(STATE::IDLE) {
+ _holdProgress(false), _state(STATE::IDLE) {
init();
disableUpdate();
@@ -272,6 +273,19 @@ int MeasurementArea::maxTiles() const { return SNAKE_MAX_TILES; }
bool MeasurementArea::ready() const { return this->_state == STATE::IDLE; }
+bool MeasurementArea::measurementCompleted() const {
+ if (ready()) {
+ for (const auto &p : _progress) {
+ if (p != 100) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
bool MeasurementArea::saveToJson(QJsonObject &json) {
if (ready()) {
if (this->GeoArea::saveToJson(json)) {
@@ -406,15 +420,41 @@ bool MeasurementArea::isCorrect() {
bool MeasurementArea::setProgress(const QVector &p) {
if (ready()) {
- if (p.size() == this->tiles()->count() && this->_progress != p) {
+ if (!_holdProgress && p.size() == this->tiles()->count() &&
+ this->_progress != p) {
this->_progress = p;
emit progressChanged();
emit progressAccepted();
return true;
}
}
+ emit progressNotAccepted();
return false;
}
+
+void MeasurementArea::randomProgress() {
+ if (ready()) {
+ std::srand(std::time(nullptr));
+ for (auto &p : _progress) {
+ p += std::rand() % 100;
+ if (p > 100) {
+ p = 100;
+ }
+ }
+
+ emit progressChanged();
+ }
+}
+
+void MeasurementArea::resetProgress() {
+ if (ready()) {
+ for (auto &p : _progress) {
+ p = 0;
+ }
+
+ emit progressChanged();
+ }
+}
//!
//! \brief MeasurementArea::doUpdate
//! \pre MeasurementArea::deferUpdate must be called first, don't call
@@ -576,3 +616,12 @@ void MeasurementArea::setState(MeasurementArea::STATE s) {
}
}
}
+
+bool MeasurementArea::holdProgress() const { return _holdProgress; }
+
+void MeasurementArea::setHoldProgress(bool holdProgress) {
+ if (_holdProgress != holdProgress) {
+ _holdProgress = holdProgress;
+ emit holdProgressChanged();
+ }
+}
diff --git a/src/MeasurementComplexItem/geometry/MeasurementArea.h b/src/MeasurementComplexItem/geometry/MeasurementArea.h
index ac0a3ad8ed30e644e332a5612466d08714f48491..6b3710e0c90e5681e740e34b16c04cb19fc61577 100644
--- a/src/MeasurementComplexItem/geometry/MeasurementArea.h
+++ b/src/MeasurementComplexItem/geometry/MeasurementArea.h
@@ -46,6 +46,8 @@ public:
Q_PROPERTY(QmlObjectListModel *tiles READ tiles NOTIFY tilesChanged)
Q_PROPERTY(int maxTiles READ maxTiles NOTIFY maxTilesChanged)
Q_PROPERTY(QVector progress READ progressQml NOTIFY progressChanged)
+ Q_PROPERTY(bool holdProgress READ holdProgress WRITE setHoldProgress NOTIFY
+ holdProgressChanged)
// Overrides from GeoArea
QString mapVisualQML(void) const override;
@@ -69,10 +71,24 @@ public:
int maxTiles() const;
bool ready() const;
+ bool measurementCompleted() const;
+
// Static Variables
static const char *settingsGroup;
static const char *nameString;
+ //!
+ //! \brief holdProgress
+ //! \return Returns a copy of the holdProgress variable.
+ //!
+ bool holdProgress() const;
+ //!
+ //! \brief setHoldProgress Sets the holdProgress variable to \p holdProgress.
+ //! \note If holdProgress() == true, than setProgress() will do nothing, but
+ //! return false and emit the progressNotAccepted() signal.
+ //!
+ void setHoldProgress(bool holdProgress);
+
signals:
void tilesChanged();
void maxTilesChanged();
@@ -80,9 +96,12 @@ signals:
void progressAccepted();
void progressNotAccepted();
void readyChanged();
+ void holdProgressChanged();
public slots:
bool setProgress(const QVector &p);
+ Q_INVOKABLE void randomProgress();
+ Q_INVOKABLE void resetProgress();
private slots:
void doUpdate();
@@ -105,6 +124,7 @@ private:
SettingsFact _showTiles;
QVector _progress;
+ bool _holdProgress;
// Tile stuff.
// Tile stuff.
mutable QTimer _timer;
diff --git a/src/MeasurementComplexItem/qml/AreaDataEditor.qml b/src/MeasurementComplexItem/qml/AreaDataEditor.qml
index 28562732558492db678d6cdd7064c4b505c2771d..36eb2f6be03d68064091bed018c2b17107fbdcab 100644
--- a/src/MeasurementComplexItem/qml/AreaDataEditor.qml
+++ b/src/MeasurementComplexItem/qml/AreaDataEditor.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
+import Qt.labs.settings 1.0
import QtQuick.Layouts 1.11
import QtQuick.Controls 1.4
import QGroundControl.Controls 1.0
@@ -40,17 +41,18 @@ GridLayout {
}
}
- ExclusiveGroup {
- id: areaGroup
- }
-
QGCLabel {
- id: tipLabel
+ text: _root.errorString
wrapMode: Text.WordWrap
- horizontalAlignment: Text.AlignHCenter
- text: qsTr("Use the Area Editor to modify areas.")
- Layout.fillWidth: true
+ horizontalAlignment: Text.AlignLeft
+ color: "orange"
Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ visible: !_root.areasCorrect
+ }
+
+ ExclusiveGroup {
+ id: areaGroup
}
Repeater {
@@ -135,7 +137,7 @@ GridLayout {
id: commandsHeader
Layout.fillWidth: true
Layout.columnSpan: parent.columns
- text: qsTr("Commands and Errors")
+ text: qsTr("Commands")
}
GridLayout {
@@ -146,16 +148,6 @@ GridLayout {
Layout.fillWidth: true
visible: commandsHeader.checked
- QGCLabel {
- text: qsTr("Message: ") + _root.errorString
- wrapMode: Text.WordWrap
- horizontalAlignment: Text.AlignHCenter
- color: "orange"
- Layout.columnSpan: parent.columns
- Layout.fillWidth: true
- visible: !_root.areasCorrect
- }
-
QGCButton {
text: "Intersection"
enabled: _root.checked
@@ -168,10 +160,44 @@ GridLayout {
QGCButton {
text: "Reset"
+ onClicked: {
+ _root.reset()
+ }
+ Layout.fillWidth: true
+ }
+
+ QGCButton {
+ text: "Abort"
onClicked: {
_root.abort()
}
Layout.fillWidth: true
+ }
+ }
+
+ SectionHeader {
+ id: hintHeader
+ Layout.fillWidth: true
+ Layout.columnSpan: parent.columns
+ text: qsTr("Hints")
+ }
+
+ GridLayout {
+ columnSpacing: _margin
+ rowSpacing: _margin
+ columns: 2
+ Layout.columnSpan: 2
+ Layout.fillWidth: true
+ visible: hintHeader.checked
+
+ QGCLabel {
+ id: hintLabel
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignLeft
+ text: qsTr("Use the Intersection button to clip the Measurement Area(s).
+Use the Reset button to restore the areas to the state before entering this tab.
+Use the Abort button to reset the areas and leave the tab.")
+ Layout.fillWidth: true
Layout.columnSpan: parent.columns
}
}
@@ -193,4 +219,8 @@ GridLayout {
}
}
}
+
+ Settings {
+ property alias showHint: hintHeader.checked
+ }
}
diff --git a/src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml b/src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml
index 2000b854c85613ea77d491db753e54071de22d4d..e791270d89c8ab1f94e151583ef979b05e187e9e 100644
--- a/src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml
+++ b/src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml
@@ -1,3 +1,5 @@
+
+
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT
@@ -6,25 +8,24 @@
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
-
-import QtQuick 2.3
+import QtQuick 2.3
import QtQuick.Controls 1.2
-import QtLocation 5.3
-import QtPositioning 5.3
+import QtLocation 5.3
+import QtPositioning 5.3
-import QGroundControl 1.0
-import QGroundControl.ScreenTools 1.0
-import QGroundControl.Palette 1.0
-import QGroundControl.Controls 1.0
-import QGroundControl.FlightMap 1.0
+import QGroundControl 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.FlightMap 1.0
Item {
id: _root
- property var map: undefined ///< Map control to place item in
- property var geoArea: undefined ///< GeoArea derived class
+ property var map: undefined ///< Map control to place item in
+ property var geoArea: undefined ///< GeoArea derived class
- opacity: 0.3
+ opacity: 0.2
signal clicked(int sequenceNumber)
@@ -35,31 +36,30 @@ Item {
// Area polygon
QGCMapPolygonVisuals {
- id: mapPolygonVisuals
-
- mapControl: _root.map
- mapPolygon: _root.geoArea
- interactive: geoArea.interactive
- borderWidth: 3
- borderColor: "green"
- interiorColor: "green"
- altColor: QGroundControl.globalPalette.surveyPolygonTerrainCollision
- z: QGroundControl.zOrderMapItems-1
- interiorOpacity: _root.opacity
+ id: mapPolygonVisuals
+
+ mapControl: _root.map
+ mapPolygon: _root.geoArea
+ interactive: geoArea.interactive
+ borderWidth: 3
+ interiorColor: "green"
+ altColor: QGroundControl.globalPalette.surveyPolygonTerrainCollision
+ z: QGroundControl.zOrderMapItems - 1
+ interiorOpacity: _root.opacity
}
// Add Snake tiles to the map
Component {
id: tileComponent
- Item{
+ Item {
id: root
property MapPolygon polygon
- MapPolygon{
- id:mapPolygon
- path: []
+ MapPolygon {
+ id: mapPolygon
+ path: []
}
Component.onCompleted: {
@@ -90,27 +90,27 @@ Item {
property bool enable: geoArea.showTiles.value
model: enable ? geoArea.tiles : []
- Item{
+ Item {
property var _tileComponent
- property int _progress: _root.geoArea.progress[index] ?
- _root.geoArea.progress[index] : 0
+ property int _progress: _root.geoArea.progress[index] ? _root.geoArea.progress[index] : 0
Component.onCompleted: {
_tileComponent = tileComponent.createObject(map)
- _tileComponent.polygon.path =
- Qt.binding(function(){return object.path})
+ _tileComponent.polygon.path = Qt.binding(function () {
+ return object.path
+ })
_tileComponent.polygon.opacity = 0.6
_tileComponent.polygon.border.color = "black"
_tileComponent.polygon.border.width = 1
- _tileComponent.polygon.color =
- Qt.binding(function(){return getColor(_progress)})
+ _tileComponent.polygon.color = Qt.binding(function () {
+ return getColor(_progress)
+ })
}
Component.onDestruction: {
_tileComponent.destroy()
}
-
}
}
}
diff --git a/src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir b/src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir
index 2fd96c7292efdbad2580817e6a86752951155a4b..ff895118245641597be9cad326801aabde3fec41 100644
--- a/src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir
+++ b/src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir
@@ -4,3 +4,4 @@ LinearGenerator 1.0 LinearGenerator.qml
CircularGenerator 1.0 CircularGenerator.qml
SafeAreaEditor 1.0 SafeAreaEditor.qml
MeasurementAreaEditor 1.0 MeasurementAreaEditor.qml
+NemoEditor 1.0 NemoEditor.qml
diff --git a/src/MeasurementComplexItem/qml/MeasurementItemEditor.qml b/src/MeasurementComplexItem/qml/MeasurementItemEditor.qml
index 8b84e6f1480c7919afc44af6433b4a5c1374d955..5d1c6c60d612694ddea7f84c96690732c018fa85 100644
--- a/src/MeasurementComplexItem/qml/MeasurementItemEditor.qml
+++ b/src/MeasurementComplexItem/qml/MeasurementItemEditor.qml
@@ -60,7 +60,7 @@ Rectangle {
Component.onCompleted: currentIndex = editing ? areaEditorIndex : parameterEditorIndex
QGCTabButton {
- icon.source: "/qmlimages/PatternCamera.png"
+ icon.source: "qrc:/res/waypoint.svg"
icon.height: ScreenTools.defaultFontPixelHeight
}
QGCTabButton {
@@ -68,7 +68,7 @@ Rectangle {
icon.height: ScreenTools.defaultFontPixelHeight
}
QGCTabButton {
- icon.source: "/qmlimages/PatternPresets.png"
+ icon.source: "qrc:/res/fish.svg"
icon.height: ScreenTools.defaultFontPixelHeight
}
@@ -124,6 +124,14 @@ Rectangle {
missionItem: _root._missionItem
availableWidth: mainColumn.width
}
+
+ MCI.NemoEditor {
+ id: nemoEditor
+
+ checked: visible
+ missionItem: _root._missionItem
+ availableWidth: mainColumn.width
+ }
}
} // main Column
} // Rectangle
diff --git a/src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml b/src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml
index 99b99c0eeae2399aa562afca28e88e1b63f2939a..b85ddca76ed2c7655f2aae578d136888aab04cda 100644
--- a/src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml
+++ b/src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml
@@ -56,9 +56,9 @@ Item {
Component.onCompleted: {
console.assert(map != undefined, "please set the map property")
- if (!_missionItem.areaData.initialized()){
+ if (!_missionItem.initialized()){
var bbox = boundingBox()
- _missionItem.areaData.initialize(bbox[0], bbox[1])
+ _missionItem.initialize(bbox[0], bbox[1])
}
// _addEntryCoordinate()
// _addExitCoordinate()
diff --git a/src/MeasurementComplexItem/qml/NemoEditor.qml b/src/MeasurementComplexItem/qml/NemoEditor.qml
new file mode 100644
index 0000000000000000000000000000000000000000..518977207fdf7cb30b69b551f093f216fb306b9a
--- /dev/null
+++ b/src/MeasurementComplexItem/qml/NemoEditor.qml
@@ -0,0 +1,227 @@
+import QtQuick 2.0
+
+import Qt.labs.settings 1.0
+import QtQuick.Layouts 1.11
+import QtQuick.Controls 1.4
+import QGroundControl.Controls 1.0
+import QGroundControl.FactControls 1.0
+import QGroundControl.ScreenTools 1.0
+
+import MeasurementComplexItem 1.0 as MCI
+
+GridLayout {
+ id: _root
+
+ property bool checked: true
+ property var missionItem: undefined
+ property int availableWidth: 300
+ property bool error: errorString.lenght >= 0
+ readonly property bool running: _nemoInterface.running
+ property string errorString: ""
+
+ signal abort
+
+ property var _areaData: missionItem.areaData
+ property real _margin: ScreenTools.defaultFontPixelWidth / 2
+ property var _nemoInterface: MCI.NemoInterface
+ property bool _holding
+
+ columnSpacing: _margin
+ rowSpacing: _margin
+ columns: 2
+
+ Component.onCompleted: {
+ console.assert(missionItem !== undefined,
+ "please set the missionItem property")
+ _holding = false
+ _stopHolding()
+ }
+
+ QGCLabel {
+ text: _root.errorString
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignLeft
+ color: "orange"
+ Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ visible: !_root.areasCorrect
+ }
+
+ QGCButton {
+ text: running ? qsTr("Stop") : qsTr("Start")
+ Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ onPressed: {
+ if (running) {
+ _nemoInterface.stop()
+ } else {
+ _nemoInterface.start()
+ }
+ }
+ }
+
+ QGCLabel {
+ text: qsTr("Status: ") + _nemoInterface.statusString
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignVCenter
+ Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ }
+
+ SectionHeader {
+ id: progressHeader
+ Layout.fillWidth: true
+ Layout.columnSpan: parent.columns
+ text: qsTr("Progress")
+ }
+
+ GridLayout {
+ columnSpacing: _margin
+ rowSpacing: _margin
+ columns: 2
+ Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ visible: progressHeader.checked
+
+ QGCButton {
+ text: !_holding ? qsTr("Hold") : qsTr("Stop Holding")
+ Layout.fillWidth: true
+ Layout.columnSpan: parent.columns
+ onPressed: {
+ if (_holding) {
+ _stopHolding()
+ _holding = false
+ } else {
+ _holdProgress()
+ _holding = true
+ }
+ }
+ }
+
+ QGCButton {
+ text: qsTr("Random")
+ Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ onPressed: {
+ _randomProgress()
+ }
+ }
+
+ QGCButton {
+ text: qsTr("Reset")
+ Layout.columnSpan: parent.columns
+ Layout.fillWidth: true
+ onPressed: {
+ _resetProgress()
+ }
+ }
+ }
+
+ // bussy indicator
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: _margin
+ Layout.maximumWidth: parent.width
+
+ BusyIndicator {
+ id: indicator
+
+ property bool calculating: missionItem.calculating
+
+ running: calculating
+ visible: calculating || timer.running
+
+ onCalculatingChanged: {
+ if (!calculating) {
+ // defer hiding
+ timer.restart()
+ }
+ }
+
+ Timer {
+ id: timer
+ interval: 1000
+ repeat: false
+ running: false
+ }
+ }
+ } // indicator column
+
+ SectionHeader {
+ id: hintHeader
+ Layout.fillWidth: true
+ Layout.columnSpan: parent.columns
+ text: qsTr("Hints")
+ }
+
+ GridLayout {
+ columnSpacing: _margin
+ rowSpacing: _margin
+ columns: 2
+ Layout.columnSpan: 2
+ Layout.fillWidth: true
+ visible: hintHeader.checked
+
+ QGCLabel {
+ id: hintLabel
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignLeft
+ text: qsTr("Use this tab to connect to a device implementing the Nemo Interface.
+Use the Random button to simulate measurement progress.")
+ Layout.fillWidth: true
+ Layout.columnSpan: parent.columns
+ }
+ }
+
+ Settings {
+ property alias showHint: hintHeader.checked
+ }
+
+ function _holdProgress() {
+ var areaArray = _areaData.measurementAreaList
+ for (var i = 0; i < areaArray.count; ++i) {
+ var area = areaArray.get(i)
+ if (area) {
+ area.holdProgress = true
+ } else {
+ console.log("empty area!")
+ }
+ }
+ }
+
+ function _stopHolding() {
+ var areaArray = _areaData.measurementAreaList
+ for (var i = 0; i < areaArray.count; ++i) {
+ var area = areaArray.get(i)
+ if (area) {
+ area.holdProgress = false
+ } else {
+ console.log("empty area!")
+ }
+ }
+ }
+
+ function _randomProgress() {
+ var areaArray = _areaData.measurementAreaList
+ for (var i = 0; i < areaArray.count; ++i) {
+ var area = areaArray.get(i)
+ if (area) {
+ area.randomProgress()
+ } else {
+ console.log("empty area!")
+ }
+ }
+ }
+
+ function _resetProgress() {
+ var areaArray = _areaData.measurementAreaList
+ for (var i = 0; i < areaArray.count; ++i) {
+ var area = areaArray.get(i)
+ if (area) {
+ area.resetProgress()
+ } else {
+ console.log("empty area!")
+ }
+ }
+ }
+}
diff --git a/src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml b/src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml
index 78985cc45660f0ff62290cb2dcdb049ac6936199..6552174c17022c9c0518de9f1135df23b7d55229 100644
--- a/src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml
+++ b/src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml
@@ -39,11 +39,10 @@ Item {
mapPolygon: geoArea
interactive: geoArea.interactive
borderWidth: 2
- borderColor: "blue"
interiorColor: "blue"
altColor: QGroundControl.globalPalette.surveyPolygonTerrainCollision
z: QGroundControl.zOrderMapItems-1
- interiorOpacity: 0.3
+ interiorOpacity: 0.2
}
Item {
diff --git a/src/MissionManager/MissionItem.h b/src/MissionManager/MissionItem.h
index 72519e3f447f62e109bb96a9bba68f17e0d09cf2..869992b956b28a4d96036a86c4933548d7f39ced 100644
--- a/src/MissionManager/MissionItem.h
+++ b/src/MissionManager/MissionItem.h
@@ -7,157 +7,155 @@
*
****************************************************************************/
-
#ifndef MissionItem_H
#define MissionItem_H
+#include
+#include
#include
#include
-#include
#include
-#include
-#include
+#include
-#include "QGCMAVLink.h"
-#include "QGC.h"
-#include "QmlObjectListModel.h"
#include "Fact.h"
+#include "QGC.h"
#include "QGCLoggingCategory.h"
+#include "QGCMAVLink.h"
#include "QmlObjectListModel.h"
class SurveyComplexItem;
-class RouteComplexItem;
class SimpleMissionItem;
class MissionController;
#ifdef UNITTEST_BUILD
- class MissionItemTest;
+class MissionItemTest;
#endif
// Represents a Mavlink mission command.
-class MissionItem : public QObject
-{
- Q_OBJECT
-
+class MissionItem : public QObject {
+ Q_OBJECT
+
public:
- MissionItem(QObject* parent = nullptr);
-
- MissionItem(int sequenceNumber,
- MAV_CMD command,
- MAV_FRAME frame,
- double param1,
- double param2,
- double param3,
- double param4,
- double param5,
- double param6,
- double param7,
- bool autoContinue,
- bool isCurrentItem,
- QObject* parent = nullptr);
-
- MissionItem(const MissionItem& other, QObject* parent = nullptr);
-
- ~MissionItem();
-
- const MissionItem& operator=(const MissionItem& other);
-
- MAV_CMD command (void) const { return (MAV_CMD)_commandFact.rawValue().toInt(); }
- bool isCurrentItem (void) const { return _isCurrentItem; }
- int sequenceNumber (void) const { return _sequenceNumber; }
- MAV_FRAME frame (void) const { return (MAV_FRAME)_frameFact.rawValue().toInt(); }
- bool autoContinue (void) const { return _autoContinueFact.rawValue().toBool(); }
- double param1 (void) const { return _param1Fact.rawValue().toDouble(); }
- double param2 (void) const { return _param2Fact.rawValue().toDouble(); }
- double param3 (void) const { return _param3Fact.rawValue().toDouble(); }
- double param4 (void) const { return _param4Fact.rawValue().toDouble(); }
- double param5 (void) const { return _param5Fact.rawValue().toDouble(); }
- double param6 (void) const { return _param6Fact.rawValue().toDouble(); }
- double param7 (void) const { return _param7Fact.rawValue().toDouble(); }
- QGeoCoordinate coordinate (void) const;
- int doJumpId (void) const { return _doJumpId; }
-
- /// @return Flight speed change value if this item supports it. If not it returns NaN.
- double specifiedFlightSpeed(void) const;
-
- /// @return Flight gimbal yaw change value if this item supports it. If not it returns NaN.
- double specifiedGimbalYaw(void) const;
-
- /// @return Flight gimbal pitch change value if this item supports it. If not it returns NaN.
- double specifiedGimbalPitch(void) const;
-
- void setCommand (MAV_CMD command);
- void setSequenceNumber (int sequenceNumber);
- void setIsCurrentItem (bool isCurrentItem);
- void setFrame (MAV_FRAME frame);
- void setAutoContinue (bool autoContinue);
- void setParam1 (double param1);
- void setParam2 (double param2);
- void setParam3 (double param3);
- void setParam4 (double param4);
- void setParam5 (double param5);
- void setParam6 (double param6);
- void setParam7 (double param7);
-
- void save(QJsonObject& json) const;
- bool load(QTextStream &loadStream);
- bool load(const QJsonObject& json, int sequenceNumber, QString& errorString);
-
- bool relativeAltitude(void) const { return frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; }
+ MissionItem(QObject *parent = nullptr);
+
+ MissionItem(int sequenceNumber, MAV_CMD command, MAV_FRAME frame,
+ double param1, double param2, double param3, double param4,
+ double param5, double param6, double param7, bool autoContinue,
+ bool isCurrentItem, QObject *parent = nullptr);
+
+ MissionItem(const MissionItem &other, QObject *parent = nullptr);
+
+ ~MissionItem();
+
+ const MissionItem &operator=(const MissionItem &other);
+
+ MAV_CMD command(void) const {
+ return (MAV_CMD)_commandFact.rawValue().toInt();
+ }
+ bool isCurrentItem(void) const { return _isCurrentItem; }
+ int sequenceNumber(void) const { return _sequenceNumber; }
+ MAV_FRAME frame(void) const {
+ return (MAV_FRAME)_frameFact.rawValue().toInt();
+ }
+ bool autoContinue(void) const {
+ return _autoContinueFact.rawValue().toBool();
+ }
+ double param1(void) const { return _param1Fact.rawValue().toDouble(); }
+ double param2(void) const { return _param2Fact.rawValue().toDouble(); }
+ double param3(void) const { return _param3Fact.rawValue().toDouble(); }
+ double param4(void) const { return _param4Fact.rawValue().toDouble(); }
+ double param5(void) const { return _param5Fact.rawValue().toDouble(); }
+ double param6(void) const { return _param6Fact.rawValue().toDouble(); }
+ double param7(void) const { return _param7Fact.rawValue().toDouble(); }
+ QGeoCoordinate coordinate(void) const;
+ int doJumpId(void) const { return _doJumpId; }
+
+ /// @return Flight speed change value if this item supports it. If not it
+ /// returns NaN.
+ double specifiedFlightSpeed(void) const;
+
+ /// @return Flight gimbal yaw change value if this item supports it. If not it
+ /// returns NaN.
+ double specifiedGimbalYaw(void) const;
+
+ /// @return Flight gimbal pitch change value if this item supports it. If not
+ /// it returns NaN.
+ double specifiedGimbalPitch(void) const;
+
+ void setCommand(MAV_CMD command);
+ void setSequenceNumber(int sequenceNumber);
+ void setIsCurrentItem(bool isCurrentItem);
+ void setFrame(MAV_FRAME frame);
+ void setAutoContinue(bool autoContinue);
+ void setParam1(double param1);
+ void setParam2(double param2);
+ void setParam3(double param3);
+ void setParam4(double param4);
+ void setParam5(double param5);
+ void setParam6(double param6);
+ void setParam7(double param7);
+
+ void save(QJsonObject &json) const;
+ bool load(QTextStream &loadStream);
+ bool load(const QJsonObject &json, int sequenceNumber, QString &errorString);
+
+ bool relativeAltitude(void) const {
+ return frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT;
+ }
signals:
- void isCurrentItemChanged (bool isCurrentItem);
- void sequenceNumberChanged (int sequenceNumber);
- void specifiedFlightSpeedChanged(double flightSpeed);
- void specifiedGimbalYawChanged (double gimbalYaw);
- void specifiedGimbalPitchChanged(double gimbalPitch);
+ void isCurrentItemChanged(bool isCurrentItem);
+ void sequenceNumberChanged(int sequenceNumber);
+ void specifiedFlightSpeedChanged(double flightSpeed);
+ void specifiedGimbalYawChanged(double gimbalYaw);
+ void specifiedGimbalPitchChanged(double gimbalPitch);
private slots:
- void _param1Changed(QVariant value);
- void _param2Changed(QVariant value);
- void _param3Changed(QVariant value);
+ void _param1Changed(QVariant value);
+ void _param2Changed(QVariant value);
+ void _param3Changed(QVariant value);
private:
- bool _convertJsonV1ToV2(const QJsonObject& json, QJsonObject& v2Json, QString& errorString);
- bool _convertJsonV2ToV3(QJsonObject& json, QString& errorString);
-
-
- Fact _autoContinueFact;
- Fact _commandFact;
- Fact _frameFact;
- Fact _param1Fact;
- Fact _param2Fact;
- Fact _param3Fact;
- Fact _param4Fact;
- Fact _param5Fact;
- Fact _param6Fact;
- Fact _param7Fact;
-
- int _sequenceNumber;
- int _doJumpId;
- bool _isCurrentItem;
-
- // Keys for Json save
- static const char* _jsonFrameKey;
- static const char* _jsonCommandKey;
- static const char* _jsonAutoContinueKey;
- static const char* _jsonParamsKey;
- static const char* _jsonDoJumpIdKey;
-
- // Deprecated V2 format keys
- static const char* _jsonCoordinateKey;
-
- // Deprecated V1 format keys
- static const char* _jsonParam1Key;
- static const char* _jsonParam2Key;
- static const char* _jsonParam3Key;
- static const char* _jsonParam4Key;
-
- friend class SurveyComplexItem;
- friend class RouteComplexItem;
- friend class SimpleMissionItem;
- friend class MissionController;
+ bool _convertJsonV1ToV2(const QJsonObject &json, QJsonObject &v2Json,
+ QString &errorString);
+ bool _convertJsonV2ToV3(QJsonObject &json, QString &errorString);
+
+ Fact _autoContinueFact;
+ Fact _commandFact;
+ Fact _frameFact;
+ Fact _param1Fact;
+ Fact _param2Fact;
+ Fact _param3Fact;
+ Fact _param4Fact;
+ Fact _param5Fact;
+ Fact _param6Fact;
+ Fact _param7Fact;
+
+ int _sequenceNumber;
+ int _doJumpId;
+ bool _isCurrentItem;
+
+ // Keys for Json save
+ static const char *_jsonFrameKey;
+ static const char *_jsonCommandKey;
+ static const char *_jsonAutoContinueKey;
+ static const char *_jsonParamsKey;
+ static const char *_jsonDoJumpIdKey;
+
+ // Deprecated V2 format keys
+ static const char *_jsonCoordinateKey;
+
+ // Deprecated V1 format keys
+ static const char *_jsonParam1Key;
+ static const char *_jsonParam2Key;
+ static const char *_jsonParam3Key;
+ static const char *_jsonParam4Key;
+
+ friend class SurveyComplexItem;
+ friend class RouteComplexItem;
+ friend class SimpleMissionItem;
+ friend class MissionController;
#ifdef UNITTEST_BUILD
- friend class MissionItemTest;
+ friend class MissionItemTest;
#endif
};
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index 3eb73244a4245f0bb21785cbd6993d19a240040f..1e79d9d8a38f8a6bef2814109772f3516120b971 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -186,6 +186,11 @@ static QObject *shapeFileHelperSingletonFactory(QQmlEngine *, QJSEngine *) {
return new ShapeFileHelper;
}
+QObject *getNemoInterface(QQmlEngine *engine, QJSEngine *) {
+ engine->setObjectOwnership(pNemoInterface, QQmlEngine::CppOwnership);
+ return pNemoInterface;
+}
+
QGCApplication::QGCApplication(int &argc, char *argv[], bool unitTesting)
: QApplication(argc, argv), _runningUnitTests(unitTesting) {
_app = this;
@@ -665,13 +670,13 @@ void QGCApplication::_initCommon() {
#endif
qmlRegisterUncreatableType(
- "RouteComplexItem", 1, 0, "LinearGenerator", kRefOnly);
- qmlRegisterType("RouteComplexItem", 1, 0, "AreaData");
- qmlRegisterUncreatableType("RouteComplexItem", 1, 0,
- "NemoInterface", kRefOnly);
+ "MeasurementComplexItem", 1, 0, "LinearGenerator", kRefOnly);
+ qmlRegisterType("MeasurementComplexItem", 1, 0, "AreaData");
+ qmlRegisterSingletonType("MeasurementComplexItem", 1, 0,
+ "NemoInterface", getNemoInterface);
qmlRegisterInterface("GeneratorBase");
qmlRegisterUncreatableType(
- "RouteComplexItem", 1, 0, "CircularGenerator", kRefOnly);
+ "MeasurementComplexItem", 1, 0, "CircularGenerator", kRefOnly);
qmlRegisterType(kQGCControllers, 1, 0, "GeoTagController");
qmlRegisterType(kQGCControllers, 1, 0,