VisualMissionItem.cc 6.85 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8
 *
 * 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
#include "PlanMasterController.h"
21

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

26 27 28 29 30
VisualMissionItem::VisualMissionItem(PlanMasterController* masterController, bool flyView, QObject* parent)
    : QObject           (parent)
    , _flyView          (flyView)
    , _masterController (masterController)
    , _controllerVehicle(masterController->controllerVehicle())
31
{
32
    _commonInit();
33 34
}

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

41 42 43 44 45
    _commonInit();
}

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

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

const VisualMissionItem& VisualMissionItem::operator=(const VisualMissionItem& other)
{
59 60
    _masterController = other._masterController;
    _controllerVehicle = other._controllerVehicle;
61 62 63

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

    return *this;
}

VisualMissionItem::~VisualMissionItem()
{    
}

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

87 88 89 90 91 92 93 94
void VisualMissionItem::setHasCurrentChildItem(bool hasCurrentChildItem)
{
    if (_hasCurrentChildItem != hasCurrentChildItem) {
        _hasCurrentChildItem = hasCurrentChildItem;
        emit hasCurrentChildItemChanged(hasCurrentChildItem);
    }
}

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

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

void VisualMissionItem::setAltPercent(double altPercent)
{
113 114 115 116
    if (!qFuzzyCompare(_altPercent, altPercent)) {
        _altPercent = altPercent;
        emit altPercentChanged(_altPercent);
    }
117 118
}

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

127 128 129 130 131 132 133 134
void VisualMissionItem::setTerrainCollision(bool terrainCollision)
{
    if (terrainCollision != _terrainCollision) {
        _terrainCollision = terrainCollision;
        emit terrainCollisionChanged(terrainCollision);
    }
}

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

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

void VisualMissionItem::setMissionVehicleYaw(double vehicleYaw)
{
    if (!qFuzzyCompare(_missionVehicleYaw, vehicleYaw)) {
        _missionVehicleYaw = vehicleYaw;
        emit missionVehicleYawChanged(_missionVehicleYaw);
    }
}
162 163 164

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

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

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

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

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

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