Commit 4948045b authored by Valentin Platzgummer's avatar Valentin Platzgummer

MeasurementArea prepared for new NemoInterface

parent 0e658bb3
......@@ -226,11 +226,6 @@ contains (DEFINES, DISABLE_AIRMAP) {
}
}
# GeograpicLib (TODO: add Windows support!)
LinuxBuild {
LIBS += -L$$PWD/libs/libGeographic -lGeographic # libGeograpic.so.17
}
# google or-tools (TODO: add Windows support!)
LinuxBuild {
OR_TOOLS_PATH = $$PWD/libs/or-tools-src-ubuntu
......
......@@ -445,7 +445,11 @@ contains (DEFINES, QGC_ENABLE_PAIRING) {
#
HEADERS += \
src/MeasurementComplexItem/geometry/ProgressArray.h \
src/MeasurementComplexItem/geometry/TileDiff.h \
src/MeasurementComplexItem/geometry/geometry.h \
src/MeasurementComplexItem/HashFunctions.h \
src/MeasurementComplexItem/nemo_interface/MeasurementTile.h \
src/QmlControls/QmlUnitsConversion.h \
src/MeasurementComplexItem/geometry/GeoArea.h \
src/MeasurementComplexItem/geometry/MeasurementArea.h \
......@@ -487,7 +491,6 @@ HEADERS += \
src/MeasurementComplexItem/nemo_interface/QNemoHeartbeat.h \
src/MeasurementComplexItem/nemo_interface/QNemoProgress.h \
src/MeasurementComplexItem/nemo_interface/QNemoProgress.h \
src/MeasurementComplexItem/nemo_interface/SnakeTile.h \
src/MeasurementComplexItem/nemo_interface/SnakeTileLocal.h \
src/MeasurementComplexItem/nemo_interface/SnakeTiles.h \
src/MeasurementComplexItem/nemo_interface/SnakeTilesLocal.h \
......@@ -498,6 +501,7 @@ HEADERS += \
src/api/QmlComponentInfo.h \
src/GPS/Drivers/src/base_station.h \
src/Settings/WimaSettings.h \
src/comm/QmlObjectListHelper.h \
src/comm/ros_bridge/include/RosBridgeClient.h \
src/comm/ros_bridge/include/com_private.h \
src/comm/ros_bridge/include/message_traits.h \
......@@ -525,6 +529,8 @@ SOURCES += \
src/MeasurementComplexItem/geometry/MeasurementArea.cc \
src/MeasurementComplexItem/geometry/SafeArea.cc \
src/MeasurementComplexItem/geometry/geometry.cpp \
src/MeasurementComplexItem/HashFunctions.cpp \
src/MeasurementComplexItem/nemo_interface/MeasurementTile.cpp \
src/Vehicle/VehicleEscStatusFactGroup.cc \
src/MeasurementComplexItem/AreaData.cc \
src/api/QGCCorePlugin.cc \
......@@ -541,7 +547,7 @@ SOURCES += \
src/MeasurementComplexItem/geometry/GeoPoint3D.cpp \
src/MeasurementComplexItem/NemoInterface.cpp \
src/MeasurementComplexItem/nemo_interface/QNemoProgress.cc \
src/MeasurementComplexItem/nemo_interface/SnakeTile.cpp \
src/comm/QmlObjectListHelper.cpp \
src/comm/ros_bridge/include/RosBridgeClient.cpp \
src/comm/ros_bridge/include/com_private.cpp \
src/comm/ros_bridge/include/messages/geographic_msgs/geopoint.cpp \
......
......@@ -10,7 +10,7 @@
#include "geometry/MeasurementArea.h"
#include "geometry/SafeArea.h"
#include "geometry/clipper/clipper.hpp"
#include "nemo_interface/SnakeTile.h"
#include "nemo_interface/MeasurementTile.h"
QGC_LOGGING_CATEGORY(CircularGeneratorLog, "CircularGeneratorLog")
......@@ -118,31 +118,22 @@ bool CircularGenerator::get(Work &work) {
auto pPolygon = std::make_shared<geometry::FPolygon>();
geometry::areaToEnu(origin, geoPolygon, *pPolygon);
// Progress and tiles.
const auto &progress = measurementArea->progress();
// Collect tiles with progress == 100 %.
const auto *tiles = measurementArea->tiles();
auto pTiles = std::make_shared<std::vector<geometry::FPolygon>>();
if (progress.size() == tiles->count()) {
for (int i = 0; i < tiles->count(); ++i) {
if (progress[i] == 100) {
const auto *obj = (*tiles)[int(i)];
const auto *tile = qobject_cast<const SnakeTile *>(obj);
if (tile != nullptr) {
geometry::FPolygon tileENU;
geometry::areaToEnu(origin, tile->coordinateList(), tileENU);
pTiles->push_back(std::move(tileENU));
} else {
qCDebug(CircularGeneratorLog)
<< "get(): progress.size() != tiles->count().";
return false;
}
for (int i = 0; i < tiles->count(); ++i) {
const auto tile =
qobject_cast<const MeasurementTile *>(tiles->operator[](i));
if (tile != nullptr) {
if (qFuzzyCompare(tile->progress(), 100)) {
geometry::FPolygon tileENU;
geometry::areaToEnu(origin, tile->coordinateList(), tileENU);
pTiles->push_back(std::move(tileENU));
}
} else {
qCDebug(CircularGeneratorLog) << "get(): tile == nullptr.";
return false;
}
} else {
qCDebug(CircularGeneratorLog)
<< "get(): progress.size() != tiles->count().";
return false;
}
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
......
#ifndef HASHFUNCTIONS_H
#define HASHFUNCTIONS_H
#include <QGeoCoordinate>
#include <functional>
#include <QmlObjectListModel.h>
namespace std {
template <> struct hash<QGeoCoordinate> {
std::size_t operator()(const QGeoCoordinate &c) {
hash<double> h;
return h(c.latitude()) ^ h(c.longitude()) ^ h(c.altitude());
}
};
template <template <class> class Container, class EntryType>
struct hash<Container<EntryType>> {
std::size_t operator()(const Container<EntryType> &list) {
std::size_t value = 0;
hash<EntryType> h;
for (const auto it = std::begin(list); it != std::end(list); ++it) {
value ^= h(*it);
}
return value;
}
};
} // namespace std
#endif // HASHFUNCTIONS_H
......@@ -9,7 +9,7 @@
#include "geometry/clipper/clipper.hpp"
#include "RoutingThread.h"
#include "nemo_interface/SnakeTile.h"
#include "nemo_interface/MeasurementTile.h"
namespace routing {
......@@ -100,29 +100,21 @@ bool LinearGenerator::get(Work &generator) {
geometry::areaToEnu(origin, geoPolygon, *pPolygon);
// Progress and tiles.
const auto &progress = measurementArea->progress();
const auto *tiles = measurementArea->tiles();
auto pTiles = std::make_shared<std::vector<geometry::FPolygon>>();
if (progress.size() == tiles->count()) {
for (int i = 0; i < tiles->count(); ++i) {
if (progress[i] == 100) {
const QObject *obj = (*tiles)[int(i)];
const auto *tile = qobject_cast<const SnakeTile *>(obj);
if (tile != nullptr) {
geometry::FPolygon tileENU;
geometry::areaToEnu(origin, tile->coordinateList(), tileENU);
pTiles->push_back(std::move(tileENU));
} else {
qCDebug(LinearGeneratorLog) << "get(): tile == nullptr";
return false;
}
for (int i = 0; i < tiles->count(); ++i) {
const auto tile =
qobject_cast<const MeasurementTile *>(tiles->operator[](i));
if (qFuzzyCompare(tile->progress(), 100)) {
if (tile != nullptr) {
geometry::FPolygon tileENU;
geometry::areaToEnu(origin, tile->coordinateList(), tileENU);
pTiles->push_back(std::move(tileENU));
} else {
qCDebug(LinearGeneratorLog) << "get(): tile == nullptr";
return false;
}
}
} else {
qCDebug(LinearGeneratorLog)
<< "get(): progress.size() != tiles->count().";
return false;
}
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
......
......@@ -8,7 +8,7 @@
#include "geometry/SafeArea.h"
#include "geometry/clipper/clipper.hpp"
#include "geometry/geometry.h"
#include "nemo_interface/SnakeTile.h"
#include "nemo_interface/MeasurementTile.h"
// QGC
#include "JsonHelper.h"
......
......@@ -17,7 +17,7 @@
#include "geometry/geometry.h"
#include "nemo_interface/QNemoHeartbeat.h"
#include "nemo_interface/QNemoProgress.h"
#include "nemo_interface/SnakeTile.h"
#include "nemo_interface/MeasurementTile.h"
#include "ros_bridge/include/messages/geographic_msgs/geopoint.h"
#include "ros_bridge/include/messages/jsk_recognition_msgs/polygon_array.h"
......@@ -158,7 +158,7 @@ void NemoInterface::Impl::setTileData(const TileData &tileData) {
UniqueLock lk2(this->tilesENUMutex, std::adopt_lock);
const auto *obj = tileData.tiles[0];
const auto *tile = qobject_cast<const SnakeTile *>(obj);
const auto *tile = qobject_cast<const MeasurementTile *>(obj);
if (tile != nullptr) {
if (tile->coordinateList().size() > 0) {
if (tile->coordinateList().first().isValid()) {
......@@ -167,7 +167,7 @@ void NemoInterface::Impl::setTileData(const TileData &tileData) {
this->tilesENU.polygons().clear();
for (int i = 0; i < tileData.tiles.count(); ++i) {
obj = tileData.tiles[i];
tile = qobject_cast<const SnakeTile *>(obj);
tile = qobject_cast<const MeasurementTile *>(obj);
if (tile != nullptr) {
SnakeTileLocal tileENU;
geometry::areaToEnu(origin, tile->coordinateList(), tileENU.path());
......
......@@ -6,14 +6,14 @@
#include <QTimer>
#include "GeoArea.h"
#include "MeasurementComplexItem/nemo_interface/MeasurementTile.h"
#include "ProgressArray.h"
#include "TileDiff.h"
#include "SettingsFact.h"
class TileData : public QObject {
public:
QmlObjectListModel tiles;
QVariantList tileCenterPoints;
TileData();
~TileData();
......@@ -26,12 +26,15 @@ public:
void clear();
std::size_t size() const;
QmlObjectListModel tiles;
QVariantList tileCenterPoints;
};
class MeasurementArea : public GeoArea {
Q_OBJECT
enum class STATE { IDLE, DEFERED, UPDATEING, RESTARTING, STOP };
using DataPtr = QSharedPointer<TileData>;
using TilePtr = QSharedPointer<QmlObjectListModel>;
public:
MeasurementArea(QObject *parent = nullptr);
......@@ -45,7 +48,6 @@ public:
Q_PROPERTY(Fact *showTiles READ showTiles CONSTANT)
Q_PROPERTY(QmlObjectListModel *tiles READ tiles NOTIFY tilesChanged)
Q_PROPERTY(int maxTiles READ maxTiles NOTIFY maxTilesChanged)
Q_PROPERTY(QVector<int> progress READ progressQml NOTIFY progressChanged)
Q_PROPERTY(bool holdProgress READ holdProgress WRITE setHoldProgress NOTIFY
holdProgressChanged)
......@@ -63,11 +65,7 @@ public:
Fact *minTileArea();
Fact *showTiles();
QmlObjectListModel *tiles();
const QVector<int> &progress() const;
QVector<int> progressQml() const;
const QmlObjectListModel *tiles() const;
const QVariantList &tileCenterPoints() const; // List of QGeoCoordinate
const TileData &tileData() const;
int maxTiles() const;
bool ready() const;
......@@ -92,14 +90,13 @@ public:
signals:
void tilesChanged();
void maxTilesChanged();
void progressChanged();
void progressAccepted();
void progressNotAccepted();
void readyChanged();
void holdProgressChanged();
void progressChanged();
public slots:
bool setProgress(const QVector<int> &p);
void updateIds(const QList<TileDiff> &array);
void updateProgress(const ProgressArray &array);
Q_INVOKABLE void randomProgress();
Q_INVOKABLE void resetProgress();
......@@ -123,12 +120,11 @@ private:
SettingsFact _minTileAreaPercent; // 0..100
SettingsFact _showTiles;
QVector<int> _progress;
bool _holdProgress;
// Tile stuff.
// Tile stuff.
mutable QTimer _timer;
mutable STATE _state;
mutable TileData _tileData;
mutable QFutureWatcher<DataPtr> _watcher;
TilePtr _tiles;
std::map<long /*id*/, MeasurementTile *> _tileMap;
bool _holdProgress;
QTimer _timer;
STATE _state;
QFutureWatcher<TilePtr> _watcher;
};
#ifndef PROGRESSARRAY_H
#define PROGRESSARRAY_H
#include <QVector>
#include <tuple>
typedef std::pair<long /*id*/, double /*progress*/> TaggedProgress;
typedef QVector<TaggedProgress> ProgressArray;
#endif // PROGRESSARRAY_H
#ifndef TILEDIFF_H
#define TILEDIFF_H
#include "nemo_interface/MeasurementTile.h"
struct TileDiff {
MeasurementTile oldTile;
MeasurementTile newTile;
};
#endif // TILEDIFF_H
......@@ -105,8 +105,9 @@ struct BoundingBox {
FPolygon corners;
};
constexpr int earth_radius = 6371000; // meters (m)
constexpr double epsilon = std::numeric_limits<double>::epsilon(); // meters (m)
static constexpr int earth_radius = 6371000; // meters (m)
static constexpr double epsilon =
std::numeric_limits<double>::epsilon(); // meters (m)
template <class GeoPoint1, class GeoPoint2>
void toENU(const GeoPoint1 &origin, const GeoPoint2 &in, FPoint &out) {
......
#include "MeasurementTile.h"
MeasurementTile::MeasurementTile(QObject *parent)
: GeoArea(parent), _progress(0), _id(0) {
init();
}
MeasurementTile::MeasurementTile(const MeasurementTile &other, QObject *parent)
: GeoArea(other, parent), _progress(other._progress), _id(other._id) {
init();
}
MeasurementTile::~MeasurementTile() {}
MeasurementTile &MeasurementTile::operator=(const MeasurementTile &other) {
GeoArea::operator=(other);
setProgress(other._progress);
setId(other._id);
return *this;
}
QString MeasurementTile::mapVisualQML() const { return QStringLiteral(""); }
QString MeasurementTile::editorQML() const { return QStringLiteral(""); }
MeasurementTile *MeasurementTile::clone(QObject *parent) const {
return new MeasurementTile(*this, parent);
}
void MeasurementTile::push_back(const QGeoCoordinate &c) {
this->appendVertex(c);
}
void MeasurementTile::init() { this->setObjectName("Tile"); }
uint64_t MeasurementTile::id() const { return _id; }
void MeasurementTile::setId(const uint64_t &id) {
if (_id != id) {
_id = id;
emit idChanged();
}
}
double MeasurementTile::progress() const { return _progress; }
void MeasurementTile::setProgress(double progress) {
if (_progress != progress) {
_progress = progress;
emit progressChanged();
}
}
#pragma once
#include "geometry/GeoArea.h"
#include <QGeoCoordinate>
class MeasurementTile : public GeoArea {
Q_OBJECT
public:
MeasurementTile(QObject *parent = nullptr);
MeasurementTile(const MeasurementTile &other, QObject *parent = nullptr);
~MeasurementTile();
MeasurementTile &operator=(const MeasurementTile &other);
Q_PROPERTY(double progress READ progress NOTIFY progressChanged)
Q_PROPERTY(long id READ id NOTIFY idChanged)
virtual QString mapVisualQML() const override;
virtual QString editorQML() const override;
virtual MeasurementTile *clone(QObject *parent) const;
void push_back(const QGeoCoordinate &c);
double progress() const;
void setProgress(double progress);
uint64_t id() const;
void setId(const uint64_t &id);
signals:
void progressChanged();
void idChanged();
private:
void init();
double _progress;
long _id;
};
#include "SnakeTile.h"
SnakeTile::SnakeTile(QObject *parent) : GeoArea(parent) { init(); }
SnakeTile::SnakeTile(const SnakeTile &other, QObject *parent)
: GeoArea(other, parent) {
init();
}
SnakeTile::~SnakeTile() {}
QString SnakeTile::mapVisualQML() const { return QStringLiteral(""); }
QString SnakeTile::editorQML() const { return QStringLiteral(""); }
SnakeTile *SnakeTile::clone(QObject *parent) const {
return new SnakeTile(*this, parent);
}
void SnakeTile::push_back(const QGeoCoordinate &c) { this->appendVertex(c); }
void SnakeTile::init() { this->setObjectName("Tile"); }
#pragma once
#include "geometry/GeoArea.h"
#include <QGeoCoordinate>
class SnakeTile : public GeoArea {
Q_OBJECT
public:
SnakeTile(QObject *parent = nullptr);
SnakeTile(const SnakeTile &other, QObject *parent = nullptr);
~SnakeTile();
virtual QString mapVisualQML() const override;
virtual QString editorQML() const override;
virtual SnakeTile *clone(QObject *parent) const;
void push_back(const QGeoCoordinate &c);
private:
void init();
};
#pragma once
#include "SnakeTile.h"
#include "MeasurementTile.h"
#include "Wima/Geometry/GenericPolygonArray.h"
using SnakeTiles = GenericPolygonArray<SnakeTile, QVector>;
using SnakeTiles = GenericPolygonArray<MeasurementTile, QVector>;
......@@ -48,7 +48,34 @@ Item {
interiorOpacity: _root.opacity
}
// Add Snake tiles to the map
Repeater {
id: progressRepeater
property bool enable: geoArea.showTiles.value
model: enable ? geoArea.tiles : []
Item {
property var _tileComponent
Component.onCompleted: {
_tileComponent = tileComponent.createObject(map)
_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(object.progress)
})
}
Component.onDestruction: {
_tileComponent.destroy()
}
}
}
Component {
id: tileComponent
......@@ -86,32 +113,4 @@ Item {
return "limegreen"
}
Repeater {
id: progressRepeater
property bool enable: geoArea.showTiles.value
model: enable ? geoArea.tiles : []
Item {
property var _tileComponent
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.opacity = 0.6
_tileComponent.polygon.border.color = "black"
_tileComponent.polygon.border.width = 1
_tileComponent.polygon.color = Qt.binding(function () {
return getColor(_progress)
})
}
Component.onDestruction: {
_tileComponent.destroy()
}
}
}
}
#include "QmlObjectListHelper.h"
#ifndef QMLOBJECTLISTHELPER_H
#define QMLOBJECTLISTHELPER_H
#include "QmlObjectListModel.h"
#include <type_traits>
template <class PtrType>
inline bool contains(const QmlObjectListModel &in, const PtrType toFind) {
static_assert(std::is_pointer<PtrType>::value, "PtrType must be a pointer.");
typedef typename std::remove_pointer<PtrType>::type Type;
for (int i = 0; i < in.count(); ++i) {
const auto obj = qobject_cast<const Type *>(in[i]);
Q_ASSERT(obj != nullptr);
Q_ASSERT(toFind != nullptr);
if (*obj == *toFind) {
return true;
}
}
return false;
}
template <class PtrType>
inline bool equals(const QmlObjectListModel &list,
const QmlObjectListModel &otherList) {
static_assert(std::is_pointer<PtrType>::value, "PtrType must be a pointer.");
typedef typename std::remove_pointer<PtrType>::type Type;
if (list.count() == otherList.count()) {
for (int i = 0; i < list.count(); ++i) {
const auto obj = qobject_cast<const Type *>(list[i]);
const auto otherObj = qobject_cast<const Type *>(otherList[i]);
Q_ASSERT(obj != nullptr);
Q_ASSERT(otherObj != nullptr);
if (*obj != *otherObj) {
return false;
}
}
return true;
} else {
return false;
}
}
#endif // QMLOBJECTLISTHELPER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment