Newer
Older
Valentin Platzgummer
committed
#include "QmlObjectListModel.h"
#include "WimaMeasurementArea.h"
Valentin Platzgummer
committed
#include "WimaMeasurementAreaData.h"
#include "WimaCorridorData.h"
#include "WimaServiceAreaData.h"
#include "PlanMasterController.h"
#include "MissionController.h"
#include "SurveyComplexItem.h"
#include "SimpleMissionItem.h"
#include "MissionSettingsItem.h"
#include "JsonHelper.h"
#include "QGCApplication.h"
#include "WimaSettings.h"
#include "SettingsManager.h"
#include "snake.h"
#include "WimaControllerDetail.h"
#define CHECK_BATTERY_INTERVAL 1000 // ms
#define SMART_RTL_MAX_ATTEMPTS 3 // times
#define SMART_RTL_ATTEMPT_INTERVAL 200 // ms
#define SNAKE_EVENT_LOOP_INTERVAL 5000 // ms
class WimaController : public QObject
{
enum FileType {WimaFile, PlanFile};
enum SnakeConnectionStatus {Connected = 1, NotConnected = 0};
WimaController(QObject *parent = nullptr);
Q_PROPERTY(PlanMasterController* masterController READ masterController WRITE setMasterController NOTIFY masterControllerChanged)
Q_PROPERTY(MissionController* missionController READ missionController WRITE setMissionController NOTIFY missionControllerChanged)
Valentin Platzgummer
committed
Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged)
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(WimaDataContainer* dataContainer READ dataContainer WRITE setDataContainer NOTIFY dataContainerChanged)
Valentin Platzgummer
committed
Q_PROPERTY(QmlObjectListModel* missionItems READ missionItems NOTIFY missionItemsChanged)
Q_PROPERTY(QmlObjectListModel* currentMissionItems READ currentMissionItems NOTIFY currentMissionItemsChanged)
Q_PROPERTY(QVariantList waypointPath READ waypointPath NOTIFY waypointPathChanged)
Valentin Platzgummer
committed
Q_PROPERTY(QVariantList currentWaypointPath READ currentWaypointPath NOTIFY currentWaypointPathChanged)
Q_PROPERTY(Fact* enableWimaController READ enableWimaController CONSTANT)
Q_PROPERTY(Fact* overlapWaypoints READ overlapWaypoints CONSTANT)
Q_PROPERTY(Fact* maxWaypointsPerPhase READ maxWaypointsPerPhase CONSTANT)
Q_PROPERTY(Fact* startWaypointIndex READ startWaypointIndex CONSTANT)
Q_PROPERTY(Fact* showAllMissionItems READ showAllMissionItems CONSTANT)
Q_PROPERTY(Fact* showCurrentMissionItems READ showCurrentMissionItems CONSTANT)
Q_PROPERTY(Fact* flightSpeed READ flightSpeed CONSTANT)
Q_PROPERTY(Fact* altitude READ altitude CONSTANT)
Q_PROPERTY(Fact* arrivalReturnSpeed READ arrivalReturnSpeed CONSTANT)
Q_PROPERTY(Fact* reverse READ reverse CONSTANT)
Valentin Platzgummer
committed
Q_PROPERTY(bool uploadOverrideRequired READ uploadOverrideRequired WRITE setUploadOverrideRequired NOTIFY uploadOverrideRequiredChanged)
Q_PROPERTY(double phaseDistance READ phaseDistance NOTIFY phaseDistanceChanged)
Q_PROPERTY(double phaseDuration READ phaseDuration NOTIFY phaseDurationChanged)
Q_PROPERTY(bool vehicleHasLowBattery READ vehicleHasLowBattery NOTIFY vehicleHasLowBatteryChanged)
Valentin Platzgummer
committed
Q_PROPERTY(Fact* enableSnake READ enableSnake CONSTANT)
Q_PROPERTY(long snakeConnectionStatus READ snakeConnectionStatus NOTIFY snakeConnectionStatusChanged)
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)
Q_PROPERTY(QList<int> snakeProgress READ snakeProgress NOTIFY snakeProgressChanged)
PlanMasterController* masterController (void) { return _masterController; }
MissionController* missionController (void) { return _missionController; }
QmlObjectListModel* visualItems (void) { return &_visualItems; }
QString currentFile (void) const { return _currentFile; }
QStringList saveNameFilters (void) const;
QString fileExtension (void) const { return wimaFileExtension; }
WimaDataContainer* dataContainer (void) { return _container; }
QmlObjectListModel* missionItems (void) { return &_missionItems; }
QmlObjectListModel* currentMissionItems (void) { return &_currentMissionItems; }
QVariantList waypointPath (void) { return _waypointPath; }
QVariantList currentWaypointPath (void) { return _currentWaypointPath; }
Fact* enableWimaController (void) { return &_enableWimaController; }
Fact* overlapWaypoints (void) { return &_overlapWaypoints; }
Fact* maxWaypointsPerPhase (void) { return &_maxWaypointsPerPhase; }
Fact* startWaypointIndex (void) { return &_nextPhaseStartWaypointIndex; }
Fact* showAllMissionItems (void) { return &_showAllMissionItems; }
Fact* showCurrentMissionItems(void) { return &_showCurrentMissionItems; }
Fact* flightSpeed (void) { return &_flightSpeed; }
Fact* arrivalReturnSpeed (void) { return &_arrivalReturnSpeed; };
Fact* altitude (void) { return &_altitude; }
Fact* reverse (void) { return &_reverse; }
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;}
QmlObjectListModel* snakeTiles (void) { return &_snakeTiles;}
Valentin Platzgummer
committed
QVariantList snakeTileCenterPoints (void) { return _snakeTileCenterPoints;}
QList<int> snakeProgress (void) { return _snakeProgress;}
Valentin Platzgummer
committed
bool uploadOverrideRequired (void) const;
double phaseDistance (void) const;
double phaseDuration (void) const;
bool vehicleHasLowBattery (void) const;
long snakeConnectionStatus (void) const;
bool snakeCalcInProgress (void) const;
// Property setters
void setMasterController (PlanMasterController* masterController);
void setMissionController (MissionController* missionController);
void setDataContainer (WimaDataContainer* container);
Valentin Platzgummer
committed
void setUploadOverrideRequired (bool overrideRequired);
// Member Methodes
Valentin Platzgummer
committed
Q_INVOKABLE void previousPhase();
Q_INVOKABLE void resetPhase();
Valentin Platzgummer
committed
Q_INVOKABLE bool forceUploadToVehicle();
Q_INVOKABLE void removeFromVehicle();
Q_INVOKABLE bool checkSmartRTLPreCondition(); // wrapper for _checkSmartRTLPreCondition(QString &errorString)
Q_INVOKABLE bool calcReturnPath(); // wrapper for _calcReturnPath(QString &errorSring)#
Q_INVOKABLE void executeSmartRTL(); // wrapper for _executeSmartRTL(QString &errorSring)
Q_INVOKABLE void initSmartRTL();
Valentin Platzgummer
committed
Q_INVOKABLE void removeVehicleTrajectoryHistory();
Q_INVOKABLE void saveToCurrent ();
Q_INVOKABLE void saveToFile (const QString& filename);
Q_INVOKABLE bool loadFromFile (const QString& filename);
// static Members
static const char* wimaFileExtension;
static const char* areaItemsName;
static const char* missionItemsName;
static const char* settingsGroup;
static const char* endWaypointIndexName;
static const char* enableWimaControllerName;
static const char* overlapWaypointsName;
static const char* maxWaypointsPerPhaseName;
static const char* startWaypointIndexName;
static const char* showAllMissionItemsName;
static const char* showCurrentMissionItemsName;
static const char* flightSpeedName;
static const char* arrivalReturnSpeedName;
static const char* reverseName;
static const char* snakeTileWidthName;
static const char* snakeTileHeightName;
static const char* snakeMinTileAreaName;
static const char* snakeLineDistanceName;
static const char* snakeMinTransectLengthName;
QJsonDocument saveToJson(FileType fileType);
bool calcShortestPath(const QGeoCoordinate &start, const QGeoCoordinate &destination, QVector<QGeoCoordinate> &path);
/// extracts the coordinates stored in missionItems (list of MissionItems) and stores them in coordinateList
Valentin Platzgummer
committed
bool extractCoordinateList(QmlObjectListModel &missionItems, QVector<QGeoCoordinate> &coordinateList);
/// extracts the coordinates (between startIndex and endIndex) stored in missionItems (list of MissionItems) and stores them in coordinateList.
Valentin Platzgummer
committed
bool extractCoordinateList(QmlObjectListModel &missionItems, QVector<QGeoCoordinate> &coordinateList, int startIndex, int endIndex);
/// extracts the coordinates stored in missionItems (list of MissionItems) and stores them in coordinateList
Valentin Platzgummer
committed
bool extractCoordinateList(QmlObjectListModel &missionItems, QVariantList &coordinateList);
/// extracts the coordinates (between startIndex and endIndex) stored in missionItems (list of MissionItems) and stores them in coordinateList.
Valentin Platzgummer
committed
bool extractCoordinateList(QmlObjectListModel &missionItems, QVariantList &coordinateList, int startIndex, int endIndex);
void masterControllerChanged (void);
void missionControllerChanged (void);
void visualItemsChanged (void);
void currentFileChanged ();
void dataContainerChanged ();
void readyForSaveSendChanged (bool ready);
void missionItemsChanged (void);
void currentMissionItemsChanged (void);
void waypointPathChanged (void);
void currentWaypointPathChanged (void);
void uploadOverrideRequiredChanged (void);
void phaseDistanceChanged (void);
void phaseDurationChanged (void);
void vehicleHasLowBatteryChanged (void);
void returnBatteryLowConfirmRequired (void);
void returnUserRequestConfirmRequired (void);
void snakeConnectionStatusChanged (void);
void snakeCalcInProgressChanged (void);
void snakeTilesChanged (void);
Valentin Platzgummer
committed
void snakeTileCenterPointsChanged (void);
void snakeProgressChanged (void);
private:
enum SRTL_Reason {BatteryLow, UserRequest};
bool _fetchContainerData();
bool _calcNextPhase(void);
void _updateWaypointPath (void);
void _updateCurrentPath (void);
void _updateNextWaypoint (void);
void _recalcCurrentPhase (void);
bool _setTakeoffLandPosition (void);
void _updateflightSpeed (void);
void _updateArrivalReturnSpeed (void);
void _updateAltitude (void);
void _checkBatteryLevel (void);
void _eventTimerHandler (void);
void _smartRTLCleanUp (bool flying); // cleans up after successfull smart RTL
void _enableDisableLowBatteryHandling (QVariant enable);
void _reverseChangedHandler ();
void _initSmartRTL ();
void _executeSmartRTL ();
void _setSnakeConnectionStatus (SnakeConnectionStatus status);
void _setSnakeCalcInProgress (bool inProgress);
bool _verifyScenarioDefined (void);
bool _verifyScenarioDefinedWithErrorMessage (void);
void _snakeStoreWorkerResults ();
private:
void _setPhaseDistance(double distance);
void _setPhaseDuration(double duration);
bool _checkSmartRTLPreCondition(QString &errorString); // should be called from gui, befor calcReturnPath()
bool _calcReturnPath(QString &errorSring); // Calculates return path (destination: service area center) for a flying vehicle
void _setVehicleHasLowBattery(bool batteryLow);
void _loadCurrentMissionItemsFromBuffer();
void _saveCurrentMissionItemsToBuffer();
PlanMasterController *_masterController;
MissionController *_missionController;
QString _currentFile; // file for saveing
WimaDataContainer *_container; // container for data exchange with WimaController
Valentin Platzgummer
committed
QmlObjectListModel _visualItems; // contains all visible areas
WimaJoinedAreaData _joinedArea; // joined area fromed by opArea, serArea, _corridor
Valentin Platzgummer
committed
WimaMeasurementAreaData _measurementArea; // measurement area
WimaServiceAreaData _serviceArea; // area for supplying
WimaCorridorData _corridor; // corridor connecting opArea and serArea
bool _localPlanDataValid;
Valentin Platzgummer
committed
QmlObjectListModel _missionItems; // all mission itmes (Mission Items) generaded by wimaPlaner, displayed in flightView
QmlObjectListModel _currentMissionItems; // contains the current mission items, which are a sub set of _missionItems,
// _currentMissionItems contains a number of mission items which can be worked off with a single battery chrage
QmlObjectListModel _missionItemsBuffer; // Buffer to store mission items, e.g. for storing _currentMissionItems when smartRTL() is invoked
QVariantList _waypointPath; // path connecting the items in _missionItems
Valentin Platzgummer
committed
QVariantList _currentWaypointPath; // path connecting the items in _currentMissionItems
Valentin Platzgummer
committed
QGeoCoordinate _takeoffLandPostion;
Valentin Platzgummer
committed
QMap<QString, FactMetaData*> _metaDataMap;
SettingsFact _enableWimaController; // enables or disables the wimaControler
SettingsFact _overlapWaypoints; // determines the number of overlapping waypoints between two consecutive mission phases
SettingsFact _maxWaypointsPerPhase; // determines the maximum number waypoints per phase
SettingsFact _nextPhaseStartWaypointIndex; // index (displayed on the map, -1 to get index of item in _missionItems) of the mission item
// defining the first element of the next phase
SettingsFact _showAllMissionItems; // bool value, Determines whether the mission items of the overall mission are displayed or not.
SettingsFact _showCurrentMissionItems; // bool value, Determines whether the mission items of the current mission phase are displayed or not.
SettingsFact _flightSpeed; // mission flight speed
SettingsFact _arrivalReturnSpeed; // arrival and return path speed
SettingsFact _altitude; // mission altitude
SettingsFact _reverse; // Reverses the phase direction. Phases go from high to low waypoint numbers, if true.
SettingsFact _enableSnake; // Enable Snake (see snake.h)
int _endWaypointIndex; // index of the mission item stored in _missionItems defining the last element
Valentin Platzgummer
committed
// (which is not part of the return path) of _currentMissionItem
int _startWaypointIndex; // index of the mission item stored in _missionItems defining the first element
Valentin Platzgummer
committed
// (which is not part of the arrival path) of _currentMissionItem
Valentin Platzgummer
committed
bool _uploadOverrideRequired; // Is set to true if uploadToVehicle() did not suceed because the vehicle is not inside the service area.
// The user can override the upload lock with a slider, this will reset this variable to false.
double _measurementPathLength; // the lenght of the phase in meters
double _arrivalPathLength; // the length of the arrival and return path in meters
double _returnPathLength; // the length of the arrival and return path in meters
double _phaseDistance; // the lenth in meters of the current phase
double _phaseDuration; // the phase duration in seconds
double _phaseDistanceBuffer; // buffer for storing _phaseDistance when doing smart RTL
double _phaseDurationBuffer; // buffer for storing _phaseDuration when doing smart RTL
QTimer _smartRTLAttemptTimer;
SRTL_Reason _srtlReason;
bool _vehicleHasLowBattery;
bool _lowBatteryHandlingTriggered;
// Snake
SnakeConnectionStatus _snakeConnectionStatus;
bool _snakeCalcInProgress;
bool _snakeRecalcNecessary;
bool _scenarioDefinedBool;
SnakeWorker _snakeWorker;
Scenario _scenario;
SettingsFact _snakeTileWidth;
SettingsFact _snakeTileHeight;
SettingsFact _snakeMinTileArea;
SettingsFact _snakeLineDistance;
SettingsFact _snakeMinTransectLength;
QmlObjectListModel _snakeTiles; // tiles
Valentin Platzgummer
committed
QVariantList _snakeTileCenterPoints;
QList<int> _snakeProgress; // measurement progress
/*
* The following explains the structure of
*
* Index Description
* --------------------------------------------
* 0 MissionSettingsItem
* 1 Takeoff Command
* 2 Speed Command: arrivalReturnSpeed
* 3 Arrival Path Waypoint 0
* ...
* 3+n-1 Arrival Path Waypoint n-1
* 3+n Speed Command: flightSpeed
* 3+n+1 Circular Survey Waypoint 0
* ...
* 3+n+m Circular Survey Waypoint m-1
* 3+n+m+1 Speed Command: arrivalReturnSpeed
* 3+n+m+2 Return Path Waypoint 0
* ...
* 3+n+m+2+l Return Path Waypoint l-1
* 3+n+m+2+l+1 Land command
*
Valentin Platzgummer
committed
* _currentMissionItems is equal to
* _missionController.visualItems() except that it
* is missing the MissionSettingsItem