地面站终端 App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
7.7 KiB

/****************************************************************************
*
* (c) 2009-2016 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.
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "GeoFenceController.h"
#include "Vehicle.h"
#include "FirmwarePlugin.h"
#include "MAVLinkProtocol.h"
#include "QGCApplication.h"
#include "ParameterLoader.h"
QGC_LOGGING_CATEGORY(GeoFenceControllerLog, "GeoFenceControllerLog")
GeoFenceController::GeoFenceController(QObject* parent)
: PlanElementController(parent)
, _dirty(false)
{
}
GeoFenceController::~GeoFenceController()
{
}
void GeoFenceController::start(bool editMode)
{
qCDebug(GeoFenceControllerLog) << "start editMode" << editMode;
PlanElementController::start(editMode);
connect(&_polygon, &QGCMapPolygon::dirtyChanged, this, &GeoFenceController::_polygonDirtyChanged);
}
void GeoFenceController::setBreachReturnPoint(const QGeoCoordinate& breachReturnPoint)
{
if (_breachReturnPoint != breachReturnPoint) {
_breachReturnPoint = breachReturnPoint;
setDirty(true);
emit breachReturnPointChanged(breachReturnPoint);
}
}
void GeoFenceController::_signalAll(void)
{
emit fenceSupportedChanged(fenceSupported());
emit circleSupportedChanged(circleSupported());
emit polygonSupportedChanged(polygonSupported());
emit breachReturnSupportedChanged(breachReturnSupported());
emit circleRadiusChanged(circleRadius());
emit paramsChanged(params());
emit paramLabelsChanged(paramLabels());
emit editorQmlChanged(editorQml());
}
void GeoFenceController::_activeVehicleBeingRemoved(Vehicle* vehicle)
{
_clearGeoFence();
_signalAll();
vehicle->geoFenceManager()->disconnect(this);
}
void GeoFenceController::_activeVehicleSet(void)
{
GeoFenceManager* geoFenceManager = _activeVehicle->geoFenceManager();
connect(geoFenceManager, &GeoFenceManager::circleSupportedChanged, this, &GeoFenceController::_setDirty);
connect(geoFenceManager, &GeoFenceManager::polygonSupportedChanged, this, &GeoFenceController::_setDirty);
connect(geoFenceManager, &GeoFenceManager::fenceSupportedChanged, this, &GeoFenceController::fenceSupportedChanged);
connect(geoFenceManager, &GeoFenceManager::circleSupportedChanged, this, &GeoFenceController::circleSupportedChanged);
connect(geoFenceManager, &GeoFenceManager::polygonSupportedChanged, this, &GeoFenceController::polygonSupportedChanged);
connect(geoFenceManager, &GeoFenceManager::breachReturnSupportedChanged, this, &GeoFenceController::breachReturnSupportedChanged);
connect(geoFenceManager, &GeoFenceManager::circleRadiusChanged, this, &GeoFenceController::circleRadiusChanged);
connect(geoFenceManager, &GeoFenceManager::polygonChanged, this, &GeoFenceController::_setPolygon);
connect(geoFenceManager, &GeoFenceManager::breachReturnPointChanged, this, &GeoFenceController::setBreachReturnPoint);
connect(geoFenceManager, &GeoFenceManager::paramsChanged, this, &GeoFenceController::paramsChanged);
connect(geoFenceManager, &GeoFenceManager::paramLabelsChanged, this, &GeoFenceController::paramLabelsChanged);
_signalAll();
if (_activeVehicle->getParameterLoader()->parametersAreReady()) {
if (!syncInProgress()) {
// We are switching between two previously existing vehicles. We have to manually ask for the items from the Vehicle.
// We don't request mission items for new vehicles since that will happen autamatically.
loadFromVehicle();
}
}
}
void GeoFenceController::loadFromFilePicker(void)
{
}
void GeoFenceController::loadFromFile(const QString& filename)
{
Q_UNUSED(filename);
}
void GeoFenceController::saveToFilePicker(void)
{
}
void GeoFenceController::saveToFile(const QString& filename)
{
Q_UNUSED(filename);
}
void GeoFenceController::removeAll(void)
{
_clearGeoFence();
}
void GeoFenceController::loadFromVehicle(void)
{
if (_activeVehicle && _activeVehicle->getParameterLoader()->parametersAreReady() && !syncInProgress()) {
_activeVehicle->geoFenceManager()->loadFromVehicle();
} else {
qCWarning(GeoFenceControllerLog) << "GeoFenceController::loadFromVehicle call at wrong time" << _activeVehicle << _activeVehicle->getParameterLoader()->parametersAreReady() << syncInProgress();
}
}
void GeoFenceController::sendToVehicle(void)
{
if (_activeVehicle && _activeVehicle->getParameterLoader()->parametersAreReady() && !syncInProgress()) {
_activeVehicle->geoFenceManager()->setPolygon(polygon());
_activeVehicle->geoFenceManager()->setBreachReturnPoint(breachReturnPoint());
setDirty(false);
_polygon.setDirty(false);
_activeVehicle->geoFenceManager()->sendToVehicle();
} else {
qCWarning(GeoFenceControllerLog) << "GeoFenceController::loadFromVehicle call at wrong time" << _activeVehicle << _activeVehicle->getParameterLoader()->parametersAreReady() << syncInProgress();
}
}
void GeoFenceController::_clearGeoFence(void)
{
setBreachReturnPoint(QGeoCoordinate());
_polygon.clear();
}
bool GeoFenceController::syncInProgress(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->inProgress();
} else {
return false;
}
}
bool GeoFenceController::dirty(void) const
{
return _dirty | _polygon.dirty();
}
void GeoFenceController::setDirty(bool dirty)
{
if (dirty != _dirty) {
_dirty = dirty;
if (!dirty) {
_polygon.setDirty(dirty);
}
emit dirtyChanged(dirty);
}
}
void GeoFenceController::_polygonDirtyChanged(bool dirty)
{
if (dirty) {
setDirty(true);
}
}
bool GeoFenceController::fenceSupported(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->fenceSupported();
} else {
return true;
}
}
bool GeoFenceController::circleSupported(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->circleSupported();
} else {
return true;
}
}
bool GeoFenceController::polygonSupported(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->polygonSupported();
} else {
return true;
}
}
bool GeoFenceController::breachReturnSupported(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->breachReturnSupported();
} else {
return true;
}
}
void GeoFenceController::_setDirty(void)
{
setDirty(true);
}
void GeoFenceController::_setPolygon(const QList<QGeoCoordinate>& polygon)
{
_polygon.setPath(polygon);
// This is coming from a GeoFenceManager::loadFromVehicle call
setDirty(false);
}
float GeoFenceController::circleRadius(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->circleRadius();
} else {
return 0.0;
}
}
QVariantList GeoFenceController::params(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->params();
} else {
return QVariantList();
}
}
QStringList GeoFenceController::paramLabels(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->paramLabels();
} else {
return QStringList();
}
}
QString GeoFenceController::editorQml(void) const
{
if (_activeVehicle) {
return _activeVehicle->geoFenceManager()->editorQml();
} else {
// FIXME: Offline editing support
return QString();
}
}