From f109339e436bda399d99e7c4baaffd0ade837a29 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Thu, 22 Feb 2018 17:02:42 -0500 Subject: [PATCH] Set mission bounding box as ROI if one exists. --- src/Airmap/AirMapFlightPlanManager.cc | 48 ++++++++++++++----- src/Airmap/AirMapFlightPlanManager.h | 4 ++ .../AirspaceFlightPlanProvider.h | 3 ++ src/AirspaceManagement/AirspaceManager.cc | 19 ++++++-- src/AirspaceManagement/AirspaceManager.h | 2 +- src/FlightDisplay/FlightDisplayViewMap.qml | 2 +- src/MissionManager/MissionController.cc | 2 + src/MissionManager/MissionController.h | 3 +- src/PlanView/PlanView.qml | 6 +-- src/QmlControls/QGCGeoBoundingCube.cc | 31 +++++++++--- src/QmlControls/QGCGeoBoundingCube.h | 14 +++--- 11 files changed, 102 insertions(+), 32 deletions(-) diff --git a/src/Airmap/AirMapFlightPlanManager.cc b/src/Airmap/AirMapFlightPlanManager.cc index b42e55f26..157af8eff 100644 --- a/src/Airmap/AirMapFlightPlanManager.cc +++ b/src/Airmap/AirMapFlightPlanManager.cc @@ -94,22 +94,24 @@ AirMapFlightPlanManager::startFlightPlanning(PlanMasterController *planControlle } //----------------------------------------------------------------------------- -void -AirMapFlightPlanManager::_createFlightPlan() +bool +AirMapFlightPlanManager::_collectFlightDtata() { - _flight.reset(); - + if(!_planController || !_planController->missionController()) { + return false; + } //-- Get flight bounding cube and prepare (box) polygon - QGCGeoBoundingCube bc = _planController->missionController()->travelBoundingCube(); - if(!bc.area()) { + QGCGeoBoundingCube bc = *_planController->missionController()->travelBoundingCube(); + if(!bc.isValid() || !bc.area()) { //-- TODO: If single point, we need to set a point and a radius instead - return; + qCDebug(AirMapManagerLog) << "Not enough points for a flight plan."; + return false; } - _flight.maxAltitude = fmax(bc.pointNW.altitude(), bc.pointSE.altitude()); _flight.takeoffCoord = _planController->missionController()->takeoffCoordinate(); _flight.coords = bc.polygon2D(); - + _flight.bc = bc; + emit missionAreaChanged(); //-- Flight Date/Time if(_flightStartTime.isNull() || _flightStartTime < QDateTime::currentDateTime()) { _flightStartTime = QDateTime::currentDateTime().addSecs(5 * 60); @@ -119,15 +121,28 @@ AirMapFlightPlanManager::_createFlightPlan() _flightEndTime = _flightStartTime.addSecs(30 * 60); emit flightEndTimeChanged(); } + return true; +} + +//----------------------------------------------------------------------------- +void +AirMapFlightPlanManager::_createFlightPlan() +{ + _flight.reset(); + + //-- Get flight data + if(!_collectFlightDtata()) { + return; + } qCDebug(AirMapManagerLog) << "About to create flight plan"; qCDebug(AirMapManagerLog) << "Takeoff: " << _flight.takeoffCoord; - qCDebug(AirMapManagerLog) << "Bounding box:" << bc.pointNW << bc.pointSE; + qCDebug(AirMapManagerLog) << "Bounding box:" << _flight.bc.pointNW << _flight.bc.pointSE; qCDebug(AirMapManagerLog) << "Flight Start:" << _flightStartTime; qCDebug(AirMapManagerLog) << "Flight End: " << _flightEndTime; //-- Not Yet - //return; + return; if (_pilotID == "") { //-- Need to get the pilot id before uploading the flight plan @@ -259,6 +274,17 @@ AirMapFlightPlanManager::_updateFlightPlan() // little to do with those used when creating it. qCDebug(AirMapManagerLog) << "Updating flight plan"; + //-- Get flight data + if(!_collectFlightDtata()) { + return; + } + + qCDebug(AirMapManagerLog) << "About to update the flight plan"; + qCDebug(AirMapManagerLog) << "Takeoff: " << _flight.takeoffCoord; + qCDebug(AirMapManagerLog) << "Bounding box:" << _flight.bc.pointNW << _flight.bc.pointSE; + qCDebug(AirMapManagerLog) << "Flight Start:" << _flightStartTime; + qCDebug(AirMapManagerLog) << "Flight End: " << _flightEndTime; + _state = State::FlightUpdate; std::weak_ptr isAlive(_instance); _shared.doRequestWithLogin([this, isAlive](const QString& login_token) { diff --git a/src/Airmap/AirMapFlightPlanManager.h b/src/Airmap/AirMapFlightPlanManager.h index bf15bac55..ac4639c2d 100644 --- a/src/Airmap/AirMapFlightPlanManager.h +++ b/src/Airmap/AirMapFlightPlanManager.h @@ -36,6 +36,7 @@ public: bool valid () override { return _valid; } QmlObjectListModel* advisories () override { return &_advisories; } QmlObjectListModel* ruleSets () override { return &_rulesets; } + QGCGeoBoundingCube* missionArea () override { return &_flight.bc; } AirspaceAdvisoryProvider::AdvisoryColor airspaceColor () override { return _airspaceColor; } void startFlightPlanning (PlanMasterController* planController) override; @@ -54,6 +55,7 @@ private: void _updateFlightPlan (); void _createFlightPlan (); void _deleteFlightPlan (); + bool _collectFlightDtata (); private: enum class State { @@ -66,10 +68,12 @@ private: }; struct Flight { + QGCGeoBoundingCube bc; QList coords; QGeoCoordinate takeoffCoord; float maxAltitude = 0; void reset() { + bc.reset(); coords.clear(); maxAltitude = 0; } diff --git a/src/AirspaceManagement/AirspaceFlightPlanProvider.h b/src/AirspaceManagement/AirspaceFlightPlanProvider.h index 4127ad402..fdef3e9df 100644 --- a/src/AirspaceManagement/AirspaceFlightPlanProvider.h +++ b/src/AirspaceManagement/AirspaceFlightPlanProvider.h @@ -46,11 +46,13 @@ public: Q_PROPERTY(bool valid READ valid NOTIFY advisoryChanged) Q_PROPERTY(QmlObjectListModel* advisories READ advisories NOTIFY advisoryChanged) Q_PROPERTY(QmlObjectListModel* ruleSets READ ruleSets NOTIFY advisoryChanged) + Q_PROPERTY(QGCGeoBoundingCube* missionArea READ missionArea NOTIFY missionAreaChanged) Q_PROPERTY(AirspaceAdvisoryProvider::AdvisoryColor airspaceColor READ airspaceColor NOTIFY advisoryChanged) virtual PermitStatus flightPermitStatus () const { return PermitNone; } virtual QDateTime flightStartTime () const = 0; virtual QDateTime flightEndTime () const = 0; + virtual QGCGeoBoundingCube* missionArea () = 0; virtual bool valid () = 0; ///< Current advisory list is valid virtual QmlObjectListModel* advisories () = 0; ///< List of AirspaceAdvisory virtual QmlObjectListModel* ruleSets () = 0; ///< List of AirspaceRuleSet @@ -65,4 +67,5 @@ signals: void flightStartTimeChanged (); void flightEndTimeChanged (); void advisoryChanged (); + void missionAreaChanged (); }; diff --git a/src/AirspaceManagement/AirspaceManager.cc b/src/AirspaceManagement/AirspaceManager.cc index 27cdbc8d0..f76c956c3 100644 --- a/src/AirspaceManagement/AirspaceManager.cc +++ b/src/AirspaceManagement/AirspaceManager.cc @@ -70,15 +70,28 @@ void AirspaceManager::setToolbox(QGCToolbox* toolbox) _flightPlan = _instantiateAirspaceFlightPlanProvider(); } -void AirspaceManager::setROI(const QGeoCoordinate& pointNW, const QGeoCoordinate& pointSE) +void AirspaceManager::setROI(const QGeoCoordinate& pointNW, const QGeoCoordinate& pointSE, bool planView) { + if(planView) { + //-- Is there a mission? + if(_flightPlan->flightPermitStatus() != AirspaceFlightPlanProvider::PermitNone) { + //-- Is there a polygon to work with? + if(_flightPlan->missionArea()->isValid() && _flightPlan->missionArea()->area() > 0.0) { + _setROI(*_flightPlan->missionArea()); + return; + } + } + } + //-- Use screen coordinates (what you see is what you get) _setROI(QGCGeoBoundingCube(pointNW, pointSE)); } void AirspaceManager::_setROI(const QGCGeoBoundingCube& roi) { - _roi = roi; - _roiUpdateTimer.start(); + if(_roi != roi) { + _roi = roi; + _roiUpdateTimer.start(); + } } void AirspaceManager::_updateToROI() diff --git a/src/AirspaceManagement/AirspaceManager.h b/src/AirspaceManagement/AirspaceManager.h index 9ffb8ad99..e8335442e 100644 --- a/src/AirspaceManagement/AirspaceManager.h +++ b/src/AirspaceManagement/AirspaceManager.h @@ -65,7 +65,7 @@ public: Q_PROPERTY(AirspaceFlightPlanProvider* flightPlan READ flightPlan CONSTANT) Q_PROPERTY(bool airspaceVisible READ airspaceVisible WRITE setAirspaceVisible NOTIFY airspaceVisibleChanged) - Q_INVOKABLE void setROI (const QGeoCoordinate& pointNW, const QGeoCoordinate& pointSE); + Q_INVOKABLE void setROI (const QGeoCoordinate& pointNW, const QGeoCoordinate& pointSE, bool planView); AirspaceWeatherInfoProvider* weatherInfo () { return _weatherProvider; } AirspaceAdvisoryProvider* advisories () { return _advisories; } diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlightDisplayViewMap.qml index c8affbe72..ba210b902 100644 --- a/src/FlightDisplay/FlightDisplayViewMap.qml +++ b/src/FlightDisplay/FlightDisplayViewMap.qml @@ -62,7 +62,7 @@ FlightMap { var coordinateNW = flightMap.toCoordinate(Qt.point(0,0), false /* clipToViewPort */) var coordinateSE = flightMap.toCoordinate(Qt.point(width,height), false /* clipToViewPort */) if(coordinateNW.isValid && coordinateSE.isValid) { - QGroundControl.airspaceManager.setROI(coordinateNW, coordinateSE) + QGroundControl.airspaceManager.setROI(coordinateNW, coordinateSE, false /*planView*/) } } } diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index 96ca4a8b3..6b1fb280b 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -1435,6 +1435,8 @@ void MissionController::_recalcMissionFlightStatus() } } } + + _updateTimer.start(UPDATE_TIMEOUT); } // This will update the sequence numbers to be sequential starting from 0 diff --git a/src/MissionManager/MissionController.h b/src/MissionManager/MissionController.h index 9fc75cf80..eaca4fbde 100644 --- a/src/MissionManager/MissionController.h +++ b/src/MissionManager/MissionController.h @@ -90,6 +90,7 @@ public: Q_PROPERTY(int batteryChangePoint READ batteryChangePoint NOTIFY batteryChangePointChanged) Q_PROPERTY(int batteriesRequired READ batteriesRequired NOTIFY batteriesRequiredChanged) + Q_PROPERTY(QGCGeoBoundingCube* travelBoundingCube READ travelBoundingCube NOTIFY missionBoundingCubeChanged) Q_INVOKABLE void removeMissionItem(int index); @@ -125,7 +126,7 @@ public: bool loadJsonFile(QFile& file, QString& errorString); bool loadTextFile(QFile& file, QString& errorString); - QGCGeoBoundingCube travelBoundingCube () { return _travelBoundingCube; } + QGCGeoBoundingCube* travelBoundingCube () { return &_travelBoundingCube; } QGeoCoordinate takeoffCoordinate () { return _takeoffCoordinate; } // Overrides from PlanElementController diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 753875713..0d2c75b21 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -73,9 +73,9 @@ QGCView { function addComplexItem(complexItemName) { var coordinate = editorMap.center - coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) + coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces) - coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces) + coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces) insertComplexMissionItem(complexItemName, coordinate, _missionController.visualItems.count) } @@ -89,7 +89,7 @@ QGCView { var coordinateNW = editorMap.toCoordinate(Qt.point(0,0), false /* clipToViewPort */) var coordinateSE = editorMap.toCoordinate(Qt.point(width,height), false /* clipToViewPort */) if(coordinateNW.isValid && coordinateSE.isValid) { - QGroundControl.airspaceManager.setROI(coordinateNW, coordinateSE) + QGroundControl.airspaceManager.setROI(coordinateNW, coordinateSE, true /*planView*/) } } } diff --git a/src/QmlControls/QGCGeoBoundingCube.cc b/src/QmlControls/QGCGeoBoundingCube.cc index 7fe03d0ff..f62aa5a09 100644 --- a/src/QmlControls/QGCGeoBoundingCube.cc +++ b/src/QmlControls/QGCGeoBoundingCube.cc @@ -25,14 +25,23 @@ QGCGeoBoundingCube::isValid() const pointNW.longitude() != MaxEast && pointSE.longitude() != MaxWest && pointNW.altitude() < MaxAlt and pointSE.altitude() > MinAlt; } +//----------------------------------------------------------------------------- +void +QGCGeoBoundingCube::reset() +{ + pointSE = QGeoCoordinate(); + pointNW = QGeoCoordinate(); +} + //----------------------------------------------------------------------------- QGeoCoordinate QGCGeoBoundingCube::center() const { + if(!isValid()) + return QGeoCoordinate(); double lat = (((pointNW.latitude() + 90.0) + (pointSE.latitude() + 90.0)) / 2.0) - 90.0; double lon = (((pointNW.longitude() + 180.0) + (pointSE.longitude() + 180.0)) / 2.0) - 180.0; double alt = (pointNW.altitude() + pointSE.altitude()) / 2.0; - //qDebug() << pointNW << pointSE << QGeoCoordinate(lat, lon, alt); return QGeoCoordinate(lat, lon, alt); } @@ -41,11 +50,13 @@ QList QGCGeoBoundingCube::polygon2D() const { QList coords; - coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude())); - coords.append(QGeoCoordinate(pointNW.latitude(), pointSE.longitude(), pointSE.altitude())); - coords.append(QGeoCoordinate(pointSE.latitude(), pointSE.longitude(), pointSE.altitude())); - coords.append(QGeoCoordinate(pointSE.latitude(), pointNW.longitude(), pointSE.altitude())); - coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude())); + if(isValid()) { + coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude())); + coords.append(QGeoCoordinate(pointNW.latitude(), pointSE.longitude(), pointSE.altitude())); + coords.append(QGeoCoordinate(pointSE.latitude(), pointSE.longitude(), pointSE.altitude())); + coords.append(QGeoCoordinate(pointSE.latitude(), pointNW.longitude(), pointSE.altitude())); + coords.append(QGeoCoordinate(pointNW.latitude(), pointNW.longitude(), pointSE.altitude())); + } return coords; } @@ -53,6 +64,8 @@ QGCGeoBoundingCube::polygon2D() const double QGCGeoBoundingCube::width() const { + if(!isValid()) + return 0.0; QGeoCoordinate ne = QGeoCoordinate(pointNW.latitude(), pointSE.longitude()); return pointNW.distanceTo(ne); } @@ -61,6 +74,8 @@ QGCGeoBoundingCube::width() const double QGCGeoBoundingCube::height() const { + if(!isValid()) + return 0.0; QGeoCoordinate sw = QGeoCoordinate(pointSE.latitude(), pointNW.longitude()); return pointNW.distanceTo(sw); } @@ -69,6 +84,8 @@ QGCGeoBoundingCube::height() const double QGCGeoBoundingCube::area() const { + if(!isValid()) + return 0.0; // Area in km^2 double a = (height() / 1000.0) * (width() / 1000.0); //qDebug() << "Area:" << a; @@ -79,5 +96,7 @@ QGCGeoBoundingCube::area() const double QGCGeoBoundingCube::radius() const { + if(!isValid()) + return 0.0; return pointNW.distanceTo(pointSE) / 2.0; } diff --git a/src/QmlControls/QGCGeoBoundingCube.h b/src/QmlControls/QGCGeoBoundingCube.h index 225f3072c..10f1ead54 100644 --- a/src/QmlControls/QGCGeoBoundingCube.h +++ b/src/QmlControls/QGCGeoBoundingCube.h @@ -39,8 +39,9 @@ public: Q_PROPERTY(QGeoCoordinate pointNW MEMBER pointNW CONSTANT) Q_PROPERTY(QGeoCoordinate pointSE MEMBER pointNW CONSTANT) - Q_INVOKABLE bool isValid() const; - Q_INVOKABLE QGeoCoordinate center() const; + Q_INVOKABLE void reset (); + Q_INVOKABLE bool isValid () const; + Q_INVOKABLE QGeoCoordinate center () const; inline bool operator ==(const QGCGeoBoundingCube& other) { @@ -61,10 +62,11 @@ public: //-- 2D QList polygon2D() const; - double width () const; - double height () const; - double area () const; - double radius () const; + + Q_INVOKABLE double width () const; + Q_INVOKABLE double height () const; + Q_INVOKABLE double area () const; + Q_INVOKABLE double radius () const; QGeoCoordinate pointNW; QGeoCoordinate pointSE; -- 2.22.0