From f47311320f9de2ada63a9fedd955f79df5868217 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Fri, 16 Feb 2018 21:52:34 -0500 Subject: [PATCH] Attempt and updating a flight plan (API seems broken) --- src/Airmap/AirMapFlightManager.h | 12 ++ src/Airmap/AirMapFlightPlanManager.cc | 129 ++++++++++++++++-- src/Airmap/AirMapFlightPlanManager.h | 13 +- .../AirspaceFlightPlanProvider.h | 22 ++- src/MissionManager/MissionController.cc | 6 +- 5 files changed, 163 insertions(+), 19 deletions(-) diff --git a/src/Airmap/AirMapFlightManager.h b/src/Airmap/AirMapFlightManager.h index 386d4a83a..b8439fc7c 100644 --- a/src/Airmap/AirMapFlightManager.h +++ b/src/Airmap/AirMapFlightManager.h @@ -20,6 +20,18 @@ class MissionItem; + + +/* + * TODO: This is here for reference. It will have to modifed quite a bit before it + * can be used. This was the original file that combined both the creation of a + * flight plan and immediate submission of a flight. The flight plan is now handled + * by its own class. This now needs to be made into a proper "Flight Manager". +*/ + + + + //----------------------------------------------------------------------------- /// class to upload a flight class AirMapFlightManager : public QObject, public LifetimeChecker diff --git a/src/Airmap/AirMapFlightPlanManager.cc b/src/Airmap/AirMapFlightPlanManager.cc index 9ebdbff8d..b76d443bf 100644 --- a/src/Airmap/AirMapFlightPlanManager.cc +++ b/src/Airmap/AirMapFlightPlanManager.cc @@ -29,11 +29,42 @@ AirMapFlightPlanManager::AirMapFlightPlanManager(AirMapSharedState& shared, QObj , _shared(shared) { connect(&_pollTimer, &QTimer::timeout, this, &AirMapFlightPlanManager::_pollBriefing); + //-- Set some valid, initial start/end time + _flightStartTime = QDateTime::currentDateTime().addSecs(10 * 60); + _flightEndTime = _flightStartTime.addSecs(30 * 60); } //----------------------------------------------------------------------------- void -AirMapFlightPlanManager::createFlight(MissionController* missionController) +AirMapFlightPlanManager::setFlightStartTime(QDateTime start) +{ + if(_flightStartTime != start) { + //-- Can't start in the past + if(start < QDateTime::currentDateTime()) { + start = QDateTime::currentDateTime().addSecs(5 * 60); + } + _flightStartTime = start; + emit flightStartTimeChanged(); + } +} + +//----------------------------------------------------------------------------- +void +AirMapFlightPlanManager::setFlightEndTime(QDateTime end) +{ + if(_flightEndTime != end) { + //-- End has to be after start + if(end < _flightStartTime) { + end = _flightStartTime.addSecs(30 * 60); + } + _flightEndTime = end; + emit flightEndTimeChanged(); + } +} + +//----------------------------------------------------------------------------- +void +AirMapFlightPlanManager::createFlightPlan(MissionController* missionController) { if (!_shared.client()) { qCDebug(AirMapManagerLog) << "No AirMap client instance. Will not create a flight"; @@ -49,7 +80,8 @@ AirMapFlightPlanManager::createFlight(MissionController* missionController) _createPlan = true; if(!_controller) { _controller = missionController; - connect(missionController, &MissionController::missionBoundingCubeChanged, this, &AirMapFlightPlanManager::_missionBoundingCubeChanged); + //-- Get notified of mission changes + connect(missionController, &MissionController::missionBoundingCubeChanged, this, &AirMapFlightPlanManager::_missionChanged); } } @@ -72,11 +104,21 @@ AirMapFlightPlanManager::_createFlightPlan() _flight.coords.append(QGeoCoordinate(bc.pointSE.latitude(), bc.pointNW.longitude(), _flight.maxAltitude)); _flight.coords.append(QGeoCoordinate(bc.pointNW.latitude(), bc.pointNW.longitude(), _flight.maxAltitude)); - _flight.maxAltitude += 5; // Add a safety buffer + if(_flightStartTime.isNull() || _flightStartTime < QDateTime::currentDateTime()) { + _flightStartTime = QDateTime::currentDateTime().addSecs(5 * 60); + emit flightStartTimeChanged(); + } + + if(_flightEndTime.isNull() || _flightEndTime < _flightStartTime) { + _flightEndTime = _flightStartTime.addSecs(30 * 60); + emit flightEndTimeChanged(); + } qCDebug(AirMapManagerLog) << "About to create flight plan"; qCDebug(AirMapManagerLog) << "Takeoff: " << _flight.takeoffCoord; qCDebug(AirMapManagerLog) << "Bounding box:" << bc.pointNW << bc.pointSE; + qCDebug(AirMapManagerLog) << "Flight Start:" << _flightStartTime; + qCDebug(AirMapManagerLog) << "Flight End: " << _flightEndTime; return; @@ -102,6 +144,7 @@ AirMapFlightPlanManager::_createFlightPlan() _state = State::Idle; QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : ""); emit error("Failed to create Flight Plan", QString::fromStdString(result.error().message()), description); + return; } }); }); @@ -129,8 +172,16 @@ AirMapFlightPlanManager::_uploadFlightPlan() params.latitude = _flight.takeoffCoord.latitude(); params.longitude = _flight.takeoffCoord.longitude(); params.pilot.id = _pilotID.toStdString(); + /* + + TODO: Convert this to fucking boost + + quint64 start = _flightStartTime.toUTC().toMSecsSinceEpoch(); + quint64 end = _flightEndTime.toUTC().toMSecsSinceEpoch(); + + */ params.start_time = Clock::universal_time() + Minutes{5}; - params.end_time = Clock::universal_time() + Hours{2}; // TODO: user-configurable? + params.end_time = Clock::universal_time() + Hours{2}; //-- Rules AirMapRulesetsManager* pRulesMgr = dynamic_cast(qgcApp()->toolbox()->airspaceManager()->ruleSets()); if(pRulesMgr) { @@ -165,6 +216,70 @@ AirMapFlightPlanManager::_uploadFlightPlan() }); } +//----------------------------------------------------------------------------- +void +AirMapFlightPlanManager::_updateFlightPlan() +{ + qCDebug(AirMapManagerLog) << "Updating flight plan"; + _state = State::FlightUpdate; + std::weak_ptr isAlive(_instance); + _shared.doRequestWithLogin([this, isAlive](const QString& login_token) { + if (!isAlive.lock()) return; + if (_state != State::FlightUpdate) return; + FlightPlans::Update::Parameters params; + params.authorization = login_token.toStdString(); + params.flight_plan.id = _flightPlan.toStdString(); + params.flight_plan.pilot.id = _pilotID.toStdString(); + //-- TODO: This is broken as the parameters for updating the plan have + // little to do with those used when creating it. + params.flight_plan.altitude_agl.max = _flight.maxAltitude; + params.flight_plan.buffer = 2.f; + params.flight_plan.takeoff.latitude = _flight.takeoffCoord.latitude(); + params.flight_plan.takeoff.longitude = _flight.takeoffCoord.longitude(); + /* + + TODO: Convert this to fucking boost + + quint64 start = _flightStartTime.toUTC().toMSecsSinceEpoch(); + quint64 end = _flightEndTime.toUTC().toMSecsSinceEpoch(); + + */ + params.flight_plan.start_time = Clock::universal_time() + Minutes{5}; + params.flight_plan.end_time = Clock::universal_time() + Hours{2}; + //-- Rules + /* + AirMapRulesetsManager* pRulesMgr = dynamic_cast(qgcApp()->toolbox()->airspaceManager()->ruleSets()); + if(pRulesMgr) { + foreach(QString ruleset, pRulesMgr->rulesetsIDs()) { + params.flight_plan.rulesets.push_back(ruleset.toStdString()); + } + } + */ + //-- Geometry: LineString + Geometry::LineString lineString; + for (const auto& qcoord : _flight.coords) { + Geometry::Coordinate coord; + coord.latitude = qcoord.latitude(); + coord.longitude = qcoord.longitude(); + lineString.coordinates.push_back(coord); + } + params.flight_plan.geometry = Geometry(lineString); + //-- Update flight plan + _shared.client()->flight_plans().update(params, [this, isAlive](const FlightPlans::Update::Result& result) { + if (!isAlive.lock()) return; + if (_state != State::FlightUpdate) return; + if (result) { + qCDebug(AirMapManagerLog) << "Flight plan updated:" << _flightPlan; + _state = State::FlightPolling; + _pollBriefing(); + } else { + QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : ""); + emit error("Flight Plan creation failed", QString::fromStdString(result.error().message()), description); + } + }); + }); +} + //----------------------------------------------------------------------------- void AirMapFlightPlanManager::_pollBriefing() @@ -259,7 +374,7 @@ AirMapFlightPlanManager::_deleteFlightPlan() //----------------------------------------------------------------------------- void -AirMapFlightPlanManager::_missionBoundingCubeChanged() +AirMapFlightPlanManager::_missionChanged() { //-- Creating a new flight plan? if(_createPlan) { @@ -267,7 +382,5 @@ AirMapFlightPlanManager::_missionBoundingCubeChanged() _createFlightPlan(); } //-- Plan is being modified - - - + // _updateFlightPlan(); } diff --git a/src/Airmap/AirMapFlightPlanManager.h b/src/Airmap/AirMapFlightPlanManager.h index 7a4d2c65e..2ae9adc43 100644 --- a/src/Airmap/AirMapFlightPlanManager.h +++ b/src/Airmap/AirMapFlightPlanManager.h @@ -27,18 +27,24 @@ public: AirMapFlightPlanManager(AirMapSharedState& shared, QObject *parent = nullptr); PermitStatus flightPermitStatus () const override { return _flightPermitStatus; } - void createFlight (MissionController* missionController) override; QString flightID () { return _flightPlan; } + QDateTime flightStartTime () const override { return _flightStartTime; } + QDateTime flightEndTime () const override { return _flightEndTime; } + + void createFlightPlan (MissionController* missionController) override; + void setFlightStartTime (QDateTime start) override; + void setFlightEndTime (QDateTime end) override; signals: void error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails); private slots: void _pollBriefing (); - void _missionBoundingCubeChanged (); + void _missionChanged (); private: void _uploadFlightPlan (); + void _updateFlightPlan (); void _createFlightPlan (); void _deleteFlightPlan (); @@ -47,6 +53,7 @@ private: Idle, GetPilotID, FlightUpload, + FlightUpdate, FlightPolling, FlightDelete }; @@ -69,6 +76,8 @@ private: QString _pilotID; ///< Pilot ID in the form "auth0|abc123" MissionController* _controller = nullptr; bool _createPlan = true; + QDateTime _flightStartTime; + QDateTime _flightEndTime; AirspaceFlightPlanProvider::PermitStatus _flightPermitStatus = AirspaceFlightPlanProvider::PermitUnknown; diff --git a/src/AirspaceManagement/AirspaceFlightPlanProvider.h b/src/AirspaceManagement/AirspaceFlightPlanProvider.h index ea28a903b..2d11d7037 100644 --- a/src/AirspaceManagement/AirspaceFlightPlanProvider.h +++ b/src/AirspaceManagement/AirspaceFlightPlanProvider.h @@ -15,6 +15,7 @@ */ #include +#include class MissionController; @@ -33,15 +34,24 @@ public: Q_ENUM(PermitStatus) - AirspaceFlightPlanProvider (QObject *parent = nullptr); - virtual ~AirspaceFlightPlanProvider () {} + AirspaceFlightPlanProvider (QObject *parent = nullptr); + virtual ~AirspaceFlightPlanProvider () {} - Q_PROPERTY(PermitStatus flightPermitStatus READ flightPermitStatus NOTIFY flightPermitStatusChanged) ///< state of flight permission + Q_PROPERTY(PermitStatus flightPermitStatus READ flightPermitStatus NOTIFY flightPermitStatusChanged) ///< State of flight permission + Q_PROPERTY(QDateTime flightStartTime READ flightStartTime WRITE setFlightStartTime NOTIFY flightStartTimeChanged) ///< Start of flight + Q_PROPERTY(QDateTime flightEndTime READ flightEndTime WRITE setFlightEndTime NOTIFY flightEndTimeChanged) ///< End of flight - virtual PermitStatus flightPermitStatus () const { return PermitUnknown; } - virtual void createFlight (MissionController* missionController) = 0; + virtual PermitStatus flightPermitStatus () const { return PermitUnknown; } + virtual QDateTime flightStartTime () const = 0; + virtual QDateTime flightEndTime () const = 0; + + virtual void setFlightStartTime (QDateTime start) = 0; + virtual void setFlightEndTime (QDateTime end) = 0; + virtual void createFlightPlan (MissionController* missionController) = 0; signals: - void flightPermitStatusChanged (); + void flightPermitStatusChanged (); + void flightStartTimeChanged (); + void flightEndTimeChanged (); }; diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index c5fa16c6e..bc410065b 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -203,7 +203,7 @@ void MissionController::_newMissionItemsAvailableFromVehicle(bool removeAllReque //-- If airspace management enabled, create new flight #if defined(QGC_AIRMAP_ENABLED) if(qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirMap()->rawValue().toBool()) { - qgcApp()->toolbox()->airspaceManager()->flightPlan()->createFlight(this); + qgcApp()->toolbox()->airspaceManager()->flightPlan()->createFlightPlan(this); } #endif } @@ -371,7 +371,7 @@ int MissionController::insertSimpleMissionItem(QGeoCoordinate coordinate, int i) //-- If airspace management enabled and this is the first item, create new flight #if defined(QGC_AIRMAP_ENABLED) if(_visualItems->count() == 2 && qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirMap()->rawValue().toBool()) { - qgcApp()->toolbox()->airspaceManager()->flightPlan()->createFlight(this); + qgcApp()->toolbox()->airspaceManager()->flightPlan()->createFlightPlan(this); } #endif @@ -464,7 +464,7 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate //-- If airspace management enabled and this is the first item, create new flight #if defined(QGC_AIRMAP_ENABLED) if(_visualItems->count() == 2 && qgcApp()->toolbox()->settingsManager()->airMapSettings()->enableAirMap()->rawValue().toBool()) { - qgcApp()->toolbox()->airspaceManager()->flightPlan()->createFlight(this); + qgcApp()->toolbox()->airspaceManager()->flightPlan()->createFlightPlan(this); } #endif -- 2.22.0