From f060c3b74919d54fb8ea8ca682b0f035dc92d335 Mon Sep 17 00:00:00 2001 From: Valentin Platzgummer Date: Tue, 29 Sep 2020 17:47:13 +0200 Subject: [PATCH] wima controller mod --- src/QmlControls/QmlObjectListModel.cc | 402 +++++++++---------- src/QmlControls/QmlObjectListModel.h | 3 + src/Wima/Geometry/WimaMeasurementArea.cc | 113 ++++-- src/Wima/Geometry/WimaMeasurementArea.h | 24 +- src/Wima/Geometry/WimaMeasurementAreaData.cc | 52 ++- src/Wima/Geometry/WimaMeasurementAreaData.h | 17 +- src/Wima/Snake/NemoInterface.cpp | 74 +++- src/Wima/Snake/NemoInterface.h | 6 +- src/Wima/WimaController.cc | 232 +++++------ src/Wima/WimaController.h | 48 +-- 10 files changed, 508 insertions(+), 463 deletions(-) diff --git a/src/QmlControls/QmlObjectListModel.cc b/src/QmlControls/QmlObjectListModel.cc index e05e0f7e9..1df531a99 100644 --- a/src/QmlControls/QmlObjectListModel.cc +++ b/src/QmlControls/QmlObjectListModel.cc @@ -7,7 +7,6 @@ * ****************************************************************************/ - /// @file /// @author Don Gagne @@ -19,261 +18,260 @@ const int QmlObjectListModel::ObjectRole = Qt::UserRole; const int QmlObjectListModel::TextRole = Qt::UserRole + 1; -QmlObjectListModel::QmlObjectListModel(QObject* parent) - : QAbstractListModel(parent) - , _dirty(false) - , _skipDirtyFirstItem(false) -{ +QmlObjectListModel::QmlObjectListModel(QObject *parent) + : QAbstractListModel(parent), _dirty(false), _skipDirtyFirstItem(false) {} -} +QmlObjectListModel::~QmlObjectListModel() {} -QmlObjectListModel::~QmlObjectListModel() -{ - +int QmlObjectListModel::rowCount(const QModelIndex &parent) const { + Q_UNUSED(parent); + + return _objectList.count(); } -int QmlObjectListModel::rowCount(const QModelIndex& parent) const -{ - Q_UNUSED(parent); - - return _objectList.count(); +QVariant QmlObjectListModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() < 0 || index.row() >= _objectList.count()) { + return QVariant(); + } + + if (role == ObjectRole) { + return QVariant::fromValue(_objectList[index.row()]); + } else if (role == TextRole) { + return QVariant::fromValue(_objectList[index.row()]->objectName()); + } else { + return QVariant(); + } } -QVariant QmlObjectListModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - if (index.row() < 0 || index.row() >= _objectList.count()) { - return QVariant(); - } - - if (role == ObjectRole) { - return QVariant::fromValue(_objectList[index.row()]); - } else if (role == TextRole) { - return QVariant::fromValue(_objectList[index.row()]->objectName()); - } else { - return QVariant(); - } +QHash QmlObjectListModel::roleNames(void) const { + QHash hash; + + hash[ObjectRole] = "object"; + hash[TextRole] = "text"; + + return hash; } -QHash QmlObjectListModel::roleNames(void) const -{ - QHash hash; - - hash[ObjectRole] = "object"; - hash[TextRole] = "text"; - - return hash; +bool QmlObjectListModel::setData(const QModelIndex &index, + const QVariant &value, int role) { + if (index.isValid() && role == ObjectRole) { + _objectList.replace(index.row(), value.value()); + emit dataChanged(index, index); + return true; + } + + return false; } -bool QmlObjectListModel::setData(const QModelIndex& index, const QVariant& value, int role) -{ - if (index.isValid() && role == ObjectRole) { - _objectList.replace(index.row(), value.value()); - emit dataChanged(index, index); - return true; - } - - return false; +bool QmlObjectListModel::insertRows(int position, int rows, + const QModelIndex &parent) { + Q_UNUSED(parent); + + if (position < 0 || position > _objectList.count() + 1) { + qWarning() << "Invalid position position:count" << position + << _objectList.count(); + } + + beginInsertRows(QModelIndex(), position, position + rows - 1); + endInsertRows(); + + emit countChanged(count()); + + return true; } -bool QmlObjectListModel::insertRows(int position, int rows, const QModelIndex& parent) -{ - Q_UNUSED(parent); - - if (position < 0 || position > _objectList.count() + 1) { - qWarning() << "Invalid position position:count" << position << _objectList.count(); - } - - beginInsertRows(QModelIndex(), position, position + rows - 1); - endInsertRows(); - - emit countChanged(count()); - - return true; +bool QmlObjectListModel::removeRows(int position, int rows, + const QModelIndex &parent) { + Q_UNUSED(parent); + + if (position < 0 || position >= _objectList.count()) { + qWarning() << "Invalid position position:count" << position + << _objectList.count(); + } else if (position + rows > _objectList.count()) { + qWarning() << "Invalid rows position:rows:count" << position << rows + << _objectList.count(); + } + + beginRemoveRows(QModelIndex(), position, position + rows - 1); + for (int row = 0; row < rows; row++) { + _objectList.removeAt(position); + } + endRemoveRows(); + + emit countChanged(count()); + + return true; } -bool QmlObjectListModel::removeRows(int position, int rows, const QModelIndex& parent) -{ - Q_UNUSED(parent); - - if (position < 0 || position >= _objectList.count()) { - qWarning() << "Invalid position position:count" << position << _objectList.count(); - } else if (position + rows > _objectList.count()) { - qWarning() << "Invalid rows position:rows:count" << position << rows << _objectList.count(); - } - - beginRemoveRows(QModelIndex(), position, position + rows - 1); - for (int row=0; row= _objectList.count()) { + return NULL; + } + return _objectList[index]; } -QObject* QmlObjectListModel::operator[](int index) -{ - if (index < 0 || index >= _objectList.count()) { - return NULL; - } - return _objectList[index]; +const QObject *QmlObjectListModel::operator[](int index) const { + if (index < 0 || index >= _objectList.count()) { + return NULL; + } + return _objectList[index]; } -const QObject* QmlObjectListModel::operator[](int index) const -{ - if (index < 0 || index >= _objectList.count()) { - return NULL; +bool QmlObjectListModel::operator==(const QmlObjectListModel &other) { + if (this->count() == other.count()) { + for (std::size_t i = 0; i < this->count(); ++i) { + if (this->get(i) != other.get(i)) { + return false; + } } - return _objectList[index]; + return true; + } else { + return false; + } } -void QmlObjectListModel::clear() -{ - while (rowCount()) { - removeAt(0); - } +bool QmlObjectListModel::operator==(const QmlObjectListModel &other) { + return !this->operator==(other); } -QObject* QmlObjectListModel::removeAt(int i) -{ - QObject* removedObject = _objectList[i]; - if(removedObject) { - // Look for a dirtyChanged signal on the object - if (_objectList[i]->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) { - if (!_skipDirtyFirstItem || i != 0) { - QObject::disconnect(_objectList[i], SIGNAL(dirtyChanged(bool)), this, SLOT(_childDirtyChanged(bool))); - } - } - } - removeRows(i, 1); - setDirty(true); - return removedObject; +void QmlObjectListModel::clear() { + while (rowCount()) { + removeAt(0); + } } -void QmlObjectListModel::insert(int i, QObject* object) -{ - if (i < 0 || i > _objectList.count()) { - qWarning() << "Invalid index index:count" << i << _objectList.count(); - } - - QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); - +QObject *QmlObjectListModel::removeAt(int i) { + QObject *removedObject = _objectList[i]; + if (removedObject) { // Look for a dirtyChanged signal on the object - if (object->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) { - if (!_skipDirtyFirstItem || i != 0) { - QObject::connect(object, SIGNAL(dirtyChanged(bool)), this, SLOT(_childDirtyChanged(bool))); - } + if (_objectList[i]->metaObject()->indexOfSignal( + QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) { + if (!_skipDirtyFirstItem || i != 0) { + QObject::disconnect(_objectList[i], SIGNAL(dirtyChanged(bool)), this, + SLOT(_childDirtyChanged(bool))); + } } - - _objectList.insert(i, object); - insertRows(i, 1); - - setDirty(true); + } + removeRows(i, 1); + setDirty(true); + return removedObject; } -void QmlObjectListModel::insert(int i, QList objects) -{ - if (i < 0 || i > _objectList.count()) { - qWarning() << "Invalid index index:count" << i << _objectList.count(); +void QmlObjectListModel::insert(int i, QObject *object) { + if (i < 0 || i > _objectList.count()) { + qWarning() << "Invalid index index:count" << i << _objectList.count(); + } + + QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + + // Look for a dirtyChanged signal on the object + if (object->metaObject()->indexOfSignal( + QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) { + if (!_skipDirtyFirstItem || i != 0) { + QObject::connect(object, SIGNAL(dirtyChanged(bool)), this, + SLOT(_childDirtyChanged(bool))); } + } - int j = i; - for (QObject* object: objects) { - QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + _objectList.insert(i, object); + insertRows(i, 1); - // Look for a dirtyChanged signal on the object - if (object->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) { - if (!_skipDirtyFirstItem || j != 0) { - QObject::connect(object, SIGNAL(dirtyChanged(bool)), this, SLOT(_childDirtyChanged(bool))); - } - } - j++; + setDirty(true); +} + +void QmlObjectListModel::insert(int i, QList objects) { + if (i < 0 || i > _objectList.count()) { + qWarning() << "Invalid index index:count" << i << _objectList.count(); + } - _objectList.insert(j, object); + int j = i; + for (QObject *object : objects) { + QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); + + // Look for a dirtyChanged signal on the object + if (object->metaObject()->indexOfSignal( + QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) { + if (!_skipDirtyFirstItem || j != 0) { + QObject::connect(object, SIGNAL(dirtyChanged(bool)), this, + SLOT(_childDirtyChanged(bool))); + } } + j++; - insertRows(i, objects.count()); + _objectList.insert(j, object); + } - setDirty(true); -} + insertRows(i, objects.count()); -void QmlObjectListModel::append(QObject* object) -{ - insert(_objectList.count(), object); + setDirty(true); } -void QmlObjectListModel::append(QList objects) -{ - insert(_objectList.count(), objects); +void QmlObjectListModel::append(QObject *object) { + insert(_objectList.count(), object); } -QObjectList QmlObjectListModel::swapObjectList(const QObjectList& newlist) -{ - QObjectList oldlist(_objectList); - beginResetModel(); - _objectList = newlist; - endResetModel(); - emit countChanged(count()); - return oldlist; +void QmlObjectListModel::append(QList objects) { + insert(_objectList.count(), objects); } -int QmlObjectListModel::count() const -{ - return rowCount(); +QObjectList QmlObjectListModel::swapObjectList(const QObjectList &newlist) { + QObjectList oldlist(_objectList); + beginResetModel(); + _objectList = newlist; + endResetModel(); + emit countChanged(count()); + return oldlist; } -void QmlObjectListModel::setDirty(bool dirty) -{ - if (_dirty != dirty) { - _dirty = dirty; - if (!dirty) { - // Need to clear dirty from all children - for(QObject* object: _objectList) { - if (object->property("dirty").isValid()) { - object->setProperty("dirty", false); - } - } +int QmlObjectListModel::count() const { return rowCount(); } + +void QmlObjectListModel::setDirty(bool dirty) { + if (_dirty != dirty) { + _dirty = dirty; + if (!dirty) { + // Need to clear dirty from all children + for (QObject *object : _objectList) { + if (object->property("dirty").isValid()) { + object->setProperty("dirty", false); } - emit dirtyChanged(_dirty); + } } + emit dirtyChanged(_dirty); + } } -void QmlObjectListModel::_childDirtyChanged(bool dirty) -{ - _dirty |= dirty; - // We want to emit dirtyChanged even if the actual value of _dirty didn't change. It can be a useful - // signal to know when a child has changed dirty state - emit dirtyChanged(_dirty); +void QmlObjectListModel::_childDirtyChanged(bool dirty) { + _dirty |= dirty; + // We want to emit dirtyChanged even if the actual value of _dirty didn't + // change. It can be a useful signal to know when a child has changed dirty + // state + emit dirtyChanged(_dirty); } -void QmlObjectListModel::deleteListAndContents() -{ - for (int i=0; i<_objectList.count(); i++) { - _objectList[i]->deleteLater(); - } - deleteLater(); +void QmlObjectListModel::deleteListAndContents() { + for (int i = 0; i < _objectList.count(); i++) { + _objectList[i]->deleteLater(); + } + deleteLater(); } -void QmlObjectListModel::clearAndDeleteContents() -{ - beginResetModel(); - for (int i=0; i<_objectList.count(); i++) { - _objectList[i]->deleteLater(); - } - clear(); - endResetModel(); +void QmlObjectListModel::clearAndDeleteContents() { + beginResetModel(); + for (int i = 0; i < _objectList.count(); i++) { + _objectList[i]->deleteLater(); + } + clear(); + endResetModel(); } -void swap(QmlObjectListModel &list1, QmlObjectListModel &list2) -{ - using std::swap; +void swap(QmlObjectListModel &list1, QmlObjectListModel &list2) { + using std::swap; - swap(list1._objectList, list2._objectList); - swap(list1._dirty, list2._dirty); - swap(list1._skipDirtyFirstItem, list2._skipDirtyFirstItem); + swap(list1._objectList, list2._objectList); + swap(list1._dirty, list2._dirty); + swap(list1._skipDirtyFirstItem, list2._skipDirtyFirstItem); } diff --git a/src/QmlControls/QmlObjectListModel.h b/src/QmlControls/QmlObjectListModel.h index 14a40df9b..5c7060d24 100644 --- a/src/QmlControls/QmlObjectListModel.h +++ b/src/QmlControls/QmlObjectListModel.h @@ -51,6 +51,9 @@ public: } QList *objectList() { return &_objectList; } + bool operator==(const QmlObjectListModel &other); + bool operator!=(const QmlObjectListModel &other); + /// Calls deleteLater on all items and this itself. void deleteListAndContents(); diff --git a/src/Wima/Geometry/WimaMeasurementArea.cc b/src/Wima/Geometry/WimaMeasurementArea.cc index 80988149f..6ff14fd93 100644 --- a/src/Wima/Geometry/WimaMeasurementArea.cc +++ b/src/Wima/Geometry/WimaMeasurementArea.cc @@ -9,6 +9,38 @@ #define SNAKE_MAX_TILES 1000 #endif +TileData::TileData() : tiles(this) {} + +TileData::~TileData() { tiles.clearAndDeleteContents(); } + +TileData &TileData::operator=(const TileData &other) { + this->tiles.clearAndDeleteContents(); + for (std::size_t i = 0; i < std::size_t(other.tiles.count()); ++i) { + const auto *obj = other.tiles.get(i); + const auto *tile = qobject_cast(obj); + if (tile != nullptr) { + this->tiles.append(new SnakeTile(*tile, this)); + } else { + qWarning("TileData::operator=: nullptr"); + } + } + this->tileCenterPoints = other.tileCenterPoints; + return *this; +} + +void TileData::clear() { + this->tiles.clearAndDeleteContents(); + this->tileCenterPoints.clear(); +} + +size_t TileData::size() const { + if (tiles.count() == tileCenterPoints.size()) { + return tiles.count(); + } else { + return 0; + } +} + const char *WimaMeasurementArea::settingsGroup = "MeasurementArea"; const char *WimaMeasurementArea::tileHeightName = "TileHeight"; const char *WimaMeasurementArea::tileWidthName = "TileWidth"; @@ -39,8 +71,7 @@ WimaMeasurementArea::WimaMeasurementArea(QObject *parent) this /* QObject parent */)), _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName], this /* QObject parent */)), - _pTiles(new QmlObjectListModel(), &tileDeleter), _calculating(false), - _polygonValid(false) { + _calculating(false) { init(); } @@ -64,8 +95,7 @@ WimaMeasurementArea::WimaMeasurementArea(const WimaMeasurementArea &other, this /* QObject parent */)), _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName], this /* QObject parent */)), - _pTiles(new QmlObjectListModel(), &tileDeleter), _calculating(false), - _polygonValid(false) { + _calculating(false) { init(); } @@ -81,9 +111,7 @@ operator=(const WimaMeasurementArea &other) { return *this; } -WimaMeasurementArea::~WimaMeasurementArea() { - this->_pTiles->clearAndDeleteContents(); -} +WimaMeasurementArea::~WimaMeasurementArea() {} QString WimaMeasurementArea::mapVisualQML() const { return "WimaMeasurementAreaMapVisual.qml"; @@ -105,10 +133,20 @@ Fact *WimaMeasurementArea::minTransectLength() { return &_minTransectLength; } Fact *WimaMeasurementArea::showTiles() { return &_showTiles; } -QmlObjectListModel *WimaMeasurementArea::tiles() { return this->_pTiles.get(); } +QmlObjectListModel *WimaMeasurementArea::tiles() { + return &this->_tileData.tiles; +} const QmlObjectListModel *WimaMeasurementArea::tiles() const { - return this->_pTiles.get(); + return &this->_tileData.tiles; +} + +const QVariantList &WimaMeasurementArea::tileCenterPoints() const { + return this->_tileData.tileCenterPoints; +} + +const TileData &WimaMeasurementArea::tileData() const { + return this->_tileData; } int WimaMeasurementArea::maxTiles() const { return SNAKE_MAX_TILES; } @@ -181,8 +219,8 @@ bool WimaMeasurementArea::loadFromJson(const QJsonObject &json, } //! //! \brief WimaMeasurementArea::doUpdate -//! \pre WimaMeasurementArea::deferUpdate must be called first, don't call this -//! function directly! +//! \pre WimaMeasurementArea::deferUpdate must be called first, don't call +//! this function directly! void WimaMeasurementArea::doUpdate() { using namespace snake; using namespace boost::units; @@ -198,14 +236,10 @@ void WimaMeasurementArea::doUpdate() { long(std::ceil(estNumTiles.value())) <= SNAKE_MAX_TILES && this->count() >= 3 && this->isSimplePolygon()) { this->_calculating = true; - if (!this->_polygonValid) { - this->_polygon = this->coordinateList(); - for (auto &v : this->_polygon) { - v.setAltitude(0); - } - this->_polygonValid = true; + auto polygon = this->coordinateList(); + for (auto &v : polygon) { + v.setAltitude(0); } - const auto &polygon = this->_polygon; const auto minArea = this->_minTileArea.rawValue().toDouble() * si::meter * si::meter; auto *th = this->thread(); @@ -213,35 +247,44 @@ void WimaMeasurementArea::doUpdate() { #ifdef SNAKE_SHOW_TIME auto start = std::chrono::high_resolution_clock::now(); #endif - TilesPtr pTiles(new QmlObjectListModel(), &tileDeleter); + DataPtr pData(new TileData()); + // Convert to ENU system. QGeoCoordinate origin = polygon.first(); BoostPolygon polygonENU; areaToEnu(origin, polygon, polygonENU); std::vector tilesENU; BoundingBox bbox; std::string errorString; + // Generate tiles. if (snake::tiles(polygonENU, height, width, minArea, tilesENU, bbox, errorString)) { + // Convert to geo system. for (const auto &t : tilesENU) { - auto geoTile = new SnakeTile(pTiles.get()); + auto geoTile = new SnakeTile(pData.get()); for (const auto &v : t.outer()) { QGeoCoordinate geoVertex; fromENU(origin, v, geoVertex); geoTile->push_back(geoVertex); } - pTiles->append(geoTile); + pData->tiles.append(geoTile); + // Calculate center. + snake::BoostPoint center; + snake::polygonCenter(t, center); + QGeoCoordinate geoCenter; + fromENU(origin, center, geoCenter); + pData->tileCenterPoints.append(QVariant::fromValue(geoCenter)); } } - pTiles->moveToThread(th); + pData->moveToThread(th); #ifdef SNAKE_SHOW_TIME - qDebug() - << "WimaMeasurementArea::doUpdate concurrent update execution time: " - << std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - start) - .count() - << " ms"; + qDebug() << "WimaMeasurementArea::doUpdate concurrent update execution " + "time: " + << std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start) + .count() + << " ms"; #endif - return pTiles; + return pData; }); // QtConcurrent::run() this->_watcher.setFuture(future); @@ -259,8 +302,8 @@ void WimaMeasurementArea::deferUpdate() { if (this->_timer.isActive()) { this->_timer.stop(); } - if (this->_pTiles->count() > 0) { - this->_pTiles->clearAndDeleteContents(); + if (this->_tileData.size() > 0) { + this->_tileData.clear(); emit this->tilesChanged(); } this->_timer.start(100); @@ -270,10 +313,10 @@ void WimaMeasurementArea::storeTiles() { #ifdef SNAKE_SHOW_TIME auto start = std::chrono::high_resolution_clock::now(); #endif - this->_pTiles = this->_watcher.result(); + this->_tileData = *this->_watcher.result(); this->_calculating = false; - emit this - ->tilesChanged(); // This is expensive. Drawing tiles is expensive too. + // This is expensive. Drawing tiles is expensive too. + emit this->tilesChanged(); #ifdef SNAKE_SHOW_TIME qDebug() << "WimaMeasurementArea::storeTiles() execution time: " << std::chrono::duration_cast( @@ -293,8 +336,6 @@ void WimaMeasurementArea::init() { &WimaMeasurementArea::deferUpdate); connect(this, &WimaArea::pathChanged, this, &WimaMeasurementArea::deferUpdate); - connect(this, &WimaArea::pathChanged, - [this] { this->_polygonValid = false; }); this->_timer.setSingleShot(true); connect(&this->_timer, &QTimer::timeout, this, &WimaMeasurementArea::doUpdate); diff --git a/src/Wima/Geometry/WimaMeasurementArea.h b/src/Wima/Geometry/WimaMeasurementArea.h index 9ccb513f4..cac4482a9 100644 --- a/src/Wima/Geometry/WimaMeasurementArea.h +++ b/src/Wima/Geometry/WimaMeasurementArea.h @@ -8,6 +8,20 @@ #include "SettingsFact.h" +class TileData : public QObject { +public: + QmlObjectListModel tiles; + QVariantList tileCenterPoints; + + TileData(); + ~TileData(); + + TileData &operator=(const TileData &other); + + void clear(); + std::size_t size() const; +}; + class WimaMeasurementArea : public WimaArea { Q_OBJECT public: @@ -38,6 +52,8 @@ public: Fact *showTiles(); QmlObjectListModel *tiles(); const QmlObjectListModel *tiles() const; + const QVariantList &tileCenterPoints() const; // List of QGeoCoordinate + const TileData &tileData() const; int maxTiles() const; bool ready() const; @@ -86,10 +102,8 @@ private: // Tile stuff. QTimer _timer; - using TilesPtr = std::shared_ptr; - TilesPtr _pTiles; - QList _polygon; - QFutureWatcher _watcher; + using DataPtr = std::shared_ptr; + TileData _tileData; + QFutureWatcher _watcher; bool _calculating; - bool _polygonValid; }; diff --git a/src/Wima/Geometry/WimaMeasurementAreaData.cc b/src/Wima/Geometry/WimaMeasurementAreaData.cc index 1e05af7e2..0fc241f54 100644 --- a/src/Wima/Geometry/WimaMeasurementAreaData.cc +++ b/src/Wima/Geometry/WimaMeasurementAreaData.cc @@ -44,33 +44,45 @@ operator=(const WimaMeasurementArea &other) { QString WimaMeasurementAreaData::type() const { return this->typeString; } +QmlObjectListModel *WimaMeasurementAreaData::tiles() { + return &this->_tileData.tiles; +} + +const QmlObjectListModel *WimaMeasurementAreaData::tiles() const { + return &this->_tileData.tiles; +} + +const QVariantList &WimaMeasurementAreaData::tileCenterPoints() const { + return this->_tileData.tileCenterPoints; +} + +QVariantList &WimaMeasurementAreaData::tileCenterPoints() { + return this->_tileData.tileCenterPoints; +} + +const TileData &WimaMeasurementAreaData::tileData() const { + return this->tileData(); +} + +TileData &WimaMeasurementAreaData::tileData() { return this->tileData(); } + +const QVector &WimaMeasurementAreaData::progress() const { + return this->_progress; +} + +QVector &WimaMeasurementAreaData::progress() { return this->_progress; } + void WimaMeasurementAreaData::assign(const WimaMeasurementAreaData &other) { WimaAreaData::assign(other); - this->tiles.clearAndDeleteContents(); - for (std::size_t i = 0; i < std::size_t(other.tiles.count()); ++i) { - const auto *obj = other.tiles.get(i); - const auto *tile = qobject_cast(obj); - if (tile != nullptr) { - this->tiles.append(new SnakeTile(*tile, this)); - } else { - qWarning() << "WimaMeasurementAreaData::assign(): type cast failed."; - } - } + this->_tileData = other._tileData; + this->_progress = other._progress; } void WimaMeasurementAreaData::assign(const WimaMeasurementArea &other) { WimaAreaData::assign(other); - this->tiles.clearAndDeleteContents(); if (other.ready()) { - for (std::size_t i = 0; i < std::size_t(other.tiles()->count()); ++i) { - const auto *obj = other.tiles()->get(i); - const auto *tile = qobject_cast(obj); - if (tile != nullptr) { - this->tiles.append(new SnakeTile(*tile, this)); - } else { - qWarning() << "WimaMeasurementAreaData::assign(): type cast failed."; - } - } + this->_tileData = other.tileData(); + qWarning() << "WimaMeasurementAreaData: add progress copy here."; } else { qWarning() << "WimaMeasurementAreaData::assign(): WimaMeasurementArea not ready."; diff --git a/src/Wima/Geometry/WimaMeasurementAreaData.h b/src/Wima/Geometry/WimaMeasurementAreaData.h index 6bcc3247e..fccdf6dd3 100644 --- a/src/Wima/Geometry/WimaMeasurementAreaData.h +++ b/src/Wima/Geometry/WimaMeasurementAreaData.h @@ -23,17 +23,22 @@ public: return new WimaMeasurementAreaData(*this); } - static const char *typeString; - -signals: + QmlObjectListModel *tiles(); + const QmlObjectListModel *tiles() const; + const QVariantList &tileCenterPoints() const; + QVariantList &tileCenterPoints(); + const TileData &tileData() const; + TileData &tileData(); + const QVector &progress() const; + QVector &progress(); -public slots: + static const char *typeString; protected: void assign(const WimaMeasurementAreaData &other); void assign(const WimaMeasurementArea &other); private: - // see WimaMeasurementArea.h for explanation - QmlObjectListModel tiles; + TileData _tileData; + QVector _progress; }; diff --git a/src/Wima/Snake/NemoInterface.cpp b/src/Wima/Snake/NemoInterface.cpp index 2b0a08e47..2aa69d4e2 100644 --- a/src/Wima/Snake/NemoInterface.cpp +++ b/src/Wima/Snake/NemoInterface.cpp @@ -12,6 +12,9 @@ #include "QNemoHeartbeat.h" #include "QNemoProgress.h" +#include "Wima/Geometry/WimaMeasurementArea.h" +#include "Wima/Snake/SnakeTile.h" +#include "Wima/Snake/snake.h" #include "ros_bridge/include/messages/geographic_msgs/geopoint.h" #include "ros_bridge/include/messages/jsk_recognition_msgs/polygon_array.h" @@ -39,8 +42,9 @@ public: void start(); void stop(); - void setTilesENU(const SnakeTilesLocal &tilesENU); - void setENUOrigin(const QGeoCoordinate &ENUOrigin); + void setTileData(const TileData &tileData); + bool hasTileData(const TileData &tileData) const; + NemoInterface::NemoStatus status(); QVector progress(); @@ -69,6 +73,9 @@ private: TimePoint nextTimeout; mutable std::shared_timed_mutex heartbeatMutex; + // Not protected data. + TileData tileData; + // Internals bool running; std::atomic_bool topicServiceSetupDone; @@ -113,24 +120,49 @@ void NemoInterface::Impl::start() { this->running = true; } void NemoInterface::Impl::stop() { this->running = false; } -void NemoInterface::Impl::setTilesENU(const SnakeTilesLocal &tilesENU) { - UniqueLock lk(this->tilesENUMutex); - this->tilesENU = tilesENU; - lk.unlock(); - if (this->running && this->topicServiceSetupDone) { - lk.lock(); - this->publishTilesENU(); +void NemoInterface::Impl::setTileData(const TileData &tileData) { + this->tileData = tileData; + if (tileData.tiles.count() > 0) { + std::lock(this->ENUOriginMutex, this->tilesENUMutex); + UniqueLock lk1(this->ENUOriginMutex, std::adopt_lock); + UniqueLock lk2(this->tilesENUMutex, std::adopt_lock); + + const auto *obj = tileData.tiles.get(0); + const auto *tile = qobject_cast(obj); + if (tile != nullptr) { + if (tile->coordinateList().size() > 0) { + this->ENUOrigin = tile->coordinateList().first(); + const auto &origin = this->ENUOrigin; + this->tilesENU.polygons().clear(); + bool error = false; + for (std::size_t i = 0; i < tileData.tiles.count(); ++i) { + *obj = tileData.tiles.get(i); + *tile = qobject_cast(obj); + if (tile != nullptr) { + snake::BoostPolygon tileENU; + snake::areaToEnu(origin, tile->coordinateList(), tileENU); + this->tilesENU.polygons().push_back(std::move(tileENU)); + } else { + qWarning() << "NemoInterface::Impl::setTileData(): nullptr."; + error = true; + break; + } + } + if (!error && this->running && this->topicServiceSetupDone) { + this->publishENUOrigin(); + this->publishTilesENU(); + } else { + qWarning() << "NemoInterface::Impl::setTileData(): first tile empty."; + } + } else { + qWarning() << "NemoInterface::Impl::setTileData(): nullptr."; + } + } } } -void NemoInterface::Impl::setENUOrigin(const QGeoCoordinate &ENUOrigin) { - UniqueLock lk(this->ENUOriginMutex); - this->ENUOrigin = ENUOrigin; - lk.unlock(); - if (this->running && this->topicServiceSetupDone) { - lk.lock(); - this->publishENUOrigin(); - } +bool NemoInterface::Impl::hasTileData(const TileData &tileData) const { + return this->tileData = tileData; } NemoInterface::NemoStatus NemoInterface::Impl::status() { @@ -341,12 +373,12 @@ void NemoInterface::start() { this->pImpl->start(); } void NemoInterface::stop() { this->pImpl->stop(); } -void NemoInterface::setTilesENU(const SnakeTilesLocal &tilesENU) { - this->pImpl->setTilesENU(tilesENU); +void NemoInterface::publishTileData(const TileData &tileData) { + this->pImpl->setTileData(tileData); } -void NemoInterface::setENUOrigin(const QGeoCoordinate &ENUOrigin) { - this->pImpl->setENUOrigin(ENUOrigin); +bool NemoInterface::hasTileData(const TileData &tileData) const { + return this->pImpl->hasTileData(tileData); } NemoInterface::NemoStatus NemoInterface::status() const { diff --git a/src/Wima/Snake/NemoInterface.h b/src/Wima/Snake/NemoInterface.h index b5c59db4d..5a23fdff7 100644 --- a/src/Wima/Snake/NemoInterface.h +++ b/src/Wima/Snake/NemoInterface.h @@ -7,6 +7,8 @@ #include +class TileData; + class NemoInterface : public QObject { Q_OBJECT class Impl; @@ -26,8 +28,8 @@ public: void start(); void stop(); - void setTilesENU(const SnakeTilesLocal &tilesENU); - void setENUOrigin(const QGeoCoordinate &ENUOrigin); + void publishTileData(const TileData &tileData); + bool hasTileData(const TileData &tileData) const; NemoStatus status() const; QVector progress() const; diff --git a/src/Wima/WimaController.cc b/src/Wima/WimaController.cc index 2377f38df..3c0f4c468 100644 --- a/src/Wima/WimaController.cc +++ b/src/Wima/WimaController.cc @@ -2,6 +2,12 @@ #include "utilities.h" +#include "MissionController.h" +#include "MissionSettingsItem.h" +#include "PlanMasterController.h" +#include "QGCApplication.h" +#include "SimpleMissionItem.h" + #include "Snake/QNemoHeartbeat.h" #include "Snake/QNemoProgress.h" @@ -33,12 +39,6 @@ const char *WimaController::showCurrentMissionItemsName = const char *WimaController::flightSpeedName = "FlightSpeed"; const char *WimaController::arrivalReturnSpeedName = "ArrivalReturnSpeed"; const char *WimaController::altitudeName = "Altitude"; -const char *WimaController::snakeTileWidthName = "SnakeTileWidth"; -const char *WimaController::snakeTileHeightName = "SnakeTileHeight"; -const char *WimaController::snakeMinTileAreaName = "SnakeMinTileArea"; -const char *WimaController::snakeLineDistanceName = "SnakeLineDistance"; -const char *WimaController::snakeMinTransectLengthName = - "SnakeMinTransectLength"; WimaController::StatusMap WimaController::_nemoStatusMap{ std::make_pair(0, "No Heartbeat"), @@ -71,14 +71,7 @@ WimaController::WimaController(QObject *parent) _flightSpeed(settingsGroup, _metaDataMap[flightSpeedName]), _arrivalReturnSpeed(settingsGroup, _metaDataMap[arrivalReturnSpeedName]), _altitude(settingsGroup, _metaDataMap[altitudeName]), - _snakeTileWidth(settingsGroup, _metaDataMap[snakeTileWidthName]), - _snakeTileHeight(settingsGroup, _metaDataMap[snakeTileHeightName]), - _snakeMinTileArea(settingsGroup, _metaDataMap[snakeMinTileAreaName]), - _snakeLineDistance(settingsGroup, _metaDataMap[snakeLineDistanceName]), - _snakeMinTransectLength(settingsGroup, - _metaDataMap[snakeMinTransectLengthName]), _lowBatteryHandlingTriggered(false), _measurementPathLength(-1), - _snakeThread(this), _emptyThread(this), _currentThread(&_emptyThread), _nemoInterface(this), _batteryLevelTicker(EVENT_TIMER_INTERVAL, 1000 /*ms*/) { @@ -98,6 +91,14 @@ WimaController::WimaController(QObject *parent) connect(&_altitude, &Fact::rawValueChanged, this, &WimaController::_updateAltitude); + // Nemo stuff. + connect(&_nemoInterface, &NemoInterface::progressChanged, this, + &WimaController::_progressChangedHandler); + connect(&_nemoInterface, &NemoInterface::statusChanged, this, + &WimaController::nemoStatusChanged); + connect(&_nemoInterface, &NemoInterface::statusChanged, this, + &WimaController::nemoStatusStringChanged); + // Init waypoint managers. bool value; size_t overlap = _overlapWaypoints.rawValue().toUInt(&value); @@ -118,14 +119,6 @@ WimaController::WimaController(QObject *parent) &WimaController::_eventTimerHandler); _eventTimer.start(EVENT_TIMER_INTERVAL); - // SnakeThread. - connect(_currentThread, &SnakeThread::finished, this, - &WimaController::_threadFinishedHandler); - connect(_currentThread, &SnakeThread::calcInProgressChanged, this, - &WimaController::snakeCalcInProgressChanged); - connect(this, &QObject::destroyed, &this->_snakeThread, &SnakeThread::quit); - connect(this, &QObject::destroyed, &this->_emptyThread, &SnakeThread::quit); - // NemoInterface. connect(&_nemoInterface, &NemoInterface::progressChanged, this, &WimaController::_progressChangedHandler); @@ -199,16 +192,15 @@ Fact *WimaController::arrivalReturnSpeed() { return &_arrivalReturnSpeed; } Fact *WimaController::altitude() { return &_altitude; } QmlObjectListModel *WimaController::snakeTiles() { - static QmlObjectListModel list; - return &list; + return &this->_measurementArea.tiles(); } QVariantList WimaController::snakeTileCenterPoints() { - return _currentThread->tileCenterPoints(); + return this->_measurementArea.tileCenterPoints(); } QVector WimaController::nemoProgress() { - return _currentThread->progress(); + return this->_measurementArea.progress(); } double WimaController::phaseDistance() const { @@ -230,7 +222,8 @@ QString WimaController::nemoStatusString() const { } bool WimaController::snakeCalcInProgress() const { - return _currentThread->calcInProgress(); + qWarning() << "using snakeCalcInProgress dummy"; + return true; } void WimaController::setMasterController(PlanMasterController *masterC) { @@ -387,12 +380,18 @@ bool WimaController::setWimaPlanData(QSharedPointer planData) { _areas.clear(); _defaultWM.clear(); _snakeWM.clear(); + _measurementArea = WimaMeasurementAreaData(); + _serviceArea = WimaServiceAreaData(); + _corridor = WimaCorridorData(); + _joinedArea = WimaJoinedAreaData(); emit visualItemsChanged(); emit missionItemsChanged(); emit currentMissionItemsChanged(); emit waypointPathChanged(); emit currentWaypointPathChanged(); + emit snakeTilesChanged(); + emit nemoProgressChanged(); _localPlanDataValid = false; @@ -451,8 +450,26 @@ bool WimaController::setWimaPlanData(QSharedPointer planData) { } emit visualItemsChanged(); + emit snakeTilesChanged(); + + // Publish tiles if necessary. + if (!this->_nemoInterface.hasTileData(this->_measurementArea.tileData())) { + this->_nemoInterface.publishTileData(this->_measurementArea.tileData()); + this->_measurementArea.progress() = + QVector(this->_measurementArea.tiles()->count, 0); + emit nemoProgressChanged(); + } else if (this->_enableSnake.rawValue().toBool()) { + const auto progess = this->_nemoInterface.progress(); + if (progess.size() == this->_measurementArea.tiles()->count()) { + this->_measurementArea.progress() = std::move(progress); + emit nemoProgressChanged(); + } + } + + // Copy raw transects. + this->_rawTransects = planData->transects(); - // Copy transects. + // Copy missionItems. auto tempMissionItems = planData->missionItems(); if (tempMissionItems.size() < 1) { qWarning("WimaController: Mission items from WimaPlaner empty!"); @@ -475,12 +492,8 @@ bool WimaController::setWimaPlanData(QSharedPointer planData) { emit currentMissionItemsChanged(); emit waypointPathChanged(); emit currentWaypointPathChanged(); - // qWarning("WimaController: Mission items from WimaPlaner empty!"); - // return false; - _snakeThread.setMeasurementArea(_measurementArea.coordinateList()); - _snakeThread.setServiceArea(_serviceArea.coordinateList()); - _snakeThread.setCorridor(_corridor.coordinateList()); - _currentThread->start(); + + qWarning("WimaController: add snake update here lkjdfl!"); _localPlanDataValid = true; return true; @@ -760,67 +773,28 @@ void WimaController::_initSmartRTL() { } void WimaController::_threadFinishedHandler() { -#ifdef SNAKE_SHOW_TIME + qWarning() << "update here as well .jisddf"; auto start = std::chrono::high_resolution_clock::now(); #endif - if (!_snakeThread.errorMessage().isEmpty()) { - qDebug() << _snakeThread.errorMessage(); - } - - if (_snakeThread.tilesUpdated()) { - this->tiles.clearAndDeleteContents(); - auto tls = _snakeThread.tiles().polygons(); - for (const auto &t : tls) { - this->tiles.append(new SnakeTile(t, &tiles)); - } - emit snakeTilesChanged(); - emit snakeTileCenterPointsChanged(); - - _nemoInterface.setTilesENU(_snakeThread.tilesENU()); - _nemoInterface.setENUOrigin(_snakeThread.ENUOrigin()); + // Copy waypoints to waypoint manager. + _snakeWM.clear(); + auto waypoints = 1; + if (waypoints.size() < 1) { + return; } -#ifdef SNAKE_SHOW_TIME - auto end = std::chrono::high_resolution_clock::now(); - std::cout << "WimaController::_threadFinishedHandler(): tiles: " - << std::chrono::duration_cast(end - - start) - .count() - << " ms" << std::endl; - start = std::chrono::high_resolution_clock::now(); -#endif - if (_snakeThread.progressUpdated()) { - emit nemoProgressChanged(); + for (auto &vertex : waypoints) { + _snakeWM.push_back(vertex); } -#ifdef SNAKE_SHOW_TIME - end = std::chrono::high_resolution_clock::now(); - std::cout << "WimaController::_threadFinishedHandler(): progress: " - << std::chrono::duration_cast(end - - start) - .count() - << " ms" << std::endl; - start = std::chrono::high_resolution_clock::now(); -#endif - if (_snakeThread.waypointsUpdated()) { - // Copy waypoints to waypoint manager. - _snakeWM.clear(); - auto waypoints = _snakeThread.waypoints(); - if (waypoints.size() < 1) { - return; - } - for (auto &vertex : waypoints) { - _snakeWM.push_back(vertex); - } - // Do update. - this->_snakeWM.update(); // this can take a while (ca. 200ms) + // Do update. + this->_snakeWM.update(); // this can take a while (ca. 200ms) - emit missionItemsChanged(); - emit currentMissionItemsChanged(); - emit currentWaypointPathChanged(); - emit waypointPathChanged(); - } + emit missionItemsChanged(); + emit currentMissionItemsChanged(); + emit currentWaypointPathChanged(); + emit waypointPathChanged(); #ifdef SNAKE_SHOW_TIME - end = std::chrono::high_resolution_clock::now(); + auto end = std::chrono::high_resolution_clock::now(); std::cout << "WimaController::_threadFinishedHandler(): waypoints: " << std::chrono::duration_cast(end - start) @@ -837,60 +811,56 @@ void WimaController::_switchToSnakeWaypointManager(QVariant variant) { } } -void WimaController::_switchThreadObject(SnakeThread &thread) { - if (_currentThread != &thread) { - // SnakeThread. - disconnect(_currentThread, &SnakeThread::finished, this, - &WimaController::_threadFinishedHandler); - disconnect(_currentThread, &SnakeThread::calcInProgressChanged, this, - &WimaController::snakeCalcInProgressChanged); - // NemoInterface. - disconnect(&_nemoInterface, &NemoInterface::progressChanged, this, - &WimaController::_progressChangedHandler); - disconnect(&_nemoInterface, &NemoInterface::statusChanged, this, - &WimaController::nemoStatusChanged); - disconnect(&_nemoInterface, &NemoInterface::statusChanged, this, - &WimaController::nemoStatusStringChanged); - - _currentThread = &thread; - - // SnakeThread. - connect(_currentThread, &SnakeThread::finished, this, - &WimaController::_threadFinishedHandler); - connect(_currentThread, &SnakeThread::calcInProgressChanged, this, - &WimaController::snakeCalcInProgressChanged); - // NemoInterface. - connect(&_nemoInterface, &NemoInterface::progressChanged, this, - &WimaController::_progressChangedHandler); - connect(&_nemoInterface, &NemoInterface::statusChanged, this, - &WimaController::nemoStatusChanged); - connect(&_nemoInterface, &NemoInterface::statusChanged, this, - &WimaController::nemoStatusStringChanged); - - emit snakeCalcInProgressChanged(); - emit snakeTilesChanged(); - emit snakeTileCenterPointsChanged(); +void WimaController::_progressChangedHandler() { + const auto progress = this->_nemoInterface.progress(); + if (this->_measurementArea.tiles().count() == progress.size()) { + this->_measurementArea.progress() = std::move(progress); emit nemoProgressChanged(); - emit nemoStatusChanged(); - emit nemoStatusStringChanged(); + } else if (_localPlanDataValid) { + this->_nemoInterface.publishTileData(this->_measurementArea.tileData()); } } -void WimaController::_progressChangedHandler() { - this->_snakeThread.setProgress(this->_nemoInterface.progress()); - this->_snakeThread.start(); -} - void WimaController::_enableSnakeChangedHandler() { if (this->_enableSnake.rawValue().toBool()) { qDebug() << "WimaController: enabling snake."; - _switchThreadObject(this->_snakeThread); this->_nemoInterface.start(); - this->_snakeThread.start(); } else { qDebug() << "WimaController: disabling snake."; this->_nemoInterface.stop(); - this->_snakeThread.quit(); - _switchThreadObject(_emptyThread); + } +} + +void WimaController::_updateRoute() { + if (_localPlanDataValid && this->_joinedArea.coordinateList().size() > 0) { + auto safeArea = this->_joinedArea.coordinateList(); + for (auto &v : safeArea) { + v.setAltitude(0); + } + const auto &origin = safeArea.front(); + snake::BoostPolygon safeAreaENU; + snake::areaToEnu(origin, safeArea, safeAreaENU); + const auto &depot = this->_serviceArea.depot(); + const auto &geoTransects = this->_rawTransects; + const auto progess = this->_nemoInterface.progress(); + auto pTiles = std::make_shared>>(); + + auto generator = [origin, depot, + geoTransects](snake::Transects &transects) -> bool { + snake::BoostPolygon depotENU; + snake::toENU(origin, depot, depotENU); + transects.push_back(snake::BoostLineString{depotENU}); + for (auto &geoTransect : geoTransects) { + snake::BoostLineString t; + for (auto &geoVertex : geoTransect) { + snake::BoostPoint v; + snake::toENU(origin, geoVertex, v); + t.push_back(v); + } + transects.push_back(t); + } + return true; + }; + this->_routingThread.route(safeAreaENU, generator); } } diff --git a/src/Wima/WimaController.h b/src/Wima/WimaController.h index 26dba002f..57d49e076 100644 --- a/src/Wima/WimaController.h +++ b/src/Wima/WimaController.h @@ -6,31 +6,21 @@ #include "QGCMapPolygon.h" #include "QmlObjectListModel.h" -#include "Geometry/WimaArea.h" -#include "Geometry/WimaCorridor.h" +//#include "Geometry/WimaArea.h" +//#include "Geometry/WimaCorridor.h" #include "Geometry/WimaCorridorData.h" -#include "Geometry/WimaMeasurementArea.h" +//#include "Geometry/WimaMeasurementArea.h" #include "Geometry/WimaMeasurementAreaData.h" -#include "Geometry/WimaServiceArea.h" +//#include "Geometry/WimaServiceArea.h" #include "Geometry/WimaServiceAreaData.h" #include "WimaPlanData.h" -#include "JsonHelper.h" -#include "MissionController.h" -#include "MissionSettingsItem.h" -#include "PlanMasterController.h" -#include "QGCApplication.h" #include "SettingsFact.h" -#include "SettingsManager.h" -#include "SimpleMissionItem.h" -#include "SurveyComplexItem.h" #include "Geometry/GeoPoint3D.h" +#include "RoutingThread.h" #include "Snake/NemoInterface.h" -#include "Snake/SnakeThread.h" -#include "Snake/SnakeTiles.h" -#include "Snake/SnakeTilesLocal.h" #include "WaypointManager/DefaultManager.h" #include "WaypointManager/RTLManager.h" @@ -89,15 +79,10 @@ public: nemoStatusStringChanged) Q_PROPERTY(bool snakeCalcInProgress READ snakeCalcInProgress NOTIFY snakeCalcInProgressChanged) - Q_PROPERTY(Fact *snakeTileWidth READ snakeTileWidth CONSTANT) - Q_PROPERTY(Fact *snakeTileHeight READ snakeTileHeight CONSTANT) - Q_PROPERTY(Fact *snakeMinTileArea READ snakeMinTileArea CONSTANT) - Q_PROPERTY(Fact *snakeLineDistance READ snakeLineDistance CONSTANT) - Q_PROPERTY(Fact *snakeMinTransectLength READ snakeMinTransectLength CONSTANT) Q_PROPERTY( QmlObjectListModel *snakeTiles READ snakeTiles NOTIFY snakeTilesChanged) Q_PROPERTY(QVariantList snakeTileCenterPoints READ snakeTileCenterPoints - NOTIFY snakeTileCenterPointsChanged) + NOTIFY snakeTilesChanged) Q_PROPERTY( QVector nemoProgress READ nemoProgress NOTIFY nemoProgressChanged) @@ -125,11 +110,6 @@ public: Fact *altitude(void); // Snake settings facts. Fact *enableSnake(void) { return &_enableSnake; } - Fact *snakeTileWidth(void) { return &_snakeTileWidth; } - Fact *snakeTileHeight(void) { return &_snakeTileHeight; } - Fact *snakeMinTileArea(void) { return &_snakeMinTileArea; } - Fact *snakeLineDistance(void) { return &_snakeLineDistance; } - Fact *snakeMinTransectLength(void) { return &_snakeMinTransectLength; } // Snake data. QmlObjectListModel *snakeTiles(void); QVariantList snakeTileCenterPoints(void); @@ -179,9 +159,6 @@ public: static const char *flightSpeedName; static const char *arrivalReturnSpeedName; static const char *altitudeName; - static const char *snakeTileWidthName; - static const char *snakeTileHeightName; - static const char *snakeMinTileAreaName; static const char *snakeLineDistanceName; static const char *snakeMinTransectLengthName; @@ -207,7 +184,6 @@ signals: // Snake. void snakeCalcInProgressChanged(void); void snakeTilesChanged(void); - void snakeTileCenterPointsChanged(void); void nemoProgressChanged(void); void nemoStatusChanged(void); void nemoStatusStringChanged(void); @@ -240,9 +216,9 @@ private slots: void _threadFinishedHandler(); void _switchWaypointManager(WaypointManager::ManagerBase &manager); void _switchToSnakeWaypointManager(QVariant variant); - void _switchThreadObject(SnakeThread &thread); void _progressChangedHandler(); void _enableSnakeChangedHandler(); + void _updateRoute(); // Periodic tasks. void _eventTimerHandler(void); @@ -293,11 +269,6 @@ private: SettingsFact _arrivalReturnSpeed; // arrival and return path speed SettingsFact _altitude; // mission altitude SettingsFact _enableSnake; // Enable Snake (see snake.h) - SettingsFact _snakeTileWidth; - SettingsFact _snakeTileHeight; - SettingsFact _snakeMinTileArea; - SettingsFact _snakeLineDistance; - SettingsFact _snakeMinTransectLength; // Smart RTL. QTimer _smartRTLTimer; @@ -308,13 +279,10 @@ private: // Snake QList> _rawTransects; - QmlObjectListModel tiles; - SnakeThread _snakeThread; // Snake Data Manager - SnakeThread _emptyThread; - SnakeThread *_currentThread; NemoInterface _nemoInterface; using StatusMap = std::map; static StatusMap _nemoStatusMap; + RoutingThread _routingThread; // Periodic tasks. QTimer _eventTimer; -- 2.22.0