Newer
Older
Valentin Platzgummer
committed
const char* WimaPlaner::wimaFileExtension = "wima";
const char* WimaPlaner::areaItemsName = "AreaItems";
const char* WimaPlaner::missionItemsName = "MissionItems";
WimaPlaner::WimaPlaner(QObject *parent)
: QObject (parent)
, _currentAreaIndex (-1)
, _container (nullptr)
, _joinedArea (this)
, _joinedAreaValid (false)
, _measurementArea (this)
, _serviceArea (this)
, _corridor (this)
, _circularSurvey (nullptr)
, _surveyRefChanging (false)
Valentin Platzgummer
committed
, _measurementAreaChanging (false)
, _corridorChanging (false)
, _serviceAreaChanging (false)
, _syncronizedWithController (false)
, _readyForSync (false)
Valentin Platzgummer
committed
_lastMeasurementAreaPath = _measurementArea.path();
_lastServiceAreaPath = _serviceArea.path();
_lastCorridorPath = _corridor.path();
Valentin Platzgummer
committed
connect(this, &WimaPlaner::currentPolygonIndexChanged, this, &WimaPlaner::recalcPolygonInteractivity);
connect(&_updateTimer, &QTimer::timeout, this, &WimaPlaner::updateTimerSlot);
connect(this, &WimaPlaner::joinedAreaValidChanged, this, &WimaPlaner::updateMission);
Valentin Platzgummer
committed
_updateTimer.setInterval(500); // 250 ms means: max update time 2*250 ms
// for debugging and testing purpose, remove if not needed anymore
connect(&_autoLoadTimer, &QTimer::timeout, this, &WimaPlaner::autoLoadMission);
_autoLoadTimer.setSingleShot(true);
_calcArrivalAndReturnPathTimer.setInterval(100);
_calcArrivalAndReturnPathTimer.setSingleShot(true);
connect(&_calcArrivalAndReturnPathTimer, &QTimer::timeout, this, &WimaPlaner::calcArrivalAndReturnPath);
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
}
QmlObjectListModel* WimaPlaner::visualItems()
{
return &_visualItems;
}
QStringList WimaPlaner::loadNameFilters() const
{
QStringList filters;
filters << tr("Supported types (*.%1 *.%2)").arg(wimaFileExtension).arg(AppSettings::planFileExtension) <<
tr("All Files (*.*)");
return filters;
}
QStringList WimaPlaner::saveNameFilters() const
{
QStringList filters;
filters << tr("Supported types (*.%1 *.%2)").arg(wimaFileExtension).arg(AppSettings::planFileExtension);
return filters;
}
QGeoCoordinate WimaPlaner::joinedAreaCenter() const
{
return _joinedArea.center();
}
void WimaPlaner::setMasterController(PlanMasterController *masterC)
{
_masterController = masterC;
emit masterControllerChanged();
}
void WimaPlaner::setMissionController(MissionController *missionC)
{
_missionController = missionC;
emit missionControllerChanged();
}
void WimaPlaner::setCurrentPolygonIndex(int index)
{
if(index >= 0 && index < _visualItems.count() && index != _currentAreaIndex){
_currentAreaIndex = index;
emit currentPolygonIndexChanged(index);
}
}
void WimaPlaner::setDataContainer(WimaDataContainer *container)
{
Valentin Platzgummer
committed
if (container != nullptr) {
_container = container;
emit dataContainerChanged();
}
}
bool WimaPlaner::syncronizedWithController()
{
return _syncronizedWithController;
}
bool WimaPlaner::readyForSync()
{
return _readyForSync;
}
void WimaPlaner::removeArea(int index)
{
if(index >= 0 && index < _visualItems.count()){
WimaArea* area = qobject_cast<WimaArea*>(_visualItems.removeAt(index));
if ( area == nullptr) {
qWarning("WimaPlaner::removeArea(): nullptr catched, internal error.");
return;
}
area->clear();
emit visualItemsChanged();
if (_visualItems.count() == 0) {
// this branch is reached if all items are removed
// to guarentee proper behavior, _currentAreaIndex must be set to a invalid value, as on constructor init.
resetAllInteractive();
_currentAreaIndex = -1;
return;
}
if(_currentAreaIndex >= _visualItems.count()){
setCurrentPolygonIndex(_visualItems.count() - 1);
}else{
recalcPolygonInteractivity(_currentAreaIndex);
}
}else{
qWarning("Index out of bounds!");
}
}
Valentin Platzgummer
committed
bool WimaPlaner::addMeasurementArea()
Valentin Platzgummer
committed
if (!_visualItems.contains(&_measurementArea)) {
_visualItems.append(&_measurementArea);
int newIndex = _visualItems.count()-1;
setCurrentPolygonIndex(newIndex);
emit visualItemsChanged();
return true;
} else {
return false;
}
}
bool WimaPlaner::addServiceArea()
{
Valentin Platzgummer
committed
if (!_visualItems.contains(&_serviceArea)) {
_visualItems.append(&_serviceArea);
int newIndex = _visualItems.count()-1;
setCurrentPolygonIndex(newIndex);
emit visualItemsChanged();
return true;
} else {
return false;
}
}
Valentin Platzgummer
committed
bool WimaPlaner::addCorridor()
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
{
if (!_visualItems.contains(&_corridor)) {
_visualItems.append(&_corridor);
int newIndex = _visualItems.count()-1;
setCurrentPolygonIndex(newIndex);
emit visualItemsChanged();
return true;
} else {
return false;
}
}
void WimaPlaner::removeAll()
{
bool changesApplied = false;
while (_visualItems.count() > 0) {
removeArea(0);
changesApplied = true;
}
_missionController->removeAll();
_currentFile = "";
_circularSurvey = nullptr;
_surveyRefChanging = false;
emit currentFileChanged();
if ( changesApplied )
emit visualItemsChanged();
}
bool WimaPlaner::updateMission()
{
setReadyForSync(false);
Valentin Platzgummer
committed
if ( !_joinedAreaValid)
// extract old survey data
QmlObjectListModel* missionItems = _missionController->visualItems();
int surveyIndex = missionItems->indexOf(_circularSurvey);
// create survey item if not yet present
_missionController->insertComplexMissionItem(_missionController->circularSurveyComplexItemName(), _measurementArea.center(), missionItems->count());
_circularSurvey = qobject_cast<CircularSurveyComplexItem*>(missionItems->get(missionItems->count()-1));
if (_circularSurvey == nullptr){
qWarning("WimaPlaner::updateMission(): survey == nullptr");
return false;
}
// establish connections
_circularSurvey->setRefPoint(_measurementArea.center());
_lastSurveyRefPoint = _measurementArea.center();
_surveyRefChanging = false;
_circularSurvey->setIsInitialized(true); // prevents reinitialisation from gui
Valentin Platzgummer
committed
connect(_circularSurvey, &TransectStyleComplexItem::missionItemReady, this, &WimaPlaner::calcArrivalAndReturnPath);
// update survey area
_circularSurvey->surveyAreaPolygon()->clear();
_circularSurvey->surveyAreaPolygon()->appendVertices(_measurementArea.coordinateList());
Valentin Platzgummer
committed
_circularSurvey->comprehensiveUpdate();
setReadyForSync(true);
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
return true;
}
void WimaPlaner::saveToCurrent()
{
saveToFile(_currentFile);
}
void WimaPlaner::saveToFile(const QString& filename)
{
if (filename.isEmpty()) {
return;
}
QString planFilename = filename;
if (!QFileInfo(filename).fileName().contains(".")) {
planFilename += QString(".%1").arg(wimaFileExtension);
}
QFile file(planFilename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qgcApp()->showMessage(tr("Plan save error %1 : %2").arg(filename).arg(file.errorString()));
_currentFile.clear();
emit currentFileChanged();
} else {
FileType fileType = FileType::WimaFile;
if ( planFilename.contains(QString(".%1").arg(wimaFileExtension)) ) {
fileType = FileType::WimaFile;
} else if ( planFilename.contains(QString(".%1").arg(AppSettings::planFileExtension)) ) {
fileType = FileType::PlanFile;
} else {
if ( planFilename.contains(".") ) {
qgcApp()->showMessage(tr("File format not supported"));
} else {
qgcApp()->showMessage(tr("File without file extension not accepted."));
return;
}
}
QJsonDocument saveDoc = saveToJson(fileType);
file.write(saveDoc.toJson());
if(_currentFile != planFilename) {
_currentFile = planFilename;
emit currentFileChanged();
}
}
}
bool WimaPlaner::loadFromCurrent()
{
return loadFromFile(_currentFile);
}
bool WimaPlaner::loadFromFile(const QString &filename)
{
#define debug 0
QString errorString;
QString errorMessage = tr("Error loading Plan file (%1). %2").arg(filename).arg("%1");
if (filename.isEmpty()) {
return false;
}
QFileInfo fileInfo(filename);
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
errorString = file.errorString() + QStringLiteral(" ") + filename;
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
if(fileInfo.suffix() == wimaFileExtension) {
QJsonDocument jsonDoc;
QByteArray bytes = file.readAll();
if (!JsonHelper::isJsonFile(bytes, jsonDoc, errorString)) {
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
QJsonObject json = jsonDoc.object();
// AreaItems
QJsonArray areaArray = json[areaItemsName].toArray();
_visualItems.clear();
int validAreaCounter = 0;
for( int i = 0; i < areaArray.size() && validAreaCounter < 3; i++) {
QJsonObject jsonArea = areaArray[i].toObject();
if (jsonArea.contains(WimaArea::areaTypeName) && jsonArea[WimaArea::areaTypeName].isString()) {
if ( jsonArea[WimaArea::areaTypeName] == WimaMeasurementArea::WimaMeasurementAreaName) {
Valentin Platzgummer
committed
bool success = _measurementArea.loadFromJson(jsonArea, errorString);
if ( !success ) {
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
Valentin Platzgummer
committed
_lastMeasurementAreaPath = _measurementArea.path(); // prevents error messages at this point
Valentin Platzgummer
committed
_visualItems.append(&_measurementArea);
emit visualItemsChanged();
} else if ( jsonArea[WimaArea::areaTypeName] == WimaServiceArea::wimaServiceAreaName) {
Valentin Platzgummer
committed
bool success = _serviceArea.loadFromJson(jsonArea, errorString);
if ( !success ) {
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
Valentin Platzgummer
committed
_lastServiceAreaPath = _serviceArea.path(); // prevents error messages at this point
Valentin Platzgummer
committed
_visualItems.append(&_serviceArea);
emit visualItemsChanged();
} else if ( jsonArea[WimaArea::areaTypeName] == WimaCorridor::WimaCorridorName) {
bool success = _corridor.loadFromJson(jsonArea, errorString);
if ( !success ) {
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
Valentin Platzgummer
committed
_lastCorridorPath = _corridor.path(); // prevents error messages at this point
validAreaCounter++;
_visualItems.append(&_corridor);
emit visualItemsChanged();
} else {
errorString += QString(tr("%s not supported.\n").arg(WimaArea::areaTypeName));
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
} else {
errorString += QString(tr("Invalid or non existing entry for %s.\n").arg(WimaArea::areaTypeName));
return false;
}
_currentFile.sprintf("%s/%s.%s", fileInfo.path().toLocal8Bit().data(), fileInfo.completeBaseName().toLocal8Bit().data(), wimaFileExtension);
emit currentFileChanged();
QJsonObject missionObject = json[missionItemsName].toObject();
//qWarning() << json[missionItemsName].type();
QJsonDocument missionJsonDoc = QJsonDocument(missionObject);
// create temporary file with missionItems
QFile temporaryFile;
QString cropedFileName = filename.section("/",0,-2);
#if debug
qWarning() << cropedFileName;
#endif
QString temporaryFileName;
for (int i = 0; ; i++) {
temporaryFileName = cropedFileName + QString("/temp%1.%2").arg(i).arg(AppSettings::planFileExtension);
// qWarning() << temporaryFileName;
if ( !QFile::exists(temporaryFileName) ) {
temporaryFile.setFileName(temporaryFileName);
if ( temporaryFile.open(QIODevice::WriteOnly | QIODevice::Text) ) {
break;
}
}
if ( i > 1000) {
qWarning("WimaPlaner::loadFromFile(): not able to create temporary file.");
return false;
}
}
temporaryFile.write(missionJsonDoc.toJson());
// load from temporary file
_masterController->loadFromFile(temporaryFileName);
QmlObjectListModel *missionItems = _missionController->visualItems();
_circularSurvey = nullptr;
for (int i = 0; i < missionItems->count(); i++) {
_circularSurvey = missionItems->value<CircularSurveyComplexItem *>(i);
if (_circularSurvey != nullptr) {
_lastSurveyRefPoint = _circularSurvey->refPoint();
_surveyRefChanging = false;
_circularSurvey->setIsInitialized(true); // prevents reinitialisation from gui
Valentin Platzgummer
committed
connect(_circularSurvey, &TransectStyleComplexItem::missionItemReady, this, &WimaPlaner::calcArrivalAndReturnPath);
break;
}
}
//if (_circularSurvey == nullptr)
recalcJoinedArea();
Valentin Platzgummer
committed
updateMission();
// remove temporary file
if ( !temporaryFile.remove() ){
qWarning("WimaPlaner::loadFromFile(): not able to remove temporary file.");
}
Valentin Platzgummer
committed
setSyncronizedWithController(false);
return true;
} else if ( fileInfo.suffix() == AppSettings::planFileExtension ){
_masterController->loadFromFile(filename);
return true;// might be wrong return value
} else {
errorString += QString(tr("File extension not supported.\n"));
qgcApp()->showMessage(errorMessage.arg(errorString));
return false;
}
}
void WimaPlaner::recalcPolygonInteractivity(int index)
{
if (index >= 0 && index < _visualItems.count()) {
resetAllInteractive();
WimaArea* interactivePoly = qobject_cast<WimaArea*>(_visualItems.get(index));
Valentin Platzgummer
committed
if (interactivePoly != nullptr)
interactivePoly->setWimaAreaInteractive(true);
bool WimaPlaner::calcArrivalAndReturnPath()
{
setReadyForSync(false);
// extract old survey data
QmlObjectListModel *missionItems = _missionController->visualItems();
int surveyIndex = missionItems->indexOf(_circularSurvey);
if (surveyIndex == -1) {
qWarning("WimaPlaner::calcArrivalAndReturnPath(): no survey item");
return false;
}
bool restorePlanViewIndex = false;
if (surveyIndex == _missionController->currentPlanViewIndex())
restorePlanViewIndex = true;
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
// remove old arrival and return path
int size = missionItems->count();
for (int i = surveyIndex+1; i < size; i++)
_missionController->removeMissionItem(surveyIndex+1);
for (int i = surveyIndex-1; i > 1; i--)
_missionController->removeMissionItem(i);
// set home position to serArea center
MissionSettingsItem* settingsItem= qobject_cast<MissionSettingsItem*>(missionItems->get(0));
if (settingsItem == nullptr){
qWarning("WimaPlaner::calcArrivalAndReturnPath(): settingsItem == nullptr");
return false;
}
// set altitudes, temporary measure to solve bugs
QGeoCoordinate center = _serviceArea.center();
center.setAltitude(0);
_serviceArea.setCenter(center);
center = _measurementArea.center();
center.setAltitude(0);
_measurementArea.setCenter(center);
center = _corridor.center();
center.setAltitude(0);
_corridor.setCenter(center);
// set HomePos. to serArea center
settingsItem->setCoordinate(_serviceArea.center());
// set takeoff position
bool setCommandNeeded = false;
if (missionItems->count() < 3) {
setCommandNeeded = true;
_missionController->insertSimpleMissionItem(_serviceArea.center(), 1);
}
SimpleMissionItem* takeOffItem = qobject_cast<SimpleMissionItem*>(missionItems->get(1));
if (takeOffItem == nullptr){
qWarning("WimaPlaner::calcArrivalAndReturnPath(): takeOffItem == nullptr");
return false;
}
if (setCommandNeeded)
_missionController->setTakeoffCommand(*takeOffItem);
takeOffItem->setCoordinate(_serviceArea.center());
if (_circularSurvey->visualTransectPoints().size() == 0) {
qWarning("WimaPlaner::calcArrivalAndReturnPath(): survey no points.");
return false;
}
// calculate path from take off to survey
QGeoCoordinate start = _serviceArea.center();
QGeoCoordinate end = _circularSurvey->coordinate();
#ifdef QT_DEBUG
//if (!_visualItems.contains(&_joinedArea))
//_visualItems.append(&_joinedArea);
QVector<QGeoCoordinate> path;
if ( !calcShortestPath(start, end, path)) {
qgcApp()->showMessage( QString(tr("Not able to calculate the path from takeoff position to measurement area.")).toLocal8Bit().data());
return false;
}
_arrivalPathLength = path.size()-1;
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
int sequenceNumber = 0;
for (int i = 1; i < path.count()-1; i++) {
sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count()-1);
_missionController->setCurrentPlanViewIndex(sequenceNumber, true);
}
// calculate return path
start = _circularSurvey->exitCoordinate();
end = _serviceArea.center();
path.clear();
if ( !calcShortestPath(start, end, path)) {
qgcApp()->showMessage(QString(tr("Not able to calculate the path from measurement area to landing position.")).toLocal8Bit().data());
return false;
}
_returnPathLength = path.size()-1; // -1: fist item is last measurement point
for (int i = 1; i < path.count()-1; i++) {
sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count());
_missionController->setCurrentPlanViewIndex(sequenceNumber, true);
}
// create land position item
sequenceNumber = _missionController->insertSimpleMissionItem(_serviceArea.center(), missionItems->count());
_missionController->setCurrentPlanViewIndex(sequenceNumber, true);
SimpleMissionItem* landItem = qobject_cast<SimpleMissionItem*>(missionItems->get(missionItems->count()-1));
if (landItem == nullptr){
qWarning("WimaPlaner::calcArrivalAndReturnPath(): landItem == nullptr");
return false;
} else {
if (!_missionController->setLandCommand(*landItem))
return false;
}
if (restorePlanViewIndex)
_missionController->setCurrentPlanViewIndex(missionItems->indexOf(_circularSurvey), false);
setSyncronizedWithControllerFalse();
setReadyForSync(true);
counter++;
qWarning() << "WimaPlaner::calcArrivalAndReturnPath(): " << counter;
bool WimaPlaner::recalcJoinedArea()
setJoinedAreaValid(false);
// check if at least service area and measurement area are available
if (_visualItems.indexOf(&_serviceArea) == -1 || _visualItems.indexOf(&_measurementArea) == -1)
return false;
Valentin Platzgummer
committed
// check if area paths form simple polygons
if ( !_serviceArea.isSimplePolygon() ) {
Valentin Platzgummer
committed
qgcApp()->showMessage(tr("Service area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"));
Valentin Platzgummer
committed
return false;
}
if ( !_corridor.isSimplePolygon() && _corridor.count() > 0) {
Valentin Platzgummer
committed
qgcApp()->showMessage(tr("Corridor is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"));
Valentin Platzgummer
committed
return false;
}
if ( !_measurementArea.isSimplePolygon() ) {
Valentin Platzgummer
committed
qgcApp()->showMessage(tr("Measurement area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"));
Valentin Platzgummer
committed
return false;
}
_joinedArea.setPath(_serviceArea.path());
_joinedArea.join(_corridor);
Valentin Platzgummer
committed
if ( !_joinedArea.join(_measurementArea) ) {
Valentin Platzgummer
committed
/*qgcApp()->showMessage(tr("Not able to join areas. Service area and measurement"
" must have a overlapping section, or be connected through a corridor."));*/
return false; // this happens if all areas are pairwise disjoint
Valentin Platzgummer
committed
}
Valentin Platzgummer
committed
setJoinedAreaValid(true);
Valentin Platzgummer
committed
/*!
* \fn void WimaPlaner::pushToContainer()
* Pushes the \c WimaPlanData object generated by \c toPlanData() to the \c WimaDataContainer.
* Should be called only after \c updateMission() was successful.
*
* \sa WimaDataContainer, WimaPlanData
*/
void WimaPlaner::pushToContainer()
{
if (_container != nullptr) {
Valentin Platzgummer
committed
if (!_readyForSync)
return;
_container->push(toPlanData());
setSyncronizedWithController(true);
} else {
qWarning("WimaPlaner::uploadToContainer(): no container assigned.");
}
}
bool WimaPlaner::calcShortestPath(const QGeoCoordinate &start, const QGeoCoordinate &destination, QVector<QGeoCoordinate> &path)
{
using namespace GeoUtilities;
using namespace PolygonCalculus;
auto startTime = std::chrono::high_resolution_clock::now();
bool retVal = PolygonCalculus::shortestPath(
toQPolygonF(toCartesian2D(_joinedArea.coordinateList(), /*origin*/ start)),
/*start point*/ QPointF(0,0),
/*destination*/ toCartesian2D(destination, start),
/*shortest path*/ path2D);
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-startTime).count();
qWarning() << "WimaPlaner::calcShortestPath: time " << duration << " us";
return retVal;
}
void WimaPlaner::resetAllInteractive()
Valentin Platzgummer
committed
{
// Marks all areas as inactive (area.interactive == false)
int itemCount = _visualItems.count();
if (itemCount > 0){
for (int i = 0; i < itemCount; i++) {
WimaArea* iteratorPoly = qobject_cast<WimaArea*>(_visualItems.get(i));
iteratorPoly->setWimaAreaInteractive(false);
}
}
}
void WimaPlaner::setInteractive()
{
recalcPolygonInteractivity(_currentAreaIndex);
}
Valentin Platzgummer
committed
/*!
* \fn WimaPlanData WimaPlaner::toPlanData()
*
* Returns a \c WimaPlanData object containing information about the current mission.
* The \c WimaPlanData object holds only the data which is relevant for the \c WimaController class.
* Should only be called if updateMission() was successful.
*
* \sa WimaController, WimaPlanData
*/
QSharedPointer<WimaPlanData> WimaPlaner::toPlanData()
Valentin Platzgummer
committed
{
//WimaPlanData *data = new WimaPlanData(nullptr);
QSharedPointer<WimaPlanData> planData(new WimaPlanData());
planData->append(WimaMeasurementAreaData(_measurementArea));
planData->append(WimaServiceAreaData(_serviceArea));
planData->append(WimaCorridorData(_corridor));
planData->append(WimaJoinedAreaData(_joinedArea));
Valentin Platzgummer
committed
// convert mission items to mavlink commands
QList<MissionItem*> rgMissionItems;
QmlObjectListModel *visualItems = _missionController->visualItems();
MissionController::convertToMissionItems(visualItems, rgMissionItems, nullptr);
planData->append(rgMissionItems);
Valentin Platzgummer
committed
}
void WimaPlaner::setSyncronizedWithController(bool sync)
Valentin Platzgummer
committed
{
if (_syncronizedWithController != sync) {
_syncronizedWithController = sync;
emit syncronizedWithControllerChanged();
Valentin Platzgummer
committed
}
}
void WimaPlaner::setReadyForSync(bool ready)
{
if( _readyForSync != ready) {
_readyForSync = ready;
emit readyForSyncChanged();
}
}
void WimaPlaner::setJoinedAreaValid(bool valid)
{
if (_joinedAreaValid != valid) {
_joinedAreaValid = valid;
emit joinedAreaValidChanged();
}
}
void WimaPlaner::updateTimerSlot()
{
// General operation of this function:
// Check if parameter has changed, wait until it stops changing, update mission
// circular survey reference point
// if (_missionController != nullptr
// && _missionController->visualItems()->indexOf(_circularSurvey) != -1
// && _circularSurvey != nullptr)
// {
// if (_surveyRefChanging) {
// if (_circularSurvey->refPoint() == _lastSurveyRefPoint) { // is it still changing?
// calcArrivalAndReturnPath();
// _surveyRefChanging = false;
// }
// } else {
// if (_circularSurvey->refPoint() != _lastSurveyRefPoint) // does it started changing?
// _surveyRefChanging = true;
// }
// }
// measurementArea
if (_measurementAreaChanging) {
if (_measurementArea.path() == _lastMeasurementAreaPath) { // is it still changing?
recalcJoinedArea();
Valentin Platzgummer
committed
calcArrivalAndReturnPath();
_measurementAreaChanging = false;
}
} else {
if (_measurementArea.path() != _lastMeasurementAreaPath) // does it started changing?
_measurementAreaChanging = true;
}
// corridor
if (_corridorChanging) {
if (_corridor.path() == _lastCorridorPath) { // is it still changing?
recalcJoinedArea();
Valentin Platzgummer
committed
calcArrivalAndReturnPath();
_corridorChanging = false;
}
} else {
if (_corridor.path() != _lastCorridorPath) // does it started changing?
_corridorChanging = true;
}
// service area
if (_serviceAreaChanging) {
if (_serviceArea.path() == _lastServiceAreaPath) { // is it still changing?
recalcJoinedArea();
Valentin Platzgummer
committed
calcArrivalAndReturnPath();
_serviceAreaChanging = false;
}
} else {
if (_serviceArea.path() != _lastServiceAreaPath) // does it started changing?
_serviceAreaChanging = true;
}
// if (_missionController != nullptr
// && _missionController->visualItems()->indexOf(_circularSurvey) != -1
// && _circularSurvey != nullptr)
// _lastSurveyRefPoint = _circularSurvey->refPoint();
_lastMeasurementAreaPath = _measurementArea.path();
_lastCorridorPath = _corridor.path();
_lastServiceAreaPath = _serviceArea.path();
void WimaPlaner::setSyncronizedWithControllerFalse()
{
setSyncronizedWithController(false);
}
void WimaPlaner::autoLoadMission()
{
loadFromFile("/home/valentin/Desktop/drones/build-qgroundcontrol-Desktop_Qt_5_11_3_GCC_64bit-Release/release/345.wima");
pushToContainer();
}
void WimaPlaner::startCalcArrivalAndReturnTimer()
{
_calcArrivalAndReturnPathTimer.start();
}
QJsonDocument WimaPlaner::saveToJson(FileType fileType)
{
/// This function save all areas (of WimaPlaner) and all mission items (of MissionController) to a QJsonDocument
/// @param fileType is either WimaFile or PlanFile (enum), if fileType == PlanFile only mission items are stored
QJsonObject json;
if ( fileType == FileType::WimaFile ) {
QJsonArray jsonArray;
for (int i = 0; i < _visualItems.count(); i++) {
QJsonObject json;
WimaArea* area = qobject_cast<WimaArea*>(_visualItems.get(i));
if (area == nullptr) {
qWarning("WimaPlaner::saveToJson(): Internal error, area == nullptr!");
return QJsonDocument();
}
// check the type of area, create and append the JsonObject to the JsonArray once determined
WimaMeasurementArea* opArea = qobject_cast<WimaMeasurementArea*>(area);
if (opArea != nullptr) {
opArea->saveToJson(json);
jsonArray.append(json);
continue;
}
Valentin Platzgummer
committed
WimaServiceArea* serArea = qobject_cast<WimaServiceArea*>(area);
if (serArea != nullptr) {
serArea->saveToJson(json);
jsonArray.append(json);
continue;
}
WimaCorridor* corridor = qobject_cast<WimaCorridor*>(area);
if (corridor != nullptr) {
corridor->saveToJson(json);
jsonArray.append(json);
continue;
}
// if non of the obove branches was trigger, type must be WimaArea
area->saveToJson(json);
jsonArray.append(json);
}
json[areaItemsName] = jsonArray;
json[missionItemsName] = _masterController->saveToJson().object();
return QJsonDocument(json);
} else if (fileType == FileType::PlanFile) {
return _masterController->saveToJson();
}
return QJsonDocument(json);
Valentin Platzgummer
committed
}