diff --git a/ChangeLog.md b/ChangeLog.md index 521030f752c392695771a4dfd9bae41471cfdb4b..ab53e94363c42b8d4c4d53ee8a87e8d4016ce8f0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,10 +2,12 @@ Note: This file only contains high level features or important fixes. -## 3.6 +## 4.0 -### 3.6.0 - Daily Build +### 4.0.0 - Daily Build +* Plan: ROI button will switch to Cancel ROI at appropriate times +* Plan: When ROI is selected the flight path lines which are affected by the ROI will change color * ADSB: Added support for connecting to SBS server. Adds support for ADSB data from USB SDR Dongle running 'dump1090 --net' for example. * Toolbar: Scrollable left/right on small screens like phones * Plan View: New create plan UI for initial plan creation diff --git a/src/FlightMap/MapItems/MissionLineView.qml b/src/FlightMap/MapItems/MissionLineView.qml index 6371aa44834ba4c452790807925938b13f779bcb..4e7bf38cf670ccdf3c9c2eceea4bb49bfb962332 100644 --- a/src/FlightMap/MapItems/MissionLineView.qml +++ b/src/FlightMap/MapItems/MissionLineView.qml @@ -17,11 +17,11 @@ import QGroundControl.Palette 1.0 /// The MissionLineView control is used to add lines between mission items MapItemView { + property bool showSpecialVisual: false delegate: MapPolyline { line.width: 3 - line.color: "#be781c" // Hack, can't get palette to work in here + line.color: object && showSpecialVisual && object.specialVisual ? "green" : "#be781c" // Hack, can't get palette to work in here z: QGroundControl.zOrderWaypointLines - - path: object && object.coordinate1.isValid && object.coordinate2.isValid ? [ object.coordinate1, object.coordinate2 ] : [] + path: object && object.coordinate1.isValid && object.coordinate2.isValid ? [ object.coordinate1, object.coordinate2 ] : [] } } diff --git a/src/MissionManager/CorridorScanPlanCreator.cc b/src/MissionManager/CorridorScanPlanCreator.cc index d08d642b76fa720a42667b5ad4e39889c6296119..9eac0b780338db6f7843cac4086323d07d52e480 100644 --- a/src/MissionManager/CorridorScanPlanCreator.cc +++ b/src/MissionManager/CorridorScanPlanCreator.cc @@ -24,5 +24,5 @@ void CorridorScanPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord) VisualMissionItem* takeoffItem = _missionController->insertTakeoffItem(mapCenterCoord, -1); _missionController->insertComplexMissionItem(MissionController::patternCorridorScanName, mapCenterCoord, -1); _missionController->insertLandItem(mapCenterCoord, -1); - _missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true); + _missionController->setCurrentPlanViewSeqNum(takeoffItem->sequenceNumber(), true); } diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index c1a72429ae8fac83d644b15be42727fefc42f280..5d8b5f7eebee81deb33d23c4f23a0121707578e4 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -68,7 +68,8 @@ MissionController::MissionController(PlanMasterController* masterController, QOb , _inRecalcSequence (false) , _appSettings (qgcApp()->toolbox()->settingsManager()->appSettings()) , _progressPct (0) - , _currentPlanViewIndex (-1) + , _currentPlanViewSeqNum (-1) + , _currentPlanViewVIIndex (-1) , _currentPlanViewItem (nullptr) , _splitSegment (nullptr) { @@ -380,7 +381,7 @@ VisualMissionItem* MissionController::_insertSimpleMissionItemWorker(QGeoCoordin _recalcAllWithCoordinate(coordinate); if (makeCurrentItem) { - setCurrentPlanViewIndex(newItem->sequenceNumber(), true); + setCurrentPlanViewSeqNum(newItem->sequenceNumber(), true); } return newItem; @@ -418,7 +419,7 @@ VisualMissionItem* MissionController::insertTakeoffItem(QGeoCoordinate /*coordin _recalcAll(); if (makeCurrentItem) { - setCurrentPlanViewIndex(newItem->sequenceNumber(), true); + setCurrentPlanViewSeqNum(newItem->sequenceNumber(), true); } return newItem; @@ -437,10 +438,26 @@ VisualMissionItem* MissionController::insertLandItem(QGeoCoordinate coordinate, VisualMissionItem* MissionController::insertROIMissionItem(QGeoCoordinate coordinate, int visualItemIndex, bool makeCurrentItem) { - MAV_CMD command = _controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(MAV_CMD_DO_SET_ROI_LOCATION) ? - MAV_CMD_DO_SET_ROI_LOCATION : - MAV_CMD_DO_SET_ROI; - return _insertSimpleMissionItemWorker(coordinate, command, visualItemIndex, makeCurrentItem); + SimpleMissionItem* simpleItem = qobject_cast(_insertSimpleMissionItemWorker(coordinate, MAV_CMD_DO_SET_ROI_LOCATION, visualItemIndex, makeCurrentItem)); + + if (!_controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(MAV_CMD_DO_SET_ROI_LOCATION)) { + simpleItem->setCommand(MAV_CMD_DO_SET_ROI) ; + simpleItem->missionItem().setParam1(MAV_ROI_LOCATION); + } + _recalcROISpecialVisuals(); + return simpleItem; +} + +VisualMissionItem* MissionController::insertCancelROIMissionItem(int visualItemIndex, bool makeCurrentItem) +{ + SimpleMissionItem* simpleItem = qobject_cast(_insertSimpleMissionItemWorker(QGeoCoordinate(), MAV_CMD_DO_SET_ROI_NONE, visualItemIndex, makeCurrentItem)); + + if (!_controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(MAV_CMD_DO_SET_ROI_NONE)) { + simpleItem->setCommand(MAV_CMD_DO_SET_ROI) ; + simpleItem->missionItem().setParam1(MAV_ROI_NONE); + } + _recalcROISpecialVisuals(); + return simpleItem; } VisualMissionItem* MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate mapCenterCoordinate, int visualItemIndex, bool makeCurrentItem) @@ -536,19 +553,19 @@ void MissionController::_insertComplexMissionItemWorker(const QGeoCoordinate& ma _recalcAllWithCoordinate(mapCenterCoordinate); if (makeCurrentItem) { - setCurrentPlanViewIndex(complexItem->sequenceNumber(), true); + setCurrentPlanViewSeqNum(complexItem->sequenceNumber(), true); } } -void MissionController::removeMissionItem(int index) +void MissionController::removeMissionItem(int viIndex) { - if (index <= 0 || index >= _visualItems->count()) { - qWarning() << "MissionController::removeMissionItem called with bad index - count:index" << _visualItems->count() << index; + if (viIndex <= 0 || viIndex >= _visualItems->count()) { + qWarning() << "MissionController::removeMissionItem called with bad index - count:index" << _visualItems->count() << viIndex; return; } - bool removeSurveyStyle = _visualItems->value(index) || _visualItems->value(index); - VisualMissionItem* item = qobject_cast(_visualItems->removeAt(index)); + bool removeSurveyStyle = _visualItems->value(viIndex) || _visualItems->value(viIndex); + VisualMissionItem* item = qobject_cast(_visualItems->removeAt(viIndex)); _deinitVisualItem(item); item->deleteLater(); @@ -1148,6 +1165,39 @@ CoordinateVector* MissionController::_addWaypointLineSegment(CoordVectHashTable& return coordVector; } +void MissionController::_recalcROISpecialVisuals(void) +{ + return; + VisualMissionItem* lastCoordinateItem = qobject_cast(_visualItems->get(0)); + bool roiActive = false; + + for (int i=1; i<_visualItems->count(); i++) { + VisualMissionItem* visualItem = qobject_cast(_visualItems->get(i)); + SimpleMissionItem* simpleItem = qobject_cast(visualItem); + VisualItemPair viPair; + + if (simpleItem) { + if (roiActive) { + if (_isROICancelItem(simpleItem)) { + roiActive = false; + } + } else { + if (_isROIBeginItem(simpleItem)) { + roiActive = true; + } + } + } + + if (visualItem->specifiesCoordinate() && !visualItem->isStandaloneCoordinate()) { + viPair = VisualItemPair(lastCoordinateItem, visualItem); + if (_linesTable.contains(viPair)) { + _linesTable[viPair]->setSpecialVisual(roiActive); + } + lastCoordinateItem = visualItem; + } + } +} + void MissionController::_recalcWaypointLines(void) { VisualItemPair lastSegmentVisualItemPair; @@ -1157,7 +1207,8 @@ void MissionController::_recalcWaypointLines(void) bool linkEndToHome = false; bool linkStartToHome = _managerVehicle->rover() ? true : false; bool foundRTL = false; - bool homePositionValid = _settingsItem->coordinate().isValid(); + bool homePositionValid = _settingsItem->coordinate().isValid(); + bool roiActive = false; qCDebug(MissionControllerLog) << "_recalcWaypointLines homePositionValid" << homePositionValid; @@ -1175,10 +1226,20 @@ void MissionController::_recalcWaypointLines(void) // Grovel through the list of items keeping track of things needed to correctly draw waypoints lines for (int i=1; i<_visualItems->count(); i++) { - VisualMissionItem* visualItem = qobject_cast(_visualItems->get(i)); - SimpleMissionItem* simpleItem = qobject_cast(visualItem); + VisualMissionItem* visualItem = qobject_cast(_visualItems->get(i)); + SimpleMissionItem* simpleItem = qobject_cast(visualItem); if (simpleItem) { + if (roiActive) { + if (_isROICancelItem(simpleItem)) { + roiActive = false; + } + } else { + if (_isROIBeginItem(simpleItem)) { + roiActive = true; + } + } + MAV_CMD command = simpleItem->mavCommand(); switch (command) { case MAV_CMD_NAV_TAKEOFF: @@ -1220,6 +1281,7 @@ void MissionController::_recalcWaypointLines(void) lastSegmentVisualItemPair = VisualItemPair(lastCoordinateItemBeforeRTL, visualItem); if (!_flyView || addDirectionArrow) { CoordinateVector* coordVector = _addWaypointLineSegment(old_table, lastSegmentVisualItemPair); + coordVector->setSpecialVisual(roiActive); if (addDirectionArrow) { _directionArrows.append(coordVector); } @@ -1240,7 +1302,8 @@ void MissionController::_recalcWaypointLines(void) if (_flyView) { _waypointPath.append(QVariant::fromValue(_settingsItem->coordinate())); } - _addWaypointLineSegment(old_table, lastSegmentVisualItemPair); + CoordinateVector* coordVector = _addWaypointLineSegment(old_table, lastSegmentVisualItemPair); + coordVector->setSpecialVisual(roiActive); } // Add direction arrow to last segment @@ -1736,7 +1799,7 @@ void MissionController::_initAllVisualItems(void) emit plannedHomePositionChanged(plannedHomePosition()); if (!_flyView) { - setCurrentPlanViewIndex(0, true); + setCurrentPlanViewSeqNum(0, true); } setDirty(false); @@ -2149,32 +2212,41 @@ void MissionController::_managerRemoveAllComplete(bool error) } } -int MissionController::currentPlanViewIndex(void) const +bool MissionController::_isROIBeginItem(SimpleMissionItem* simpleItem) { - return _currentPlanViewIndex; + return simpleItem->mavCommand() == MAV_CMD_DO_SET_ROI_LOCATION || + simpleItem->mavCommand() == MAV_CMD_DO_SET_ROI_WPNEXT_OFFSET || + (simpleItem->mavCommand() == MAV_CMD_DO_SET_ROI && + static_cast(simpleItem->missionItem().param1()) == MAV_ROI_LOCATION); } -VisualMissionItem* MissionController::currentPlanViewItem(void) const +bool MissionController::_isROICancelItem(SimpleMissionItem* simpleItem) { - return _currentPlanViewItem; + return simpleItem->mavCommand() == MAV_CMD_DO_SET_ROI_NONE || + (simpleItem->mavCommand() == MAV_CMD_DO_SET_ROI && + static_cast(simpleItem->missionItem().param1()) == MAV_ROI_NONE); } -void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) +void MissionController::setCurrentPlanViewSeqNum(int sequenceNumber, bool force) { - if (_visualItems && (force || sequenceNumber != _currentPlanViewIndex)) { - bool foundLand = false; - int takeoffIndex = -1; - int landIndex = -1; + if (_visualItems && (force || sequenceNumber != _currentPlanViewSeqNum)) { + bool foundLand = false; + int takeoffIndex = -1; + int landIndex = -1; _splitSegment = nullptr; _currentPlanViewItem = nullptr; - _currentPlanViewIndex = -1; + _currentPlanViewSeqNum = -1; + _currentPlanViewVIIndex = -1; _isInsertTakeoffValid = true; _isInsertLandValid = true; + _isROIActive = false; + _isROIBeginCurrentItem = false; _flyThroughCommandsAllowed = true; - for (int i = 0; i < _visualItems->count(); i++) { - VisualMissionItem* pVI = qobject_cast(_visualItems->get(i)); + for (int viIndex=0; viIndex<_visualItems->count(); viIndex++) { + VisualMissionItem* pVI = qobject_cast(_visualItems->get(viIndex)); + SimpleMissionItem* simpleItem = qobject_cast(pVI); if (sequenceNumber != 0 && pVI->sequenceNumber() <= sequenceNumber) { if (pVI->specifiesCoordinate() && !pVI->isStandaloneCoordinate()) { @@ -2184,12 +2256,11 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) } if (qobject_cast(pVI)) { - takeoffIndex = i; + takeoffIndex = viIndex; _isInsertTakeoffValid = false; } if (!foundLand) { - SimpleMissionItem* simpleItem = qobject_cast(pVI); if (simpleItem) { switch (simpleItem->mavCommand()) { case MAV_CMD_NAV_LAND: @@ -2197,7 +2268,7 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) case MAV_CMD_DO_LAND_START: case MAV_CMD_NAV_RETURN_TO_LAUNCH: foundLand = true; - landIndex = i; + landIndex = viIndex; break; default: break; @@ -2206,19 +2277,38 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) FixedWingLandingComplexItem* fwLanding = qobject_cast(pVI); if (fwLanding) { foundLand = true; - landIndex = i; + landIndex = viIndex; + } + } + } + + // ROI state handling + if (simpleItem) { + if (pVI->sequenceNumber() <= sequenceNumber) { + if (_isROIActive) { + if (_isROICancelItem(simpleItem)) { + _isROIActive = false; + } + } else { + if (_isROIBeginItem(simpleItem)) { + _isROIActive = true; + } } } + if (pVI->sequenceNumber() == sequenceNumber && _isROIBeginItem(simpleItem)) { + _isROIBeginCurrentItem = true; + } } if (pVI->sequenceNumber() == sequenceNumber) { pVI->setIsCurrentItem(true); _currentPlanViewItem = pVI; - _currentPlanViewIndex = sequenceNumber; + _currentPlanViewSeqNum = sequenceNumber; + _currentPlanViewVIIndex = viIndex; if (pVI->specifiesCoordinate() && !pVI->isStandaloneCoordinate()) { // Determine split segment used to display line split editing ui. - for (int j=i-1; j>0; j--) { + for (int j=viIndex-1; j>0; j--) { VisualMissionItem* pPrev = qobject_cast(_visualItems->get(j)); if (pPrev->specifiesCoordinate() && !pPrev->isStandaloneCoordinate()) { VisualItemPair splitPair(pPrev, pVI); @@ -2252,11 +2342,14 @@ void MissionController::setCurrentPlanViewIndex(int sequenceNumber, bool force) } } - emit currentPlanViewIndexChanged(); + emit currentPlanViewSeqNumChanged(); + emit currentPlanViewVIIndexChanged(); emit currentPlanViewItemChanged(); emit splitSegmentChanged(); emit isInsertTakeoffValidChanged(); emit isInsertLandValidChanged(); + emit isROIActiveChanged(); + emit isROIBeginCurrentItemChanged(); emit flyThroughCommandsAllowedChanged(); } } @@ -2349,16 +2442,3 @@ bool MissionController::isEmpty(void) const { return _visualItems->count() <= 1; } - -int MissionController::visualItemIndexFromSequenceNumber(int sequenceNumber) const -{ - for (int i=0; i<_visualItems->count(); i++) { - const VisualMissionItem* vi = _visualItems->value(i); - if (vi->sequenceNumber() == sequenceNumber) { - return i; - } - } - - qWarning() << "MissionController::getVisualItemIndex visual item not found"; - return 0; -} diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 310372060da80157ae7fadd0a0cf5ce531af934b..718521c849d2e2afd4c2f47a7086d8c9b548680f 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -77,7 +77,8 @@ public: Q_PROPERTY(int missionItemCount READ missionItemCount NOTIFY missionItemCountChanged) ///< True mission item command count (only valid in Fly View) Q_PROPERTY(int currentMissionIndex READ currentMissionIndex NOTIFY currentMissionIndexChanged) Q_PROPERTY(int resumeMissionIndex READ resumeMissionIndex NOTIFY resumeMissionIndexChanged) ///< Returns the item index two which a mission should be resumed. -1 indicates resume mission not available. - Q_PROPERTY(int currentPlanViewIndex READ currentPlanViewIndex NOTIFY currentPlanViewIndexChanged) + Q_PROPERTY(int currentPlanViewSeqNum READ currentPlanViewSeqNum NOTIFY currentPlanViewSeqNumChanged) + Q_PROPERTY(int currentPlanViewVIIndex READ currentPlanViewVIIndex NOTIFY currentPlanViewVIIndexChanged) Q_PROPERTY(VisualMissionItem* currentPlanViewItem READ currentPlanViewItem NOTIFY currentPlanViewItemChanged) Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged) Q_PROPERTY(double missionTime READ missionTime NOTIFY missionTimeChanged) @@ -94,9 +95,11 @@ public: Q_PROPERTY(QString structureScanComplexItemName READ structureScanComplexItemName CONSTANT) Q_PROPERTY(bool isInsertTakeoffValid MEMBER _isInsertTakeoffValid NOTIFY isInsertTakeoffValidChanged) Q_PROPERTY(bool isInsertLandValid MEMBER _isInsertLandValid NOTIFY isInsertLandValidChanged) + Q_PROPERTY(bool isROIActive MEMBER _isROIActive NOTIFY isROIActiveChanged) + Q_PROPERTY(bool isROIBeginCurrentItem MEMBER _isROIBeginCurrentItem NOTIFY isROIBeginCurrentItemChanged) Q_PROPERTY(bool flyThroughCommandsAllowed MEMBER _flyThroughCommandsAllowed NOTIFY flyThroughCommandsAllowedChanged) - Q_INVOKABLE void removeMissionItem(int index); + Q_INVOKABLE void removeMissionItem(int viIndex); /// Add a new simple mission item to the list /// @param coordinate: Coordinate for item @@ -126,6 +129,12 @@ public: /// @return Newly created item Q_INVOKABLE VisualMissionItem* insertROIMissionItem(QGeoCoordinate coordinate, int visualItemIndex, bool makeCurrentItem = false); + /// Add a new Cancel ROI mission item to the list + /// @param visualItemIndex: index to insert at, -1 for end of list + /// @param makeCurrentItem: true: Make this item the current item + /// @return Newly created item + Q_INVOKABLE VisualMissionItem* insertCancelROIMissionItem(int visualItemIndex, bool makeCurrentItem = false); + /// Add a new complex mission item to the list /// @param itemName: Name of complex item to create (from complexMissionItemNames) /// @param mapCenterCoordinate: coordinate for current center of map @@ -150,10 +159,7 @@ public: /// Sets a new current mission item (PlanView). /// @param sequenceNumber - index for new item, -1 to clear current item - Q_INVOKABLE void setCurrentPlanViewIndex(int sequenceNumber, bool force); - - /// Returns the index of this item in the visual item list - Q_INVOKABLE int visualItemIndexFromSequenceNumber(int sequenceNumber) const; + Q_INVOKABLE void setCurrentPlanViewSeqNum(int sequenceNumber, bool force); /// Determines if the mission has all data needed to be saved or sent to the vehicle. /// IMPORTANT NOTE: The return value is a VisualMissionItem::ReadForSaveState value. It is an int here to work around @@ -196,7 +202,7 @@ public: QVariantList waypointPath (void) { return _waypointPath; } QStringList complexMissionItemNames (void) const; QGeoCoordinate plannedHomePosition (void) const; - VisualMissionItem* currentPlanViewItem (void) const; + VisualMissionItem* currentPlanViewItem (void) const { return _currentPlanViewItem; } double progressPct (void) const { return _progressPct; } QString surveyComplexItemName (void) const { return patternSurveyName; } QString corridorScanComplexItemName (void) const { return patternCorridorScanName; } @@ -206,7 +212,8 @@ public: int missionItemCount (void) const { return _missionItemCount; } int currentMissionIndex (void) const; int resumeMissionIndex (void) const; - int currentPlanViewIndex (void) const; + int currentPlanViewSeqNum (void) const { return _currentPlanViewSeqNum; } + int currentPlanViewVIIndex (void) const { return _currentPlanViewVIIndex; } double missionDistance (void) const { return _missionFlightStatus.totalDistance; } double missionTime (void) const { return _missionFlightStatus.totalTime; } @@ -249,12 +256,15 @@ signals: void plannedHomePositionChanged (QGeoCoordinate plannedHomePosition); void progressPctChanged (double progressPct); void currentMissionIndexChanged (int currentMissionIndex); - void currentPlanViewIndexChanged (void); + void currentPlanViewSeqNumChanged (void); + void currentPlanViewVIIndexChanged (void); void currentPlanViewItemChanged (void); void missionBoundingCubeChanged (void); void missionItemCountChanged (int missionItemCount); void isInsertTakeoffValidChanged (void); void isInsertLandValidChanged (void); + void isROIActiveChanged (void); + void isROIBeginCurrentItemChanged (void); void flyThroughCommandsAllowedChanged (void); private slots: @@ -278,6 +288,7 @@ private: void _recalcSequence(void); void _recalcChildItems(void); void _recalcAllWithCoordinate(const QGeoCoordinate& coordinate); + void _recalcROISpecialVisuals(void); void _initAllVisualItems(void); void _deinitAllVisualItems(void); void _initVisualItem(VisualMissionItem* item); @@ -309,6 +320,8 @@ private: VisualMissionItem* _insertSimpleMissionItemWorker(QGeoCoordinate coordinate, MAV_CMD command, int visualItemIndex, bool makeCurrentItem); void _insertComplexMissionItemWorker(const QGeoCoordinate& mapCenterCoordinate, ComplexMissionItem* complexItem, int visualItemIndex, bool makeCurrentItem); void _warnIfTerrainFrameUsed(void); + bool _isROIBeginItem(SimpleMissionItem* simpleItem); + bool _isROICancelItem(SimpleMissionItem* simpleItem); private: MissionManager* _missionManager; @@ -325,7 +338,8 @@ private: MissionFlightStatus_t _missionFlightStatus; AppSettings* _appSettings; double _progressPct; - int _currentPlanViewIndex; + int _currentPlanViewSeqNum; + int _currentPlanViewVIIndex; VisualMissionItem* _currentPlanViewItem; QTimer _updateTimer; QGCGeoBoundingCube _travelBoundingCube; @@ -333,7 +347,9 @@ private: CoordinateVector* _splitSegment; bool _isInsertTakeoffValid = true; bool _isInsertLandValid = true; + bool _isROIActive = false; bool _flyThroughCommandsAllowed = true; + bool _isROIBeginCurrentItem = false; static const char* _settingsGroup; diff --git a/src/MissionManager/StructureScanPlanCreator.cc b/src/MissionManager/StructureScanPlanCreator.cc index 25c02615dd613b7a14ed1f6b034542a56f8fc906..9629b83630fe496aae93dafed4a72289f86d28d3 100644 --- a/src/MissionManager/StructureScanPlanCreator.cc +++ b/src/MissionManager/StructureScanPlanCreator.cc @@ -24,5 +24,5 @@ void StructureScanPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord) VisualMissionItem* takeoffItem = _missionController->insertTakeoffItem(mapCenterCoord, -1); _missionController->insertComplexMissionItem(MissionController::patternStructureScanName, mapCenterCoord, -1)->setWizardMode(true); _missionController->insertLandItem(mapCenterCoord, -1); - _missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true); + _missionController->setCurrentPlanViewSeqNum(takeoffItem->sequenceNumber(), true); } diff --git a/src/MissionManager/SurveyPlanCreator.cc b/src/MissionManager/SurveyPlanCreator.cc index b4cc2cbfa6a7a6ce951e1dc05047cdad9c79dbfd..2afa81ef8457148b98bb60587cff0ea0b19b024a 100644 --- a/src/MissionManager/SurveyPlanCreator.cc +++ b/src/MissionManager/SurveyPlanCreator.cc @@ -25,5 +25,5 @@ void SurveyPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord) VisualMissionItem* takeoffItem = _missionController->insertTakeoffItem(mapCenterCoord, -1); _missionController->insertComplexMissionItem(MissionController::patternSurveyName, mapCenterCoord, -1); _missionController->insertLandItem(mapCenterCoord, -1); - _missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true); + _missionController->setCurrentPlanViewSeqNum(takeoffItem->sequenceNumber(), true); } diff --git a/src/PlanView/MissionItemEditor.qml b/src/PlanView/MissionItemEditor.qml index 4b14cdcf1c92f9ea08b0c7e254ff72714b2f9b0f..d72ce3d929dbdf49b1b119ed3cc93bdbb60e44b8 100644 --- a/src/PlanView/MissionItemEditor.qml +++ b/src/PlanView/MissionItemEditor.qml @@ -30,8 +30,6 @@ Rectangle { signal clicked signal remove - signal insertWaypoint - signal insertComplexItem(string complexItemName) signal selectNextNotReadyItem property var _masterController: masterController diff --git a/src/PlanView/MissionItemStatus.qml b/src/PlanView/MissionItemStatus.qml index 150be13b3cf9195000340c23a4ac689bd6429bb0..37d5d9fba0e4a2c5d2cf55de83fede7afc67da7d 100644 --- a/src/PlanView/MissionItemStatus.qml +++ b/src/PlanView/MissionItemStatus.qml @@ -60,7 +60,7 @@ Rectangle { orientation: ListView.Horizontal spacing: 0 clip: true - currentIndex: _missionController.currentPlanViewIndex + currentIndex: _missionController.currentPlanViewSeqNum onCountChanged: { var calcLength = (statusListView.count + 1) * (statusListView.count ? statusListView.contentItem.children[0].width : 1) diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 13f46b6c113fd00731949c4fd449b2db3e1c3eba..540456e82f66818efec4cba74960a78ed50f53b4 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -68,25 +68,6 @@ Item { return coordinate } - function addComplexItem(complexItemName) { - var next_index = _missionController.visualItemIndexFromSequenceNumber(_missionController.currentPlanViewIndex)+1 - if(next_index ==1 && _missionController.visualItems.count >1){ - console.log(next_index, _missionController.visualItems.count) - insertComplexMissionItem(complexItemName, mapCenter(), next_index+1) - } - else if(next_index <= _missionController.visualItems.count){ - insertComplexMissionItem(complexItemName, mapCenter(), next_index) - } - } - - function insertComplexMissionItem(complexItemName, coordinate, index) { - _missionController.insertComplexMissionItem(complexItemName, coordinate, index, true /* makeCurrentItem */) - } - - function insertComplexMissionItemFromKMLOrSHP(complexItemName, file, index) { - _missionController.insertComplexMissionItemFromKMLOrSHP(complexItemName, file, index, true /* makeCurrentItem */) - } - function updateAirspace(reset) { if(_airspaceEnabled) { var coordinateNW = editorMap.toCoordinate(Qt.point(0,0), false /* clipToViewPort */) @@ -195,7 +176,7 @@ Item { Component.onCompleted: { _planMasterController.start(false /* flyView */) - _missionController.setCurrentPlanViewIndex(0, true) + _missionController.setCurrentPlanViewSeqNum(0, true) mainWindow.planMasterControllerPlan = _planMasterController } @@ -258,16 +239,6 @@ Item { mapFitFunctions.fitMapViewportToMissionItems() } - function loadShapeFromSelectedFile() { - fileDialog.title = qsTr("Load Shape") - fileDialog.planFiles = false - fileDialog.selectExisting = true - fileDialog.nameFilters = ShapeFileHelper.fileDialogKMLOrSHPFilters - fileDialog.fileExtension = _appSettings.kmlFileExtension - fileDialog.fileExtension2 = _appSettings.shpFileExtension - fileDialog.openForLoad() - } - function saveKmlToSelectedFile() { if (!checkReadyForSaveUpload(true /* save */)) { return @@ -289,31 +260,38 @@ Item { if (_visualItems && _visualItems.count !== 1) { mapFitFunctions.fitMapViewportToMissionItems() } - _missionController.setCurrentPlanViewIndex(0, true) + _missionController.setCurrentPlanViewSeqNum(0, true) } } - /// Inserts a new simple mission item - /// @param coordinate Location to insert item - /// @param index Insert item at this index - function insertSimpleMissionItem(coordinate, index) { - _missionController.insertSimpleMissionItem(coordinate, index, true /* makeCurrentItem */) + function insertSimpleItemAfterCurrent(coordinate) { + var nextIndex = _missionController.currentPlanViewVIIndex + 1 + _missionController.insertSimpleMissionItem(coordinate, nextIndex, true /* makeCurrentItem */) + } + + function insertROIAfterCurrent(coordinate) { + var nextIndex = _missionController.currentPlanViewVIIndex + 1 + _missionController.insertROIMissionItem(coordinate, nextIndex, true /* makeCurrentItem */) + _addROIOnClick = false } - /// Inserts a new ROI mission item - /// @param coordinate Location to insert item - /// @param index Insert item at this index - function insertROIMissionItem(coordinate, index) { - _missionController.insertROIMissionItem(coordinate, index, true /* makeCurrentItem */) + function insertCancelROIAfterCurrent() { + var nextIndex = _missionController.currentPlanViewVIIndex + 1 + _missionController.insertCancelROIMissionItem(nextIndex, true /* makeCurrentItem */) _addROIOnClick = false } + function insertComplexItemAfterCurrent(complexItemName) { + var nextIndex = _missionController.currentPlanViewVIIndex + 1 + _missionController.insertComplexMissionItem(complexItemName, mapCenter(), nextIndex, true /* makeCurrentItem */) + } + function selectNextNotReady() { var foundCurrent = false for (var i=0; i<_missionController.visualItems.count; i++) { var vmi = _missionController.visualItems.get(i) if (vmi.readyForSaveState === VisualMissionItem.NotReadyForSaveData) { - _missionController.setCurrentPlanViewIndex(vmi.sequenceNumber, true) + _missionController.setCurrentPlanViewSeqNum(vmi.sequenceNumber, true) break } } @@ -337,66 +315,13 @@ Item { } onAcceptedForLoad: { - if (planFiles) { - _planMasterController.loadFromFile(file) - _planMasterController.fitViewportToItems() - _missionController.setCurrentPlanViewIndex(0, true) - } else { - var retList = ShapeFileHelper.determineShapeType(file) - if (retList[0] == ShapeFileHelper.Error) { - mainWindow.showMessageDialog("Error", retList[1]) - } else if (retList[0] == ShapeFileHelper.Polygon) { - var editVehicle = activeVehicle ? activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle - if (editVehicle.fixedWing) { - insertComplexMissionItemFromKMLOrSHP(_missionController.surveyComplexItemName, file, -1) - } else { - polygonSelectPatternFile = file - mainWindow.showComponentDialog(patternPolygonSelectDialog, fileDialog.title, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel) - } - } else if (retList[0] == ShapeFileHelper.Polyline) { - insertComplexMissionItemFromKMLOrSHP(_missionController.corridorScanComplexItemName, file, -1) - } - } + _planMasterController.loadFromFile(file) + _planMasterController.fitViewportToItems() + _missionController.setCurrentPlanViewSeqNum(0, true) close() } } - property string polygonSelectPatternFile - Component { - id: patternPolygonSelectDialog - QGCViewDialog { - function accept() { - var complexItemName - if (surveyRadio.checked) { - complexItemName = _missionController.surveyComplexItemName - } else { - complexItemName = _missionController.structureScanComplexItemName - } - insertComplexMissionItemFromKMLOrSHP(complexItemName, polygonSelectPatternFile, -1) - hideDialog() - } - Column { - anchors.left: parent.left - anchors.right: parent.right - spacing: ScreenTools.defaultFontPixelHeight - QGCLabel { - anchors.left: parent.left - anchors.right: parent.right - wrapMode: Text.WordWrap - text: qsTr("Create which pattern type?") - } - QGCRadioButton { - id: surveyRadio - text: qsTr("Survey") - checked: true - } - QGCRadioButton { - text: qsTr("Structure Scan") - } - } - } - } - Component { id: moveDialog QGCViewDialog { @@ -477,17 +402,10 @@ Item { switch (_editingLayer) { case _layerMission: if (_addWaypointOnClick) { - var next_index = _missionController.visualItemIndexFromSequenceNumber(_missionController.currentPlanViewIndex)+1 - if(next_index ==1 && _missionController.visualItems.count >1){ - console.log(next_index, _missionController.visualItems.count) - insertSimpleMissionItem(coordinate, next_index+1) - } - else if(next_index <= _missionController.visualItems.count){ - insertSimpleMissionItem(coordinate, next_index) - } + insertSimpleItemAfterCurrent(coordinate) } else if (_addROIOnClick) { _addROIOnClick = false - insertROIMissionItem(coordinate, _missionController.visualItems.count) + insertROIAfterCurrent(coordinate) } break @@ -505,14 +423,15 @@ Item { model: _editingLayer == _layerMission ? _missionController.visualItems : undefined delegate: MissionItemMapVisual { map: editorMap - onClicked: _missionController.setCurrentPlanViewIndex(sequenceNumber, false) + onClicked: _missionController.setCurrentPlanViewSeqNum(sequenceNumber, false) visible: _editingLayer == _layerMission } } // Add lines between waypoints MissionLineView { - model: _editingLayer == _layerMission ? _missionController.waypointLines : undefined + showSpecialVisual: _missionController.isROIBeginCurrentItem + model: _editingLayer == _layerMission ? _missionController.waypointLines : undefined } MapItemView { @@ -535,7 +454,9 @@ Item { visible: _editingLayer == _layerMission sourceItem: SplitIndicator { - onClicked: insertSimpleMissionItem(splitSegmentItem.coordinate, _missionController.visualItemIndexFromSequenceNumber(_missionController.currentPlanViewIndex)) + onClicked: _missionController.insertSimpleMissionItem(splitSegmentItem.coordinate, + _missionController.currentPlanViewVIIndex, + true /* makeCurrentItem */) } function _updateSplitCoord() { @@ -665,11 +586,11 @@ Item { checked: _addWaypointOnClick }, { - name: qsTr("ROI"), + name: _missionController.isROIActive ? qsTr("Cancel ROI") : qsTr("ROI"), iconSource: "/qmlimages/MapAddMission.svg", buttonEnabled: true, buttonVisible: _isMissionLayer, - toggle: true + toggle: !_missionController.isROIActive }, { name: _singleComplexItem ? _missionController.complexMissionItemNames[0] : qsTr("Pattern"), @@ -718,12 +639,16 @@ Item { break case roiButtonIndex: allAddClickBoolsOff() - _addROIOnClick = checked + if (_missionController.isROIActive) { + insertCancelROIAfterCurrent() + } else { + _addROIOnClick = checked + } break case patternButtonIndex: allAddClickBoolsOff() if (_singleComplexItem) { - addComplexItem(_missionController.complexMissionItemNames[0]) + insertComplexItemAfterCurrent(_missionController.complexMissionItemNames[0]) } break case landButtonIndex: @@ -876,7 +801,7 @@ Item { model: _missionController.visualItems cacheBuffer: Math.max(height * 2, 0) clip: true - currentIndex: _missionController.currentPlanViewIndex + currentIndex: _missionController.currentPlanViewSeqNum highlightMoveDuration: 250 visible: _editingLayer == _layerMission && !planControlColapsed //-- List Elements @@ -886,17 +811,15 @@ Item { missionItem: object width: parent.width readOnly: false - onClicked: _missionController.setCurrentPlanViewIndex(object.sequenceNumber, false) + onClicked: _missionController.setCurrentPlanViewSeqNum(object.sequenceNumber, false) onRemove: { var removeIndex = index _missionController.removeMissionItem(removeIndex) if (removeIndex >= _missionController.visualItems.count) { removeIndex-- } - _missionController.setCurrentPlanViewIndex(removeIndex, true) + _missionController.setCurrentPlanViewSeqNum(removeIndex, true) } - onInsertWaypoint: insertSimpleMissionItem(editorMap.center, index) - onInsertComplexItem: insertComplexMissionItem(complexItemName, editorMap.center, index) onSelectNextNotReadyItem: selectNextNotReady() } } @@ -1008,7 +931,7 @@ Item { message: qsTr("Are you sure you want to remove all mission items and clear the mission from the vehicle?") function accept() { _planMasterController.removeAllFromVehicle() - _missionController.setCurrentPlanViewIndex(0, true) + _missionController.setCurrentPlanViewSeqNum(0, true) hideDialog() } } @@ -1041,7 +964,7 @@ Item { Layout.fillWidth: true onClicked: { - addComplexItem(modelData) + insertComplexItemAfterCurrent(modelData) dropPanel.hide() } } diff --git a/src/QmlControls/CoordinateVector.cc b/src/QmlControls/CoordinateVector.cc index ff8964a869f7efff79b60be76a556b426899d870..dcf47a60553a3c0d1f828689582a81e330ca74d7 100644 --- a/src/QmlControls/CoordinateVector.cc +++ b/src/QmlControls/CoordinateVector.cc @@ -44,3 +44,11 @@ void CoordinateVector::setCoordinate2(const QGeoCoordinate &coordinate) emit coordinate2Changed(_coordinate2); } } + +void CoordinateVector::setSpecialVisual(bool specialVisual) +{ + if (_specialVisual != specialVisual) { + _specialVisual = specialVisual; + emit specialVisualChanged(specialVisual); + } +} diff --git a/src/QmlControls/CoordinateVector.h b/src/QmlControls/CoordinateVector.h index 5d265e7d2f95433eea69925720c1654ad65712ff..b6534ff4e0ee503b8b3db0358510efdfec93569f 100644 --- a/src/QmlControls/CoordinateVector.h +++ b/src/QmlControls/CoordinateVector.h @@ -21,25 +21,30 @@ public: CoordinateVector(QObject* parent = nullptr); CoordinateVector(const QGeoCoordinate& coordinate1, const QGeoCoordinate& coordinate2, QObject* parent = nullptr); - Q_PROPERTY(QGeoCoordinate coordinate1 MEMBER _coordinate1 NOTIFY coordinate1Changed) - Q_PROPERTY(QGeoCoordinate coordinate2 MEMBER _coordinate2 NOTIFY coordinate2Changed) + Q_PROPERTY(QGeoCoordinate coordinate1 MEMBER _coordinate1 NOTIFY coordinate1Changed) + Q_PROPERTY(QGeoCoordinate coordinate2 MEMBER _coordinate2 NOTIFY coordinate2Changed) + Q_PROPERTY(bool specialVisual READ specialVisual WRITE setSpecialVisual NOTIFY specialVisualChanged) - QGeoCoordinate coordinate1(void) const { return _coordinate1; } - QGeoCoordinate coordinate2(void) const { return _coordinate2; } + QGeoCoordinate coordinate1(void) const { return _coordinate1; } + QGeoCoordinate coordinate2(void) const { return _coordinate2; } + bool specialVisual(void) const { return _specialVisual; } void setCoordinates(const QGeoCoordinate& coordinate1, const QGeoCoordinate& coordinate2); + void setSpecialVisual(bool specialVisual); public slots: void setCoordinate1(const QGeoCoordinate& coordinate); void setCoordinate2(const QGeoCoordinate& coordinate); signals: - void coordinate1Changed(QGeoCoordinate coordinate); - void coordinate2Changed(QGeoCoordinate coordinate); + void coordinate1Changed (QGeoCoordinate coordinate); + void coordinate2Changed (QGeoCoordinate coordinate); + void specialVisualChanged (bool specialVisual); private: QGeoCoordinate _coordinate1; QGeoCoordinate _coordinate2; + bool _specialVisual = false; }; #endif