Commit d17f10d2 authored by Beat Küng's avatar Beat Küng

AirMap: refactor for multi-vehicle support & base class API

- add multi-vehicle support: each vehicle has now a per-vehicle AirMap
  object that takes care of flight creation, traffic & telemetry
- add a base class API layer so that the interface between QGC and the
  AirMap implementation is clear, and easier to change
- removes polygon upload to vehicle (needs a better solution)
parent 3f64f28b
......@@ -505,7 +505,9 @@ HEADERS += \
src/MG.h \
src/MissionManager/CameraCalc.h \
src/MissionManager/AirMapController.h \
src/MissionManager/AirspaceController.h \
src/MissionManager/AirMapManager.h \
src/MissionManager/AirspaceManagement.h \
src/MissionManager/CameraSection.h \
src/MissionManager/CameraSpec.h \
src/MissionManager/ComplexMissionItem.h \
......@@ -712,7 +714,9 @@ SOURCES += \
src/LogCompressor.cc \
src/MissionManager/CameraCalc.cc \
src/MissionManager/AirMapController.cc \
src/MissionManager/AirspaceController.cc \
src/MissionManager/AirMapManager.cc \
src/MissionManager/AirspaceManagement.cc \
src/MissionManager/CameraSection.cc \
src/MissionManager/CameraSpec.cc \
src/MissionManager/ComplexMissionItem.cc \
......
......@@ -615,11 +615,11 @@ QGCView {
}
}
//-- AirMap Indicator
//-- Airspace Indicator
Rectangle {
id: airMapIndicator
width: airMapRow.width + (ScreenTools.defaultFontPixelWidth * 3)
height: airMapRow.height * 1.25
id: airspaceIndicator
width: airspaceRow.width + (ScreenTools.defaultFontPixelWidth * 3)
height: airspaceRow.height * 1.25
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
visible: _mainIsMap && flightPermit && flightPermit !== AirspaceAuthorization.PermitUnknown && !messageArea.visible && !criticalMmessageArea.visible
radius: 3
......@@ -629,27 +629,27 @@ QGCView {
anchors.topMargin: ScreenTools.toolbarHeight + (ScreenTools.defaultFontPixelHeight * 0.25)
anchors.horizontalCenter: parent.horizontalCenter
Row {
id: airMapRow
id: airspaceRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.centerIn: parent
QGCLabel { text: qsTr("AirMap:"); anchors.verticalCenter: parent.verticalCenter; }
QGCLabel { text: airspaceIndicator.providerName+":"; anchors.verticalCenter: parent.verticalCenter; }
QGCLabel {
text: {
if(airMapIndicator.flightPermit) {
if(airMapIndicator.flightPermit === AirspaceAuthorization.PermitPending)
if(airspaceIndicator.flightPermit) {
if(airspaceIndicator.flightPermit === AirspaceAuthorization.PermitPending)
return qsTr("Approval Pending")
if(airMapIndicator.flightPermit === AirspaceAuthorization.PermitAccepted)
if(airspaceIndicator.flightPermit === AirspaceAuthorization.PermitAccepted)
return qsTr("Flight Approved")
if(airMapIndicator.flightPermit === AirspaceAuthorization.PermitRejected)
return qsTr("Flight Denied")
if(airspaceIndicator.flightPermit === AirspaceAuthorization.PermitRejected)
return qsTr("Flight Rejected")
}
return ""
}
color: {
if(airMapIndicator.flightPermit) {
if(airMapIndicator.flightPermit === AirspaceAuthorization.PermitPending)
if(airspaceIndicator.flightPermit) {
if(airspaceIndicator.flightPermit === AirspaceAuthorization.PermitPending)
return qgcPal.colorOrange
if(airMapIndicator.flightPermit === AirspaceAuthorization.PermitAccepted)
if(airspaceIndicator.flightPermit === AirspaceAuthorization.PermitAccepted)
return qgcPal.colorGreen
}
return qgcPal.colorRed
......@@ -657,7 +657,8 @@ QGCView {
anchors.verticalCenter: parent.verticalCenter;
}
}
property var flightPermit: _activeVehicle ? _activeVehicle.airMapController.flightPermitStatus : null
property var flightPermit: _activeVehicle ? _activeVehicle.flightPermitStatus : null
property var providerName: _activeVehicle ? _activeVehicle.airspaceController.providerName : ""
}
}
......@@ -59,7 +59,7 @@ FlightMap {
onZoomLevelChanged: QGroundControl.flightMapZoom = zoomLevel
onCenterChanged: {
if(_activeVehicle) {
_activeVehicle.airMapController.setROI(center, 5000)
_activeVehicle.airspaceController.setROI(center, 5000)
}
QGroundControl.flightMapPosition = center
}
......@@ -329,9 +329,9 @@ FlightMap {
]
}
// AirMap overlap support
// Airspace overlap support
MapItemView {
model: _activeVehicle ? _activeVehicle.airMapController.circles : []
model: _activeVehicle ? _activeVehicle.airspaceController.circles : []
delegate: MapCircle {
center: object.center
radius: object.radius
......@@ -342,7 +342,7 @@ FlightMap {
}
MapItemView {
model: _activeVehicle ? _activeVehicle.airMapController.polygons : []
model: _activeVehicle ? _activeVehicle.airspaceController.polygons : []
delegate: MapPolygon {
border.color: "white"
color: "yellow"
......
This diff is collapsed.
......@@ -15,6 +15,7 @@
#include "QmlObjectListModel.h"
#include "MissionItem.h"
#include "MultiVehicleManager.h"
#include "AirspaceManagement.h"
#include <qmqtt.h>
......@@ -32,44 +33,6 @@
Q_DECLARE_LOGGING_CATEGORY(AirMapManagerLog)
class AirspaceRestriction : public QObject
{
Q_OBJECT
public:
AirspaceRestriction(QObject* parent = NULL);
};
class PolygonAirspaceRestriction : public AirspaceRestriction
{
Q_OBJECT
public:
PolygonAirspaceRestriction(const QVariantList& polygon, QObject* parent = NULL);
Q_PROPERTY(QVariantList polygon MEMBER _polygon CONSTANT)
const QVariantList& getPolygon() const { return _polygon; }
private:
QVariantList _polygon;
};
class CircularAirspaceRestriction : public AirspaceRestriction
{
Q_OBJECT
public:
CircularAirspaceRestriction(const QGeoCoordinate& center, double radius, QObject* parent = NULL);
Q_PROPERTY(QGeoCoordinate center MEMBER _center CONSTANT)
Q_PROPERTY(double radius MEMBER _radius CONSTANT)
private:
QGeoCoordinate _center;
double _radius;
};
class AirMapLogin : public QObject
{
......@@ -165,6 +128,8 @@ public:
*/
void abort();
bool hasAPIKey() const { return _networkingData.airmapAPIKey != ""; }
signals:
/// signal when the request finished (get or post). All requests are assumed to return JSON.
void finished(QJsonParseError parseError, QJsonDocument document);
......@@ -196,16 +161,13 @@ private:
/// class to download polygons from AirMap
class AirspaceRestrictionManager : public QObject
class AirMapRestrictionManager : public AirspaceRestrictionProvider
{
Q_OBJECT
public:
AirspaceRestrictionManager(AirMapNetworking::SharedData& sharedData);
void updateROI(const QGeoCoordinate& center, double radiusMeters);
AirMapRestrictionManager(AirMapNetworking::SharedData& sharedData);
QmlObjectListModel* polygonRestrictions(void) { return &_polygonList; }
QmlObjectListModel* circularRestrictions(void) { return &_circleList; }
void setROI(const QGeoCoordinate& center, double radiusMeters) override;
signals:
void networkError(QNetworkReply::NetworkError code, const QString& errorString, const QString& serverErrorMessage);
......@@ -223,26 +185,9 @@ private:
State _state = State::Idle;
int _numAwaitingItems = 0;
AirMapNetworking _networking;
QmlObjectListModel _polygonList;
QmlObjectListModel _circleList;
QList<PolygonAirspaceRestriction*> _nextPolygonList;
QList<CircularAirspaceRestriction*> _nextcircleList;
};
class AirspaceAuthorization : public QObject {
Q_OBJECT
public:
enum PermitStatus {
PermitUnknown = 0,
PermitPending,
PermitAccepted,
PermitRejected,
};
Q_ENUMS(PermitStatus);
};
/// class to upload a flight
class AirMapFlightManager : public QObject
{
......@@ -344,6 +289,8 @@ public:
void stopTelemetryStream();
bool isTelemetryStreaming() const;
signals:
void networkError(QNetworkReply::NetworkError code, const QString& errorString, const QString& serverErrorMessage);
......@@ -360,8 +307,6 @@ private:
void _handleGlobalPositionInt(const mavlink_message_t& message);
void _handleGPSRawInt(const mavlink_message_t& message);
bool _isTelemetryStreaming() const;
enum class State {
Idle,
StartCommunication,
......@@ -418,68 +363,74 @@ private:
/// AirMap server communication support.
class AirMapManager : public QGCTool
/// AirMap per vehicle management class.
class AirMapManagerPerVehicle : public AirspaceManagerPerVehicle
{
Q_OBJECT
public:
AirMapManager(QGCApplication* app, QGCToolbox* toolbox);
~AirMapManager();
AirMapManagerPerVehicle(AirMapNetworking::SharedData& sharedData, const Vehicle& vehicle, QGCToolbox& toolbox);
virtual ~AirMapManagerPerVehicle() = default;
/// Set the ROI for airspace information
/// @param center Center coordinate for ROI
/// @param radiusMeters Radius in meters around center which is of interest
void setROI(QGeoCoordinate& center, double radiusMeters);
/// Send flight path to AirMap
void createFlight(const QList<MissionItem*>& missionItems);
void createFlight(const QList<MissionItem*>& missionItems) override;
AirspaceAuthorization::PermitStatus flightPermitStatus() const override;
QmlObjectListModel* polygonRestrictions(void) { return _airspaceRestrictionManager.polygonRestrictions(); }
QmlObjectListModel* circularRestrictions(void) { return _airspaceRestrictionManager.circularRestrictions(); }
void startTelemetryStream() override;
void setToolbox(QGCToolbox* toolbox) override;
void stopTelemetryStream() override;
AirspaceAuthorization::PermitStatus flightPermitStatus() const { return _flightManager.flightPermitStatus(); }
bool isTelemetryStreaming() const override;
signals:
void flightPermitStatusChanged();
void trafficUpdate(QString traffic_id, QString vehicle_id, QGeoCoordinate location, float heading);
void networkError(QNetworkReply::NetworkError code, const QString& errorString, const QString& serverErrorMessage);
private slots:
void _updateToROI(void);
void _networkError(QNetworkReply::NetworkError code, const QString& errorString, const QString& serverErrorMessage);
public slots:
void endFlight() override;
void _activeVehicleChanged(Vehicle* activeVehicle);
void _vehicleArmedChanged(bool armed);
void settingsChanged();
protected slots:
virtual void vehicleMavlinkMessageReceived(const mavlink_message_t& message) override;
private slots:
void _flightPermitStatusChanged();
void _settingsChanged();
private:
bool _hasAPIKey() const { return _networkingData.airmapAPIKey != ""; }
AirMapNetworking _networking;
/**
* A new vehicle got connected, listen to its state
*/
void _connectVehicle(Vehicle* vehicle);
AirMapNetworking::SharedData _networkingData;
AirspaceRestrictionManager _airspaceRestrictionManager;
AirMapFlightManager _flightManager;
AirMapTelemetry _telemetry;
AirMapTrafficAlertClient _trafficAlerts;
QGeoCoordinate _roiCenter;
double _roiRadius;
QGCToolbox& _toolbox;
};
QTimer _updateTimer;
class AirMapManager : public AirspaceManager
{
Q_OBJECT
public:
AirMapManager(QGCApplication* app, QGCToolbox* toolbox);
virtual ~AirMapManager() = default;
void setToolbox(QGCToolbox* toolbox) override;
AirspaceManagerPerVehicle* instantiateVehicle(const Vehicle& vehicle) override;
AirspaceRestrictionProvider* instantiateRestrictionProvider() override;
QString name() const override { return "AirMap"; }
Vehicle* _vehicle = nullptr; ///< current vehicle
bool _vehicleWasInMissionMode = false; ///< true if the vehicle was in mission mode when arming
signals:
void settingsChanged();
private slots:
void _networkError(QNetworkReply::NetworkError code, const QString& errorString, const QString& serverErrorMessage);
void _settingsChanged();
private:
AirMapNetworking::SharedData _networkingData;
};
#endif
......@@ -7,21 +7,14 @@
*
****************************************************************************/
#include "AirMapController.h"
#include "AirMapManager.h"
#include "AirspaceController.h"
#include "AirspaceManagement.h"
#include "QGCApplication.h"
#include "QGCQGeoCoordinate.h"
QGC_LOGGING_CATEGORY(AirMapControllerLog, "AirMapControllerLog")
AirMapController::AirMapController(QObject* parent)
AirspaceController::AirspaceController(QObject* parent)
: QObject(parent)
, _manager(qgcApp()->toolbox()->airMapManager())
, _manager(qgcApp()->toolbox()->airspaceManager())
{
connect(_manager, &AirMapManager::flightPermitStatusChanged, this, &AirMapController::flightPermitStatusChanged);
}
AirMapController::~AirMapController()
{
}
......@@ -7,44 +7,30 @@
*
****************************************************************************/
#ifndef AirMapController_H
#define AirMapController_H
#pragma once
#include "AirMapManager.h"
#include "AirspaceManagement.h"
#include "QGCMapPolygon.h"
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(AirMapControllerLog)
class AirMapManager;
class AirMapController : public QObject
class AirspaceController : public QObject
{
Q_OBJECT
public:
AirMapController(QObject* parent = NULL);
~AirMapController();
AirspaceController(QObject* parent = NULL);
~AirspaceController() = default;
Q_PROPERTY(QmlObjectListModel* polygons READ polygons CONSTANT) ///< List of PolygonAirspaceRestriction objects
Q_PROPERTY(QmlObjectListModel* circles READ circles CONSTANT) ///< List of CircularAirspaceRestriction objects
Q_PROPERTY(AirspaceAuthorization::PermitStatus flightPermitStatus READ flightPermitStatus NOTIFY flightPermitStatusChanged) ///< state of flight permission
Q_INVOKABLE void setROI(QGeoCoordinate center, double radius) { _manager->setROI(center, radius); }
QmlObjectListModel* polygons(void) { return _manager->polygonRestrictions(); }
QmlObjectListModel* circles(void) { return _manager->circularRestrictions(); }
QmlObjectListModel* polygons() { return _manager->polygonRestrictions(); }
QmlObjectListModel* circles() { return _manager->circularRestrictions(); }
AirspaceAuthorization::PermitStatus flightPermitStatus() const { return _manager->flightPermitStatus(); }
signals:
void flightPermitStatusChanged();
Q_PROPERTY(QString providerName READ providerName CONSTANT)
QString providerName() { return _manager->name(); }
private:
AirMapManager* _manager;
QmlObjectListModel _polygonList;
QmlObjectListModel _circleList;
AirspaceManager* _manager;
};
#endif
/****************************************************************************
*
* (c) 2017 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "AirspaceManagement.h"
#include <Vehicle.h>
QGC_LOGGING_CATEGORY(AirspaceManagementLog, "AirspaceManagementLog")
AirspaceRestriction::AirspaceRestriction(QObject* parent)
: QObject(parent)
{
}
PolygonAirspaceRestriction::PolygonAirspaceRestriction(const QVariantList& polygon, QObject* parent)
: AirspaceRestriction(parent)
, _polygon(polygon)
{
}
CircularAirspaceRestriction::CircularAirspaceRestriction(const QGeoCoordinate& center, double radius, QObject* parent)
: AirspaceRestriction(parent)
, _center(center)
, _radius(radius)
{
}
AirspaceManager::AirspaceManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
{
_roiUpdateTimer.setInterval(2000);
_roiUpdateTimer.setSingleShot(true);
connect(&_roiUpdateTimer, &QTimer::timeout, this, &AirspaceManager::_updateToROI);
qmlRegisterUncreatableType<AirspaceAuthorization>("QGroundControl", 1, 0, "AirspaceAuthorization", "Reference only");
}
AirspaceManager::~AirspaceManager()
{
if (_restrictionsProvider) {
delete _restrictionsProvider;
}
_polygonRestrictions.clearAndDeleteContents();
_circleRestrictions.clearAndDeleteContents();
}
void AirspaceManager::setToolbox(QGCToolbox* toolbox)
{
QGCTool::setToolbox(toolbox);
// we should not call virtual methods in the constructor, so we instantiate the restriction provider here
_restrictionsProvider = instantiateRestrictionProvider();
if (_restrictionsProvider) {
connect(_restrictionsProvider, &AirspaceRestrictionProvider::requestDone, this,
&AirspaceManager::_restrictionsUpdated);
}
}
void AirspaceManager::setROI(const QGeoCoordinate& center, double radiusMeters)
{
_roiCenter = center;
_roiRadius = radiusMeters;
_roiUpdateTimer.start();
}
void AirspaceManager::_updateToROI()
{
if (_restrictionsProvider) {
_restrictionsProvider->setROI(_roiCenter, _roiRadius);
}
}
void AirspaceManager::_restrictionsUpdated(bool success)
{
_polygonRestrictions.clearAndDeleteContents();
_circleRestrictions.clearAndDeleteContents();
if (success) {
for (const auto& circle : _restrictionsProvider->circles()) {
_circleRestrictions.append(circle);
}
for (const auto& polygon : _restrictionsProvider->polygons()) {
_polygonRestrictions.append(polygon);
}
} else {
// TODO: show error?
}
}
AirspaceManagerPerVehicle::AirspaceManagerPerVehicle(const Vehicle& vehicle)
: _vehicle(vehicle)
{
connect(&_vehicle, &Vehicle::armedChanged, this, &AirspaceManagerPerVehicle::_vehicleArmedChanged);
connect(&_vehicle, &Vehicle::mavlinkMessageReceived, this, &AirspaceManagerPerVehicle::vehicleMavlinkMessageReceived);
}
void AirspaceManagerPerVehicle::_vehicleArmedChanged(bool armed)
{
if (armed) {
startTelemetryStream();
_vehicleWasInMissionMode = _vehicle.flightMode() == _vehicle.missionFlightMode();
} else {
stopTelemetryStream();
// end the flight if we were in mission mode during arming or disarming
// TODO: needs to be improved. for instance if we do RTL and then want to continue the mission...
if (_vehicleWasInMissionMode || _vehicle.flightMode() == _vehicle.missionFlightMode()) {
endFlight();
}
}
}
/****************************************************************************
*
* (c) 2017 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
/**
* @file AirspaceManagement.h
* This file contains the interface definitions used by an airspace management implementation (AirMap).
* There are 3 base classes that must be subclassed:
* - AirspaceManager
* main manager that contains the restrictions for display. It acts as a factory to create instances of the other
* classes.
* - AirspaceManagerPerVehicle
* this provides the multi-vehicle support - each vehicle has an instance
* - AirspaceRestrictionProvider
* provides airspace restrictions. Currently only used by AirspaceManager, but
* each vehicle could have its own restrictions.
*/
#include "QGCToolbox.h"
#include "MissionItem.h"
#include <QObject>
#include <QString>
#include <QList>
#include <QGCLoggingCategory.h>
Q_DECLARE_LOGGING_CATEGORY(AirspaceManagementLog)
/**
* Contains the status of the Airspace authorization
*/
class AirspaceAuthorization : public QObject {
Q_OBJECT
public:
enum PermitStatus {
PermitUnknown = 0,
PermitPending,
PermitAccepted,
PermitRejected,
};
Q_ENUMS(PermitStatus);
};
/**
* Base class for an airspace restriction
*/
class AirspaceRestriction : public QObject
{
Q_OBJECT
public:
AirspaceRestriction(QObject* parent = NULL);
};
class PolygonAirspaceRestriction : public AirspaceRestriction
{
Q_OBJECT
public:
PolygonAirspaceRestriction(const QVariantList& polygon, QObject* parent = NULL);
Q_PROPERTY(QVariantList polygon MEMBER _polygon CONSTANT)
const QVariantList& getPolygon() const { return _polygon; }
private:
QVariantList _polygon;
};
class CircularAirspaceRestriction : public AirspaceRestriction
{
Q_OBJECT
public:
CircularAirspaceRestriction(const QGeoCoordinate& center, double radius, QObject* parent = NULL);
Q_PROPERTY(QGeoCoordinate center MEMBER _center CONSTANT)
Q_PROPERTY(double radius MEMBER _radius CONSTANT)
private:
QGeoCoordinate _center;
double _radius;
};
/**
* @class AirspaceRestrictionProvider
* Base class that queries for airspace restrictions
*/
class AirspaceRestrictionProvider : public QObject {
Q_OBJECT
public:
AirspaceRestrictionProvider() = default;
~AirspaceRestrictionProvider() = default;
/**
* Set region of interest that should be queried. When finished, the requestDone() signal will be emmited.
* @param center Center coordinate for ROI
* @param radiusMeters Radius in meters around center which is of interest
*/
virtual void setROI(const QGeoCoordinate& center, double radiusMeters) = 0;
const QList<PolygonAirspaceRestriction*>& polygons() const { return _polygonList; }
const QList<CircularAirspaceRestriction*>& circles() const { return _circleList; }
signals:
void requestDone(bool success);
protected:
QList<PolygonAirspaceRestriction*> _polygonList;
QList<CircularAirspaceRestriction*> _circleList;
};
class AirspaceManagerPerVehicle;
class Vehicle;
/**
* @class AirspaceManager
* Base class for airspace management. There is one (global) instantiation of this
*/
class AirspaceManager : public QGCTool {
Q_OBJECT
public:
AirspaceManager(QGCApplication* app, QGCToolbox* toolbox);
virtual ~AirspaceManager();
/**
* Factory method to create an AirspaceManagerPerVehicle object
*/
virtual AirspaceManagerPerVehicle* instantiateVehicle(const Vehicle& vehicle) = 0;
/**
*
* Factory method to create an AirspaceRestrictionProvider object
*/
virtual AirspaceRestrictionProvider* instantiateRestrictionProvider() = 0;
/**
* Set the ROI for airspace information (restrictions shown in UI)
* @param center Center coordinate for ROI
* @param radiusMeters Radius in meters around center which is of interest
*/
void setROI(const QGeoCoordinate& center, double radiusMeters);
QmlObjectListModel* polygonRestrictions(void) { return &_polygonRestrictions; }
QmlObjectListModel* circularRestrictions(void) { return &_circleRestrictions; }
void setToolbox(QGCToolbox* toolbox) override;
/**
* Name of the airspace management provider (used in the UI)
*/
virtual QString name() const = 0;
private slots:
void _restrictionsUpdated(bool success);
private:
void _updateToROI();
AirspaceRestrictionProvider* _restrictionsProvider = nullptr; ///< restrictions that are shown in the UI
QmlObjectListModel _polygonRestrictions; ///< current polygon restrictions
QmlObjectListModel _circleRestrictions; ///< current circle restrictions
QTimer _roiUpdateTimer;
QGeoCoordinate _roiCenter;
double _roiRadius;
};
/**
* @class AirspaceManagerPerVehicle
* Base class for per-vehicle management (each vehicle has one (or zero) of these)
*/
class AirspaceManagerPerVehicle : public QObject {
Q_OBJECT
public:
AirspaceManagerPerVehicle(const Vehicle& vehicle);
virtual ~AirspaceManagerPerVehicle() = default;
/**
* create/upload a flight from a mission. This should update the flight permit status.
* There can only be one active flight for each vehicle.
*/
virtual void createFlight(const QList<MissionItem*>& missionItems) = 0;
/**
* get the current flight permit status
*/
virtual AirspaceAuthorization::PermitStatus flightPermitStatus() const = 0;
/**
* Setup the connection and start sending telemetry
*/
virtual void startTelemetryStream() = 0;
virtual void stopTelemetryStream() = 0;
virtual bool isTelemetryStreaming() const = 0;
public slots:
virtual void endFlight() = 0;
signals:
void trafficUpdate(QString traffic_id, QString vehicle_id, QGeoCoordinate location, float heading);
void flightPermitStatusChanged();
protected slots:
virtual void vehicleMavlinkMessageReceived(const mavlink_message_t& message) = 0;
protected:
const Vehicle& _vehicle;
private slots:
void _vehicleArmedChanged(bool armed);
private:
bool _vehicleWasInMissionMode = false; ///< true if the vehicle was in mission mode when arming
};
......@@ -21,7 +21,7 @@ GeoFenceManager::GeoFenceManager(Vehicle* vehicle)
: _vehicle (vehicle)
, _planManager (vehicle, MAV_MISSION_TYPE_FENCE)
, _firstParamLoadComplete (false)
, _airmapManager (qgcApp()->toolbox()->airMapManager())
, _airspaceManager (qgcApp()->toolbox()->airspaceManager())
{
connect(&_planManager, &PlanManager::inProgressChanged, this, &GeoFenceManager::inProgressChanged);
connect(&_planManager, &PlanManager::error, this, &GeoFenceManager::error);
......@@ -101,31 +101,6 @@ void GeoFenceManager::sendToVehicle(const QGeoCoordinate& breachReturn,
fenceItems.append(item);
}
// send AirMap polygons
const QmlObjectListModel& airmapPolygons = *_airmapManager->polygonRestrictions();
for (int i = 0; i < airmapPolygons.count(); ++i) {
PolygonAirspaceRestriction *polygon = (PolygonAirspaceRestriction*)airmapPolygons[i];
int polygonCount = polygon->getPolygon().count() - 1; // last vertex is equal to the first
for (int j = 0; j < polygonCount; ++j) {
const QGeoCoordinate& vertex = polygon->getPolygon()[j].value<QGeoCoordinate>();
MissionItem* item = new MissionItem(0,
MAV_CMD_NAV_FENCE_POLYGON_VERTEX_EXCLUSION,
MAV_FRAME_GLOBAL,
polygonCount, // vertex count
0, 0, 0, // param 2-4 unused
vertex.latitude(),
vertex.longitude(),
0, // param 7 unused
false, // autocontinue
false, // isCurrentItem
this); // parent
fenceItems.append(item);
}
}
// TODO: circles too
_planManager.writeMissionItems(fenceItems);
for (int i=0; i<fenceItems.count(); i++) {
......
......@@ -13,7 +13,7 @@
#include <QObject>
#include <QGeoCoordinate>
#include "AirMapManager.h"
#include "AirspaceManagement.h"
#include "QGCLoggingCategory.h"
#include "FactSystem.h"
#include "PlanManager.h"
......@@ -97,7 +97,7 @@ private:
bool _firstParamLoadComplete;
QList<QGCFencePolygon> _sendPolygons;
QList<QGCFenceCircle> _sendCircles;
AirMapManager* _airmapManager;
AirspaceManager* _airspaceManager;
};
#endif
......@@ -18,7 +18,6 @@
#include "QGCApplication.h"
#include "MissionCommandTree.h"
#include "MissionCommandUIInfo.h"
#include "AirMapManager.h"
QGC_LOGGING_CATEGORY(PlanManagerLog, "PlanManagerLog")
......@@ -80,9 +79,10 @@ void PlanManager::writeMissionItems(const QList<MissionItem*>& missionItems)
}
if (_planType == MAV_MISSION_TYPE_MISSION) {
AirMapManager *airmapManager = qgcApp()->toolbox()->airMapManager();
if(airmapManager) {
airmapManager->createFlight(missionItems);
// upload the flight to the airspace management backend
AirspaceManagerPerVehicle* airspaceManager = _vehicle->airspaceManager();
if (airspaceManager) {
airspaceManager->createFlight(missionItems);
}
}
......
......@@ -84,6 +84,7 @@
#include "CameraCalc.h"
#include "VisualMissionItem.h"
#include "AirMapController.h"
#include "AirspaceController.h"
#ifndef NO_SERIAL_LINK
#include "SerialLink.h"
......@@ -362,6 +363,7 @@ void QGCApplication::_initCommon(void)
qmlRegisterUncreatableType<QGCCameraManager> ("QGroundControl.Vehicle", 1, 0, "QGCCameraManager", "Reference only");
qmlRegisterUncreatableType<QGCCameraControl> ("QGroundControl.Vehicle", 1, 0, "QGCCameraControl", "Reference only");
qmlRegisterUncreatableType<AirMapController> ("QGroundControl.Vehicle", 1, 0, "AirMapController", "Reference only");
qmlRegisterUncreatableType<AirspaceController> ("QGroundControl.Vehicle", 1, 0, "AirspaceController", "Reference only");
qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");
qmlRegisterUncreatableType<QGCPositionManager> ("QGroundControl.QGCPositionManager", 1, 0, "QGCPositionManager", "Reference only");
......
......@@ -57,7 +57,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
, _mavlinkLogManager (NULL)
, _corePlugin (NULL)
, _settingsManager (NULL)
, _airMapManager (NULL)
, _airspaceManager (NULL)
{
// SettingsManager must be first so settings are available to any subsequent tools
_settingsManager = new SettingsManager(app, this);
......@@ -82,7 +82,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
_followMe = new FollowMe (app, this);
_videoManager = new VideoManager (app, this);
_mavlinkLogManager = new MAVLinkLogManager (app, this);
_airMapManager = new AirMapManager (app, this);
_airspaceManager = new AirMapManager (app, this);
}
void QGCToolbox::setChildToolboxes(void)
......@@ -109,7 +109,7 @@ void QGCToolbox::setChildToolboxes(void)
_qgcPositionManager->setToolbox(this);
_videoManager->setToolbox(this);
_mavlinkLogManager->setToolbox(this);
_airMapManager->setToolbox(this);
_airspaceManager->setToolbox(this);
}
void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
......
......@@ -32,7 +32,7 @@ class VideoManager;
class MAVLinkLogManager;
class QGCCorePlugin;
class SettingsManager;
class AirMapManager;
class AirspaceManager;
/// This is used to manage all of our top level services/tools
class QGCToolbox : public QObject {
......@@ -57,7 +57,7 @@ public:
MAVLinkLogManager* mavlinkLogManager(void) { return _mavlinkLogManager; }
QGCCorePlugin* corePlugin(void) { return _corePlugin; }
SettingsManager* settingsManager(void) { return _settingsManager; }
AirMapManager* airMapManager(void) { return _airMapManager; }
AirspaceManager* airspaceManager(void) { return _airspaceManager; }
#ifndef __mobile__
GPSManager* gpsManager(void) { return _gpsManager; }
......@@ -88,7 +88,7 @@ private:
MAVLinkLogManager* _mavlinkLogManager;
QGCCorePlugin* _corePlugin;
SettingsManager* _settingsManager;
AirMapManager* _airMapManager;
AirspaceManager* _airspaceManager;
friend class QGCApplication;
};
......
......@@ -34,6 +34,7 @@
#include "ADSBVehicle.h"
#include "QGCCameraManager.h"
#include "AirMapController.h"
#include "AirspaceController.h"
QGC_LOGGING_CATEGORY(VehicleLog, "VehicleLog")
......@@ -132,7 +133,8 @@ Vehicle::Vehicle(LinkInterface* link,
, _rallyPointManager(NULL)
, _rallyPointManagerInitialRequestSent(false)
, _parameterManager(NULL)
, _airMapController(NULL)
, _airspaceController(NULL)
, _airspaceManagerPerVehicle(NULL)
, _armed(false)
, _base_mode(0)
, _custom_mode(0)
......@@ -255,8 +257,17 @@ Vehicle::Vehicle(LinkInterface* link,
_adsbTimer.setSingleShot(false);
_adsbTimer.start(1000);
_airMapController = new AirMapController(this);
connect(qgcApp()->toolbox()->airMapManager(), &AirMapManager::trafficUpdate, this, &Vehicle::_trafficUpdate);
_airspaceController = new AirspaceController(this);
AirspaceManager* airspaceManager = _toolbox->airspaceManager();
if (airspaceManager) {
_airspaceManagerPerVehicle = airspaceManager->instantiateVehicle(*this);
if (_airspaceManagerPerVehicle) {
connect(_airspaceManagerPerVehicle, &AirspaceManagerPerVehicle::trafficUpdate, this, &Vehicle::_trafficUpdate);
connect(_airspaceManagerPerVehicle, &AirspaceManagerPerVehicle::flightPermitStatusChanged, this, &Vehicle::flightPermitStatusChanged);
}
}
}
// Disconnected Vehicle for offline editing
......@@ -315,7 +326,8 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType,
, _rallyPointManager(NULL)
, _rallyPointManagerInitialRequestSent(false)
, _parameterManager(NULL)
, _airMapController(NULL)
, _airspaceController(NULL)
, _airspaceManagerPerVehicle(NULL)
, _armed(false)
, _base_mode(0)
, _custom_mode(0)
......@@ -445,6 +457,9 @@ Vehicle::~Vehicle()
delete _mav;
_mav = NULL;
if (_airspaceManagerPerVehicle) {
delete _airspaceManagerPerVehicle;
}
}
void Vehicle::prepareDelete()
......
......@@ -20,6 +20,7 @@
#include "MAVLinkProtocol.h"
#include "UASMessageHandler.h"
#include "SettingsFact.h"
#include <AirspaceManagement.h>
class UAS;
class UASInterface;
......@@ -36,6 +37,7 @@ class SettingsManager;
class ADSBVehicle;
class QGCCameraManager;
class AirMapController;
class AirspaceController;
Q_DECLARE_LOGGING_CATEGORY(VehicleLog)
......@@ -322,6 +324,8 @@ public:
Q_PROPERTY(QGCCameraManager* dynamicCameras READ dynamicCameras NOTIFY dynamicCamerasChanged)
Q_PROPERTY(QString hobbsMeter READ hobbsMeter NOTIFY hobbsMeterChanged)
Q_PROPERTY(AirMapController* airMapController READ airMapController CONSTANT)
Q_PROPERTY(AirspaceAuthorization::PermitStatus flightPermitStatus READ flightPermitStatus NOTIFY flightPermitStatusChanged) ///< state of flight permission
Q_PROPERTY(AirspaceController* airspaceController READ airspaceController CONSTANT)
// Vehicle state used for guided control
Q_PROPERTY(bool flying READ flying NOTIFY flyingChanged) ///< Vehicle is flying
......@@ -537,7 +541,7 @@ public:
QmlObjectListModel* cameraTriggerPoints(void) { return &_cameraTriggerPoints; }
QmlObjectListModel* adsbVehicles(void) { return &_adsbVehicles; }
AirMapController* airMapController() { return _airMapController; }
AirspaceController* airspaceController() { return _airspaceController; }
int flowImageIndex() { return _flowImageIndex; }
......@@ -718,6 +722,11 @@ public:
/// Vehicle is about to be deleted
void prepareDelete();
AirspaceAuthorization::PermitStatus flightPermitStatus() const
{ return _airspaceManagerPerVehicle ? _airspaceManagerPerVehicle->flightPermitStatus() : AirspaceAuthorization::PermitUnknown; }
AirspaceManagerPerVehicle* airspaceManager() const { return _airspaceManagerPerVehicle; }
signals:
void allLinksInactive(Vehicle* vehicle);
void coordinateChanged(QGeoCoordinate coordinate);
......@@ -749,6 +758,8 @@ signals:
void capabilitiesKnownChanged(bool capabilitiesKnown);
void initialPlanRequestCompleteChanged(bool initialPlanRequestComplete);
void capabilityBitsChanged(uint64_t capabilityBits);
void flightPermitStatusChanged();
void messagesReceivedChanged ();
void messagesSentChanged ();
......@@ -997,7 +1008,8 @@ private:
ParameterManager* _parameterManager;
AirMapController* _airMapController;
AirspaceController* _airspaceController;
AirspaceManagerPerVehicle* _airspaceManagerPerVehicle;
bool _armed; ///< true: vehicle is armed
uint8_t _base_mode; ///< base_mode from HEARTBEAT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment