Commit 58b2b82d authored by Valentin Platzgummer's avatar Valentin Platzgummer

circular and linera transect generators added

parent 06e9bcab
......@@ -420,8 +420,7 @@ HEADERS += \
src/Wima/RoutingThread.h \
src/Wima/Snake/CircularGenerator.h \
src/Wima/Snake/GeneratorBase.h \
src/Wima/Snake/GeneratorData.h \
src/Wima/Snake/StandardData.h \
src/Wima/Snake/LinearGenerator.h \
src/Wima/Snake/clipper/clipper.hpp \
src/Wima/Snake/mapbox/feature.hpp \
src/Wima/Snake/mapbox/geometry.hpp \
......@@ -516,7 +515,7 @@ SOURCES += \
src/Wima/RoutingThread.cpp \
src/Wima/Snake/CircularGenerator.cpp \
src/Wima/Snake/GeneratorBase.cc \
src/Wima/Snake/StandardData.cpp \
src/Wima/Snake/LinearGenerator.cpp \
src/Wima/Snake/clipper/clipper.cpp \
src/Wima/Snake/snake.cpp \
src/Wima/Geometry/GeoPoint3D.cpp \
......@@ -1456,5 +1455,8 @@ contains (CONFIG, QGC_DISABLE_INSTALLER_SETUP) {
}
DISTFILES += \
src/Wima/Routing/json/CircularGenerator.SettingsGroup.json \
src/Wima/Snake/json/LinearGenerator.SettingsGroup.json \
src/Wima/json/CircularSurvey.SettingsGroup.json \
src/WimaView/WimaMeasurementAreaEditor.qml \
src/Settings/Wima.SettingsGroup.json
......@@ -287,6 +287,8 @@
<file alias="WimaArea.SettingsGroup.json">src/Wima/Geometry/json/WimaArea.SettingsGroup.json</file>
<file alias="WimaController.SettingsGroup.json">src/Wima/json/WimaController.SettingsGroup.json</file>
<file alias="Wima.SettingsGroup.json">src/Settings/Wima.SettingsGroup.json</file>
<file alias="CircularGenerator.SettingsGroup.json">src/Wima/Snake/json/CircularGenerator.SettingsGroup.json</file>
<file alias="LinearGenerator.SettingsGroup.json">src/Wima/Snake/json/LinearGenerator.SettingsGroup.json</file>
</qresource>
<qresource prefix="/MockLink">
<file alias="APMArduCopterMockLink.params">src/comm/APMArduCopterMockLink.params</file>
......
......@@ -9,6 +9,10 @@
#define CLIPPER_SCALE 1000000
#include "clipper/clipper.hpp"
using namespace ClipperLib;
template <> inline auto get<0>(const IntPoint &p) { return p.X; }
template <> inline auto get<1>(const IntPoint &p) { return p.Y; }
#include "Geometry/GenericCircle.h"
#include "Snake/SnakeTile.h"
......@@ -18,19 +22,6 @@
QGC_LOGGING_CATEGORY(CircularSurveyLog, "CircularSurveyLog")
using namespace ClipperLib;
template <> auto get<0>(const IntPoint &p) { return p.X; }
template <> auto get<1>(const IntPoint &p) { return p.Y; }
template <class Functor> class CommandRAII {
public:
CommandRAII(Functor f) : fun(f) {}
~CommandRAII() { fun(); }
private:
Functor fun;
};
template <typename T>
constexpr typename std::underlying_type<T>::type integral(T value) {
return static_cast<typename std::underlying_type<T>::type>(value);
......@@ -456,7 +447,7 @@ void CircularSurvey::_updateWorker() {
// Routing par.
RoutingParameter par;
par.numSolutionsPerRun = 5;
par.numSolutions = 5;
if (this->_numRuns.rawValue().toUInt() < 1) {
disconnect(&this->_numRuns, &Fact::rawValueChanged, this,
&CircularSurvey::_rebuildTransects);
......
......@@ -59,7 +59,7 @@ void RoutingThread::run() {
lk.unlock();
auto safeAreaENU = par.safeArea;
auto numRuns = par.numRuns;
auto numSolutionsPerRun = par.numSolutionsPerRun;
auto numSolutionsPerRun = par.numSolutions;
PtrRoutingData pRouteData(new RoutingData());
auto &transectsENU = pRouteData->transects;
......
......@@ -17,9 +17,9 @@ struct RoutingData {
};
struct RoutingParameter {
RoutingParameter() : numSolutionsPerRun(1), numRuns(1) {}
RoutingParameter() : numSolutions(1), numRuns(1) {}
snake::FPolygon safeArea;
std::size_t numSolutionsPerRun;
std::size_t numSolutions;
std::size_t numRuns;
};
//!
......
This diff is collapsed.
#include "GeneratorBase.h"
#include "StandardData.h"
#include <QGeoCoordinate>
namespace routing {
class CircularGenerator : public GeneratorBase {
Q_OBJECT
public:
CircularGenerator(QObject *parent = nullptr) override;
CircularGenerator(QObject *parent = nullptr);
CircularGenerator(Data d, QObject *parent = nullptr);
Q_PROPERTY(QGeoCoordinate reference READ reference WRITE setReference NOTIFY
referenceChanged)
Q_PROPERTY(Fact *distance READ distance CONSTANT)
Q_PROPERTY(Fact *deltaAlpha READ deltaAlpha CONSTANT)
Q_PROPERTY(Fact *minLength READ minLength CONSTANT)
virtual QString editorQML() override;
virtual QString mapVisualQML() override;
......@@ -14,7 +22,36 @@ public:
virtual QString name() override;
virtual QString abbreviation() override;
virtual bool get(const WimaPlanData &data, GeneratorBase &generator);
virtual bool get(Generator &generator) override;
QGeoCoordinate reference() const;
Fact *distance();
Fact *deltaAlpha();
Fact *minLength();
void setReference(const QGeoCoordinate &reference);
void resetReference();
static const char *settingsGroup;
static const char *distanceName;
static const char *deltaAlphaName;
static const char *minLengthName;
signals:
void referenceChanged();
protected:
virtual void establishConnections() override;
virtual void deleteConnections() override;
private:
bool _connectionsEstablished;
QGeoCoordinate _reference;
QMap<QString, FactMetaData *> _metaDataMap;
SettingsFact _distance;
SettingsFact _deltaAlpha;
SettingsFact _minLength;
};
} // namespace routing
......@@ -2,12 +2,26 @@
namespace routing {
GeneratorBase::GeneratorBase(QObject *parent) : QObject(parent) {}
GeneratorBase::GeneratorBase(QObject *parent)
: GeneratorBase(nullptr, parent) {}
GeneratorBase::GeneratorBase(std::shared_ptr<GeneratorData> par,
QObject *parent)
: QObject(parent) {}
GeneratorBase::GeneratorBase(GeneratorBase::Data d, QObject *parent)
: QObject(parent), _d(d) {
establishConnections();
}
GeneratorBase::~GeneratorBase() {}
GeneratorBase::Data GeneratorBase::data() const { return _d; }
void GeneratorBase::setData(const Data &d) {
deleteConnections();
_d = d;
establishConnections();
}
void GeneratorBase::establishConnections() {}
void GeneratorBase::deleteConnections() {}
} // namespace routing
......@@ -12,9 +12,11 @@ namespace routing {
class GeneratorBase : public QObject {
Q_OBJECT
public:
using Data = std::shared_ptr<WimaPlanData>;
using Generator = std::function<bool(snake::Transects &)>;
explicit GeneratorBase(QObject *parent = nullptr);
explicit GeneratorBase(Data d, QObject *parent = nullptr);
~GeneratorBase();
virtual QString editorQML() = 0;
......@@ -23,10 +25,18 @@ public:
virtual QString name() = 0;
virtual QString abbreviation() = 0;
virtual bool get(const WimaPlanData &data, GeneratorBase &generator) = 0;
virtual bool get(Generator &generator) = 0;
Data data() const;
void setData(const Data &d);
signals:
void generatorChanged();
protected:
virtual void establishConnections();
virtual void deleteConnections();
Data _d;
};
} // namespace routing
#pragma once
#include <QObject>
class GeneratorData : public QObject {
Q_OBJECT
public:
explicit GeneratorData(QObject *parent = nullptr);
};
This diff is collapsed.
#include "GeneratorBase.h"
#include <QGeoCoordinate>
namespace routing {
class LinearGenerator : public GeneratorBase {
Q_OBJECT
public:
LinearGenerator(QObject *parent = nullptr);
LinearGenerator(Data d, QObject *parent = nullptr);
Q_PROPERTY(Fact *distance READ distance CONSTANT)
Q_PROPERTY(Fact *alpha READ alpha CONSTANT)
Q_PROPERTY(Fact *minLength READ minLength CONSTANT)
virtual QString editorQML() override;
virtual QString mapVisualQML() override;
virtual QString name() override;
virtual QString abbreviation() override;
virtual bool get(Generator &generator) override;
Fact *distance();
Fact *alpha();
Fact *minLength();
static const char *settingsGroup;
static const char *distanceName;
static const char *alphaName;
static const char *minLengthName;
protected:
virtual void establishConnections() override;
virtual void deleteConnections() override;
private:
bool _connectionsEstablished;
QMap<QString, FactMetaData *> _metaDataMap;
SettingsFact _distance;
SettingsFact _alpha;
SettingsFact _minLength;
};
} // namespace routing
#include "StandardData.h"
StandardParameter::StandardParameter() {}
#pragma once
#include "GeneratorData.h"
namespace routing {
class StandardData : public GeneratorData {};
} // namespace routing
[
{
"name": "TransectDistance",
"shortDescription": "The distance between transects.",
"type": "double",
"units": "m",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 5.0
},
{
"name": "DeltaAlpha",
"shortDescription": "Angle discretisation.",
"type": "double",
"units": "Deg",
"min": 0.3,
"max": 90,
"decimalPlaces": 1,
"defaultValue": 5.0
},
{
"name": "MinLength",
"shortDescription": "The minimal transect length.",
"type": "double",
"units": "m",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 5.0
}
]
[
{
"name": "TransectDistance",
"shortDescription": "The distance between transects.",
"type": "double",
"units": "m",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 5.0
},
{
"name": "Alpha",
"shortDescription": "Transect angle.",
"type": "double",
"units": "Deg",
"min": 0,
"max": 180,
"decimalPlaces": 1,
"defaultValue": 0.0
},
{
"name": "MinLength",
"shortDescription": "The minimal transect length.",
"type": "double",
"units": "m",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 5.0
}
]
......@@ -230,74 +230,53 @@ void WimaController::planDataChangedHandler() {
_serviceArea = WimaServiceAreaData();
_corridor = WimaCorridorData();
_joinedArea = WimaJoinedAreaData();
_planDataValid = false;
emit visualItemsChanged();
emit missionItemsChanged();
emit waypointPathChanged();
_planDataValid = false;
// Extract areas.
auto planData = WimaBridge::instance()->planData();
// extract list with WimaAreas
QList<const WimaAreaData *> areaList = planData.areaList();
int areaCounter = 0;
const int numAreas = 4; // extract only numAreas Areas, if there are more
// they are invalid and ignored
for (int i = 0; i < areaList.size(); i++) {
const WimaAreaData *areaData = areaList[i];
if (areaData->type() ==
WimaServiceAreaData::typeString) { // is it a service area?
_serviceArea = *qobject_cast<const WimaServiceAreaData *>(areaData);
areaCounter++;
_areas.append(&_serviceArea);
continue;
}
if (areaData->type() ==
WimaMeasurementAreaData::typeString) { // is it a measurement area?
_measurementArea =
*qobject_cast<const WimaMeasurementAreaData *>(areaData);
areaCounter++;
// Measurement Area.
if (planData.measurementArea().coordinateList().size() >= 3) {
_measurementArea = planData.measurementArea();
_areas.append(&_measurementArea);
continue;
}
if (areaData->type() == WimaCorridorData::typeString) { // is it a corridor?
_corridor = *qobject_cast<const WimaCorridorData *>(areaData);
areaCounter++;
//_visualItems.append(&_corridor); // not needed
// Service Area.
if (planData.serviceArea().coordinateList().size() >= 3) {
_serviceArea = planData.serviceArea();
_areas.append(&_serviceArea);
continue;
}
_WMSettings.setHomePosition(
QGeoCoordinate(_serviceArea.depot().latitude(),
_serviceArea.depot().longitude(), 0));
if (areaData->type() ==
WimaJoinedAreaData::typeString) { // is it a corridor?
_joinedArea = *qobject_cast<const WimaJoinedAreaData *>(areaData);
areaCounter++;
// Joined Area.
if (planData.joinedArea().coordinateList().size() >= 3) {
_joinedArea = planData.joinedArea();
_areas.append(&_joinedArea);
continue;
}
_planDataValid = true;
if (areaCounter >= numAreas)
break;
// Corridor.
if (planData.corridor().coordinateList().size() >= 3) {
_corridor = planData.corridor();
}
}
}
if (areaCounter != numAreas) {
Q_ASSERT(false);
return;
}
if (_planDataValid) {
emit visualItemsChanged();
_WMSettings.setHomePosition(QGeoCoordinate(
_serviceArea.depot().latitude(), _serviceArea.depot().longitude(), 0));
_planDataValid = true;
} else {
_areas.clear();
_measurementArea = WimaMeasurementAreaData();
_serviceArea = WimaServiceAreaData();
_corridor = WimaCorridorData();
_joinedArea = WimaJoinedAreaData();
}
}
void WimaController::progressChangedHandler() {
......
#include "WimaPlanData.h"
enum Signal {
measuremtAreaChanged,
serviceAreaChanged,
joinedAreaChanged,
corridorChanged,
};
WimaPlanData::WimaPlanData(QObject *parent)
: QObject(parent), _editing(false) {}
WimaPlanData::WimaPlanData(QObject *parent) : QObject(parent) {}
WimaPlanData::WimaPlanData(const WimaPlanData &other, QObject *parent)
: QObject(parent), _editing(false) {
: QObject(parent) {
*this = other;
}
WimaPlanData &WimaPlanData::operator=(const WimaPlanData &other) {
this->_measurementArea = other._measurementArea;
this->_serviceArea = other._serviceArea;
this->_joinedArea = other._joinedArea;
this->_corridor = other._corridor;
this->set(other.measurementArea());
this->set(other.serviceArea());
this->set(other.joinedArea());
this->set(other.corridor());
return *this;
}
......@@ -27,36 +19,44 @@ WimaPlanData &WimaPlanData::operator=(const WimaPlanData &other) {
void WimaPlanData::set(const WimaJoinedAreaData &areaData) {
if (_joinedArea != areaData) {
_joinedArea = areaData;
emitJoinedAreaChanged();
emit joinedAreaChanged();
}
}
void WimaPlanData::set(const WimaServiceAreaData &areaData) {
if (_serviceArea != areaData) {
_serviceArea = areaData;
emitServiceAreaChanged();
emit serviceAreaChanged();
}
}
void WimaPlanData::set(const WimaCorridorData &areaData) {
if (_corridor != areaData) {
_corridor = areaData;
emitCorridorChanged();
emit corridorChanged();
}
}
void WimaPlanData::set(const WimaMeasurementAreaData &areaData) {
if (_measurementArea != areaData) {
_measurementArea = areaData;
emitMeasurementAreaChanged();
emit measurementAreaChanged();
if (_measurementArea.coordinateList().size() > 0) {
setOrigin(_measurementArea.coordinateList().first());
} else {
setOrigin(QGeoCoordinate());
}
}
}
void WimaPlanData::clear() {
_joinedArea = WimaJoinedAreaData();
_serviceArea = WimaServiceAreaData();
_corridor = WimaCorridorData();
_measurementArea = WimaMeasurementAreaData();
void WimaPlanData::clear() { *this = WimaPlanData(); }
QGeoCoordinate WimaPlanData::origin() { return _origin; }
bool WimaPlanData::isValid() {
return _measurementArea.coordinateList().size() >= 3 &&
_serviceArea.coordinateList().size() >= 3 && _origin.isValid();
}
const WimaJoinedAreaData &WimaPlanData::joinedArea() const {
......@@ -75,24 +75,14 @@ const WimaMeasurementAreaData &WimaPlanData::measurementArea() const {
return this->_measurementArea;
}
void WimaPlanData::startEditing() {
if (!this->_editing) {
this->_editing = true;
}
}
WimaJoinedAreaData &WimaPlanData::joinedArea() { return this->_joinedArea; }
void WimaPlanData::stopEditing() {
if (this->_editing) {
this->_editing = false;
for (auto &s : this->_queuedSignals) {
s.second();
}
this->_queuedSignals.clear();
}
}
WimaServiceAreaData &WimaPlanData::serviceArea() { return this->_serviceArea; }
WimaPlanData::Guard WimaPlanData::guard() {
return Guard(std::bind(&WimaPlanData::stopEditing, this));
WimaCorridorData &WimaPlanData::corridor() { return this->_corridor; }
WimaMeasurementAreaData &WimaPlanData::measurementArea() {
return this->_measurementArea;
}
bool WimaPlanData::operator==(const WimaPlanData &other) const {
......@@ -105,42 +95,9 @@ bool WimaPlanData::operator!=(const WimaPlanData &other) const {
return !(*this == other);
}
void WimaPlanData::emitJoinedAreaChanged() {
if (!this->_editing) {
emit joinedAreaChanged();
} else {
this->_queuedSignals.insert(
std::make_pair(Signal::joinedAreaChanged,
std::bind(&WimaPlanData::joinedAreaChanged, this)));
}
}
void WimaPlanData::emitMeasurementAreaChanged() {
if (!this->_editing) {
emit measurementAreaChanged();
} else {
this->_queuedSignals.insert(
std::make_pair(Signal::measuremtAreaChanged,
std::bind(&WimaPlanData::measurementAreaChanged, this)));
}
}
void WimaPlanData::emitServiceAreaChanged() {
if (!this->_editing) {
emit serviceAreaChanged();
} else {
this->_queuedSignals.insert(
std::make_pair(Signal::serviceAreaChanged,
std::bind(&WimaPlanData::serviceAreaChanged, this)));
}
}
void WimaPlanData::emitCorridorChanged() {
if (!this->_editing) {
emit corridorChanged();
} else {
this->_queuedSignals.insert(
std::make_pair(Signal::corridorChanged,
std::bind(&WimaPlanData::corridorChanged, this)));
void WimaPlanData::setOrigin(const QGeoCoordinate &origin) {
if (this->_origin != origin) {
this->_origin = origin;
emit originChanged();
}
}
#pragma once
#include <functional>
#include <map>
#include <QGeoCoordinate>
#include <QObject>
......@@ -16,15 +13,6 @@
class WimaPlanData : public QObject {
Q_OBJECT
public:
class Guard {
public:
Guard(std::function<void(void)> fun) : fun_(fun) {}
~Guard() { fun_(); }
private:
std::function<void(void)> fun_;
};
WimaPlanData(QObject *parent = nullptr);
WimaPlanData(const WimaPlanData &other, QObject *parent = nullptr);
WimaPlanData &operator=(const WimaPlanData &other);
......@@ -41,9 +29,13 @@ public:
const WimaCorridorData &corridor() const;
const WimaMeasurementAreaData &measurementArea() const;
void startEditing();
void stopEditing();
Guard guard();
WimaJoinedAreaData &joinedArea();
WimaServiceAreaData &serviceArea();
WimaCorridorData &corridor();
WimaMeasurementAreaData &measurementArea();
QGeoCoordinate origin();
bool isValid();
bool operator==(const WimaPlanData &other) const;
bool operator!=(const WimaPlanData &other) const;
......@@ -53,19 +45,15 @@ signals:
void serviceAreaChanged();
void corridorChanged();
void measurementAreaChanged();
void originChanged();
private:
void emitJoinedAreaChanged();
void emitServiceAreaChanged();
void emitCorridorChanged();
void emitMeasurementAreaChanged();
void setOrigin(const QGeoCoordinate &origin);
WimaJoinedAreaData _joinedArea;
WimaServiceAreaData _serviceArea;
WimaCorridorData _corridor;
WimaMeasurementAreaData _measurementArea;
std::map<int, std::function<void(void)>> _queuedSignals;
bool _editing;
QGeoCoordinate _origin;
};
......@@ -955,10 +955,10 @@ void WimaPlaner::setInteractive() {
bool WimaPlaner::toPlanData(WimaPlanData &planData) {
// store areas
planData.append(WimaMeasurementAreaData(_measurementArea));
planData.append(WimaServiceAreaData(_serviceArea));
planData.append(WimaCorridorData(_corridor));
planData.append(WimaJoinedAreaData(_joinedArea));
planData.set(WimaMeasurementAreaData(_measurementArea));
planData.set(WimaServiceAreaData(_serviceArea));
planData.set(WimaCorridorData(_corridor));
planData.set(WimaJoinedAreaData(_joinedArea));
return true;
}
......
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