VisualMissionItem.cc 6.75 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *
 *   (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.
 *
 ****************************************************************************/
9 10 11 12 13 14 15 16 17


#include <QStringList>
#include <QDebug>

#include "VisualMissionItem.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include "JsonHelper.h"
18
#include "TerrainQuery.h"
19
#include "TakeoffMissionItem.h"
20

Don Gagne's avatar
Don Gagne committed
21 22 23 24
const char* VisualMissionItem::jsonTypeKey =                "type";
const char* VisualMissionItem::jsonTypeSimpleItemValue =    "SimpleItem";
const char* VisualMissionItem::jsonTypeComplexItemValue =   "ComplexItem";

25
VisualMissionItem::VisualMissionItem(Vehicle* vehicle, bool flyView, QObject* parent)
26 27
    : QObject                   (parent)
    , _vehicle                  (vehicle)
28
    , _flyView                  (flyView)
29
{
30
    _commonInit();
31 32
}

33
VisualMissionItem::VisualMissionItem(const VisualMissionItem& other, bool flyView, QObject* parent)
34
    : QObject                   (parent)
35
    , _vehicle                  (nullptr)
36
    , _flyView                  (flyView)
37 38
{
    *this = other;
39

40 41 42 43 44
    _commonInit();
}

void VisualMissionItem::_commonInit(void)
{
45
    // Don't get terrain altitude information for submarines or boats
46
    if (_vehicle->vehicleType() != MAV_TYPE_SUBMARINE && _vehicle->vehicleType() != MAV_TYPE_SURFACE_BOAT) {
47 48 49 50
        _updateTerrainTimer.setInterval(500);
        _updateTerrainTimer.setSingleShot(true);
        connect(&_updateTerrainTimer, &QTimer::timeout, this, &VisualMissionItem::_reallyUpdateTerrainAltitude);

51 52
        connect(this, &VisualMissionItem::coordinateChanged, this, &VisualMissionItem::_updateTerrainAltitude);
    }
53 54 55 56 57 58 59 60
}

const VisualMissionItem& VisualMissionItem::operator=(const VisualMissionItem& other)
{
    _vehicle = other._vehicle;

    setIsCurrentItem(other._isCurrentItem);
    setDirty(other._dirty);
61
    _homePositionSpecialCase = other._homePositionSpecialCase;
62
    _terrainAltitude = other._terrainAltitude;
63 64
    setAltDifference(other._altDifference);
    setAltPercent(other._altPercent);
65
    setTerrainPercent(other._terrainPercent);
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    setAzimuth(other._azimuth);
    setDistance(other._distance);

    return *this;
}

VisualMissionItem::~VisualMissionItem()
{    
}

void VisualMissionItem::setIsCurrentItem(bool isCurrentItem)
{
    if (_isCurrentItem != isCurrentItem) {
        _isCurrentItem = isCurrentItem;
        emit isCurrentItemChanged(isCurrentItem);
    }
}

84 85 86 87 88 89 90 91
void VisualMissionItem::setHasCurrentChildItem(bool hasCurrentChildItem)
{
    if (_hasCurrentChildItem != hasCurrentChildItem) {
        _hasCurrentChildItem = hasCurrentChildItem;
        emit hasCurrentChildItemChanged(hasCurrentChildItem);
    }
}

92 93
void VisualMissionItem::setDistance(double distance)
{
94 95 96 97
    if (!qFuzzyCompare(_distance, distance)) {
        _distance = distance;
        emit distanceChanged(_distance);
    }
98 99 100 101
}

void VisualMissionItem::setAltDifference(double altDifference)
{
102 103 104 105
    if (!qFuzzyCompare(_altDifference, altDifference)) {
        _altDifference = altDifference;
        emit altDifferenceChanged(_altDifference);
    }
106 107 108 109
}

void VisualMissionItem::setAltPercent(double altPercent)
{
110 111 112 113
    if (!qFuzzyCompare(_altPercent, altPercent)) {
        _altPercent = altPercent;
        emit altPercentChanged(_altPercent);
    }
114 115
}

116 117 118 119 120 121 122 123
void VisualMissionItem::setTerrainPercent(double terrainPercent)
{
    if (!qFuzzyCompare(_terrainPercent, terrainPercent)) {
        _terrainPercent = terrainPercent;
        emit terrainPercentChanged(terrainPercent);
    }
}

124 125 126 127 128 129 130 131
void VisualMissionItem::setTerrainCollision(bool terrainCollision)
{
    if (terrainCollision != _terrainCollision) {
        _terrainCollision = terrainCollision;
        emit terrainCollisionChanged(terrainCollision);
    }
}

132 133
void VisualMissionItem::setAzimuth(double azimuth)
{
134 135 136 137
    if (!qFuzzyCompare(_azimuth, azimuth)) {
        _azimuth = azimuth;
        emit azimuthChanged(_azimuth);
    }
138
}
139

DonLakeFlyer's avatar
DonLakeFlyer committed
140 141 142
void VisualMissionItem::setMissionFlightStatus(MissionController::MissionFlightStatus_t& missionFlightStatus)
{
    _missionFlightStatus = missionFlightStatus;
DonLakeFlyer's avatar
DonLakeFlyer committed
143 144 145
    if (qIsNaN(_missionFlightStatus.gimbalYaw) && qIsNaN(_missionGimbalYaw)) {
        return;
    }
DonLakeFlyer's avatar
DonLakeFlyer committed
146 147 148 149 150 151 152 153 154 155 156 157 158
    if (_missionFlightStatus.gimbalYaw != _missionGimbalYaw) {
        _missionGimbalYaw = _missionFlightStatus.gimbalYaw;
        emit missionGimbalYawChanged(_missionGimbalYaw);
    }
}

void VisualMissionItem::setMissionVehicleYaw(double vehicleYaw)
{
    if (!qFuzzyCompare(_missionVehicleYaw, vehicleYaw)) {
        _missionVehicleYaw = vehicleYaw;
        emit missionVehicleYawChanged(_missionVehicleYaw);
    }
}
159 160 161

void VisualMissionItem::_updateTerrainAltitude(void)
{
162 163 164 165
    if (coordinate().latitude() == 0 && coordinate().longitude() == 0) {
        // This is an intermediate state we don't react to
        return;
    }
166 167 168 169 170 171 172 173 174
    if (!_flyView && specifiesCoordinate() && coordinate().isValid()) {
        if (specifiesCoordinate()) {
            if (coordinate().isValid()) {
                // We use a timer so that any additional requests before the timer fires result in only a single request
                _updateTerrainTimer.start();
            }
        } else {
            _terrainAltitude = qQNaN();
        }
175 176 177 178 179 180
    }
}

void VisualMissionItem::_reallyUpdateTerrainAltitude(void)
{
    QGeoCoordinate coord = coordinate();
181
    if (specifiesCoordinate() && coord.isValid() && (qIsNaN(_terrainAltitude) || !qFuzzyCompare(_lastLatTerrainQuery, coord.latitude()) || qFuzzyCompare(_lastLonTerrainQuery, coord.longitude()))) {
182 183
        _lastLatTerrainQuery = coord.latitude();
        _lastLonTerrainQuery = coord.longitude();
184
        TerrainAtCoordinateQuery* terrain = new TerrainAtCoordinateQuery(this);
DonLakeFlyer's avatar
DonLakeFlyer committed
185
        connect(terrain, &TerrainAtCoordinateQuery::terrainDataReceived, this, &VisualMissionItem::_terrainDataReceived);
186 187
        QList<QGeoCoordinate> rgCoord;
        rgCoord.append(coordinate());
188
        terrain->requestData(rgCoord);
189 190 191
    }
}

192
void VisualMissionItem::_terrainDataReceived(bool success, QList<double> heights)
193
{
Don Gagne's avatar
Don Gagne committed
194 195 196
    _terrainAltitude = success ? heights[0] : qQNaN();
    emit terrainAltitudeChanged(_terrainAltitude);
    sender()->deleteLater();
197
}
198 199 200 201 202 203 204 205 206

void VisualMissionItem::_setBoundingCube(QGCGeoBoundingCube bc)
{
    if (bc != _boundingCube) {
        _boundingCube = bc;
        emit boundingCubeChanged();
    }
}

207 208 209 210 211 212 213
void VisualMissionItem::setWizardMode(bool wizardMode)
{
    if (wizardMode != _wizardMode) {
        _wizardMode = wizardMode;
        emit wizardModeChanged(_wizardMode);
    }
}
214 215 216 217 218 219 220 221

void VisualMissionItem::setParentItem(VisualMissionItem* parentItem)
{
    if (_parentItem != parentItem) {
        _parentItem = parentItem;
        emit parentItemChanged(parentItem);
    }
}