Commit 8da5e19a authored by Valentin Platzgummer's avatar Valentin Platzgummer

measurement works mostly, some smaller issues left

parent 5a5b161e
......@@ -261,19 +261,18 @@
<file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file>
<file alias="RadioComponent.qml">src/AutoPilotPlugins/Common/RadioComponent.qml</file>
<file alias="SerialSettings.qml">src/ui/preferences/SerialSettings.qml</file>
<file alias="CircularGeneratorEditor.qml">src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml</file>
<file alias="MeasurementComplexItem/CircularGeneratorEditor.qml">src/MeasurementComplexItem/qml/CircularGeneratorEditor.qml</file>
<file alias="QGroundControl/Controls/CircularGeneratorMapVisual.qml">src/MeasurementComplexItem/qml/CircularGeneratorMapVisual.qml</file>
<file alias="MeasurementItemEditor.qml">src/MeasurementComplexItem/qml/MeasurementItemEditor.qml</file>
<file alias="QGroundControl/Controls/MeasurementItemMapVisual.qml">src/MeasurementComplexItem/qml/MeasurementItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/CoordinateIndicator.qml">src/MeasurementComplexItem/qml/CoordinateIndicator.qml</file>
<file alias="QGroundControl/Controls/CoordinateIndicatorDrag.qml">src/MeasurementComplexItem/qml/CoordinateIndicatorDrag.qml</file>
<file alias="QGroundControl/Controls/DragCoordinate.qml">src/MeasurementComplexItem/qml/DragCoordinate.qml</file>
<file alias="LinearGeneratorEditor.qml">src/MeasurementComplexItem/qml/LinearGeneratorEditor.qml</file>
<file alias="ProgressIndicator.qml">src/MeasurementComplexItem/qml/ProgressIndicator.qml</file>
<file alias="MeasurementComplexItem/LinearGeneratorEditor.qml">src/MeasurementComplexItem/qml/LinearGeneratorEditor.qml</file>
<file alias="QGroundControl/Controls/GeoAreaVisualLoader.qml">src/MeasurementComplexItem/qml/GeoAreaVisualLoader.qml</file>
<file alias="MeasurementAreaEditor.qml">src/MeasurementComplexItem/qml/MeasurementAreaEditor.qml</file>
<file alias="MeasurementComplexItem/MeasurementAreaEditor.qml">src/MeasurementComplexItem/qml/MeasurementAreaEditor.qml</file>
<file alias="QGroundControl/Controls/MeasurementAreaMapVisual.qml">src/MeasurementComplexItem/qml/MeasurementAreaMapVisual.qml</file>
<file alias="SafeAreaEditor.qml">src/MeasurementComplexItem/qml/SafeAreaEditor.qml</file>
<file alias="MeasurementComplexItem/SafeAreaEditor.qml">src/MeasurementComplexItem/qml/SafeAreaEditor.qml</file>
<file alias="QGroundControl/Controls/SafeAreaMapVisual.qml">src/MeasurementComplexItem/qml/SafeAreaMapVisual.qml</file>
<file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
......@@ -290,6 +289,10 @@
<file alias="VirtualJoystick.qml">src/FlightDisplay/VirtualJoystick.qml</file>
<file alias="VTOLLandingPatternEditor.qml">src/PlanView/VTOLLandingPatternEditor.qml</file>
<file>src/MeasurementComplexItem/qml/GeoAreaEditorLoader.qml</file>
<file alias="QGroundControl/Controls/ItemDragger.qml">src/MeasurementComplexItem/qml/ItemDragger.qml</file>
<file alias="MeasurementComplexItem/AreaDataEditor.qml">src/MeasurementComplexItem/qml/AreaDataEditor.qml</file>
<file alias="MeasurementComplexItem/ParameterEditor.qml">src/MeasurementComplexItem/qml/ParameterEditor.qml</file>
<file alias="MeasurementComplexItem/qmldir">src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir</file>
</qresource>
<qresource prefix="/FirstRunPromptDialogs">
<file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file>
......
This diff is collapsed.
......@@ -18,6 +18,8 @@ public:
AreaData &operator=(const AreaData &other);
Q_PROPERTY(QmlObjectListModel *areaList READ areaList NOTIFY areaListChanged)
Q_PROPERTY(bool showErrorMessages READ showErrorMessages WRITE
setShowErrorMessages NOTIFY showErrorMessagesChanged)
// Member Methodes
//!
......@@ -27,7 +29,8 @@ public:
//!
//! \brief remove
//! \param areaData Removes the area.
//! \note Deletes the area if it has no parent.
//! \note Deletes the area if it has either no parent or the parent is this
//! object.
void remove(GeoArea *areaData);
void clear();
//!
......@@ -46,8 +49,7 @@ public:
//! \note Origin might change if the list of areas changes.
const QGeoCoordinate &origin() const;
Q_INVOKABLE bool isValid() const;
Q_INVOKABLE bool tryMakeValid();
Q_INVOKABLE bool isCorrect();
//!
//! \brief initialize Initializes the areas in a valid way, such that they
//! area inside the bounding box. \param bottomLeft bottom left corner of the
......@@ -65,18 +67,33 @@ public:
//! either.
//!
Q_INVOKABLE bool initialized();
Q_INVOKABLE void intersection();
bool operator==(const AreaData &other) const;
bool operator!=(const AreaData &other) const;
QString errorString() const; // Contains a message about the last error.
bool showErrorMessages() const;
void setShowErrorMessages(bool showErrorMessages);
signals:
void areaListChanged();
void originChanged();
void error(); // Emitted if errorString() contains a new message.
void showErrorMessagesChanged();
private slots:
void _updateOrigin();
private:
void _setOrigin(const QGeoCoordinate &origin);
QGeoCoordinate _newOrigin();
void _processError(const QString &str);
bool _areasCorrect();
bool _getAreas(MeasurementArea **measurementArea, SafeArea **safeArea);
QGeoCoordinate _origin;
QmlObjectListModel _areaList;
bool _initialized;
QString _errorString;
bool _showErrorMessages;
};
......@@ -62,7 +62,7 @@ QString CircularGenerator::abbreviation() { return QStringLiteral("C. Gen."); }
bool CircularGenerator::get(Generator &generator) {
if (this->_d) {
if (this->_d->isValid()) {
if (this->_d->isCorrect()) {
// Prepare data.
auto origin = this->_d->origin();
origin.setAltitude(0);
......@@ -200,7 +200,7 @@ void CircularGenerator::resetReference() {
}
void CircularGenerator::establishConnections() {
if (this->_d && !this->_connectionsEstablished) {
if (this->_d != nullptr && !this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
......@@ -233,7 +233,7 @@ void CircularGenerator::establishConnections() {
}
void CircularGenerator::deleteConnections() {
if (this->_d && this->_connectionsEstablished) {
if (this->_d != nullptr && this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
......
......@@ -8,16 +8,26 @@ GeneratorBase::GeneratorBase(QObject *parent)
GeneratorBase::GeneratorBase(GeneratorBase::Data d, QObject *parent)
: QObject(parent), _d(d) {
establishConnections();
connect(_d, &AreaData::areaListChanged, this,
&GeneratorBase::_areaListChangedHandler);
}
GeneratorBase::~GeneratorBase() {}
GeneratorBase::Data GeneratorBase::data() const { return _d; }
void GeneratorBase::setData(const Data &d) {
deleteConnections();
_d = d;
establishConnections();
void GeneratorBase::setData(Data d) {
if (d != nullptr) {
if (_d != nullptr) {
disconnect(_d, &AreaData::areaListChanged, this,
&GeneratorBase::_areaListChangedHandler);
}
deleteConnections();
_d = d;
establishConnections();
connect(_d, &AreaData::areaListChanged, this,
&GeneratorBase::_areaListChangedHandler);
}
}
void GeneratorBase::establishConnections() {}
......@@ -27,6 +37,7 @@ void GeneratorBase::deleteConnections() {}
void GeneratorBase::_areaListChangedHandler() {
deleteConnections();
establishConnections();
emit generatorChanged();
}
} // namespace routing
......@@ -33,7 +33,7 @@ public:
virtual bool get(Generator &generator) = 0;
Data data() const;
void setData(const Data &d);
void setData(Data d);
signals:
void generatorChanged();
......
......@@ -48,7 +48,7 @@ QString LinearGenerator::abbreviation() { return QStringLiteral("L. Gen."); }
bool LinearGenerator::get(Generator &generator) {
if (_d) {
if (this->_d->isValid()) {
if (this->_d->isCorrect()) {
// Prepare data.
auto origin = this->_d->origin();
origin.setAltitude(0);
......@@ -148,7 +148,7 @@ Fact *LinearGenerator::alpha() { return &_alpha; }
Fact *LinearGenerator::minLength() { return &_minLength; }
void LinearGenerator::establishConnections() {
if (this->_d && !this->_connectionsEstablished) {
if (this->_d != nullptr && !this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
......@@ -178,7 +178,7 @@ void LinearGenerator::establishConnections() {
}
void LinearGenerator::deleteConnections() {
if (this->_d && this->_connectionsEstablished) {
if (this->_d != nullptr && this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
......
......@@ -376,72 +376,76 @@ void MeasurementComplexItem::_setAreaData(
}
}
bool MeasurementComplexItem::_updateRoute() {
// Reset data.
this->_route.clear();
this->_variantVector.clear();
this->_variantNames.clear();
emit variantNamesChanged();
if (this->_pAreaData->isValid()) {
// Prepare data.
auto origin = this->_pAreaData->origin();
origin.setAltitude(0);
if (!origin.isValid()) {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): origin invalid." << origin;
return false;
}
// Convert safe area.
auto serviceArea =
getGeoArea<const SafeArea *>(*this->_pAreaData->areaList());
auto geoSafeArea = serviceArea->coordinateList();
if (!(geoSafeArea.size() >= 3)) {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): safe area invalid." << geoSafeArea;
return false;
}
for (auto &v : geoSafeArea) {
if (v.isValid()) {
v.setAltitude(0);
} else {
void MeasurementComplexItem::_updateRoute() {
if (!editing()) {
// Reset data.
this->_route.clear();
this->_variantVector.clear();
this->_variantNames.clear();
emit variantNamesChanged();
if (this->_pAreaData->isCorrect()) {
// Prepare data.
auto origin = this->_pAreaData->origin();
origin.setAltitude(0);
if (!origin.isValid()) {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): safe area contains invalid coordinate."
<< geoSafeArea;
return false;
<< "_updateWorker(): origin invalid." << origin;
return;
}
}
// Routing par.
RoutingParameter par;
par.numSolutions = 5;
auto &safeAreaENU = par.safeArea;
snake::areaToEnu(origin, geoSafeArea, safeAreaENU);
// Convert safe area.
auto serviceArea =
getGeoArea<const SafeArea *>(*this->_pAreaData->areaList());
auto geoSafeArea = serviceArea->coordinateList();
if (!(geoSafeArea.size() >= 3)) {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): safe area invalid." << geoSafeArea;
return;
}
for (auto &v : geoSafeArea) {
if (v.isValid()) {
v.setAltitude(0);
} else {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): safe area contains invalid coordinate."
<< geoSafeArea;
return;
}
}
// Create generator.
if (this->_pGenerator != nullptr) {
routing::GeneratorBase::Generator g; // Transect generator.
if (this->_pGenerator->get(g)) {
// Start/Restart routing worker.
this->_pWorker->route(par, g);
return true;
// Routing par.
RoutingParameter par;
par.numSolutions = 5;
auto &safeAreaENU = par.safeArea;
snake::areaToEnu(origin, geoSafeArea, safeAreaENU);
// Create generator.
if (this->_pGenerator != nullptr) {
routing::GeneratorBase::Generator g; // Transect generator.
if (this->_pGenerator->get(g)) {
// Start/Restart routing worker.
this->_pWorker->route(par, g);
_setState(STATE::ROUTING);
return;
} else {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): generator creation failed.";
return;
}
} else {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): generator creation failed.";
return false;
<< "_updateWorker(): pGenerator == nullptr, number of registered "
"generators: "
<< this->_generatorList.size();
return;
}
} else {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): pGenerator == nullptr, number of registered "
"generators: "
<< this->_generatorList.size();
return false;
<< "_updateWorker(): plan data invalid.";
return;
}
} else {
qCDebug(MeasurementComplexItemLog) << "_updateWorker(): plan data invalid.";
return false;
}
}
......@@ -471,7 +475,7 @@ void MeasurementComplexItem::_changeVariant() {
}
auto &newVariantCoordinates = this->_variantVector[variant];
this->_route.swap(newVariantCoordinates);
emit routeChanged();
} else { // error
qCDebug(MeasurementComplexItemLog)
<< "Variant out of bounds (variant =" << variant << ").";
......@@ -497,6 +501,7 @@ void MeasurementComplexItem::_reverseRoute() {
auto &t = this->_route;
std::reverse(t.begin(), t.end());
}
emit routeChanged();
}
}
......@@ -661,27 +666,35 @@ int MeasurementComplexItem::generatorIndex() {
return this->_generatorList.indexOf(this->_pGenerator);
}
void MeasurementComplexItem::editingStart() {
if (!_editing(this->_state)) {
void MeasurementComplexItem::startEditing() {
if (!editing()) {
*_pEditorData = *_pAreaData;
_setAreaData(_pEditorData);
_setState(STATE::EDITING);
}
}
void MeasurementComplexItem::editingStop() {
if (_editing(this->_state)) {
if (_pEditorData->isValid()) {
void MeasurementComplexItem::stopEditing() {
if (editing()) {
bool correct = _pEditorData->isCorrect();
if (correct) {
*_pAreaData = *_pEditorData;
}
_setAreaData(_pAreaData);
_setState(STATE::IDLE);
if (_pEditorData->isValid() && *_pEditorData != *_pAreaData) {
if (correct && *_pEditorData != *_pAreaData) {
_updateRoute();
}
}
}
void MeasurementComplexItem::abortEditing() {
if (editing()) {
_setAreaData(_pAreaData);
_setState(STATE::IDLE);
}
}
void MeasurementComplexItem::_storeRoutingData(
MeasurementComplexItem::PtrRoutingData pRoute) {
if (this->_state == STATE::ROUTING) {
......@@ -781,10 +794,11 @@ void MeasurementComplexItem::_storeRoutingData(
this->_variant.setCookedValue(QVariant(0));
connect(&this->_variant, &Fact::rawValueChanged, this,
&MeasurementComplexItem::_changeVariant);
this->_changeVariant();
this->_setState(STATE::IDLE);
this->_route.swap(this->_variantVector.first());
emit routeChanged();
this->_setState(STATE::IDLE);
} else {
qCDebug(MeasurementComplexItemLog)
<< "_setTransects(): failed, variantVector empty.";
......
......@@ -105,19 +105,26 @@ public:
// Editing.
//!
//! \brief editingStart Starts area data editing.
//! \brief startEditing Starts area data editing.
//!
//! Starts area data editing. Route will not be updated bewteen a call
//! sequence of editingStart() and editingStop().
//!
void editingStart();
Q_INVOKABLE void startEditing();
//!
//! \brief editingStop Stops area editing.
//! \brief stopEditing Stops area editing.
//!
//! Stops area editing. Will reset area data to the state before
//! editingStart() if it is invalid. Triggers a route update.
//!
void editingStop();
Q_INVOKABLE void stopEditing();
//!
//! \brief abortEditing Aborts area editing.
//!
//! Will reset area data to the state before
//! editingStart().
//!
Q_INVOKABLE void abortEditing();
// Property getters
const AreaData *areaData() const;
......@@ -156,7 +163,7 @@ private slots:
// Worker functions.
void _storeRoutingData(PtrRoutingData pRoute);
bool _updateRoute();
void _updateRoute();
void _changeVariant();
void _reverseRoute();
......
This diff is collapsed.
#pragma once
#include "QmlObjectListModel.h"
#include <QObject>
#include <QScopedPointer>
#include <QSharedPointer>
#include "Geometry/WimaCorridor.h"
#include "Geometry/WimaCorridorData.h"
#include "Geometry/WimaJoinedArea.h"
#include "Geometry/WimaJoinedAreaData.h"
#include "Geometry/WimaMeasurementArea.h"
#include "Geometry/WimaMeasurementAreaData.h"
#include "Geometry/WimaServiceArea.h"
#include "Geometry/WimaServiceAreaData.h"
#include "WimaPlanData.h"
#include "Snake/NemoInterface.h"
#include "JsonHelper.h"
class MissionController;
class PlanMasterController;
namespace wima_planer_detail {
class WimaStateMachine;
}
class WimaPlaner : public QObject {
Q_OBJECT
enum FileType { WimaFile, PlanFile };
public:
WimaPlaner(QObject *parent = nullptr);
~WimaPlaner();
template <class T> WimaPlaner(T t, QObject *parent = nullptr) = delete;
template <class T> WimaPlaner(T t) = delete;
Q_PROPERTY(PlanMasterController *masterController READ masterController WRITE
setMasterController NOTIFY masterControllerChanged)
Q_PROPERTY(MissionController *missionController READ missionController WRITE
setMissionController NOTIFY missionControllerChanged)
Q_PROPERTY(QmlObjectListModel *visualItems READ visualItems NOTIFY
visualItemsChanged)
Q_PROPERTY(int currentPolygonIndex READ currentPolygonIndex WRITE
setCurrentPolygonIndex NOTIFY currentPolygonIndexChanged)
Q_PROPERTY(QString currentFile READ currentFile NOTIFY currentFileChanged)
Q_PROPERTY(QStringList loadNameFilters READ loadNameFilters CONSTANT)
Q_PROPERTY(QStringList saveNameFilters READ saveNameFilters CONSTANT)
Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT)
Q_PROPERTY(QGeoCoordinate joinedAreaCenter READ joinedAreaCenter CONSTANT)
Q_PROPERTY(NemoInterface *nemoInterface READ nemoInterface CONSTANT)
Q_PROPERTY(bool synchronized READ synchronized NOTIFY synchronizedChanged)
Q_PROPERTY(bool needsUpdate READ needsUpdate NOTIFY needsUpdateChanged)
Q_PROPERTY(bool readyForSynchronization READ readyForSynchronization NOTIFY
readyForSynchronizationChanged)
Q_PROPERTY(bool surveyReady READ surveyReady NOTIFY surveyReadyChanged)
Q_PROPERTY(bool progressLocked READ progressLocked WRITE setProgressLocked
NOTIFY progressLockedChanged)
// Property accessors
PlanMasterController *masterController(void);
MissionController *missionController(void);
QmlObjectListModel *visualItems(void);
int currentPolygonIndex(void) const;
QString currentFile(void) const;
QStringList loadNameFilters(void) const;
QStringList saveNameFilters(void) const;
QString fileExtension(void) const;
QGeoCoordinate joinedAreaCenter(void) const;
NemoInterface *nemoInterface(void);
bool synchronized();
bool needsUpdate();
bool readyForSynchronization();
bool surveyReady();
bool progressLocked();
// Property setters
void setMasterController(PlanMasterController *masterController);
void setMissionController(MissionController *missionController);
/// Sets the integer index pointing to the current polygon. Current polygon is
/// set interactive.
void setCurrentPolygonIndex(int index);
void setProgressLocked(bool l);
Q_INVOKABLE bool addMeasurementArea();
/// Removes an area from _visualItems
/// @param index Index of the area to be removed
Q_INVOKABLE void removeArea(int index);
Q_INVOKABLE bool addServiceArea();
Q_INVOKABLE bool addCorridor();
/// Remove all areas from WimaPlaner and all mission items from
/// MissionController
Q_INVOKABLE void removeAll();
/// Recalculates vehicle corridor, flight path, etc.
Q_INVOKABLE void update();
/// Pushes the generated mission data to the wimaController.
Q_INVOKABLE void synchronize();
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);
// static Members
static const char *wimaFileExtension;
static const char *areaItemsName;
static const char *missionItemsName;
signals:
void masterControllerChanged(void);
void missionControllerChanged(void);
void visualItemsChanged(void);
void currentPolygonIndexChanged(int index);
void currentFileChanged();
void wimaBridgeChanged();
void synchronizedChanged(void);
void needsUpdateChanged(void);
void readyForSynchronizationChanged(void);
void surveyReadyChanged(void);
void progressLockedChanged();
private slots:
void updatePolygonInteractivity(int index);
void _update();
void CSDestroyedHandler();
void CSVisualTransectPointsChangedHandler();
void mAreaPathChangedHandler();
void mAreaTilesChangedHandler();
void mAreaProgressChangedHandler();
void mAreaProgressAcceptedHandler();
void mAreaReadyChangedHandler();
void sAreaPathChangedHandler();
void corridorPathChangedHandler();
void depotChangedHandler();
void missionControllerVisualItemsChangedHandler();
void missionControllerWaypointPathChangedHandler();
void missionControllerNewItemsFromVehicleHandler();
void missionControllerMissionItemCountChangedHandler();
void nemoInterfaceProgressChangedHandler();
#ifndef NDEBUG
void autoLoadMission(void);
#endif
private:
signals:
void joinedAreaValidChanged();
void stateChanged();
private:
// Member Functions
bool toPlanData(AreaData &planData);
bool shortestPath(const QGeoCoordinate &start,
const QGeoCoordinate &destination,
QVector<QGeoCoordinate> &path);
void setSynchronized(bool s);
void enableAreaMonitoring();
void disableAreaMonitoring();
void enableMissionControllerMonitoring();
void disableMissionControllerMonitoring();
bool areasMonitored();
bool missionControllerMonitored();
// Member Variables
PlanMasterController *_masterController;
MissionController *_missionController;
int _currentAreaIndex;
QString _currentFile;
WimaMeasurementArea _measurementArea;
WimaServiceArea _serviceArea;
WimaCorridor _corridor;
WimaJoinedArea _joinedArea;
QmlObjectListModel _visualItems; // all areas
CircularSurvey *_survey;
#ifndef NDEBUG
QTimer _autoLoadTimer; // timer to auto load mission after some time, prevents
// seg. faults
#endif
NemoInterface _nemoInterface;
// State
QScopedPointer<wima_planer_detail::WimaStateMachine> _stateMachine;
bool _areasMonitored;
bool _missionControllerMonitored;
bool _progressLocked;
bool _synchronized; // true if planData is synchronized with
// wimaController
};
This diff is collapsed.
#pragma once
#include <QDataStream>
#include <QObject>
namespace wima_planer_detail {
enum class STATE {
NEEDS_INIT,
WAITING_FOR_TILE_UPDATE,
NEEDS_J_AREA_UPDATE,
NEEDS_SURVEY_UPDATE,
WAITING_FOR_SURVEY_UPDATE,
NEEDS_PATH_UPDATE,
UP_TO_DATE
};
QDebug &operator<<(QDebug &ds, STATE s);
enum class EVENT {
INIT_DONE,
M_AREA_NOT_READY,
M_AREA_READY,
M_AREA_PATH_CHANGED,
S_AREA_PATH_CHANGED,
CORRIDOR_PATH_CHANGED,
M_AREA_TILES_CHANGED,
M_AREA_PROGRESS_CHANGED,
J_AREA_UPDATED,
DEPOT_CHANGED,
SURVEY_DESTROYED,
MISSION_ITEMS_DESTROYED,
SURVEY_UPDATE_TRIGGERED,
SURVEY_UPDATED,
PATH_CHANGED,
PATH_UPDATED
};
QDebug &operator<<(QDebug &ds, EVENT s);
class WimaStateMachine : public QObject {
Q_OBJECT
public:
explicit WimaStateMachine(QObject *parent = nullptr);
STATE state();
void updateState(EVENT e);
bool upToDate();
bool surveyReady();
signals:
void stateChanged();
void upToDateChanged();
void surveyReadyChanged();