GeoFenceController.cc 6.99 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/****************************************************************************
 *
 *   (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)
{
27

28 29 30 31 32 33 34 35 36 37 38 39 40
}

GeoFenceController::~GeoFenceController()
{

}

void GeoFenceController::start(bool editMode)
{
    qCDebug(GeoFenceControllerLog) << "start editMode" << editMode;

    PlanElementController::start(editMode);

41
    connect(&_polygon, &QGCMapPolygon::dirtyChanged, this, &GeoFenceController::_polygonDirtyChanged);
42 43 44 45
}

void GeoFenceController::setBreachReturnPoint(const QGeoCoordinate& breachReturnPoint)
{
46 47 48
    if (_breachReturnPoint != breachReturnPoint) {
        _breachReturnPoint = breachReturnPoint;
        setDirty(true);
49 50 51 52
        emit breachReturnPointChanged(breachReturnPoint);
    }
}

53
void GeoFenceController::_signalAll(void)
54
{
55 56 57 58 59 60 61
    emit fenceSupportedChanged(fenceSupported());
    emit circleSupportedChanged(circleSupported());
    emit polygonSupportedChanged(polygonSupported());
    emit breachReturnSupportedChanged(breachReturnSupported());
    emit circleRadiusChanged(circleRadius());
    emit paramsChanged(params());
    emit paramLabelsChanged(paramLabels());
62
    emit editorQmlChanged(editorQml());
63 64
}

65
void GeoFenceController::_activeVehicleBeingRemoved(void)
66 67
{
    _clearGeoFence();
68
    _signalAll();
69
    _activeVehicle->geoFenceManager()->disconnect(this);
70 71 72 73
}

void GeoFenceController::_activeVehicleSet(void)
{
74 75 76 77 78 79 80 81 82 83 84 85 86
    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);

Don Gagne's avatar
Don Gagne committed
87 88
    _signalAll();

89 90 91 92 93 94
    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();
        }
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    }
}

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)
{
125
    if (_activeVehicle->getParameterLoader()->parametersAreReady() && !syncInProgress()) {
126
        _activeVehicle->geoFenceManager()->loadFromVehicle();
127
    } else {
128
        qCWarning(GeoFenceControllerLog) << "GeoFenceController::loadFromVehicle call at wrong time" << _activeVehicle->getParameterLoader()->parametersAreReady() << syncInProgress();
129 130 131 132 133
    }
}

void GeoFenceController::sendToVehicle(void)
{
134
    if (_activeVehicle->getParameterLoader()->parametersAreReady() && !syncInProgress()) {
135 136
        _activeVehicle->geoFenceManager()->setPolygon(polygon());
        _activeVehicle->geoFenceManager()->setBreachReturnPoint(breachReturnPoint());
137
        setDirty(false);
138 139
        _polygon.setDirty(false);
        _activeVehicle->geoFenceManager()->sendToVehicle();
140
    } else {
141
        qCWarning(GeoFenceControllerLog) << "GeoFenceController::loadFromVehicle call at wrong time" << _activeVehicle->getParameterLoader()->parametersAreReady() << syncInProgress();
142 143 144 145 146 147
    }
}

void GeoFenceController::_clearGeoFence(void)
{
    setBreachReturnPoint(QGeoCoordinate());
148
    _polygon.clear();
149 150 151 152
}

bool GeoFenceController::syncInProgress(void) const
{
153
    return _activeVehicle->geoFenceManager()->inProgress();
154 155 156 157
}

bool GeoFenceController::dirty(void) const
{
158
    return _dirty | _polygon.dirty();
159 160 161 162 163 164 165 166
}


void GeoFenceController::setDirty(bool dirty)
{
    if (dirty != _dirty) {
        _dirty = dirty;
        if (!dirty) {
167
            _polygon.setDirty(dirty);
168 169 170 171 172 173 174 175 176 177 178
        }
        emit dirtyChanged(dirty);
    }
}

void GeoFenceController::_polygonDirtyChanged(bool dirty)
{
    if (dirty) {
        setDirty(true);
    }
}
179 180 181

bool GeoFenceController::fenceSupported(void) const
{
182
    return _activeVehicle->geoFenceManager()->fenceSupported();
183 184 185 186
}

bool GeoFenceController::circleSupported(void) const
{
187
    return _activeVehicle->geoFenceManager()->circleSupported();
188 189 190 191
}

bool GeoFenceController::polygonSupported(void) const
{
192
    return _activeVehicle->geoFenceManager()->polygonSupported();
193 194 195 196
}

bool GeoFenceController::breachReturnSupported(void) const
{
197
    return _activeVehicle->geoFenceManager()->breachReturnSupported();
198 199 200 201 202 203 204 205 206 207
}

void GeoFenceController::_setDirty(void)
{
    setDirty(true);
}

void GeoFenceController::_setPolygon(const QList<QGeoCoordinate>& polygon)
{
    _polygon.setPath(polygon);
Don Gagne's avatar
Don Gagne committed
208 209
    // This is coming from a GeoFenceManager::loadFromVehicle call
    setDirty(false);
210 211 212 213
}

float GeoFenceController::circleRadius(void) const
{
214
    return _activeVehicle->geoFenceManager()->circleRadius();
215 216 217 218
}

QVariantList GeoFenceController::params(void) const
{
219
    return _activeVehicle->geoFenceManager()->params();
220 221 222 223
}

QStringList GeoFenceController::paramLabels(void) const
{
224
    return _activeVehicle->geoFenceManager()->paramLabels();
225
}
226 227 228

QString GeoFenceController::editorQml(void) const
{
229
    return _activeVehicle->geoFenceManager()->editorQml();
230
}