diff --git a/src/FlightDisplay/FlightDisplayWimaMenu.qml b/src/FlightDisplay/FlightDisplayWimaMenu.qml index d92a75c69acb806487cc6ae721adaa20e76220f9..58896b9180799500acb48930594796b808f9c04f 100644 --- a/src/FlightDisplay/FlightDisplayWimaMenu.qml +++ b/src/FlightDisplay/FlightDisplayWimaMenu.qml @@ -46,8 +46,6 @@ Item { // Use Settings to store menu appearance through different sessions. Settings { - property alias missionHeaderChecker: missionHeader.checked - property alias navigateHeaderChecker: navigateHeader.checked property alias vehicleHeaderChecker: vehicleHeader.checked property alias statsHeaderChecker: statsHeader.checked } @@ -173,124 +171,11 @@ Item { id: mainColumn spacing: ScreenTools.defaultFontPixelHeight * 0.3 - - SectionHeader{ - id: missionHeader - text: qsTr("Phase Settings") - } - GridLayout { - columns: 2 - rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 - columnSpacing: ScreenTools.defaultFontPixelHeight * 0.5 - visible: missionHeader.checked - - QGCLabel { - text: qsTr("Next Waypoint") - Layout.fillWidth: true - } - FactTextField { - fact: wimaController.startWaypointIndex - Layout.fillWidth: true - } - - QGCLabel { - text: qsTr("Max Waypoints") - Layout.fillWidth: true - } - FactTextField { - fact: wimaController.maxWaypointsPerPhase - Layout.fillWidth: true - } - - QGCLabel { - text: qsTr("Overlap") - Layout.fillWidth: true - } - FactTextField { - fact: wimaController.overlapWaypoints - Layout.fillWidth: true - } - - QGCLabel { - text: qsTr("Measurement Speed") - Layout.fillWidth: true - } - FactTextField { - fact: wimaController.flightSpeed - Layout.fillWidth: true - } - - QGCLabel { - text: qsTr("AaR Speed") - Layout.fillWidth: true - } - FactTextField { - fact: wimaController.arrivalReturnSpeed - Layout.fillWidth: true - } - - QGCLabel { - text: qsTr("Altitude") - Layout.fillWidth: true - } - FactTextField { - fact: wimaController.altitude - Layout.fillWidth: true - } - - FactCheckBox { - text: qsTr("Show Mission") - fact: wimaController.showAllMissionItems - Layout.fillWidth: true - } - - FactCheckBox { - text: qsTr("Show Phase") - fact: wimaController.showCurrentMissionItems - Layout.fillWidth: true - } - - } - - SectionHeader{ - id: navigateHeader - text: qsTr("Navigate") - } - - GridLayout {// Buttons - columns: 2 - rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 - columnSpacing: ScreenTools.defaultFontPixelHeight * 0.5 - visible: navigateHeader.checked - width: missionHeader.width - - QGCButton { - id: buttonPreviousMissionPhase - text: qsTr("Go Reverse") - onClicked: wimaController.previousPhase() - Layout.fillWidth: true - } - - QGCButton { - id: buttonNextMissionPhase - text: qsTr("Go Forward") - onClicked: wimaController.nextPhase() - Layout.fillWidth: true - } - - QGCButton { - id: buttonResetPhase - text: qsTr("Reset Phase") - onClicked: wimaController.resetPhase(); - Layout.columnSpan: 2 - Layout.fillWidth: true - } - } // Grid Buttons - SectionHeader{ id: vehicleHeader text: qsTr("Vehicle") } + GridLayout { columns: 2 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 @@ -298,17 +183,6 @@ Item { visible: vehicleHeader.checked width: parent.width - QGCButton { - id: buttonUpload - text: qsTr("Upload") - onClicked: { - if (!planMasterController.offline) { - wimaController.upload() - } - } - Layout.fillWidth: true - } - QGCButton { id: buttonRemoveFromVehicle text: qsTr("Remove") @@ -320,7 +194,6 @@ Item { id: buttonSmartRTL text: qsTr("Smart RTL") onClicked: wimaController.requestSmartRTL(); - Layout.columnSpan: 2 Layout.fillWidth: true } @@ -350,7 +223,7 @@ Item { Layout.columnSpan: 2 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - text: "Done" + text: "Upload Complete" visible: false Layout.fillWidth: true } @@ -360,6 +233,7 @@ Item { id: statsHeader text: qsTr("Statistics") } + GridLayout { columns: 3 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 @@ -374,24 +248,6 @@ Item { height: 0 } - SmallValue { - property var phaseDistance: wimaController.phaseDistance - - shortDescription: qsTr("Phase Length") - value: phaseDistance >= 0 ? phaseDistance.toFixed(2): "-.-" - unit: "m" - //width: widthItem.width*0.49 - } - - SmallValue { - property var phaseDuration: wimaController.phaseDuration - - shortDescription: qsTr("Phase Duration") - value: phaseDuration >= 0 ? getTime(phaseDuration) : "-.-" - //unit: "m" - //width: widthItem.width*0.49 - } - SmallValue { property var currentMissionIndex: missionController.currentMissionIndex diff --git a/src/PlanView/CircularSurveyItemEditor.qml b/src/PlanView/CircularSurveyItemEditor.qml index 5f8fbb2f0e8f064d22057d749ebb588349542e98..2bc9fb7a0a63fc051bca2559126edb12ea520d93 100644 --- a/src/PlanView/CircularSurveyItemEditor.qml +++ b/src/PlanView/CircularSurveyItemEditor.qml @@ -154,44 +154,6 @@ Rectangle { } } } - - - QGCLabel { - text: qsTr("Runs") - } - FactTextField { - fact: missionItem.numRuns - } - - GridLayout{ - Layout.columnSpan: 2 - - columnSpacing: _margin - rowSpacing: _margin - columns: 6 - - Repeater{ - id: runRepeater - - property var fact: missionItem.run - property int run: fact.value - property var names: missionItem.runNames - property int len: missionItem.runNames.length - - model: len > 1 ? len : 0 - QGCRadioButton { - checked: index === runRepeater.run - text: runRepeater.names[index] - - onCheckedChanged: { - if (checked){ - missionItem.run.value = index - } - checked = Qt.binding(function(){ return index === runRepeater.run}) - } - } - } - } } SectionHeader { @@ -273,31 +235,20 @@ Rectangle { anchors.horizontalCenter: parent.horizontalCenter property bool calculating: missionItem.calculating running: calculating + visible: calculating || timer.running onCalculatingChanged: { - if(calculating){ - visible = true - } else { + if(!calculating){ + // defer hideing timer.restart() } } - Component.onCompleted: { - if (calculating){ - visible = true - } - } - Timer{ id: timer interval: 1000 repeat: false - - onTriggered: { - if (indicator.calculating == false){ - indicator.visible = false - } - } + running: false } } } diff --git a/src/Wima/CircularSurvey.cc b/src/Wima/CircularSurvey.cc index b010ac15fcaf5668ad89bb71bda66b0bae203e71..460abb69e707bbe3b8dc8bf4f5dd909e20f3839a 100644 --- a/src/Wima/CircularSurvey.cc +++ b/src/Wima/CircularSurvey.cc @@ -109,6 +109,12 @@ CircularSurvey::CircularSurvey(Vehicle *vehicle, bool flyView, connect(this->_pWorker.get(), &RoutingThread::calculatingChanged, this, &CircularSurvey::calculatingChanged); this->_transectsDirty = true; + + // Altitude + connect(&_cameraCalc, &CameraCalc::distanceToSurfaceRelativeChanged, this, + &CircularSurvey::coordinateHasRelativeAltitudeChanged); + connect(&_cameraCalc, &CameraCalc::distanceToSurfaceRelativeChanged, this, + &CircularSurvey::exitCoordinateHasRelativeAltitudeChanged); } CircularSurvey::~CircularSurvey() {} diff --git a/src/Wima/StateMachine.cpp b/src/Wima/StateMachine.cpp index 4cb6abdf6988b84eee152c95415ee890abaac7c6..b6fb708a8fdbf869e4b56306d280010617636e75 100644 --- a/src/Wima/StateMachine.cpp +++ b/src/Wima/StateMachine.cpp @@ -26,6 +26,8 @@ void StateMachine::updateState(EVENT e) { case EVENT::INIT_DONE: setState(STATE::NEEDS_J_AREA_UPDATE); break; + case EVENT::M_AREA_NOT_READY: + case EVENT::M_AREA_READY: case EVENT::M_AREA_PATH_CHANGED: case EVENT::S_AREA_PATH_CHANGED: case EVENT::CORRIDOR_PATH_CHANGED: @@ -34,20 +36,52 @@ void StateMachine::updateState(EVENT e) { case EVENT::J_AREA_UPDATED: case EVENT::DEPOT_CHANGED: case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: case EVENT::SURVEY_UPDATE_TRIGGERED: case EVENT::SURVEY_UPDATED: + case EVENT::PATH_CHANGED: case EVENT::PATH_UPDATED: break; - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown event: " << e; Q_ASSERT(false); + } + break; // STATE::NEEDS_INIT + case STATE::WAITING_FOR_TILE_UPDATE: + switch (e) { + case EVENT::INIT_DONE: + case EVENT::M_AREA_NOT_READY: break; + case EVENT::M_AREA_READY: + setState(STATE::NEEDS_J_AREA_UPDATE); + break; + case EVENT::M_AREA_PATH_CHANGED: + case EVENT::S_AREA_PATH_CHANGED: + case EVENT::CORRIDOR_PATH_CHANGED: + case EVENT::M_AREA_TILES_CHANGED: + case EVENT::M_AREA_PROGRESS_CHANGED: + case EVENT::J_AREA_UPDATED: + case EVENT::DEPOT_CHANGED: + case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: + case EVENT::SURVEY_UPDATE_TRIGGERED: + case EVENT::SURVEY_UPDATED: + case EVENT::PATH_CHANGED: + case EVENT::PATH_UPDATED: + break; + qCCritical(WimaPlanerLog) + << "StateMachine::updateState: Unknown event: " << e; + Q_ASSERT(false); } break; // STATE::NEEDS_INIT case STATE::NEEDS_J_AREA_UPDATE: switch (e) { case EVENT::INIT_DONE: + break; + case EVENT::M_AREA_NOT_READY: + setState(STATE::WAITING_FOR_TILE_UPDATE); + break; + case EVENT::M_AREA_READY: case EVENT::M_AREA_PATH_CHANGED: case EVENT::S_AREA_PATH_CHANGED: case EVENT::CORRIDOR_PATH_CHANGED: @@ -58,20 +92,24 @@ void StateMachine::updateState(EVENT e) { setState(STATE::NEEDS_SURVEY_UPDATE); case EVENT::DEPOT_CHANGED: case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: case EVENT::SURVEY_UPDATE_TRIGGERED: case EVENT::SURVEY_UPDATED: + case EVENT::PATH_CHANGED: case EVENT::PATH_UPDATED: break; - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown event: " << e; Q_ASSERT(false); - break; } break; // STATE::NEEDS_J_AREA_UPDATE case STATE::NEEDS_SURVEY_UPDATE: switch (e) { case EVENT::INIT_DONE: + case EVENT::M_AREA_NOT_READY: + setState(STATE::WAITING_FOR_TILE_UPDATE); + break; + case EVENT::M_AREA_READY: case EVENT::M_AREA_PATH_CHANGED: case EVENT::S_AREA_PATH_CHANGED: case EVENT::CORRIDOR_PATH_CHANGED: @@ -82,23 +120,27 @@ void StateMachine::updateState(EVENT e) { case EVENT::J_AREA_UPDATED: case EVENT::DEPOT_CHANGED: case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: break; case EVENT::SURVEY_UPDATE_TRIGGERED: setState(STATE::WAITING_FOR_SURVEY_UPDATE); break; case EVENT::SURVEY_UPDATED: + case EVENT::PATH_CHANGED: case EVENT::PATH_UPDATED: break; - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown event: " << e; Q_ASSERT(false); - break; } break; // STATE::NEEDS_SURVEY_UPDATE case STATE::WAITING_FOR_SURVEY_UPDATE: switch (e) { case EVENT::INIT_DONE: + case EVENT::M_AREA_NOT_READY: + setState(STATE::WAITING_FOR_TILE_UPDATE); + break; + case EVENT::M_AREA_READY: case EVENT::M_AREA_PATH_CHANGED: case EVENT::S_AREA_PATH_CHANGED: case EVENT::CORRIDOR_PATH_CHANGED: @@ -109,24 +151,28 @@ void StateMachine::updateState(EVENT e) { case EVENT::J_AREA_UPDATED: case EVENT::DEPOT_CHANGED: case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: setState(STATE::NEEDS_SURVEY_UPDATE); break; case EVENT::SURVEY_UPDATE_TRIGGERED: break; case EVENT::SURVEY_UPDATED: setState(STATE::NEEDS_PATH_UPDATE); + case EVENT::PATH_CHANGED: case EVENT::PATH_UPDATED: break; - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown event: " << e; Q_ASSERT(false); - break; } break; // STATE::WAYTING_FOR_SURVEY_UPDATE case STATE::NEEDS_PATH_UPDATE: switch (e) { case EVENT::INIT_DONE: + case EVENT::M_AREA_NOT_READY: + setState(STATE::WAITING_FOR_TILE_UPDATE); + break; + case EVENT::M_AREA_READY: case EVENT::M_AREA_PATH_CHANGED: case EVENT::S_AREA_PATH_CHANGED: case EVENT::CORRIDOR_PATH_CHANGED: @@ -137,26 +183,30 @@ void StateMachine::updateState(EVENT e) { case EVENT::J_AREA_UPDATED: case EVENT::DEPOT_CHANGED: case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: setState(STATE::NEEDS_SURVEY_UPDATE); break; case EVENT::SURVEY_UPDATE_TRIGGERED: setState(STATE::WAITING_FOR_SURVEY_UPDATE); break; case EVENT::SURVEY_UPDATED: + case EVENT::PATH_CHANGED: break; case EVENT::PATH_UPDATED: setState(STATE::UP_TO_DATE); break; - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown event: " << e; Q_ASSERT(false); - break; } break; // STATE::NEEDS_PATH_UPDATE case STATE::UP_TO_DATE: switch (e) { case EVENT::INIT_DONE: + case EVENT::M_AREA_NOT_READY: + setState(STATE::WAITING_FOR_TILE_UPDATE); + break; + case EVENT::M_AREA_READY: case EVENT::M_AREA_PATH_CHANGED: case EVENT::S_AREA_PATH_CHANGED: case EVENT::CORRIDOR_PATH_CHANGED: @@ -167,52 +217,93 @@ void StateMachine::updateState(EVENT e) { case EVENT::J_AREA_UPDATED: case EVENT::DEPOT_CHANGED: case EVENT::SURVEY_DESTROYED: + case EVENT::MISSION_ITEMS_DESTROYED: setState(STATE::NEEDS_SURVEY_UPDATE); break; case EVENT::SURVEY_UPDATE_TRIGGERED: setState(STATE::WAITING_FOR_SURVEY_UPDATE); break; case EVENT::SURVEY_UPDATED: + case EVENT::PATH_CHANGED: setState(STATE::NEEDS_PATH_UPDATE); break; case EVENT::PATH_UPDATED: break; - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown event: " << e; Q_ASSERT(false); - break; } break; // STATE::UP_TO_DATE - default: qCCritical(WimaPlanerLog) << "StateMachine::updateState: Unknown state: " << this->_state; Q_ASSERT(false); - break; } } -bool StateMachine::upToDate() { return this->_state == STATE::UP_TO_DATE; } +bool StateMachine::upToDate() { return upToDate(this->_state); } + +bool StateMachine::surveyReady() { return surveyReady(this->_state); } void StateMachine::setState(STATE s) { if (this->_state != s) { auto oldState = this->_state; this->_state = s; emit stateChanged(); - if (oldState == STATE::UP_TO_DATE || s == STATE::UP_TO_DATE) { + if (upToDate(oldState) != upToDate(s)) { emit upToDateChanged(); } + if (surveyReady(oldState) != surveyReady(s)) { + emit surveyReady(); + } qCDebug(WimaPlanerLog) << "StateMachine::setState():" << oldState << "->" << s; } } -QDebug &operator<<(QDebug &ds, STATE s) { +bool StateMachine::surveyReady(STATE s) { + // Using a switch to enable compiler checking of used states. + bool value = false; + switch (s) { + case STATE::NEEDS_INIT: + case STATE::WAITING_FOR_TILE_UPDATE: + case STATE::NEEDS_J_AREA_UPDATE: + case STATE::NEEDS_SURVEY_UPDATE: + case STATE::WAITING_FOR_SURVEY_UPDATE: + break; + case STATE::NEEDS_PATH_UPDATE: + case STATE::UP_TO_DATE: + value = true; + break; + } + return value; +} + +bool StateMachine::upToDate(STATE s) { + // Using a switch to enable compiler checking of used states. + bool value = false; switch (s) { + case STATE::NEEDS_INIT: + case STATE::WAITING_FOR_TILE_UPDATE: + case STATE::NEEDS_J_AREA_UPDATE: + case STATE::NEEDS_SURVEY_UPDATE: + case STATE::WAITING_FOR_SURVEY_UPDATE: + case STATE::NEEDS_PATH_UPDATE: + break; + case STATE::UP_TO_DATE: + value = true; + break; + } + return value; +} +QDebug &operator<<(QDebug &ds, STATE s) { + switch (s) { case STATE::NEEDS_INIT: ds << "NEEDS_INIT"; break; + case STATE::WAITING_FOR_TILE_UPDATE: + ds << "WAITING_FOR_TILE_UPDATE"; + break; case STATE::NEEDS_J_AREA_UPDATE: ds << "NEEDS_J_AREA_UPDATE"; break; @@ -237,6 +328,12 @@ QDebug &operator<<(QDebug &ds, EVENT s) { case EVENT::INIT_DONE: ds << "INIT_DONE"; break; + case EVENT::M_AREA_NOT_READY: + ds << "M_AREA_NOT_READY"; + break; + case EVENT::M_AREA_READY: + ds << "M_AREA_READY"; + break; case EVENT::M_AREA_PATH_CHANGED: ds << "M_AREA_PATH_CHANGED"; break; @@ -261,12 +358,18 @@ QDebug &operator<<(QDebug &ds, EVENT s) { case EVENT::SURVEY_DESTROYED: ds << "SURVEY_DESTROYED"; break; + case EVENT::MISSION_ITEMS_DESTROYED: + ds << "MISSION_ITEMS_DESTROYED"; + break; case EVENT::SURVEY_UPDATE_TRIGGERED: ds << "SURVEY_UPDATE_TRIGGERED"; break; case EVENT::SURVEY_UPDATED: ds << "SURVEY_UPDATED"; break; + case EVENT::PATH_CHANGED: + ds << "PATH_CHANGED"; + break; case EVENT::PATH_UPDATED: ds << "PATH_UPDATED"; break; diff --git a/src/Wima/StateMachine.h b/src/Wima/StateMachine.h index 2f65006274c0089b0aae81112f5f46486f2a2692..f98642ebff50c236f2cc42bd6731596a6e7a59b1 100644 --- a/src/Wima/StateMachine.h +++ b/src/Wima/StateMachine.h @@ -7,6 +7,7 @@ namespace wima_planer_detail { enum class STATE { NEEDS_INIT, + WAITING_FOR_TILE_UPDATE, NEEDS_J_AREA_UPDATE, NEEDS_SURVEY_UPDATE, WAITING_FOR_SURVEY_UPDATE, @@ -18,6 +19,8 @@ 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, @@ -26,9 +29,11 @@ enum class EVENT { J_AREA_UPDATED, DEPOT_CHANGED, SURVEY_DESTROYED, + MISSION_ITEMS_DESTROYED, SURVEY_UPDATE_TRIGGERED, SURVEY_UPDATED, - PATH_UPDATED, + PATH_CHANGED, + PATH_UPDATED }; QDebug &operator<<(QDebug &ds, EVENT s); @@ -41,13 +46,17 @@ public: STATE state(); void updateState(EVENT e); bool upToDate(); + bool surveyReady(); signals: void stateChanged(); void upToDateChanged(); + void surveyReadyChanged(); private: void setState(STATE s); + bool surveyReady(STATE s); + bool upToDate(STATE s); STATE _state; }; diff --git a/src/Wima/WimaPlaner.cc b/src/Wima/WimaPlaner.cc index 03f6e8f36a6e2b9b4725cd27581f4a777077c9f5..53c5037d4b1955569f0aaf1b8e04373600a9275f 100644 --- a/src/Wima/WimaPlaner.cc +++ b/src/Wima/WimaPlaner.cc @@ -42,13 +42,15 @@ WimaPlaner::WimaPlaner(QObject *parent) _copySAreaToSurvey(true), _corridorChanged(true), _joinedArea(this), _arrivalPathLength(0), _returnPathLength(0), _survey(nullptr), _surveyChanged(true), _synchronized(false), _nemoInterface(this), - _stateMachine(new StateMachine) { + _stateMachine(new StateMachine), _areasMonitored(false), + _missionControllerMonitored(false) { connect(this, &WimaPlaner::currentPolygonIndexChanged, this, &WimaPlaner::updatePolygonInteractivity); - // Enable monitoring (state update) - enableMonitoring(); + // Monitoring. + enableAreaMonitoring(); + // Mission controller not set at this point. Not enabling monitoring. #ifndef NDEBUG // for debugging and testing purpose, remove if not needed anymore @@ -67,6 +69,8 @@ WimaPlaner::WimaPlaner(QObject *parent) // StateMachine connect(this->_stateMachine.get(), &StateMachine::upToDateChanged, this, &WimaPlaner::needsUpdateChanged); + connect(this->_stateMachine.get(), &StateMachine::surveyReadyChanged, this, + &WimaPlaner::readyForSynchronizationChanged); } WimaPlaner::~WimaPlaner() {} @@ -115,13 +119,19 @@ WimaBridge *WimaPlaner::wimaBridge() { return _wimaBridge; } NemoInterface *WimaPlaner::nemoInterface() { return &_nemoInterface; } void WimaPlaner::setMasterController(PlanMasterController *masterC) { - _masterController = masterC; - emit masterControllerChanged(); + if (_masterController != masterC) { + _masterController = masterC; + emit masterControllerChanged(); + } } void WimaPlaner::setMissionController(MissionController *missionC) { - _missionController = missionC; - emit missionControllerChanged(); + if (_missionController != missionC) { + disableMissionControllerMonitoring(); + _missionController = missionC; + enableMissionControllerMonitoring(); + emit missionControllerChanged(); + } } void WimaPlaner::setCurrentPolygonIndex(int index) { @@ -144,6 +154,10 @@ bool WimaPlaner::synchronized() { return _synchronized; } bool WimaPlaner::needsUpdate() { return !this->_stateMachine->upToDate(); } +bool WimaPlaner::readyForSynchronization() { + return this->_stateMachine->surveyReady(); +} + WimaPlaner *WimaPlaner::thisPointer() { return this; } void WimaPlaner::removeArea(int index) { @@ -246,8 +260,15 @@ void WimaPlaner::_update() { switch (this->_stateMachine->state()) { case STATE::NEEDS_INIT: { - this->_stateMachine->updateState(EVENT::INIT_DONE); - this->_update(); + if (this->_measurementArea.ready()) { + this->_stateMachine->updateState(EVENT::INIT_DONE); + this->_update(); + } else { + this->_stateMachine->updateState(EVENT::M_AREA_NOT_READY); + } + } break; + + case STATE::WAITING_FOR_TILE_UPDATE: { } break; case STATE::NEEDS_J_AREA_UPDATE: { @@ -415,11 +436,9 @@ void WimaPlaner::_update() { return; } _arrivalPathLength = path.size() - 1; - int sequenceNumber = 0; for (int i = 1; i < path.count() - 1; i++) { - sequenceNumber = _missionController->insertSimpleMissionItem( + (void)_missionController->insertSimpleMissionItem( path[i], missionItems->count() - 1); - _missionController->setCurrentPlanViewIndex(sequenceNumber, true); } // calculate return path @@ -437,15 +456,16 @@ void WimaPlaner::_update() { _returnPathLength = path.size() - 1; // -1: fist item is last measurement point for (int i = 1; i < path.count() - 1; i++) { - sequenceNumber = _missionController->insertSimpleMissionItem( + (void)_missionController->insertSimpleMissionItem( path[i], missionItems->count()); - _missionController->setCurrentPlanViewIndex(sequenceNumber, true); } + // Add waypoint (rover ignores land command). + (void)_missionController->insertSimpleMissionItem(depot, + missionItems->count()); // create land position item - sequenceNumber = _missionController->insertSimpleMissionItem( - depot, missionItems->count()); - _missionController->setCurrentPlanViewIndex(sequenceNumber, true); + (void)_missionController->insertSimpleMissionItem(depot, + missionItems->count()); SimpleMissionItem *landItem = qobject_cast( missionItems->get(missionItems->count() - 1)); if (landItem == nullptr) { @@ -495,6 +515,14 @@ void WimaPlaner::mAreaProgressChangedHandler() { void WimaPlaner::mAreaProgressAcceptedHandler() { this->_update(); } +void WimaPlaner::mAreaReadyChangedHandler() { + if (this->_measurementArea.ready()) { + this->_stateMachine->updateState(EVENT::M_AREA_READY); + } else { + this->_stateMachine->updateState(EVENT::M_AREA_NOT_READY); + } +} + void WimaPlaner::sAreaPathChangedHandler() { this->_stateMachine->updateState(EVENT::S_AREA_PATH_CHANGED); } @@ -507,6 +535,29 @@ void WimaPlaner::depotChangedHandler() { this->_stateMachine->updateState(EVENT::DEPOT_CHANGED); } +void WimaPlaner::missionControllerVisualItemsChangedHandler() { + // Search for survey. + auto surveyIndex = _missionController->visualItems()->indexOf(_survey); + if (surveyIndex < 0) { + // survey not found. + this->_stateMachine->updateState(EVENT::SURVEY_DESTROYED); + } else { + this->_stateMachine->updateState(EVENT::PATH_CHANGED); + } +} + +void WimaPlaner::missionControllerWaypointPathChangedHandler() { + missionControllerVisualItemsChangedHandler(); +} + +void WimaPlaner::missionControllerNewItemsFromVehicleHandler() { + this->_stateMachine->updateState(EVENT::MISSION_ITEMS_DESTROYED); +} + +void WimaPlaner::missionControllerMissionItemCountChangedHandler() { + missionControllerVisualItemsChangedHandler(); +} + void WimaPlaner::saveToCurrent() { saveToFile(_currentFile); } void WimaPlaner::saveToFile(const QString &filename) { @@ -554,8 +605,13 @@ bool WimaPlaner::loadFromCurrent() { return loadFromFile(_currentFile); } bool WimaPlaner::loadFromFile(const QString &filename) { // Remove obsolete connections. - disableMonitoring(); - CommandRAII onExit([this] { this->enableMonitoring(); }); + disableAreaMonitoring(); + disableMissionControllerMonitoring(); + CommandRAII onExit([this] { + this->enableAreaMonitoring(); + this->enableMissionControllerMonitoring(); + }); + // disconnect old survey if (_survey != nullptr) { disconnect(_survey, &CircularSurvey::calculatingChanged, this, @@ -734,7 +790,7 @@ void WimaPlaner::updatePolygonInteractivity(int index) { void WimaPlaner::synchronize() { if (_wimaBridge != nullptr) { - if (!needsUpdate()) { + if (readyForSynchronization()) { auto planData = toPlanData(); if (planData) { (void)_wimaBridge->setWimaPlanData(planData); @@ -773,36 +829,87 @@ void WimaPlaner::setSynchronized(bool s) { } } -void WimaPlaner::enableMonitoring() { - connect(&this->_measurementArea, &WimaArea::pathChanged, this, - &WimaPlaner::mAreaPathChangedHandler); - connect(&this->_measurementArea, &WimaMeasurementArea::tilesChanged, this, - &WimaPlaner::mAreaTilesChangedHandler); - connect(&this->_measurementArea, &WimaMeasurementArea::progressChanged, this, - &WimaPlaner::mAreaProgressChangedHandler); - connect(&this->_measurementArea, &WimaMeasurementArea::progressAccepted, this, - &WimaPlaner::mAreaProgressAcceptedHandler); - connect(&this->_serviceArea, &WimaArea::pathChanged, this, - &WimaPlaner::sAreaPathChangedHandler); - connect(&this->_serviceArea, &WimaServiceArea::depotChanged, this, - &WimaPlaner::depotChangedHandler); - connect(&this->_corridor, &WimaArea::pathChanged, this, - &WimaPlaner::corridorPathChangedHandler); -} - -void WimaPlaner::disableMonitoring() { - disconnect(&this->_measurementArea, &WimaArea::pathChanged, this, - &WimaPlaner::mAreaPathChangedHandler); - disconnect(&this->_measurementArea, &WimaMeasurementArea::tilesChanged, this, - &WimaPlaner::mAreaTilesChangedHandler); - disconnect(&this->_measurementArea, &WimaMeasurementArea::progressChanged, - this, &WimaPlaner::mAreaProgressChangedHandler); - disconnect(&this->_serviceArea, &WimaArea::pathChanged, this, - &WimaPlaner::sAreaPathChangedHandler); - disconnect(&this->_serviceArea, &WimaServiceArea::depotChanged, this, - &WimaPlaner::depotChangedHandler); - disconnect(&this->_corridor, &WimaArea::pathChanged, this, - &WimaPlaner::corridorPathChangedHandler); +void WimaPlaner::enableAreaMonitoring() { + if (!areasMonitored()) { + connect(&this->_measurementArea, &WimaArea::pathChanged, this, + &WimaPlaner::mAreaPathChangedHandler); + connect(&this->_measurementArea, &WimaMeasurementArea::tilesChanged, this, + &WimaPlaner::mAreaTilesChangedHandler); + connect(&this->_measurementArea, &WimaMeasurementArea::progressChanged, + this, &WimaPlaner::mAreaProgressChangedHandler); + connect(&this->_measurementArea, &WimaMeasurementArea::progressAccepted, + this, &WimaPlaner::mAreaProgressAcceptedHandler); + connect(&this->_measurementArea, &WimaMeasurementArea::readyChanged, this, + &WimaPlaner::mAreaReadyChangedHandler); + connect(&this->_serviceArea, &WimaArea::pathChanged, this, + &WimaPlaner::sAreaPathChangedHandler); + connect(&this->_serviceArea, &WimaServiceArea::depotChanged, this, + &WimaPlaner::depotChangedHandler); + connect(&this->_corridor, &WimaArea::pathChanged, this, + &WimaPlaner::corridorPathChangedHandler); + this->_areasMonitored = true; + } +} + +void WimaPlaner::disableAreaMonitoring() { + if (areasMonitored()) { + disconnect(&this->_measurementArea, &WimaArea::pathChanged, this, + &WimaPlaner::mAreaPathChangedHandler); + disconnect(&this->_measurementArea, &WimaMeasurementArea::tilesChanged, + this, &WimaPlaner::mAreaTilesChangedHandler); + disconnect(&this->_measurementArea, &WimaMeasurementArea::progressChanged, + this, &WimaPlaner::mAreaProgressChangedHandler); + disconnect(&this->_measurementArea, &WimaMeasurementArea::progressAccepted, + this, &WimaPlaner::mAreaProgressAcceptedHandler); + disconnect(&this->_measurementArea, &WimaMeasurementArea::readyChanged, + this, &WimaPlaner::mAreaReadyChangedHandler); + disconnect(&this->_serviceArea, &WimaArea::pathChanged, this, + &WimaPlaner::sAreaPathChangedHandler); + disconnect(&this->_serviceArea, &WimaServiceArea::depotChanged, this, + &WimaPlaner::depotChangedHandler); + disconnect(&this->_corridor, &WimaArea::pathChanged, this, + &WimaPlaner::corridorPathChangedHandler); + this->_areasMonitored = false; + } +} + +void WimaPlaner::enableMissionControllerMonitoring() { + if (!missionControllerMonitored() && this->missionController() != nullptr) { + connect(this->missionController(), &MissionController::visualItemsChanged, + this, &WimaPlaner::missionControllerVisualItemsChangedHandler); + connect(this->missionController(), &MissionController::waypointPathChanged, + this, &WimaPlaner::missionControllerWaypointPathChangedHandler); + connect(this->missionController(), &MissionController::newItemsFromVehicle, + this, &WimaPlaner::missionControllerNewItemsFromVehicleHandler); + connect(this->missionController(), + &MissionController::missionItemCountChanged, this, + &WimaPlaner::missionControllerMissionItemCountChangedHandler); + this->_missionControllerMonitored = true; + } +} + +void WimaPlaner::disableMissionControllerMonitoring() { + if (missionControllerMonitored() && this->missionController() != nullptr) { + disconnect(this->missionController(), + &MissionController::visualItemsChanged, this, + &WimaPlaner::missionControllerVisualItemsChangedHandler); + disconnect(this->missionController(), + &MissionController::waypointPathChanged, this, + &WimaPlaner::missionControllerWaypointPathChangedHandler); + disconnect(this->missionController(), + &MissionController::newItemsFromVehicle, this, + &WimaPlaner::missionControllerNewItemsFromVehicleHandler); + disconnect(this->missionController(), + &MissionController::missionItemCountChanged, this, + &WimaPlaner::missionControllerMissionItemCountChangedHandler); + this->_missionControllerMonitored = false; + } +} + +bool WimaPlaner::areasMonitored() { return this->_areasMonitored; } + +bool WimaPlaner::missionControllerMonitored() { + return this->_missionControllerMonitored; } void WimaPlaner::resetAllInteractive() { diff --git a/src/Wima/WimaPlaner.h b/src/Wima/WimaPlaner.h index 09293f598b7868052a98212b6529e3ce9ada5fb7..f8f7e788b6ddb319ac00dab9b7f4731f248a9b99 100644 --- a/src/Wima/WimaPlaner.h +++ b/src/Wima/WimaPlaner.h @@ -56,6 +56,8 @@ public: 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) // Property accessors PlanMasterController *masterController(void); @@ -71,6 +73,7 @@ public: NemoInterface *nemoInterface(void); bool synchronized(); bool needsUpdate(); + bool readyForSynchronization(); // Property setters void setMasterController(PlanMasterController *masterController); @@ -116,6 +119,7 @@ signals: void wimaBridgeChanged(); void synchronizedChanged(void); void needsUpdateChanged(void); + void readyForSynchronizationChanged(void); private slots: void updatePolygonInteractivity(int index); @@ -127,9 +131,14 @@ private slots: void mAreaTilesChangedHandler(); void mAreaProgressChangedHandler(); void mAreaProgressAcceptedHandler(); + void mAreaReadyChangedHandler(); void sAreaPathChangedHandler(); void corridorPathChangedHandler(); void depotChangedHandler(); + void missionControllerVisualItemsChangedHandler(); + void missionControllerWaypointPathChangedHandler(); + void missionControllerNewItemsFromVehicleHandler(); + void missionControllerMissionItemCountChangedHandler(); #ifndef NDEBUG void autoLoadMission(void); @@ -147,8 +156,12 @@ private: const QGeoCoordinate &destination, QVector &path); void setSynchronized(bool s); - void enableMonitoring(); - void disableMonitoring(); + void enableAreaMonitoring(); + void disableAreaMonitoring(); + void enableMissionControllerMonitoring(); + void disableMissionControllerMonitoring(); + bool areasMonitored(); + bool missionControllerMonitored(); // Member Variables PlanMasterController *_masterController; @@ -189,4 +202,6 @@ private: // State QScopedPointer _stateMachine; + bool _areasMonitored; + bool _missionControllerMonitored; }; diff --git a/src/WimaView/WimaToolBar.qml b/src/WimaView/WimaToolBar.qml index 9a26c954b35cef3c9a32cd6160219afc351f45b0..6aae857745d3f9a4181e327f6b8c356051674304 100644 --- a/src/WimaView/WimaToolBar.qml +++ b/src/WimaView/WimaToolBar.qml @@ -138,7 +138,7 @@ Rectangle { anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: logoRow.right - anchors.right: uploadButton.left + anchors.right: buttonsRow.left font.pointSize: ScreenTools.largeFontPointSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter @@ -153,7 +153,7 @@ Rectangle { anchors.leftMargin: _margins anchors.rightMargin: _margins anchors.left: logoRow.right - anchors.right: uploadButton.visible ? uploadButton.left : parent.right + anchors.right: buttonsRow.left columnSpacing: 0 columns: 4 @@ -346,35 +346,50 @@ Rectangle { } } - QGCButton { - id: uploadButton + Row { + id:buttonsRow anchors.rightMargin: _margins anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - text: wimaPlaner && wimaPlaner.needsUpdate ? qsTr("Update") : qsTr("Sync.") - enabled: true - onClicked: { - if (wimaPlaner){ - if (!wimaPlaner.needsUpdate) { - wimaPlaner.synchronize() - } else { - wimaPlaner.update() + spacing: _margins + + QGCButton { + id: uploadButton + text: qsTr("Upload") + enabled: true + onClicked: { + if (wimaPlaner){ + if (wimaPlaner.readyForSynchronization) { + wimaPlaner.synchronize() + planMasterController.sendToVehicle() + } } } - } - PropertyAnimation on opacity { - easing.type: Easing.OutQuart - from: 0.5 - to: 1 - loops: Animation.Infinite - running: wimaPlaner ? wimaPlaner.needsUpdate || - (!wimaPlaner.needsUpdate && !wimaPlaner.synchronized) - : false - alwaysRunToEnd: true - duration: 2000 - } - } + PropertyAnimation on opacity { + easing.type: Easing.OutQuart + from: 0.5 + to: 1 + loops: Animation.Infinite + running: wimaPlaner ? (wimaPlaner.readyForSynchronization + && !wimaPlaner.synchronized) + : false + alwaysRunToEnd: true + duration: 2000 + } + } // uploadButton + + QGCButton { + id: updateButton + text: qsTr("Update") + enabled: true + onClicked: { + if (wimaPlaner){ + wimaPlaner.update() + } + } + } // updateButton + } // buttonRow // Small mission download progress bar Rectangle {