VisualMissionItem.h 20.5 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 9
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10
#pragma once
11 12 13 14 15 16 17 18 19 20 21 22 23 24

#include <QObject>
#include <QString>
#include <QtQml>
#include <QTextStream>
#include <QJsonObject>
#include <QGeoCoordinate>

#include "QGCMAVLink.h"
#include "QGC.h"
#include "QmlObjectListModel.h"
#include "Fact.h"
#include "QGCLoggingCategory.h"
#include "QmlObjectListModel.h"
25
#include "Vehicle.h"
DonLakeFlyer's avatar
DonLakeFlyer committed
26
#include "MissionController.h"
27

28
class MissionItem;
29
class PlanMasterController;
30 31
class MissionController;
class TerrainAtCoordinateQuery;
32

33 34 35 36
// Abstract base class for all Simple and Complex visual mission objects.
class VisualMissionItem : public QObject
{
    Q_OBJECT
37

38
public:
39
    VisualMissionItem(PlanMasterController* masterController, bool flyView, QObject* parent);
40
    VisualMissionItem(const VisualMissionItem& other, bool flyView, QObject* parent);
41 42 43 44 45

    ~VisualMissionItem();

    const VisualMissionItem& operator=(const VisualMissionItem& other);

DonLakeFlyer's avatar
DonLakeFlyer committed
46 47 48 49 50 51 52
    enum ReadyForSaveState {
        ReadyForSave,
        NotReadyForSaveTerrain,
        NotReadyForSaveData,
    };
    Q_ENUM(ReadyForSaveState)

53
    Q_PROPERTY(bool             homePosition                        READ homePosition                                                       CONSTANT)                                           ///< true: This item is being used as a home position indicator
54 55
    Q_PROPERTY(QGeoCoordinate   coordinate                          READ coordinate                         WRITE setCoordinate             NOTIFY coordinateChanged)                           ///< Does not include altitude
    Q_PROPERTY(double           amslEntryAlt                        READ amslEntryAlt                                                       NOTIFY amslEntryAltChanged)
56
    Q_PROPERTY(double           terrainAltitude                     READ terrainAltitude                                                    NOTIFY terrainAltitudeChanged)                      ///< The altitude of terrain at the coordinate position, NaN if not known
57 58
    Q_PROPERTY(QGeoCoordinate   exitCoordinate                      READ exitCoordinate                                                     NOTIFY exitCoordinateChanged)                       ///< Does not include altitude
    Q_PROPERTY(double           amslExitAlt                         READ amslExitAlt                                                        NOTIFY amslExitAltChanged)
59 60 61 62 63 64 65 66 67 68 69 70 71 72
    Q_PROPERTY(bool             exitCoordinateSameAsEntry           READ exitCoordinateSameAsEntry                                          NOTIFY exitCoordinateSameAsEntryChanged)            ///< true: exitCoordinate and coordinate are the same value
    Q_PROPERTY(QString          commandDescription                  READ commandDescription                                                 NOTIFY commandDescriptionChanged)
    Q_PROPERTY(QString          commandName                         READ commandName                                                        NOTIFY commandNameChanged)
    Q_PROPERTY(QString          abbreviation                        READ abbreviation                                                       NOTIFY abbreviationChanged)
    Q_PROPERTY(bool             dirty                               READ dirty                              WRITE setDirty                  NOTIFY dirtyChanged)                                ///< Item is dirty and requires save/send
    Q_PROPERTY(bool             isCurrentItem                       READ isCurrentItem                      WRITE setIsCurrentItem          NOTIFY isCurrentItemChanged)
    Q_PROPERTY(bool             hasCurrentChildItem                 READ hasCurrentChildItem                WRITE setHasCurrentChildItem    NOTIFY hasCurrentChildItemChanged)                  ///< true: On of this items children is current
    Q_PROPERTY(int              sequenceNumber                      READ sequenceNumber                     WRITE setSequenceNumber         NOTIFY sequenceNumberChanged)
    Q_PROPERTY(int              lastSequenceNumber                  READ lastSequenceNumber                                                 NOTIFY lastSequenceNumberChanged)
    Q_PROPERTY(bool             specifiesCoordinate                 READ specifiesCoordinate                                                NOTIFY specifiesCoordinateChanged)                  ///< true: Item is associated with a coordinate position
    Q_PROPERTY(bool             isStandaloneCoordinate              READ isStandaloneCoordinate                                             NOTIFY isStandaloneCoordinateChanged)               ///< true: Waypoint line does not go through item
    Q_PROPERTY(bool             specifiesAltitudeOnly               READ specifiesAltitudeOnly                                              NOTIFY specifiesAltitudeOnlyChanged)                ///< true: Item has altitude only, no full coordinate
    Q_PROPERTY(bool             isSimpleItem                        READ isSimpleItem                                                       NOTIFY isSimpleItemChanged)                         ///< Simple or Complex MissionItem
    Q_PROPERTY(bool             isTakeoffItem                       READ isTakeoffItem                                                      NOTIFY isTakeoffItemChanged)                        ///< true: Takeoff item special case
DoinLakeFlyer's avatar
DoinLakeFlyer committed
73
    Q_PROPERTY(bool             isLandCommand                       READ isLandCommand                                                      NOTIFY isLandCommandChanged)
74 75
    Q_PROPERTY(QString          editorQml                           MEMBER _editorQml                                                       CONSTANT)                                           ///< Qml code for editing this item
    Q_PROPERTY(QString          mapVisualQML                        READ mapVisualQML                                                       CONSTANT)                                           ///< QMl code for map visuals
76 77 78 79
    Q_PROPERTY(double           specifiedFlightSpeed                READ specifiedFlightSpeed                                               NOTIFY specifiedFlightSpeedChanged)                 ///< NaN for not specified
    Q_PROPERTY(double           specifiedGimbalYaw                  READ specifiedGimbalYaw                                                 NOTIFY specifiedGimbalYawChanged)                   ///< NaN for not specified
    Q_PROPERTY(double           specifiedGimbalPitch                READ specifiedGimbalPitch                                               NOTIFY specifiedGimbalPitchChanged)                 ///< NaN for not specified
    Q_PROPERTY(double           specifiedVehicleYaw                 READ specifiedVehicleYaw                                                NOTIFY specifiedVehicleYawChanged)                  ///< NaN for not specified
80 81 82
    Q_PROPERTY(double           missionGimbalYaw                    READ missionGimbalYaw                                                   NOTIFY missionGimbalYawChanged)                     ///< Current gimbal yaw state at this point in mission
    Q_PROPERTY(double           missionVehicleYaw                   READ missionVehicleYaw                                                  NOTIFY missionVehicleYawChanged)                    ///< Expected vehicle yaw at this point in mission
    Q_PROPERTY(bool             flyView                             READ flyView                                                            CONSTANT)
83
    Q_PROPERTY(bool             wizardMode                          READ wizardMode                         WRITE setWizardMode             NOTIFY wizardModeChanged)
84

85 86 87 88 89
    Q_PROPERTY(PlanMasterController*    masterController    READ masterController                                                   CONSTANT)
    Q_PROPERTY(ReadyForSaveState        readyForSaveState   READ readyForSaveState                                                  NOTIFY readyForSaveStateChanged)
    Q_PROPERTY(VisualMissionItem*       parentItem          READ parentItem                        WRITE setParentItem              NOTIFY parentItemChanged)
    Q_PROPERTY(QmlObjectListModel*      childItems          READ childItems                                                         CONSTANT)
    Q_PROPERTY(QGCGeoBoundingCube*      boundingCube        READ boundingCube                                                       NOTIFY boundingCubeChanged)
90

91
    // The following properties are calculated/set by the MissionController recalc methods
92

93 94 95 96 97 98 99
    Q_PROPERTY(double altDifference     READ altDifference          WRITE setAltDifference      NOTIFY altDifferenceChanged)        ///< Change in altitude from previous waypoint
    Q_PROPERTY(double altPercent        READ altPercent             WRITE setAltPercent         NOTIFY altPercentChanged)           ///< Percent of total altitude change in mission altitude
    Q_PROPERTY(double terrainPercent    READ terrainPercent         WRITE setTerrainPercent     NOTIFY terrainPercentChanged)       ///< Percent of terrain altitude in mission altitude
    Q_PROPERTY(bool   terrainCollision  READ terrainCollision       WRITE setTerrainCollision   NOTIFY terrainCollisionChanged)     ///< true: Item collides with terrain
    Q_PROPERTY(double azimuth           READ azimuth                WRITE setAzimuth            NOTIFY azimuthChanged)              ///< Azimuth to previous waypoint
    Q_PROPERTY(double distance          READ distance               WRITE setDistance           NOTIFY distanceChanged)             ///< Distance to previous waypoint
    Q_PROPERTY(double distanceFromStart READ distanceFromStart      WRITE setDistanceFromStart  NOTIFY distanceFromStartChanged)    ///< Flight path cumalative horizontal distance from home point to this item
100 101

    // Property accesors
102 103 104 105 106 107 108
    bool    homePosition        (void) const { return _homePositionSpecialCase; }
    double  altDifference       (void) const { return _altDifference; }
    double  altPercent          (void) const { return _altPercent; }
    double  terrainPercent      (void) const { return _terrainPercent; }
    bool    terrainCollision    (void) const { return _terrainCollision; }
    double  azimuth             (void) const { return _azimuth; }
    double  distance            (void) const { return _distance; }
109
    double  distanceFromStart   (void) const { return _distanceFromStart; }
110 111 112 113 114 115
    bool    isCurrentItem       (void) const { return _isCurrentItem; }
    bool    hasCurrentChildItem (void) const { return _hasCurrentChildItem; }
    double  terrainAltitude     (void) const { return _terrainAltitude; }
    bool    flyView             (void) const { return _flyView; }
    bool    wizardMode          (void) const { return _wizardMode; }
    VisualMissionItem* parentItem(void) { return _parentItem; }
116 117 118

    QmlObjectListModel* childItems(void) { return &_childItems; }

119 120 121 122 123 124 125 126
    void setIsCurrentItem           (bool isCurrentItem);
    void setHasCurrentChildItem     (bool hasCurrentChildItem);
    void setAltDifference           (double altDifference);
    void setAltPercent              (double altPercent);
    void setTerrainPercent          (double terrainPercent);
    void setTerrainCollision        (bool terrainCollision);
    void setAzimuth                 (double azimuth);
    void setDistance                (double distance);
127
    void setDistanceFromStart       (double distanceFromStart);
128 129
    void setWizardMode              (bool wizardMode);
    void setParentItem              (VisualMissionItem* parentItem);
130 131

    void setHomePositionSpecialCase (bool homePositionSpecialCase) { _homePositionSpecialCase = homePositionSpecialCase; }
132

133 134 135
    FlightPathSegment* simpleFlightPathSegment(void) { return _simpleFlightPathSegment; }
    void setSimpleFlighPathSegment  (FlightPathSegment* segment) { _simpleFlightPathSegment = segment; }

136
    PlanMasterController* masterController(void) { return _masterController; }
137 138 139 140 141

    // Pure virtuals which must be provides by derived classes

    virtual bool            dirty                   (void) const = 0;
    virtual bool            isSimpleItem            (void) const = 0;
142
    virtual bool            isTakeoffItem           (void) const { return false; }
143
    virtual bool            isLandCommand           (void) const { return false; }
144 145
    virtual bool            isStandaloneCoordinate  (void) const = 0;
    virtual bool            specifiesCoordinate     (void) const = 0;
146
    virtual bool            specifiesAltitudeOnly   (void) const = 0;
147 148
    virtual QString         commandDescription      (void) const = 0;
    virtual QString         commandName             (void) const = 0;
149
    virtual QString         abbreviation            (void) const = 0;
150 151
    virtual QGeoCoordinate  coordinate              (void) const = 0;
    virtual QGeoCoordinate  exitCoordinate          (void) const = 0;
152 153
    virtual double          amslEntryAlt            (void) const = 0;
    virtual double          amslExitAlt             (void) const = 0;
154
    virtual int             sequenceNumber          (void) const = 0;
DonLakeFlyer's avatar
DonLakeFlyer committed
155 156
    virtual double          specifiedFlightSpeed    (void) = 0;
    virtual double          specifiedGimbalYaw      (void) = 0;
157
    virtual double          specifiedGimbalPitch    (void) = 0;
158
    virtual double          specifiedVehicleYaw     (void) { return qQNaN(); }
DonLakeFlyer's avatar
DonLakeFlyer committed
159

160 161 162
    //-- Default implementation returns an invalid bounding cube
    virtual QGCGeoBoundingCube* boundingCube        (void) { return &_boundingCube; }

DonLakeFlyer's avatar
DonLakeFlyer committed
163 164 165
    /// Update item to mission flight status at point where this item appears in mission.
    /// IMPORTANT: Overrides must call base class implementation
    virtual void setMissionFlightStatus(MissionController::MissionFlightStatus_t& missionFlightStatus);
166 167 168 169 170

    virtual bool exitCoordinateSameAsEntry          (void) const = 0;

    virtual void setDirty           (bool dirty) = 0;
    virtual void setCoordinate      (const QGeoCoordinate& coordinate) = 0;
171
    virtual void setSequenceNumber  (int sequenceNumber) = 0;
172
    virtual int  lastSequenceNumber (void) const = 0;
173

DonLakeFlyer's avatar
DonLakeFlyer committed
174 175
    /// @return Returns whether the item is ready for save and if not, why
    virtual ReadyForSaveState readyForSaveState(void) const { return ReadyForSave; }
176

177
    /// Save the item(s) in Json format
178
    ///     @param missionItems Current set of mission items, new items should be appended to the end
179
    virtual void save(QJsonArray&  missionItems) = 0;
180

181 182 183
    /// @return The QML resource file which contains the control which visualizes the item on the map.
    virtual QString mapVisualQML(void) const = 0;

184 185 186 187 188
    /// Returns the mission items associated with the complex item. Caller is responsible for freeing.
    ///     @param items List to append to
    ///     @param missionItemParent Parent object for newly created MissionItems
    virtual void appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent) = 0;

DonLakeFlyer's avatar
DonLakeFlyer committed
189 190 191
    /// Adjust the altitude of the item if appropriate to the new altitude.
    virtual void applyNewAltitude(double newAltitude) = 0;

192 193 194
    /// @return Amount of additional time delay in seconds needed to fly this item
    virtual double additionalTimeDelay(void) const = 0;

DonLakeFlyer's avatar
DonLakeFlyer committed
195 196 197 198
    double  missionGimbalYaw    (void) const { return _missionGimbalYaw; }
    double  missionVehicleYaw   (void) const { return _missionVehicleYaw; }
    void    setMissionVehicleYaw(double vehicleYaw);

Don Gagne's avatar
Don Gagne committed
199 200 201 202
    static const char* jsonTypeKey;                 ///< Json file attribute which specifies the item type
    static const char* jsonTypeSimpleItemValue;     ///< Item type is MISSION_ITEM
    static const char* jsonTypeComplexItemValue;    ///< Item type is Complex Item

203 204 205
signals:
    void altDifferenceChanged           (double altDifference);
    void altPercentChanged              (double altPercent);
206
    void terrainPercentChanged          (double terrainPercent);
207
    void terrainCollisionChanged        (bool terrainCollision);
208 209 210
    void azimuthChanged                 (double azimuth);
    void commandDescriptionChanged      (void);
    void commandNameChanged             (void);
211
    void abbreviationChanged            (void);
212 213 214 215
    void coordinateChanged              (const QGeoCoordinate& coordinate);
    void exitCoordinateChanged          (const QGeoCoordinate& exitCoordinate);
    void dirtyChanged                   (bool dirty);
    void distanceChanged                (double distance);
216
    void distanceFromStartChanged       (double distanceFromStart);
217
    void isCurrentItemChanged           (bool isCurrentItem);
218
    void hasCurrentChildItemChanged     (bool hasCurrentChildItem);
219 220
    void sequenceNumberChanged          (int sequenceNumber);
    void isSimpleItemChanged            (bool isSimpleItem);
221
    void isTakeoffItemChanged           (bool isTakeoffItem);
222
    void isLandCommandChanged           (void);
223 224
    void specifiesCoordinateChanged     (void);
    void isStandaloneCoordinateChanged  (void);
DonLakeFlyer's avatar
DonLakeFlyer committed
225 226 227
    void specifiesAltitudeOnlyChanged   (void);
    void specifiedFlightSpeedChanged    (void);
    void specifiedGimbalYawChanged      (void);
228
    void specifiedGimbalPitchChanged    (void);
229
    void specifiedVehicleYawChanged     (void);
230
    void lastSequenceNumberChanged      (int sequenceNumber);
DonLakeFlyer's avatar
DonLakeFlyer committed
231 232
    void missionGimbalYawChanged        (double missionGimbalYaw);
    void missionVehicleYawChanged       (double missionVehicleYaw);
233
    void terrainAltitudeChanged         (double terrainAltitude);
234
    void additionalTimeDelayChanged     (void);
235
    void boundingCubeChanged            (void);
DonLakeFlyer's avatar
DonLakeFlyer committed
236
    void readyForSaveStateChanged       (void);
237
    void wizardModeChanged              (bool wizardMode);
238
    void parentItemChanged              (VisualMissionItem* parentItem);
239 240
    void amslEntryAltChanged            (double alt);
    void amslExitAltChanged             (double alt);
241

242
    void exitCoordinateSameAsEntryChanged           (bool exitCoordinateSameAsEntry);
243

244 245 246 247
protected slots:
    void _amslEntryAltChanged(void);    // signals new amslEntryAlt value
    void _amslExitAltChanged(void);     // signals new amslExitAlt value

248
protected:
249 250 251 252 253 254 255 256 257 258 259 260 261
    bool     _flyView    =               false;
    bool    _isCurrentItem =            false;
    bool    _hasCurrentChildItem =      false;
    bool    _dirty =                    false;
    bool    _homePositionSpecialCase =  false;      ///< true: This item is being used as a ui home position indicator
    bool    _wizardMode =               false;      ///< true: Item editor is showing wizard completion panel
    double  _terrainAltitude =          qQNaN();    ///< Altitude of terrain at coordinate position, NaN for not known
    double  _altDifference =            0;          ///< Difference in altitude from previous waypoint
    double  _altPercent =               0;          ///< Percent of total altitude change in mission
    double  _terrainPercent =           qQNaN();    ///< Percent of terrain altitude for coordinate
    bool    _terrainCollision =         false;      ///< true: item collides with terrain
    double  _azimuth =                  0;          ///< Azimuth to previous waypoint
    double  _distance =                 0;          ///< Distance to previous waypoint
262
    double  _distanceFromStart =        0;          ///< Flight path cumalative horizontal distance from home point to this item
263 264 265 266
    QString _editorQml;                             ///< Qml resource for editing item
    double  _missionGimbalYaw =         qQNaN();
    double  _missionVehicleYaw =        qQNaN();

267 268 269 270 271 272
    PlanMasterController*   _masterController =         nullptr;
    MissionController*      _missionController =        nullptr;
    Vehicle*                _controllerVehicle =        nullptr;
    FlightPathSegment *     _simpleFlightPathSegment =  nullptr;    ///< The simple item flight segment (if any) which starts with this visual item.
    VisualMissionItem*      _parentItem =               nullptr;
    QGCGeoBoundingCube      _boundingCube;                          ///< The bounding "cube" of this element.
273

DonLakeFlyer's avatar
DonLakeFlyer committed
274
    MissionController::MissionFlightStatus_t    _missionFlightStatus;
275 276 277

    /// This is used to reference any subsequent mission items which do not specify a coordinate.
    QmlObjectListModel  _childItems;
278

279 280 281
protected:
    void    _setBoundingCube                (QGCGeoBoundingCube bc);

282 283 284
private slots:
    void _updateTerrainAltitude (void);
    void _reallyUpdateTerrainAltitude (void);
285
    void _terrainDataReceived   (bool success, QList<double> heights);
286 287

private:
288 289
    void _commonInit(void);

290 291 292
    QTimer                      _updateTerrainTimer;
    TerrainAtCoordinateQuery*   _currentTerrainAtCoordinateQuery = nullptr;

293 294
    double _lastLatTerrainQuery = 0;
    double _lastLonTerrainQuery = 0;
295
};