Commit 912e993b authored by Valentin Platzgummer's avatar Valentin Platzgummer

wima planer edited

parent 6fd60bb5
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -15,7 +15,8 @@ template <> ClipperLib::cInt get<1>(ClipperLib::IntPoint &p) { return p.Y; }
CSWorker::CSWorker(QObject *parent)
: QThread(parent), _deltaR(2 * bu::si::meter),
_deltaAlpha(3 * bu::degree::degree), _minLength(10 * bu::si::meter),
_calculating(false), _stop(false), _restart(false) {}
_useDepotSafeArea(false), _calculating(false), _stop(false),
_restart(false) {}
CSWorker::~CSWorker() {
this->_stop = true;
......@@ -34,11 +35,46 @@ void CSWorker::update(const QList<QGeoCoordinate> &polygon,
// Sample input.
Lock lk(this->_mutex);
this->_polygon = polygon;
for (auto &v : this->_polygon) {
v.setAltitude(0);
}
this->_origin = origin;
this->_origin.setAltitude(0);
this->_deltaR = deltaR;
this->_deltaAlpha = deltaAlpha;
this->_minLength = minLength;
lk.unlock();
this->_useDepotSafeArea = false;
if (!this->isRunning()) {
this->start();
} else {
Lock lk(this->_mutex);
this->_restart = true;
this->_cv.notify_one();
}
}
void CSWorker::update(const QGeoCoordinate &depot,
const QList<QGeoCoordinate> &safeArea,
const QList<QGeoCoordinate> &polygon,
const QGeoCoordinate &origin, snake::Length deltaR,
snake::Length minLength, snake::Angle deltaAlpha) {
// Sample input.
Lock lk(this->_mutex);
this->_depot = depot;
this->_safeArea = safeArea;
this->_polygon = polygon;
for (auto &v : this->_polygon) {
v.setAltitude(0);
}
this->_origin = origin;
this->_origin.setAltitude(0);
this->_deltaR = deltaR;
this->_deltaAlpha = deltaAlpha;
this->_minLength = minLength;
lk.unlock();
this->_useDepotSafeArea = true;
if (!this->isRunning()) {
this->start();
......@@ -53,7 +89,15 @@ void CSWorker::run() {
qWarning() << "CSWorker::run(): thread start.";
while (!this->_stop) {
// Copy input.
QGeoCoordinate depot;
QList<QGeoCoordinate> safeArea;
Lock lk(this->_mutex);
if (this->_useDepotSafeArea) {
depot = this->_depot;
safeArea = this->_safeArea;
} else {
safeArea = this->_polygon;
}
const auto polygon = this->_polygon;
const auto origin = this->_origin;
const auto deltaR = this->_deltaR;
......@@ -74,11 +118,16 @@ void CSWorker::run() {
emit calculatingChanged();
// Convert geo polygon to ENU polygon.
snake::BoostPolygon polygonENU;
snake::BoostPolygon safeAreaENU;
snake::BoostPoint originENU{0, 0};
snake::BoostPoint depotENU;
snake::areaToEnu(origin, polygon, polygonENU);
snake::areaToEnu(origin, safeArea, safeAreaENU);
snake::toENU(origin, depot, depotENU);
std::string error;
// Check validity.
if (!bg::is_valid(polygonENU, error)) {
if (!bg::is_valid(polygonENU, error) ||
!bg::is_valid(safeAreaENU, error)) {
#ifdef DEBUG_CIRCULAR_SURVEY
qWarning() << "CSWorker::run(): "
"invalid polygon.";
......@@ -159,7 +208,9 @@ void CSWorker::run() {
}
// Clip sectors to polygonENU.
ClipperLib::Path polygonClipper;
auto &outer = polygonENU.outer();
snake::BoostPolygon shrinked;
snake::offsetPolygon(polygonENU, shrinked, -0.1);
auto &outer = shrinked.outer();
polygonClipper.reserve(outer.size() - 1);
for (auto it = outer.begin(); it < outer.end() - 1; ++it) {
auto x = ClipperLib::cInt(std::round(it->get<0>() * CLIPPER_SCALE));
......@@ -176,6 +227,9 @@ void CSWorker::run() {
// Extract transects from PolyTree and convert them to
// BoostLineString
snake::Transects transectsENU;
if (this->_useDepotSafeArea) {
transectsENU.push_back(snake::BoostLineString{depotENU});
}
for (const auto &child : transectsClipper.Childs) {
snake::BoostLineString transect;
transect.reserve(child->Contour.size());
......@@ -233,44 +287,49 @@ void CSWorker::run() {
}
}
// Remove short transects
for (auto it = transectsENU.begin(); it < transectsENU.end();) {
auto begin = this->_useDepotSafeArea ? transectsENU.begin() + 1
: transectsENU.begin();
for (auto it = begin; it < transectsENU.end();) {
if (bg::length(*it) < minLength.value()) {
it = transectsENU.erase(it);
} else {
++it;
}
}
// Move transect with min. distance to the front.
auto minDist = std::numeric_limits<double>::max();
auto minIt = transectsENU.begin();
bool reverse = false;
for (auto it = transectsENU.begin(); it < transectsENU.end(); ++it) {
auto distFront = bg::distance(originENU, it->front());
auto distBack = bg::distance(originENU, it->back());
if (distFront < minDist) {
minDist = distFront;
minIt = it;
reverse = false;
}
if (distBack < minDist) {
minDist = distBack;
minIt = it;
reverse = true;
if (!this->_useDepotSafeArea) {
// Move transect with min. distance to the front.
auto minDist = std::numeric_limits<double>::max();
auto minIt = transectsENU.begin();
bool reverse = false;
for (auto it = transectsENU.begin(); it < transectsENU.end(); ++it) {
auto distFront = bg::distance(originENU, it->front());
auto distBack = bg::distance(originENU, it->back());
if (distFront < minDist) {
minDist = distFront;
minIt = it;
reverse = false;
}
if (distBack < minDist) {
minDist = distBack;
minIt = it;
reverse = true;
}
}
}
// Swap and reverse (if necessary).
if (minIt != transectsENU.begin()) {
auto minTransect = *minIt;
if (reverse) {
snake::BoostLineString rev;
for (auto it = minTransect.end() - 1; it >= minTransect.begin();
--it) {
rev.push_back(*it);
// Swap and reverse (if necessary).
if (minIt != transectsENU.begin()) {
auto minTransect = *minIt;
if (reverse) {
snake::BoostLineString rev;
for (auto it = minTransect.end() - 1; it >= minTransect.begin();
--it) {
rev.push_back(*it);
}
minTransect = rev;
}
minTransect = rev;
*minIt = *transectsENU.begin();
*transectsENU.begin() = minTransect;
}
*minIt = *transectsENU.begin();
*transectsENU.begin() = minTransect;
}
#ifdef SHOW_CIRCULAR_SURVEY_TIME
qWarning() << "CSWorker::run(): transect gen. time: "
......@@ -305,9 +364,9 @@ void CSWorker::run() {
};
std::string errorString;
// Route transects;
bool success = snake::route(polygonENU, transectsENU, transectsInfo,
bool success = snake::route(safeAreaENU, transectsENU, transectsInfo,
route, stopLambda, errorString);
if (!success && !this->_restart) {
if ((!success || route.size() < 3) && !this->_restart) {
#ifdef DEBUG_CIRCULAR_SURVEY
qWarning() << "CSWorker::run(): "
"routing failed.";
......@@ -318,19 +377,38 @@ void CSWorker::run() {
"restart requested.";
#endif
} else {
// Remove return path.
// Find index of first waypoint.
std::size_t idxFirst = 0;
const auto &info1 =
this->_useDepotSafeArea ? transectsInfo[1] : transectsInfo[0];
const auto &firstTransect = transectsENU[info1.index];
const auto &firstWaypoint =
info1.reversed ? firstTransect.back() : firstTransect.front();
double th = 0.001;
for (std::size_t i = 0; i < route.size(); ++i) {
auto dist = bg::distance(route[i], firstWaypoint);
if (dist < th) {
idxFirst = i;
break;
}
}
// Find index of last waypoint.
std::size_t idxLast = 0;
const auto &info = transectsInfo.back();
const auto &lastTransect = transectsENU[info.index];
const auto &lastWaypoint =
info.reversed ? lastTransect.front() : lastTransect.back();
auto &wp = route.back();
while (wp != lastWaypoint) {
route.pop_back();
wp = route.back();
for (long i = route.size() - 1; i >= 0; --i) {
auto dist = bg::distance(route[i], lastWaypoint);
if (dist < th) {
idxLast = i;
break;
}
}
// Convert to geo coordinates and notify main thread.
auto pRoute = PtrRoute(new Route());
for (const auto &vertex : route) {
for (std::size_t i = idxFirst; i <= idxLast; ++i) {
auto vertex = route[i];
QGeoCoordinate c;
snake::fromENU(origin, vertex, c);
pRoute->append(c);
......
......@@ -31,6 +31,11 @@ public slots:
void update(const QList<QGeoCoordinate> &polygon,
const QGeoCoordinate &origin, snake::Length deltaR,
snake::Length minLength, snake::Angle deltaAlpha);
void update(const QGeoCoordinate &depot,
const QList<QGeoCoordinate> &safeArea,
const QList<QGeoCoordinate> &polygon,
const QGeoCoordinate &origin, snake::Length deltaR,
snake::Length minLength, snake::Angle deltaAlpha);
signals:
void ready(PtrRoute pTransects);
......@@ -43,6 +48,8 @@ private:
mutable std::mutex _mutex;
mutable std::condition_variable _cv;
// Internal data
QGeoCoordinate _depot;
QList<QGeoCoordinate> _safeArea;
QList<QGeoCoordinate> _polygon;
QGeoCoordinate _origin;
snake::Length _deltaR;
......@@ -51,6 +58,7 @@ private:
std::size_t _maxWaypoints;
// State
std::atomic_bool _useDepotSafeArea;
std::atomic_bool _calculating;
std::atomic_bool _stop;
std::atomic_bool _restart;
......
......@@ -36,8 +36,8 @@ CircularSurvey::CircularSurvey(Vehicle *vehicle, bool flyView,
_deltaR(settingsGroup, _metaDataMap[deltaRName]),
_deltaAlpha(settingsGroup, _metaDataMap[deltaAlphaName]),
_minLength(settingsGroup, _metaDataMap[transectMinLengthName]),
_isInitialized(false), _pWorker(std::make_unique<CSWorker>()),
_needsStoring(false), _needsReversal(false) {
_pWorker(std::make_unique<CSWorker>()), _needsStoring(false),
_needsReversal(false) {
Q_UNUSED(kmlOrShpFile)
_editorQml = "qrc:/qml/CircularSurveyItemEditor.qml";
......@@ -50,6 +50,10 @@ CircularSurvey::CircularSurvey(Vehicle *vehicle, bool flyView,
&CircularSurvey::_rebuildTransects);
connect(this, &CircularSurvey::refPointChanged, this,
&CircularSurvey::_rebuildTransects);
connect(this, &CircularSurvey::depotChanged, this,
&CircularSurvey::_rebuildTransects);
connect(this, &CircularSurvey::safeAreaChanged, this,
&CircularSurvey::_rebuildTransects);
// Connect worker.
qRegisterMetaType<PtrRoute>("PtrRoute");
connect(this->_pWorker.get(), &CSWorker::ready, this,
......@@ -78,21 +82,40 @@ void CircularSurvey::setRefPoint(const QGeoCoordinate &refPt) {
}
}
void CircularSurvey::setIsInitialized(bool isInitialized) {
if (isInitialized != _isInitialized) {
_isInitialized = isInitialized;
emit isInitializedChanged();
}
}
QGeoCoordinate CircularSurvey::refPoint() const { return _referencePoint; }
Fact *CircularSurvey::deltaR() { return &_deltaR; }
Fact *CircularSurvey::deltaAlpha() { return &_deltaAlpha; }
bool CircularSurvey::isInitialized() { return _isInitialized; }
bool CircularSurvey::hidePolygon() const { return _hidePolygon; }
QGeoCoordinate CircularSurvey::depot() const { return this->_depot; }
QList<QGeoCoordinate> CircularSurvey::safeArea() const {
return this->_safeArea;
}
void CircularSurvey::setHidePolygon(bool hide) {
if (this->_hidePolygon != hide) {
this->_hidePolygon = hide;
emit hidePolygonChanged();
}
}
void CircularSurvey::setDepot(const QGeoCoordinate &depot) {
if (this->_depot != depot) {
this->_depot = depot;
emit depotChanged();
}
}
void CircularSurvey::setSafeArea(const QList<QGeoCoordinate> &safeArea) {
if (this->_safeArea != safeArea) {
this->_safeArea = safeArea;
emit safeAreaChanged();
}
}
bool CircularSurvey::load(const QJsonObject &complexObject, int sequenceNumber,
QString &errorString) {
......@@ -161,7 +184,6 @@ bool CircularSurvey::load(const QJsonObject &complexObject, int sequenceNumber,
_referencePoint.setLongitude(complexObject[refPointLongitudeName].toDouble());
_referencePoint.setLatitude(complexObject[refPointLatitudeName].toDouble());
_referencePoint.setAltitude(complexObject[refPointAltitudeName].toDouble());
setIsInitialized(true);
_ignoreRecalc = false;
......@@ -319,12 +341,21 @@ void CircularSurvey::_rebuildTransectsPhase1(void) {
} else {
this->_transects.clear();
auto polygon = this->_surveyAreaPolygon.coordinateList();
this->_pWorker->update(
polygon, this->_referencePoint,
this->_deltaR.rawValue().toDouble() * bu::si::meter,
this->_minLength.rawValue().toDouble() * bu::si::meter,
snake::Angle(this->_deltaAlpha.rawValue().toDouble() *
bu::degree::degree));
if (this->_depot.isValid() && this->_safeArea.size() >= 3) {
this->_pWorker->update(
this->_depot, this->_safeArea, polygon, this->_referencePoint,
this->_deltaR.rawValue().toDouble() * bu::si::meter,
this->_minLength.rawValue().toDouble() * bu::si::meter,
snake::Angle(this->_deltaAlpha.rawValue().toDouble() *
bu::degree::degree));
} else {
this->_pWorker->update(
polygon, this->_referencePoint,
this->_deltaR.rawValue().toDouble() * bu::si::meter,
this->_minLength.rawValue().toDouble() * bu::si::meter,
snake::Angle(this->_deltaAlpha.rawValue().toDouble() *
bu::degree::degree));
}
}
}
......@@ -351,7 +382,9 @@ void CircularSurvey::_setTransects(CircularSurvey::PtrRoute pRoute) {
Fact *CircularSurvey::transectMinLength() { return &_minLength; }
bool CircularSurvey::calculating() { return this->_pWorker->calculating(); }
bool CircularSurvey::calculating() const {
return this->_pWorker->calculating();
}
/*!
\class CircularSurveyComplexItem
......
......@@ -28,48 +28,43 @@ public:
Q_PROPERTY(Fact *deltaR READ deltaR CONSTANT)
Q_PROPERTY(Fact *deltaAlpha READ deltaAlpha CONSTANT)
Q_PROPERTY(Fact *transectMinLength READ transectMinLength CONSTANT)
Q_PROPERTY(bool isInitialized READ isInitialized WRITE setIsInitialized NOTIFY
isInitializedChanged)
Q_PROPERTY(bool calculating READ calculating NOTIFY calculatingChanged)
Q_PROPERTY(bool hidePolygon READ hidePolygon NOTIFY hidePolygon)
Q_INVOKABLE void resetReference(void);
Q_INVOKABLE void reverse(void);
// Property setters
void setRefPoint(const QGeoCoordinate &refPt);
// Set this to true if survey was automatically generated, prevents
// initialisation from gui.
void setIsInitialized(bool isInitialized);
void setHidePolygon(bool hide);
void setDepot(const QGeoCoordinate &depot);
void setSafeArea(const QList<QGeoCoordinate> &safeArea);
// Property getters
QGeoCoordinate refPoint() const;
Fact *deltaR();
Fact *deltaAlpha();
Fact *transectMinLength();
bool calculating();
// Is true if survey was automatically generated, prevents initialisation from
// gui.
bool isInitialized();
bool calculating() const;
bool hidePolygon() const;
QGeoCoordinate depot() const;
QList<QGeoCoordinate> safeArea() const;
// Overrides from ComplexMissionItem
// Overrides
bool load(const QJsonObject &complexObject, int sequenceNumber,
QString &errorString) final;
QString mapVisualQML(void) const final;
// Overrides from TransectStyleComplexItem
void save(QJsonArray &planItems) final;
bool specifiesCoordinate(void) const final;
QString &errorString) override final;
QString mapVisualQML(void) const override final;
void save(QJsonArray &planItems) override final;
bool specifiesCoordinate(void) const override final;
void appendMissionItems(QList<MissionItem *> &items,
QObject *missionItemParent) final;
void applyNewAltitude(double newAltitude) final;
double timeBetweenShots(void) final;
// Overrides from VisualMissionionItem
QString commandDescription(void) const final;
QString commandName(void) const final;
QString abbreviation(void) const final;
bool readyForSave(void) const final;
double additionalTimeDelay(void) const final;
QObject *missionItemParent) override final;
void applyNewAltitude(double newAltitude) override final;
double timeBetweenShots(void) override final;
QString commandDescription(void) const override final;
QString commandName(void) const override final;
QString abbreviation(void) const override final;
bool readyForSave(void) const override final;
double additionalTimeDelay(void) const override final;
static const char *settingsGroup;
static const char *deltaRName;
......@@ -82,8 +77,10 @@ public:
signals:
void refPointChanged();
void isInitializedChanged();
void calculatingChanged();
void hidePolygonChanged();
void depotChanged();
void safeAreaChanged();
private slots:
// Overrides from TransectStyleComplexItem
......@@ -109,14 +106,14 @@ private:
// minimal transect lenght, transects are rejected if they are shorter than
// this value
SettingsFact _minLength;
// indicates if the polygon and refpoint etc. are initialized, prevents
// reinitialisation from gui and execution of _rebuildTransectsPhase1 during
// init from gui
bool _isInitialized;
using PtrWorker = std::shared_ptr<CSWorker>;
PtrWorker _pWorker;
PtrRoute _pRoute;
bool _needsStoring;
bool _needsReversal;
bool _hidePolygon;
QGeoCoordinate _depot;
QList<QGeoCoordinate> _safeArea;
};
......@@ -135,14 +135,14 @@ bool WimaMeasurementArea::loadFromJson(const QJsonObject &json,
}
if (json.contains(tileWidthName) && json[tileWidthName].isDouble()) {
_tileHeight.setRawValue(json[tileWidthName].toDouble());
_tileWidth.setRawValue(json[tileWidthName].toDouble());
} else {
errorString.append(tr("Could not load tile width!\n"));
retVal = false;
}
if (json.contains(minTileAreaName) && json[minTileAreaName].isDouble()) {
_tileHeight.setRawValue(json[minTileAreaName].toDouble());
_minTileArea.setRawValue(json[minTileAreaName].toDouble());
} else {
errorString.append(tr("Could not load minimal tile area!\n"));
retVal = false;
......@@ -150,7 +150,7 @@ bool WimaMeasurementArea::loadFromJson(const QJsonObject &json,
if (json.contains(transectDistanceName) &&
json[transectDistanceName].isDouble()) {
_tileHeight.setRawValue(json[transectDistanceName].toDouble());
_transectDistance.setRawValue(json[transectDistanceName].toDouble());
} else {
errorString.append(tr("Could not load transect distance!\n"));
retVal = false;
......@@ -158,14 +158,14 @@ bool WimaMeasurementArea::loadFromJson(const QJsonObject &json,
if (json.contains(minTransectLengthName) &&
json[minTransectLengthName].isDouble()) {
_tileHeight.setRawValue(json[minTransectLengthName].toDouble());
_minTransectLength.setRawValue(json[minTransectLengthName].toDouble());
} else {
errorString.append(tr("Could not load minimal transect length!\n"));
retVal = false;
}
if (json.contains(showTilesName) && json[showTilesName].isBool()) {
_tileHeight.setRawValue(json[showTilesName].toDouble());
_showTiles.setRawValue(json[showTilesName].toBool());
} else {
errorString.append(tr("Could not load show tiles !\n"));
retVal = false;
......
#include "WimaServiceArea.h"
const char* WimaServiceArea::wimaServiceAreaName = "Service Area";
const char *WimaServiceArea::wimaServiceAreaName = "Service Area";
WimaServiceArea::WimaServiceArea(QObject *parent)
: WimaArea (parent)
{
init();
}
WimaServiceArea::WimaServiceArea(QObject *parent) : WimaArea(parent) { init(); }
WimaServiceArea::WimaServiceArea(const WimaServiceArea &other, QObject *parent)
: WimaArea (other, parent)
{
init();
: WimaArea(other, parent) {
init();
}
/*!
......@@ -21,63 +14,53 @@ WimaServiceArea::WimaServiceArea(const WimaServiceArea &other, QObject *parent)
*
* Calls the inherited operator WimaArea::operator=().
*/
WimaServiceArea &WimaServiceArea::operator=(const WimaServiceArea &other)
{
WimaArea::operator=(other);
return *this;
}
WimaServiceArea &WimaServiceArea::operator=(const WimaServiceArea &other) {
WimaArea::operator=(other);
void WimaServiceArea::setTakeOffPosition(const QGeoCoordinate &coordinate)
{
if(_takeOffPosition != coordinate){
_takeOffPosition = coordinate;
emit takeOffPositionChanged();
}
return *this;
}
void WimaServiceArea::setLandPosition(const QGeoCoordinate &coordinate)
{
if(_landPosition != coordinate){
_landPosition = coordinate;
emit landPositionChanged();
}
void WimaServiceArea::setDepot(const QGeoCoordinate &coordinate) {
if (_depot != coordinate) {
_depot = coordinate;
emit depotChanged();
}
}
void WimaServiceArea::saveToJson(QJsonObject &json)
{
this->WimaArea::saveToJson(json);
json[areaTypeName] = wimaServiceAreaName;
void WimaServiceArea::saveToJson(QJsonObject &json) {
this->WimaArea::saveToJson(json);
json[areaTypeName] = wimaServiceAreaName;
}
bool WimaServiceArea::loadFromJson(const QJsonObject &json, QString &errorString)
{
if ( this->WimaArea::loadFromJson(json, errorString)) {
bool retVal = true;
// code for loading here
return retVal;
} else {
qWarning() << errorString;
return false;
}
bool WimaServiceArea::loadFromJson(const QJsonObject &json,
QString &errorString) {
if (this->WimaArea::loadFromJson(json, errorString)) {
bool retVal = true;
// code for loading here
return retVal;
} else {
qWarning() << errorString;
return false;
}
}
void print(const WimaServiceArea &area)
{
QString message;
print(area, message);
qWarning() << message;
void print(const WimaServiceArea &area) {
QString message;
print(area, message);
qWarning() << message;
}
void print(const WimaServiceArea &area, QString &outputStr)
{
print(static_cast<const WimaArea&>(area), outputStr);
outputStr.append(QString("Takeoff Position: %s\n").arg(area._takeOffPosition.toString(QGeoCoordinate::Degrees)));
outputStr.append(QString("Land Position: %s\n").arg(area._landPosition.toString(QGeoCoordinate::Degrees)));
void print(const WimaServiceArea &area, QString &outputStr) {
print(static_cast<const WimaArea &>(area), outputStr);
outputStr.append(QString("Depot Position: %s\n")
.arg(area._depot.toString(QGeoCoordinate::Degrees)));
}
void WimaServiceArea::init()
{
this->setObjectName(wimaServiceAreaName);
void WimaServiceArea::init() {
this->setObjectName(wimaServiceAreaName);
connect(this, &WimaServiceArea::centerChanged, [this] {
if (!this->_depot.isValid()) {
this->setDepot(this->center());
}
});
}
#pragma once
#include <QObject>
#include "WimaArea.h"
#include "WimaTrackerPolyline.h"
#include <QObject>
class WimaServiceArea : public WimaArea
{
Q_OBJECT
class WimaServiceArea : public WimaArea {
Q_OBJECT
public:
WimaServiceArea(QObject* parent = nullptr);
WimaServiceArea(const WimaServiceArea& other, QObject* parent);
WimaServiceArea& operator=(const WimaServiceArea &other);
Q_PROPERTY(const QGeoCoordinate& takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged)
Q_PROPERTY(const QGeoCoordinate& landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged)
WimaServiceArea(QObject *parent = nullptr);
WimaServiceArea(const WimaServiceArea &other, QObject *parent);
WimaServiceArea &operator=(const WimaServiceArea &other);
// Overrides from WimaPolygon
QString mapVisualQML (void) const { return "WimaServiceAreaMapVisual.qml";}
QString editorQML (void) const { return "WimaServiceAreaEditor.qml";}
Q_PROPERTY(QGeoCoordinate depot READ depot WRITE setDepot NOTIFY depotChanged)
// Property acessors
const QGeoCoordinate& takeOffPosition (void) const { return _takeOffPosition;}
const QGeoCoordinate& landPosition (void) const { return _landPosition;}
// Overrides from WimaPolygon
QString mapVisualQML(void) const { return "WimaServiceAreaMapVisual.qml"; }
QString editorQML(void) const { return "WimaServiceAreaEditor.qml"; }
// Member Methodes
void saveToJson(QJsonObject& json);
bool loadFromJson(const QJsonObject& json, QString& errorString);
// Property acessors
const QGeoCoordinate &depot(void) const { return _depot; }
// Member Methodes
void saveToJson(QJsonObject &json);
bool loadFromJson(const QJsonObject &json, QString &errorString);
// Friends
friend void print(const WimaServiceArea &area, QString &outputStr);
friend void print(const WimaServiceArea &area);
// Friends
friend void print(const WimaServiceArea& area, QString& outputStr);
friend void print(const WimaServiceArea& area);
// static Members
static const char* wimaServiceAreaName;
// static Members
static const char *wimaServiceAreaName;
signals:
void takeOffPositionChanged (void);
void landPositionChanged (void);
void depotChanged(void);
public slots:
void setTakeOffPosition (const QGeoCoordinate& coordinate);
void setLandPosition (const QGeoCoordinate& coordinate);
void setDepot(const QGeoCoordinate &coordinate);
private:
// Member Methodes
void init();
// Member Methodes
void init();
// Members
QGeoCoordinate _takeOffPosition;
QGeoCoordinate _landPosition;
// Members
QGeoCoordinate _depot;
};
......@@ -100,7 +100,7 @@ void WimaServiceAreaData::assign(const WimaServiceArea &other)
{
WimaAreaData::assign(other);
setLandPosition(other.landPosition());
setTakeOffPosition(other.takeOffPosition());
setTakeOffPosition(other.depot());
}
......
This diff is collapsed.
......@@ -44,9 +44,8 @@ public:
Q_PROPERTY(QGeoCoordinate joinedAreaCenter READ joinedAreaCenter CONSTANT)
Q_PROPERTY(WimaBridge *wimaBridge READ wimaBridge WRITE setWimaBridge NOTIFY
wimaBridgeChanged)
Q_PROPERTY(bool syncronized READ syncronizedWithController NOTIFY
syncronizedWithControllerChanged)
Q_PROPERTY(bool readyForSync READ readyForSync NOTIFY readyForSyncChanged)
Q_PROPERTY(bool synchronized READ synchronized NOTIFY synchronizedChanged)
Q_PROPERTY(bool needsUpdate READ needsUpdate NOTIFY needsUpdateChanged)
// Property accessors
PlanMasterController *masterController(void);
......@@ -59,6 +58,8 @@ public:
QString fileExtension(void) const;
QGeoCoordinate joinedAreaCenter(void) const;
WimaBridge *wimaBridge(void);
bool synchronized();
bool needsUpdate();
// Property setters
void setMasterController(PlanMasterController *masterController);
......@@ -68,11 +69,6 @@ public:
void setCurrentPolygonIndex(int index);
void setWimaBridge(WimaBridge *bridge);
// Property acessors
bool syncronizedWithController();
bool readyForSync();
// Member Methodes
Q_INVOKABLE WimaPlaner *thisPointer();
Q_INVOKABLE bool addMeasurementArea();
/// Removes an area from _visualItems
......@@ -84,24 +80,17 @@ public:
/// MissionController
Q_INVOKABLE void removeAll();
/// Recalculates vehicle corridor, flight path, etc.
Q_INVOKABLE bool updateMission();
Q_INVOKABLE bool update();
/// Pushes the generated mission data to the wimaController.
Q_INVOKABLE void pushToWimaController();
Q_INVOKABLE void saveToCurrent();
Q_INVOKABLE void saveToFile(const QString &filename);
Q_INVOKABLE bool loadFromCurrent();
Q_INVOKABLE bool loadFromFile(const QString &filename);
Q_INVOKABLE void resetAllInteractive(void);
Q_INVOKABLE void setInteractive(void);
QJsonDocument saveToJson(FileType fileType);
bool calcShortestPath(const QGeoCoordinate &start,
const QGeoCoordinate &destination,
QVector<QGeoCoordinate> &path);
// static Members
static const char *wimaFileExtension;
static const char *areaItemsName;
......@@ -114,21 +103,14 @@ signals:
void currentPolygonIndexChanged(int index);
void currentFileChanged();
void wimaBridgeChanged();
void syncronizedWithControllerChanged(void);
void readyForSyncChanged(void);
void synchronizedChanged(void);
void needsUpdateChanged(void);
private slots:
void recalcPolygonInteractivity(int index);
bool calcArrivalAndReturnPath(void);
bool recalcJoinedArea();
// called by _updateTimer::timeout signal, updates different mission parts, if
// parameters (e.g. survey or areas) have changed
void updateTimerSlot();
void setSyncronizedWithControllerFalse(void);
void updatePolygonInteractivity(int index);
#ifndef NDEBUG
void autoLoadMission(void);
#endif
void startCalcArrivalAndReturnTimer(void);
private:
signals:
......@@ -137,9 +119,10 @@ signals:
private:
// Member Functions
WimaPlanData toPlanData();
void setSyncronizedWithController(bool sync);
void setReadyForSync(bool ready);
void setJoinedAreaValid(bool valid);
bool shortestPath(const QGeoCoordinate &start,
const QGeoCoordinate &destination,
QVector<QGeoCoordinate> &path);
void setNeedsUpdate(bool needsUpdate);
// Member Variables
PlanMasterController *_masterController;
......@@ -151,8 +134,11 @@ private:
bool _joinedAreaValid;
WimaMeasurementArea _measurementArea;
bool _mAreaChanged;
WimaServiceArea _serviceArea;
bool _sAreaChanged;
WimaCorridor _corridor;
bool _corridorChanged;
// contains all visible areas
QmlObjectListModel _visualItems;
// joined area fromed by _measurementArea, _serviceArea, _corridor
......@@ -162,36 +148,15 @@ private:
// path from last measurement point to land
unsigned long _returnPathLength;
CircularSurvey *_TSComplexItem; // pointer to the CircularSurvey item in
// _missionController.visualItems()
// auto update
QTimer _updateTimer; // on this timers timeout different mission parts will be
// updated, if parameters (e.g. survey or areas) have
// changed
QGeoCoordinate _lastSurveyRefPoint; // stores the SurveyRefPoint of the
// previous timer call
bool _surveyRefChanging; // true if SurveyRefPoint is changing
QVariantList
_lastMeasurementAreaPath; // stores the path of _measurementArea, at the
// time instance of the previous timer call
bool _measurementAreaChanging; // true if the path of the _measurementArea is
// changing
QVariantList _lastCorridorPath; // stores the path of _corridor, at the time
// instance of the previous timer call
bool _corridorChanging; // true if the path of the _corridor is changing
QVariantList _lastServiceAreaPath; // stores the path of _serviceArea, at the
// time instance of the previous timer call
bool _serviceAreaChanging; // true if the path of the _serviceArea is changing
CircularSurvey *_TSComplexItem;
bool _surveyChanged;
// sync stuff
bool _syncronizedWithController; // true if planData is syncronized with
// wimaController
bool _readyForSync; // gets set by updateMission and calcArrivalAndReturnPath
bool _synchronized; // true if planData is synchronized with
// wimaController
bool _needsUpdate; // gets set by updateMission and calcArrivalAndReturnPath
#ifndef NDEBUG
QTimer _autoLoadTimer; // timer to auto load mission after some time, prevents
// seg. faults
#endif
QTimer _calcArrivalAndReturnPathTimer;
};
......@@ -88,13 +88,11 @@ Item {
}
Component.onCompleted: {
if ( !_missionItem.isInitialized ) {
if ( _missionItem.visualTransectPoints.length === 0 ) {
_addInitialPolygon()
_missionItem.isInitialized = true // set isInitialized to true, to trigger _rebuildTransectsPhase1 in the last line
_setRefPoint()
}
_addVisualElements()
}
Component.onDestruction: {
......@@ -111,6 +109,7 @@ Item {
borderColor: "black"
interiorColor: "green"
interiorOpacity: 0.5
visible: !_missionItem.hidePolygon
}
// Transect lines
......
......@@ -27,11 +27,9 @@ Item {
property var areaItem: object
property var _polygon: areaItem
//property var _polyline: areaItem.polyline
signal clicked(int sequenceNumber)
/// Add an initial 4 sided polygon if there is none
/// Add an initial 4 sided polygon if there is none
function _addInitialPolygon() {
......@@ -109,4 +107,30 @@ Item {
interiorOpacity: 1
}
// Depot Point.
Component {
id: depotPointComponent
DragCoordinate {
map: _root.map
qgcView: _root.qgcView
z: QGroundControl.zOrderMapItems
checked: areaItem.interactive
coordinate: areaItem.depot
property var point: areaItem.depot
onRefPointChanged: {
if (point !== coordinate) {
coordinate = point
}
}
onDragReleased: {
areaItem.depot = coordinate
}
}
}
}
......@@ -285,12 +285,15 @@ Rectangle {
anchors.rightMargin: _margins
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Sync WiMA")
text: wimaPlaner && wimaPlaner.needsUpdate ? qsTr("Update") : qsTr("Sync.")
enabled: true
visible: wimaPlaner ? wimaPlaner.readyForSync : false
onClicked: {
if (wimaPlaner && wimaPlaner.readyForSync) {
wimaPlaner.pushToWimaController()
if (wimaPlaner){
if (!wimaPlaner.needsUpdate) {
wimaPlaner.pushToWimaController()
} else {
wimaPlaner.update()
}
}
}
......@@ -299,7 +302,7 @@ Rectangle {
from: 0.5
to: 1
loops: Animation.Infinite
running: wimaPlaner ? !wimaPlaner.syncronized && wimaPlaner.readyForSync : false
running: wimaPlaner ? wimaPlaner.needsUpdate : false
alwaysRunToEnd: true
duration: 2000
}
......
......@@ -699,7 +699,7 @@ QGCView {
iconSource: "/res/street.png"
},
{
name: qsTr("Calculate"),
name: qsTr("Update"),
iconSource: "/res/calculator.png"
},
{
......@@ -729,7 +729,7 @@ QGCView {
wimaPlaner.addCorridor();
break
case 4:
wimaPlaner.updateMission();
wimaPlaner.update();
break
case 6:
editorMap.zoomLevel += 0.5
......
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