FirmwarePlugin.h 19.7 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.
 *
 ****************************************************************************/

Don Gagne's avatar
Don Gagne committed
10 11 12 13 14 15 16

/// @file
///     @author Don Gagne <don@thegagnes.com>

#ifndef FirmwarePlugin_H
#define FirmwarePlugin_H

Don Gagne's avatar
Don Gagne committed
17
#include "QGCMAVLink.h"
Don Gagne's avatar
Don Gagne committed
18 19
#include "VehicleComponent.h"
#include "AutoPilotPlugin.h"
20
#include "GeoFenceManager.h"
21
#include "RallyPointManager.h"
22
#include "FollowMe.h"
Don Gagne's avatar
Don Gagne committed
23 24 25

#include <QList>
#include <QString>
26
#include <QVariantList>
Don Gagne's avatar
Don Gagne committed
27

28
class Vehicle;
29 30
class QGCCameraControl;
class QGCCameraManager;
31

Don Gagne's avatar
Don Gagne committed
32 33
/// This is the base class for Firmware specific plugins
///
34 35 36 37
/// The FirmwarePlugin class represents the methods and objects which are specific to a certain Firmware flight stack.
/// This is the only place where flight stack specific code should reside in QGroundControl. The remainder of the
/// QGroundControl source is generic to a common mavlink implementation. The implementation in the base class supports
/// mavlink generic firmware. Override the base clase virtuals to create your own firmware specific plugin.
Don Gagne's avatar
Don Gagne committed
38

Don Gagne's avatar
Don Gagne committed
39
class FirmwarePlugin : public QObject
Don Gagne's avatar
Don Gagne committed
40 41 42 43 44 45
{
    Q_OBJECT

public:
    /// Set of optional capabilites which firmware may support
    typedef enum {
Don Gagne's avatar
Don Gagne committed
46
        SetFlightModeCapability =           1 << 0, ///< FirmwarePlugin::setFlightMode method is supported
47 48 49 50
        PauseVehicleCapability =            1 << 1, ///< Vehicle supports pausing at current location
        GuidedModeCapability =              1 << 2, ///< Vehicle supports guided mode commands
        OrbitModeCapability =               1 << 3, ///< Vehicle supports orbit mode
        TakeoffVehicleCapability =          1 << 4, ///< Vehicle supports guided takeoff
51
        ROIModeCapability =                 1 << 5, ///< Vehicle supports ROI (both in Fly guided mode and from Plan creation)
Don Gagne's avatar
Don Gagne committed
52
    } FirmwareCapabilities;
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

    /// Maps from on parameter name to another
    ///     key:    parameter name to translate from
    ///     value:  mapped parameter name
    typedef QMap<QString, QString> remapParamNameMap_t;

    /// Maps from firmware minor version to remapParamNameMap_t entry
    ///     key:    firmware minor version
    ///     value:  remapParamNameMap_t entry
    typedef QMap<int, remapParamNameMap_t> remapParamNameMinorVersionRemapMap_t;

    /// Maps from firmware major version number to remapParamNameMinorVersionRemapMap_t entry
    ///     key:    firmware major version
    ///     value:  remapParamNameMinorVersionRemapMap_t entry
    typedef QMap<int, remapParamNameMinorVersionRemapMap_t> remapParamNameMajorVersionMap_t;
68

Patrick José Pereira's avatar
Patrick José Pereira committed
69
    /// @return The AutoPilotPlugin associated with this firmware plugin. Must be overridden.
70 71
    virtual AutoPilotPlugin* autopilotPlugin(Vehicle* vehicle);

72
    /// Called when Vehicle is first created to perform any firmware specific setup.
Don Gagne's avatar
Don Gagne committed
73 74
    virtual void initializeVehicle(Vehicle* vehicle);

Don Gagne's avatar
Don Gagne committed
75
    /// @return true: Firmware supports all specified capabilites
76
    virtual bool isCapable(const Vehicle *vehicle, FirmwareCapabilities capabilities);
77

Don Gagne's avatar
Don Gagne committed
78 79 80 81
    /// Returns VehicleComponents for specified Vehicle
    ///     @param vehicle Vehicle  to associate with components
    /// @return List of VehicleComponents for the specified vehicle. Caller owns returned objects and must
    ///         free when no longer needed.
82
    virtual QList<VehicleComponent*> componentsForVehicle(AutoPilotPlugin* vehicle);
83

84 85 86 87 88
    /// Returns the list of available flight modes for the Fly View dropdown. This may or may not be the full
    /// list available from the firmware. Call will be made again if advanced mode changes.
    virtual QStringList flightModes(Vehicle* /*vehicle*/) { return QStringList(); }

    /// Returns the list of additional flight modes to add to the list for joystick button actions.
89
    /// Call will be made again if advanced mode changes.
90
    virtual QStringList extraJoystickFlightModes(Vehicle* /*vehicle*/) { return QStringList(); }
91

Don Gagne's avatar
Don Gagne committed
92 93 94
    /// Returns the name for this flight mode. Flight mode names must be human readable as well as audio speakable.
    ///     @param base_mode Base mode from mavlink HEARTBEAT message
    ///     @param custom_mode Custom mode from mavlink HEARTBEAT message
Don Gagne's avatar
Don Gagne committed
95
    virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode) const;
96

Don Gagne's avatar
Don Gagne committed
97 98 99
    /// Sets base_mode and custom_mode to specified flight mode.
    ///     @param[out] base_mode Base mode for SET_MODE mavlink message
    ///     @param[out] custom_mode Custom mode for SET_MODE mavlink message
100
    virtual bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode);
Don Gagne's avatar
Don Gagne committed
101

102 103 104 105 106 107 108 109 110
    /// Returns The flight mode which indicates the vehicle is paused
    virtual QString pauseFlightMode(void) const { return QString(); }

    /// Returns the flight mode for running missions
    virtual QString missionFlightMode(void) const { return QString(); }

    /// Returns the flight mode for RTL
    virtual QString rtlFlightMode(void) const { return QString(); }

DonLakeFlyer's avatar
DonLakeFlyer committed
111 112 113 114 115
    /// Returns the flight mode for Smart RTL
    virtual QString smartRTLFlightMode(void) const { return QString(); }

    virtual bool supportsSmartRTL(void) const { return false; }

116 117 118 119 120 121
    /// Returns the flight mode for Land
    virtual QString landFlightMode(void) const { return QString(); }

    /// Returns the flight mode to use when the operator wants to take back control from autonomouse flight.
    virtual QString takeControlFlightMode(void) const { return QString(); }

Don Gagne's avatar
Don Gagne committed
122 123 124
    /// Returns whether the vehicle is in guided mode or not.
    virtual bool isGuidedMode(const Vehicle* vehicle) const;

Don Gagne's avatar
Don Gagne committed
125 126 127
    /// Returns the flight mode which the vehicle will be in if it is performing a goto location
    virtual QString gotoFlightMode(void) const;

128
    /// Returns the flight mode which the vehicle will be for follow me
129
    virtual QString followFlightMode(void) const { return QString(); }
130

Don Gagne's avatar
Don Gagne committed
131 132 133 134 135 136 137 138
    /// Set guided flight mode
    virtual void setGuidedMode(Vehicle* vehicle, bool guidedMode);

    /// Causes the vehicle to stop at current position. If guide mode is supported, vehicle will be let in guide mode.
    /// If not, vehicle will be left in Loiter.
    virtual void pauseVehicle(Vehicle* vehicle);

    /// Command vehicle to return to launch
DonLakeFlyer's avatar
DonLakeFlyer committed
139
    virtual void guidedModeRTL(Vehicle* vehicle, bool smartRTL);
Don Gagne's avatar
Don Gagne committed
140 141 142 143

    /// Command vehicle to land at current location
    virtual void guidedModeLand(Vehicle* vehicle);

144
    /// Command vehicle to takeoff from current location to a firmware specific height.
145
    virtual void guidedModeTakeoff(Vehicle* vehicle, double takeoffAltRel);
146

147
    /// @return The minimum takeoff altitude (relative) for guided takeoff.
148
    virtual double minimumTakeoffAltitude(Vehicle* /*vehicle*/) { return 10; }
149

150 151
    /// Command the vehicle to start the mission
    virtual void startMission(Vehicle* vehicle);
Don Gagne's avatar
Don Gagne committed
152 153 154 155

    /// Command vehicle to move to specified location (altitude is included and relative)
    virtual void guidedModeGotoLocation(Vehicle* vehicle, const QGeoCoordinate& gotoCoord);

156 157 158
    /// Command vehicle to change altitude
    ///     @param altitudeChange If > 0, go up by amount specified, if < 0, go down by amount specified
    virtual void guidedModeChangeAltitude(Vehicle* vehicle, double altitudeChange);
159

160 161 162 163
    /// Default tx mode to apply to joystick axes
    /// TX modes are as outlined here: http://www.rc-airplane-world.com/rc-transmitter-modes.html
    virtual int defaultJoystickTXMode(void);

164 165 166 167 168
    /// Returns true if the vehicle and firmware supports the use of a throttle joystick that
    /// is zero when centered. Typically not supported on vehicles that have bidirectional
    /// throttle.
    virtual bool supportsThrottleModeCenterZero(void);

169 170
    /// Returns true if the vehicle and firmware supports the use of negative thrust
    /// Typically supported rover.
171
    virtual bool supportsNegativeThrust(Vehicle *);
172

173 174 175 176
    /// Returns true if the firmware supports the use of the RC radio and requires the RC radio
    /// setup page. Returns true by default.
    virtual bool supportsRadio(void);

177 178 179 180
    /// Returns true if the firmware supports the AP_JSButton library, which allows joystick buttons
    /// to be assigned via parameters in firmware. Default is false.
    virtual bool supportsJSButton(void);

181 182 183 184
    /// Returns true if the firmware supports calibrating motor interference offsets for the compass
    /// (CompassMot). Default is true.
    virtual bool supportsMotorInterference(void);

nopeppermint's avatar
nopeppermint committed
185
    /// Called before any mavlink message is processed by Vehicle such that the firmwre plugin
Don Gagne's avatar
Don Gagne committed
186 187
    /// can adjust any message characteristics. This is handy to adjust or differences in mavlink
    /// spec implementations such that the base code can remain mavlink generic.
188
    ///     @param vehicle Vehicle message came from
Don Gagne's avatar
Don Gagne committed
189
    ///     @param message[in,out] Mavlink message to adjust if needed.
190 191
    /// @return false: skip message, true: process message
    virtual bool adjustIncomingMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message);
192

Don Gagne's avatar
Don Gagne committed
193 194 195
    /// Called before any mavlink message is sent to the Vehicle so plugin can adjust any message characteristics.
    /// This is handy to adjust or differences in mavlink spec implementations such that the base code can remain
    /// mavlink generic.
196 197 198
    ///
    /// This method must be thread safe.
    ///
Don Gagne's avatar
Don Gagne committed
199
    ///     @param vehicle Vehicle message came from
200
    ///     @param outgoingLink Link that messae is going out on
Don Gagne's avatar
Don Gagne committed
201
    ///     @param message[in,out] Mavlink message to adjust if needed.
202
    virtual void adjustOutgoingMavlinkMessageThreadSafe(Vehicle* vehicle, LinkInterface* outgoingLink, mavlink_message_t* message);
Don Gagne's avatar
Don Gagne committed
203

204 205 206 207 208 209
    /// Determines how to handle the first item of the mission item list. Internally to QGC the first item
    /// is always the home position.
    /// @return
    ///     true: Send first mission item as home position to vehicle. When vehicle has no mission items on
    ///             it, it may or may not return a home position back in position 0.
    ///     false: Do not send first item to vehicle, sequence numbers must be adjusted
210
    virtual bool sendHomePositionToVehicle(void);
211

212
    /// Returns the parameter set version info pulled from inside the meta data file. -1 if not found.
213
    /// Note: The implementation for this must not vary by vehicle type.
214 215
    /// Important: Only CompInfoParam code should use this method
    virtual void _getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion);
216 217

    /// Returns the internal resource parameter meta date file.
218 219
    /// Important: Only CompInfoParam code should use this method
    virtual QString _internalParameterMetaDataFile(Vehicle* /*vehicle*/) { return QString(); }
220 221

    /// Loads the specified parameter meta data file.
Ricardo de Almeida Gonzaga's avatar
Ricardo de Almeida Gonzaga committed
222
    /// @return Opaque parameter meta data information which must be stored with Vehicle. Vehicle is responsible to
223
    ///         call deleteParameterMetaData when no longer needed.
224 225
    /// Important: Only CompInfoParam code should use this method
    virtual QObject* _loadParameterMetaData(const QString& /*metaDataFile*/) { return nullptr; }
226

227 228
    /// Returns the FactMetaData associated with the parameter name
    ///     @param opaqueParameterMetaData Opaque pointer returned from loadParameterMetaData
229 230
    /// Important: Only CompInfoParam code should use this method
    virtual FactMetaData* _getMetaDataForFact(QObject* /*parameterMetaData*/, const QString& /*name*/, FactMetaData::ValueType_t /* type */, MAV_TYPE /*vehicleType*/) { return nullptr; }
231

232
    /// Returns the FactMetaData associated with the parameter name
233
    ///     @param opaqueParameterMetaData Opaque pointer returned from loadParameterMetaData
234 235
    /// Important: Only CompInfoParam code should use this method
    virtual bool _isParameterVolatile(QObject* /*parameterMetaData*/, const QString& /*name*/, MAV_TYPE /*vehicleType*/) { return false; }
Don Gagne's avatar
Don Gagne committed
236 237

    /// List of supported mission commands. Empty list for all commands supported.
238
    virtual QList<MAV_CMD> supportedMissionCommands(QGCMAVLink::VehicleClass_t vehicleClass);
239

240
    /// Returns the name of the mission command json override file for the specified vehicle type.
241 242
    ///     @param vehicleClass Vehicle class to return file for, VehicleClassGeneric is a request for overrides for all vehicle types
    virtual QString missionCommandOverrides(QGCMAVLink::VehicleClass_t vehicleClass) const;
243

244 245 246 247 248
    /// Returns the mapping structure which is used to map from one parameter name to another based on firmware version.
    virtual const remapParamNameMajorVersionMap_t& paramNameRemapMajorVersionMap(void) const;

    /// Returns the highest major version number that is known to the remap for this specified major version.
    virtual int remapParamNameHigestMinorVersionNumber(int majorVersionNumber) const;
Don Gagne's avatar
Don Gagne committed
249 250

    /// @return true: Motors are coaxial like an X8 config, false: Quadcopter for example
251
    virtual bool multiRotorCoaxialMotors(Vehicle* /*vehicle*/) { return false; }
Don Gagne's avatar
Don Gagne committed
252 253

    /// @return true: X confiuration, false: Plus configuration
254
    virtual bool multiRotorXConfig(Vehicle* /*vehicle*/) { return false; }
255

256
    /// Return the resource file which contains the set of params loaded for offline editing.
257
    virtual QString offlineEditingParamFile(Vehicle* /*vehicle*/) { return QString(); }
258

259
    /// Return the resource file which contains the brand image for the vehicle for Indoor theme.
260
    virtual QString brandImageIndoor(const Vehicle* /*vehicle*/) const { return QString(); }
261 262

    /// Return the resource file which contains the brand image for the vehicle for Outdoor theme.
263
    virtual QString brandImageOutdoor(const Vehicle* /*vehicle*/) const { return QString(); }
264

265 266 267 268 269 270 271 272 273
    /// Return the resource file which contains the vehicle icon used in the flight view when the view is dark (Satellite for instance)
    virtual QString vehicleImageOpaque(const Vehicle* vehicle) const;

    /// Return the resource file which contains the vehicle icon used in the flight view when the view is light (Map for instance)
    virtual QString vehicleImageOutline(const Vehicle* vehicle) const;

    /// Return the resource file which contains the vehicle icon used in the compass
    virtual QString vehicleImageCompass(const Vehicle* vehicle) const;

274 275 276 277 278 279 280 281 282
    /// Returns the list of toolbar tool indicators associated with a vehicle
    ///     signals toolIndicatorsChanged
    /// @return A list of QUrl with the indicators
    virtual const QVariantList& toolIndicators(const Vehicle* vehicle);

    /// Returns the list of toolbar mode indicators associated with a vehicle
    ///     signals modeIndicatorsChanged
    /// @return A list of QUrl with the indicators
    virtual const QVariantList& modeIndicators(const Vehicle* vehicle);
283

284
    /// Returns a list of CameraMetaData objects for available cameras on the vehicle.
285
    /// TODO: This should go into QGCCameraManager
286 287
    virtual const QVariantList& cameraList(const Vehicle* vehicle);

288
    /// Creates vehicle camera manager.
289
    virtual QGCCameraManager* createCameraManager(Vehicle *vehicle);
290

291 292
    /// Camera control.
    virtual QGCCameraControl* createCameraControl(const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr);
293

294 295
    /// Returns a pointer to a dictionary of firmware-specific FactGroups
    virtual QMap<QString, FactGroup*>* factGroups(void);
296

297 298 299 300
    /// Returns the data needed to do battery consumption calculations
    ///     @param[out] mAhBattery Battery milliamp-hours rating (0 for no battery data available)
    ///     @param[out] hoverAmps Current draw in amps during hover
    ///     @param[out] cruiseAmps Current draw in amps during cruise
Don Gagne's avatar
Don Gagne committed
301
    virtual void batteryConsumptionData(Vehicle* vehicle, int& mAhBattery, double& hoverAmps, double& cruiseAmps) const;
302

303
    // Returns the parameter which control auto-disarm. Assume == 0 means no auto disarm
304 305
    virtual QString autoDisarmParameter(Vehicle* vehicle);

306 307 308 309 310 311 312
    /// Used to determine whether a vehicle has a gimbal.
    ///     @param[out] rollSupported Gimbal supports roll
    ///     @param[out] pitchSupported Gimbal supports pitch
    ///     @param[out] yawSupported Gimbal supports yaw
    /// @return true: vehicle has gimbal, false: gimbal support unknown
    virtual bool hasGimbal(Vehicle* vehicle, bool& rollSupported, bool& pitchSupported, bool& yawSupported);

313 314 315
    /// Convert from HIGH_LATENCY2.custom_mode value to correct 32 bit value.
    virtual uint32_t highLatencyCustomModeTo32Bits(uint16_t hlCustomMode);

316 317 318
    /// Used to check if running firmware is latest stable version.
    virtual void checkIfIsLatestStable(Vehicle* vehicle);

319 320 321 322 323
    /// Used to check if running current version is equal or higher than the one being compared.
    /// returns 1 if current > compare, 0 if current == compare, -1 if current < compare
    int versionCompare(Vehicle* vehicle, QString& compare);
    int versionCompare(Vehicle* vehicle, int major, int minor, int patch);

324 325 326
    /// Allows the Firmware plugin to override the facts meta data.
    ///     @param vehicleType - Type of current vehicle
    ///     @param metaData - MetaData for fact
327
    virtual void adjustMetaData(MAV_TYPE /*vehicleType*/, FactMetaData* /*metaData*/) {}
328

329 330 331
    /// Sends the appropriate mavlink message for follow me support
    virtual void sendGCSMotionReport(Vehicle* vehicle, FollowMe::GCSMotionReport& motionReport, uint8_t estimatationCapabilities);

332
    // FIXME: Hack workaround for non pluginize FollowMe support
333
    static const QString px4FollowMeFlightMode;
334

335
signals:
336 337
    void toolIndicatorsChanged(void);
    void modeIndicatorsChanged(void);
338

339
protected:
340
    // Arms the vehicle with validation and retries
341
    // @return: true - vehicle armed, false - vehicle failed to arm
342
    bool _armVehicleAndValidate(Vehicle* vehicle);
343

344 345 346 347
    // Sets the vehicle to the specified flight mode with validation and retries
    // @return: true - vehicle in specified flight mode, false - flight mode change failed
    bool _setFlightModeAndValidate(Vehicle* vehicle, const QString& flightMode);

348
    // returns url with latest firmware release information.
349
    virtual QString _getLatestVersionFileUrl(Vehicle* /*vehicle*/) { return QString(); }
350 351 352 353 354 355 356

    // Callback to process file with latest release information
    virtual void _versionFileDownloadFinished(QString& remoteFile, QString& localFile, Vehicle* vehicle);

    // Returns regex QString to extract version information from text
    virtual QString _versionRegex() { return QString(); }

357
private:
358 359 360
    QVariantList _toolIndicatorList;
    QVariantList _modeIndicatorList;

361
    static QVariantList _cameraList;    ///< Standard QGC camera list
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
};

class FirmwarePluginFactory : public QObject
{
    Q_OBJECT

public:
    FirmwarePluginFactory(void);

    /// Returns appropriate plugin for autopilot type.
    ///     @param autopilotType Type of autopilot to return plugin for.
    ///     @param vehicleType Vehicle type of autopilot to return plugin for.
    /// @return Singleton FirmwarePlugin instance for the specified MAV_AUTOPILOT.
    virtual FirmwarePlugin* firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType) = 0;

377 378
    /// @return List of firmware classes this plugin supports.
    virtual QList<QGCMAVLink::FirmwareClass_t> supportedFirmwareClasses(void) const = 0;
379

380 381
    /// @return List of vehicle classes this plugin supports.
    virtual QList<QGCMAVLink::VehicleClass_t> supportedVehicleClasses(void) const;
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
};

class FirmwarePluginFactoryRegister : public QObject
{
    Q_OBJECT

public:
    static FirmwarePluginFactoryRegister* instance(void);

    /// Registers the specified logging category to the system.
    void registerPluginFactory(FirmwarePluginFactory* pluginFactory) { _factoryList.append(pluginFactory); }

    QList<FirmwarePluginFactory*> pluginFactories(void) const { return _factoryList; }

private:
    QList<FirmwarePluginFactory*> _factoryList;
Don Gagne's avatar
Don Gagne committed
398 399 400
};

#endif