From 96995949579b09aa87370b29cbe4be70a603c94e Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Mon, 8 Feb 2016 15:15:03 -0800 Subject: [PATCH] Support command editor overrides - override by vehicle type - override by firmware type --- qgroundcontrol.pro | 2 + qgroundcontrol.qrc | 8 +- src/FirmwarePlugin/APM/APMFirmwarePlugin.cc | 7 + src/FirmwarePlugin/APM/APMFirmwarePlugin.h | 1 + src/FirmwarePlugin/APM/MavCmdInfoCommon.json | 6 + .../APM/MavCmdInfoFixedWing.json | 21 ++ .../APM/MavCmdInfoMultiRotor.json | 59 ++++ src/FirmwarePlugin/FirmwarePlugin.h | 6 + .../Generic/GenericFirmwarePlugin.cc | 8 + .../Generic/GenericFirmwarePlugin.h | 26 +- src/FirmwarePlugin/PX4/MavCmdInfoCommon.json | 6 + .../PX4/MavCmdInfoFixedWing.json | 6 + .../PX4/MavCmdInfoMultiRotor.json | 44 +++ src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc | 8 + src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h | 25 +- ...{MavCmdInfo.json => MavCmdInfoCommon.json} | 0 src/MissionManager/MissionCommandList.cc | 274 ++++++++++++++++ src/MissionManager/MissionCommandList.h | 174 ++++++++++ src/MissionManager/MissionCommands.cc | 309 +++++------------- src/MissionManager/MissionCommands.h | 153 ++------- src/MissionManager/MissionController.cc | 6 +- src/MissionManager/MissionItem.cc | 49 +-- src/MissionManager/MissionItem.h | 8 +- src/MissionManager/MissionItemTest.cc | 7 +- src/MissionManager/MissionManager.cc | 3 +- src/MissionManager/MissionManagerTest.cc | 4 +- src/QGCLoggingCategory.cc | 2 + src/QGCLoggingCategory.h | 1 + 28 files changed, 806 insertions(+), 417 deletions(-) create mode 100644 src/FirmwarePlugin/APM/MavCmdInfoCommon.json create mode 100644 src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json create mode 100644 src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json create mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoCommon.json create mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json create mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json rename src/MissionManager/{MavCmdInfo.json => MavCmdInfoCommon.json} (100%) create mode 100644 src/MissionManager/MissionCommandList.cc create mode 100644 src/MissionManager/MissionCommandList.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 2ee11297d..a6d86ac83 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -251,6 +251,7 @@ HEADERS += \ src/Joystick/JoystickManager.h \ src/LogCompressor.h \ src/MG.h \ + src/MissionManager/MissionCommandList.h \ src/MissionManager/MissionCommands.h \ src/MissionManager/MissionController.h \ src/MissionManager/MissionItem.h \ @@ -374,6 +375,7 @@ SOURCES += \ src/Joystick/JoystickManager.cc \ src/LogCompressor.cc \ src/main.cc \ + src/MissionManager/MissionCommandList.cc \ src/MissionManager/MissionCommands.cc \ src/MissionManager/MissionController.cc \ src/MissionManager/MissionItem.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 7e73bdfa1..e9247708a 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -141,6 +141,12 @@ src/VehicleSetup/VehicleSummary.qml - src/MissionManager/MavCmdInfo.json + src/MissionManager/MavCmdInfoCommon.json + src/FirmwarePlugin/APM/MavCmdInfoCommon.json + src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json + src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json + src/FirmwarePlugin/PX4/MavCmdInfoCommon.json + src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json + src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc index d18c6c22f..48623a7b5 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc @@ -495,3 +495,10 @@ QList APMFirmwarePlugin::supportedMissionCommands(void) << MAV_CMD_CONDITION_DELAY << MAV_CMD_CONDITION_CHANGE_ALT << MAV_CMD_CONDITION_DISTANCE << MAV_CMD_CONDITION_YAW; return list; } + +void APMFirmwarePlugin::missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const +{ + commonJsonFilename = QStringLiteral(":/json/APM/MavCmdInfoCommon.json"); + fixedWingJsonFilename = QStringLiteral(":/json/APM/MavCmdInfoFixedWing.json"); + multiRotorJsonFilename = QStringLiteral(":/json/APM/MavCmdInfoMultiRotor.json"); +} diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h index 9395404b3..58edaa150 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h @@ -92,6 +92,7 @@ public: virtual void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType); virtual QString getDefaultComponentIdParam(void) const { return QString("SYSID_SW_TYPE"); } virtual QList supportedMissionCommands(void); + void missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const final; protected: /// All access to singleton is through stack specific implementation diff --git a/src/FirmwarePlugin/APM/MavCmdInfoCommon.json b/src/FirmwarePlugin/APM/MavCmdInfoCommon.json new file mode 100644 index 000000000..77a8d8030 --- /dev/null +++ b/src/FirmwarePlugin/APM/MavCmdInfoCommon.json @@ -0,0 +1,6 @@ +{ + "version": 1, + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json b/src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json new file mode 100644 index 000000000..fde6c6960 --- /dev/null +++ b/src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json @@ -0,0 +1,21 @@ +{ + "version": 1, + + "mavCmdInfo": [ + { + "id": 22, + "rawName": "MAV_CMD_NAV_TAKEOFF", + "friendlyName": "Takeoff", + "description": "Take off from the ground.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic", + "param1": { + "label": "Pitch:", + "units": "radians", + "default": 0.26179939, + "decimalPlaces": 2 + } + } + ] +} diff --git a/src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json b/src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json new file mode 100644 index 000000000..13c75c6fd --- /dev/null +++ b/src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json @@ -0,0 +1,59 @@ +{ + "version": 1, + + "mavCmdInfo": [ + { + "id": 22, + "rawName": "MAV_CMD_NAV_TAKEOFF", + "friendlyName": "Takeoff", + "description": "Take off from the ground.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic" + }, + { + "id": 17, + "rawName": "MAV_CMD_NAV_LOITER_UNLIM", + "friendlyName": "Loiter", + "description": "Travel to a position and Loiter indefinitely.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic" + }, + { + "id": 18, + "rawName": "MAV_CMD_NAV_LOITER_TURNS", + "friendlyName": "Loiter (turns)", + "description": "Travel to a position and Circle with the specified radius for a number of turns.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic", + "param1": { + "label": "Turns:", + "default": 1, + "decimalPlaces": 0 + }, + "param3": { + "label": "Radius:", + "units": "meters", + "default": 10.0, + "decimalPlaces": 2 + } + }, + { + "id": 19, + "rawName": "MAV_CMD_NAV_LOITER_TIME", + "friendlyName": "Loiter (time)", + "description": "Travel to a position and Loiter for an amount of time.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic", + "param1": { + "label": "Hold:", + "units": "seconds", + "default": 30, + "decimalPlaces": 0 + } + } + ] +} diff --git a/src/FirmwarePlugin/FirmwarePlugin.h b/src/FirmwarePlugin/FirmwarePlugin.h index 5fe39e1e9..14d497cc5 100644 --- a/src/FirmwarePlugin/FirmwarePlugin.h +++ b/src/FirmwarePlugin/FirmwarePlugin.h @@ -113,6 +113,12 @@ public: /// List of supported mission commands. Empty list for all commands supported. virtual QList supportedMissionCommands(void) = 0; + + /// Returns the names for the mission command json override files. Empty string to specify no overrides. + /// @param[out] commonJsonFilename Filename for common overrides + /// @param[out] fixedWingJsonFilename Filename for fixed wing overrides + /// @param[out] multiRotorJsonFilename Filename for multi rotor overrides + virtual void missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const = 0; }; #endif diff --git a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc index b35fddc31..a8b4cb25c 100644 --- a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc +++ b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.cc @@ -127,3 +127,11 @@ QList GenericFirmwarePlugin::supportedMissionCommands(void) // Generic supports all commands return QList(); } + +void GenericFirmwarePlugin::missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const +{ + // No overrides + commonJsonFilename.clear(); + fixedWingJsonFilename.clear(); + multiRotorJsonFilename.clear(); +} diff --git a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h index d1b828459..0a21101ee 100644 --- a/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h +++ b/src/FirmwarePlugin/Generic/GenericFirmwarePlugin.h @@ -35,19 +35,19 @@ class GenericFirmwarePlugin : public FirmwarePlugin public: // Overrides from FirmwarePlugin - - virtual bool isCapable(FirmwareCapabilities capabilities) { Q_UNUSED(capabilities); return false; } - virtual QList componentsForVehicle(AutoPilotPlugin* vehicle); - virtual QStringList flightModes(void) { return QStringList(); } - virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode); - virtual bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode); - virtual int manualControlReservedButtonCount(void); - virtual void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message); - virtual void initializeVehicle(Vehicle* vehicle); - virtual bool sendHomePositionToVehicle(void); - virtual void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType); - virtual QString getDefaultComponentIdParam(void) const { return QString(); } - virtual QList supportedMissionCommands(void); + bool isCapable(FirmwareCapabilities capabilities) final { Q_UNUSED(capabilities); return false; } + QList componentsForVehicle(AutoPilotPlugin* vehicle) final; + QStringList flightModes(void) final { return QStringList(); } + QString flightMode(uint8_t base_mode, uint32_t custom_mode) final; + bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode) final; + int manualControlReservedButtonCount(void) final; + void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message) final; + void initializeVehicle(Vehicle* vehicle) final; + bool sendHomePositionToVehicle(void) final; + void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType) final; + QString getDefaultComponentIdParam(void) const final { return QString(); } + QList supportedMissionCommands(void) final; + void missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const final; }; #endif diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoCommon.json b/src/FirmwarePlugin/PX4/MavCmdInfoCommon.json new file mode 100644 index 000000000..77a8d8030 --- /dev/null +++ b/src/FirmwarePlugin/PX4/MavCmdInfoCommon.json @@ -0,0 +1,6 @@ +{ + "version": 1, + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json b/src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json new file mode 100644 index 000000000..77a8d8030 --- /dev/null +++ b/src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json @@ -0,0 +1,6 @@ +{ + "version": 1, + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json b/src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json new file mode 100644 index 000000000..b4022f7e1 --- /dev/null +++ b/src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json @@ -0,0 +1,44 @@ +{ + "version": 1, + + "mavCmdInfo": [ + { + "id": 17, + "rawName": "MAV_CMD_NAV_LOITER_UNLIM", + "friendlyName": "Loiter", + "description": "Travel to a position and Loiter indefinitely.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic" + }, + { + "id": 18, + "rawName": "MAV_CMD_NAV_LOITER_TURNS", + "friendlyName": "Loiter (turns)", + "description": "Travel to a position and Loiter for a number of turns.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic", + "param1": { + "label": "Turns:", + "default": 1, + "decimalPlaces": 0 + } + }, + { + "id": 19, + "rawName": "MAV_CMD_NAV_LOITER_TIME", + "friendlyName": "Loiter (time)", + "description": "Travel to a position and Loiter for an amount of time.", + "specifiesCoordinate": true, + "friendlyEdit": true, + "category": "Basic", + "param1": { + "label": "Hold:", + "units": "seconds", + "default": 30, + "decimalPlaces": 0 + } + } + ] +} diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc index 02e0e9a3a..bcb6ee483 100644 --- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc +++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc @@ -225,3 +225,11 @@ QList PX4FirmwarePlugin::supportedMissionCommands(void) << MAV_CMD_DO_CHANGE_SPEED; return list; } + +void PX4FirmwarePlugin::missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const +{ + // No overrides + commonJsonFilename = QStringLiteral(":/json/PX4/MavCmdInfoCommon.json"); + fixedWingJsonFilename = QStringLiteral(":/json/PX4/MavCmdInfoFixedWing.json"); + multiRotorJsonFilename = QStringLiteral(":/json/PX4/MavCmdInfoMultiRotor.json"); +} diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h index 4af5a1c01..c796af369 100644 --- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h +++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h @@ -36,18 +36,19 @@ class PX4FirmwarePlugin : public FirmwarePlugin public: // Overrides from FirmwarePlugin - virtual bool isCapable(FirmwareCapabilities capabilities); - virtual QList componentsForVehicle(AutoPilotPlugin* vehicle); - virtual QStringList flightModes(void); - virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode); - virtual bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode); - virtual int manualControlReservedButtonCount(void); - virtual void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message); - virtual void initializeVehicle(Vehicle* vehicle); - virtual bool sendHomePositionToVehicle(void); - virtual void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType); - virtual QString getDefaultComponentIdParam(void) const { return QString("SYS_AUTOSTART"); } - virtual QList supportedMissionCommands(void); + bool isCapable(FirmwareCapabilities capabilities) final; + QList componentsForVehicle(AutoPilotPlugin* vehicle) final; + QStringList flightModes(void) final; + QString flightMode(uint8_t base_mode, uint32_t custom_mode) final; + bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode) final; + int manualControlReservedButtonCount(void) final; + void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message) final; + void initializeVehicle(Vehicle* vehicle) final; + bool sendHomePositionToVehicle(void) final; + void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType) final; + QString getDefaultComponentIdParam(void) const final { return QString("SYS_AUTOSTART"); } + QList supportedMissionCommands(void) final; + void missionCommandOverrides(QString& commonJsonFilename, QString& fixedWingJsonFilename, QString& multiRotorJsonFilename) const final; private: PX4ParameterMetaData _parameterMetaData; diff --git a/src/MissionManager/MavCmdInfo.json b/src/MissionManager/MavCmdInfoCommon.json similarity index 100% rename from src/MissionManager/MavCmdInfo.json rename to src/MissionManager/MavCmdInfoCommon.json diff --git a/src/MissionManager/MissionCommandList.cc b/src/MissionManager/MissionCommandList.cc new file mode 100644 index 000000000..8a0a6dc22 --- /dev/null +++ b/src/MissionManager/MissionCommandList.cc @@ -0,0 +1,274 @@ +/*=================================================================== +QGroundControl Open Source Ground Control Station + +(c) 2009, 2010 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +#include "MissionCommandList.h" +#include "FactMetaData.h" +#include "Vehicle.h" +#include "FirmwarePluginManager.h" +#include "QGCApplication.h" +#include "QGroundControlQmlGlobal.h" + +#include +#include +#include +#include +#include +#include + +const QString MissionCommandList::_categoryJsonKey (QStringLiteral("category")); +const QString MissionCommandList::_decimalPlacesJsonKey (QStringLiteral("decimalPlaces")); +const QString MissionCommandList::_defaultJsonKey (QStringLiteral("default")); +const QString MissionCommandList::_descriptionJsonKey (QStringLiteral("description")); +const QString MissionCommandList::_enumStringsJsonKey (QStringLiteral("enumStrings")); +const QString MissionCommandList::_enumValuesJsonKey (QStringLiteral("enumValues")); +const QString MissionCommandList::_friendlyEditJsonKey (QStringLiteral("friendlyEdit")); +const QString MissionCommandList::_friendlyNameJsonKey (QStringLiteral("friendlyName")); +const QString MissionCommandList::_idJsonKey (QStringLiteral("id")); +const QString MissionCommandList::_labelJsonKey (QStringLiteral("label")); +const QString MissionCommandList::_mavCmdInfoJsonKey (QStringLiteral("mavCmdInfo")); +const QString MissionCommandList::_param1JsonKey (QStringLiteral("param1")); +const QString MissionCommandList::_param2JsonKey (QStringLiteral("param2")); +const QString MissionCommandList::_param3JsonKey (QStringLiteral("param3")); +const QString MissionCommandList::_param4JsonKey (QStringLiteral("param4")); +const QString MissionCommandList::_paramJsonKeyFormat (QStringLiteral("param%1")); +const QString MissionCommandList::_rawNameJsonKey (QStringLiteral("rawName")); +const QString MissionCommandList::_standaloneCoordinateJsonKey (QStringLiteral("standaloneCoordinate")); +const QString MissionCommandList::_specifiesCoordinateJsonKey (QStringLiteral("specifiesCoordinate")); +const QString MissionCommandList::_unitsJsonKey (QStringLiteral("units")); +const QString MissionCommandList::_versionJsonKey (QStringLiteral("version")); + +MissionCommandList::MissionCommandList(const QString& jsonFilename, QObject* parent) + : QObject(parent) +{ + _loadMavCmdInfoJson(jsonFilename); +} + +bool MissionCommandList::_validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList& types) +{ + for (int i=0; i types; + keys << _idJsonKey << _rawNameJsonKey << _friendlyNameJsonKey << _descriptionJsonKey << _standaloneCoordinateJsonKey << _specifiesCoordinateJsonKey <<_friendlyEditJsonKey + << _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _categoryJsonKey; + types << QJsonValue::Double << QJsonValue::String << QJsonValue::String<< QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool << QJsonValue::Bool + << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::String; + if (!_validateKeyTypes(jsonObject, keys, types)) { + return; + } + + MavCmdInfo* mavCmdInfo = new MavCmdInfo(this); + + mavCmdInfo->_command = (MAV_CMD) jsonObject.value(_idJsonKey).toInt(); + mavCmdInfo->_category = jsonObject.value(_categoryJsonKey).toString("Advanced"); + mavCmdInfo->_rawName = jsonObject.value(_rawNameJsonKey).toString(); + mavCmdInfo->_friendlyName = jsonObject.value(_friendlyNameJsonKey).toString(QString()); + mavCmdInfo->_description = jsonObject.value(_descriptionJsonKey).toString(QString()); + mavCmdInfo->_standaloneCoordinate = jsonObject.value(_standaloneCoordinateJsonKey).toBool(false); + mavCmdInfo->_specifiesCoordinate = jsonObject.value(_specifiesCoordinateJsonKey).toBool(false); + mavCmdInfo->_friendlyEdit = jsonObject.value(_friendlyEditJsonKey).toBool(false); + + qCDebug(MissionCommandsLog) << "Command" + << mavCmdInfo->_command + << mavCmdInfo->_category + << mavCmdInfo->_rawName + << mavCmdInfo->_friendlyName + << mavCmdInfo->_description + << mavCmdInfo->_standaloneCoordinate + << mavCmdInfo->_specifiesCoordinate + << mavCmdInfo->_friendlyEdit; + + if (_mavCmdInfoMap.contains((MAV_CMD)mavCmdInfo->command())) { + qWarning() << "Duplicate command" << mavCmdInfo->command(); + return; + } + + _mavCmdInfoMap[mavCmdInfo->_command] = mavCmdInfo; + + // Read params + + for (int i=1; i<=7; i++) { + QString paramKey = QString(_paramJsonKeyFormat).arg(i); + + if (jsonObject.contains(paramKey)) { + QJsonObject paramObject = jsonObject.value(paramKey).toObject(); + + // Validate key types + QStringList keys; + QList types; + keys << _defaultJsonKey << _decimalPlacesJsonKey << _enumStringsJsonKey << _enumValuesJsonKey << _labelJsonKey << _unitsJsonKey; + types << QJsonValue::Double << QJsonValue::Double << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::String; + if (!_validateKeyTypes(paramObject, keys, types)) { + return; + } + + mavCmdInfo->_friendlyEdit = true; // Assume friendly edit if we have params + + if (!paramObject.contains(_labelJsonKey)) { + qWarning() << "param object missing label key" << mavCmdInfo->rawName() << paramKey; + return; + } + + MavCmdParamInfo* paramInfo = new MavCmdParamInfo(this); + + paramInfo->_label = paramObject.value(_labelJsonKey).toString(); + paramInfo->_defaultValue = paramObject.value(_defaultJsonKey).toDouble(0.0); + paramInfo->_decimalPlaces = paramObject.value(_decimalPlacesJsonKey).toInt(FactMetaData::defaultDecimalPlaces); + paramInfo->_enumStrings = paramObject.value(_enumStringsJsonKey).toString().split(",", QString::SkipEmptyParts); + paramInfo->_param = i; + paramInfo->_units = paramObject.value(_unitsJsonKey).toString(); + + QStringList enumValues = paramObject.value(_enumValuesJsonKey).toString().split(",", QString::SkipEmptyParts); + foreach (const QString &enumValue, enumValues) { + bool convertOk; + double value = enumValue.toDouble(&convertOk); + + if (!convertOk) { + qWarning() << "Bad enumValue" << enumValue; + return; + } + + paramInfo->_enumValues << QVariant(value); + } + if (paramInfo->_enumValues.count() != paramInfo->_enumStrings.count()) { + qWarning() << "enum strings/values count mismatch" << paramInfo->_enumStrings.count() << paramInfo->_enumValues.count(); + return; + } + + qCDebug(MissionCommandsLog) << "Param" + << paramInfo->_label + << paramInfo->_defaultValue + << paramInfo->_decimalPlaces + << paramInfo->_param + << paramInfo->_units + << paramInfo->_enumStrings + << paramInfo->_enumValues; + + mavCmdInfo->_paramInfoMap[i] = paramInfo; + } + } + + if (mavCmdInfo->friendlyEdit()) { + if (mavCmdInfo->description().isEmpty()) { + qWarning() << "Missing description" << mavCmdInfo->rawName(); + return; + } + if (mavCmdInfo->rawName() == mavCmdInfo->friendlyName()) { + qWarning() << "Missing friendly name" << mavCmdInfo->rawName() << mavCmdInfo->friendlyName(); + return; + } + } + } +} + +bool MissionCommandList::contains(MAV_CMD command) const +{ + return _mavCmdInfoMap.contains(command); +} + +MavCmdInfo* MissionCommandList::getMavCmdInfo(MAV_CMD command) const +{ + if (!contains(command)) { + qWarning() << "Unknown command" << command; + return NULL; + } + + return _mavCmdInfoMap[command]; +} + +QList MissionCommandList::commandsIds(void) const +{ + QList list; + + foreach (const MavCmdInfo* mavCmdInfo, _mavCmdInfoMap) { + list << (MAV_CMD)mavCmdInfo->command(); + } + + return list; +} diff --git a/src/MissionManager/MissionCommandList.h b/src/MissionManager/MissionCommandList.h new file mode 100644 index 000000000..98c3ef78c --- /dev/null +++ b/src/MissionManager/MissionCommandList.h @@ -0,0 +1,174 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#ifndef MissionCommandList_H +#define MissionCommandList_H + +#include "QGCToolbox.h" +#include "QGCMAVLink.h" +#include "QGCLoggingCategory.h" +#include "QmlObjectListModel.h" +#include "MavlinkQmlSingleton.h" + +#include +#include +#include +#include + +class MissionCommandList; +class Vehicle; + +/// The information associated with a mission command parameter. +class MavCmdParamInfo : public QObject { + + Q_OBJECT + +public: + MavCmdParamInfo(QObject* parent = NULL) + : QObject(parent) + { + + } + + Q_PROPERTY(int decimalPlaces READ decimalPlaces CONSTANT) + Q_PROPERTY(double defaultValue READ defaultValue CONSTANT) + Q_PROPERTY(QStringList enumStrings READ enumStrings CONSTANT) + Q_PROPERTY(QVariantList enumValues READ enumValues CONSTANT) + Q_PROPERTY(QString label READ label CONSTANT) + Q_PROPERTY(int param READ param CONSTANT) + Q_PROPERTY(QString units READ units CONSTANT) + + int decimalPlaces (void) const { return _decimalPlaces; } + double defaultValue (void) const { return _defaultValue; } + QStringList enumStrings (void) const { return _enumStrings; } + QVariantList enumValues (void) const { return _enumValues; } + QString label (void) const { return _label; } + int param (void) const { return _param; } + QString units (void) const { return _units; } + +private: + int _decimalPlaces; + double _defaultValue; + QStringList _enumStrings; + QVariantList _enumValues; + QString _label; + int _param; + QString _units; + + friend class MissionCommandList; +}; + +// The information associated with a mission command. +class MavCmdInfo : public QObject { + Q_OBJECT + +public: + MavCmdInfo(QObject* parent = NULL) + : QObject(parent) + { + + } + + Q_PROPERTY(QString category READ category CONSTANT) + Q_PROPERTY(MavlinkQmlSingleton::Qml_MAV_CMD command READ qmlCommand CONSTANT) + Q_PROPERTY(QString description READ description CONSTANT) + Q_PROPERTY(bool friendlyEdit READ friendlyEdit CONSTANT) + Q_PROPERTY(QString friendlyName READ friendlyName CONSTANT) + Q_PROPERTY(QString rawName READ rawName CONSTANT) + Q_PROPERTY(bool standaloneCoordinate READ standaloneCoordinate CONSTANT) + Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate CONSTANT) + + MavlinkQmlSingleton::Qml_MAV_CMD qmlCommand(void) const { return (MavlinkQmlSingleton::Qml_MAV_CMD)_command; } + MAV_CMD command(void) const { return _command; } + + QString category (void) const { return _category; } + QString description (void) const { return _description; } + bool friendlyEdit (void) const { return _friendlyEdit; } + QString friendlyName (void) const { return _friendlyName; } + QString rawName (void) const { return _rawName; } + bool standaloneCoordinate(void) const { return _standaloneCoordinate; } + bool specifiesCoordinate (void) const { return _specifiesCoordinate; } + + const QMap& paramInfoMap(void) const { return _paramInfoMap; } + +private: + QString _category; + MAV_CMD _command; + QString _description; + bool _friendlyEdit; + QString _friendlyName; + QMap _paramInfoMap; + QString _rawName; + bool _standaloneCoordinate; + bool _specifiesCoordinate; + + friend class MissionCommandList; +}; + +// A list of mission command info loaded from a json file. +class MissionCommandList : public QObject +{ + Q_OBJECT + +public: + MissionCommandList(const QString& jsonFilename, QObject* parent = NULL); + + Q_INVOKABLE bool contains(MavlinkQmlSingleton::Qml_MAV_CMD command) const { return contains((MAV_CMD)command); } + bool contains(MAV_CMD command) const; + + Q_INVOKABLE QVariant getMavCmdInfo(MavlinkQmlSingleton::Qml_MAV_CMD command) const { return QVariant::fromValue(getMavCmdInfo((MAV_CMD)command)); } + MavCmdInfo* getMavCmdInfo(MAV_CMD command) const; + + QList commandsIds(void) const; + +private: + void _loadMavCmdInfoJson(const QString& jsonFilename); + bool _validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList& types); + +private: + QMap _mavCmdInfoMap; + + static const QString _categoryJsonKey; + static const QString _decimalPlacesJsonKey; + static const QString _defaultJsonKey; + static const QString _descriptionJsonKey; + static const QString _enumStringsJsonKey; + static const QString _enumValuesJsonKey; + static const QString _friendlyNameJsonKey; + static const QString _friendlyEditJsonKey; + static const QString _idJsonKey; + static const QString _labelJsonKey; + static const QString _mavCmdInfoJsonKey; + static const QString _param1JsonKey; + static const QString _param2JsonKey; + static const QString _param3JsonKey; + static const QString _param4JsonKey; + static const QString _paramJsonKeyFormat; + static const QString _rawNameJsonKey; + static const QString _standaloneCoordinateJsonKey; + static const QString _specifiesCoordinateJsonKey; + static const QString _unitsJsonKey; + static const QString _versionJsonKey; +}; + +#endif diff --git a/src/MissionManager/MissionCommands.cc b/src/MissionManager/MissionCommands.cc index 1ac697b5a..e16831c46 100644 --- a/src/MissionManager/MissionCommands.cc +++ b/src/MissionManager/MissionCommands.cc @@ -27,241 +27,64 @@ This file is part of the QGROUNDCONTROL project #include "QGCApplication.h" #include "QGroundControlQmlGlobal.h" -#include -#include -#include -#include -#include -#include - -QGC_LOGGING_CATEGORY(MissionCommandsLog, "MissionCommandsLog") - -const QString MissionCommands::_categoryJsonKey (QStringLiteral("category")); -const QString MissionCommands::_decimalPlacesJsonKey (QStringLiteral("decimalPlaces")); -const QString MissionCommands::_defaultJsonKey (QStringLiteral("default")); -const QString MissionCommands::_descriptionJsonKey (QStringLiteral("description")); -const QString MissionCommands::_enumStringsJsonKey (QStringLiteral("enumStrings")); -const QString MissionCommands::_enumValuesJsonKey (QStringLiteral("enumValues")); -const QString MissionCommands::_friendlyEditJsonKey (QStringLiteral("friendlyEdit")); -const QString MissionCommands::_friendlyNameJsonKey (QStringLiteral("friendlyName")); -const QString MissionCommands::_idJsonKey (QStringLiteral("id")); -const QString MissionCommands::_labelJsonKey (QStringLiteral("label")); -const QString MissionCommands::_mavCmdInfoJsonKey (QStringLiteral("mavCmdInfo")); -const QString MissionCommands::_param1JsonKey (QStringLiteral("param1")); -const QString MissionCommands::_param2JsonKey (QStringLiteral("param2")); -const QString MissionCommands::_param3JsonKey (QStringLiteral("param3")); -const QString MissionCommands::_param4JsonKey (QStringLiteral("param4")); -const QString MissionCommands::_paramJsonKeyFormat (QStringLiteral("param%1")); -const QString MissionCommands::_rawNameJsonKey (QStringLiteral("rawName")); -const QString MissionCommands::_standaloneCoordinateJsonKey (QStringLiteral("standaloneCoordinate")); -const QString MissionCommands::_specifiesCoordinateJsonKey (QStringLiteral("specifiesCoordinate")); -const QString MissionCommands::_unitsJsonKey (QStringLiteral("units")); -const QString MissionCommands::_versionJsonKey (QStringLiteral("version")); - MissionCommands::MissionCommands(QGCApplication* app) : QGCTool(app) + , _commonMissionCommands(QStringLiteral(":/json/MavCmdInfoCommon.json")) { - } void MissionCommands::setToolbox(QGCToolbox* toolbox) { QGCTool::setToolbox(toolbox); - _loadMavCmdInfoJson(); - _createFirmwareSpecificLists(); -} -bool MissionCommands::_validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList& types) -{ - for (int i=0; i firmwareList; + firmwareList << MAV_AUTOPILOT_GENERIC << MAV_AUTOPILOT_PX4 << MAV_AUTOPILOT_ARDUPILOTMEGA; -void MissionCommands::_loadMavCmdInfoJson(void) -{ - QFile jsonFile(":/json/MavCmdInfo.json"); - if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "Unable to open MavCmdInfo.json" << jsonFile.errorString(); - return; - } - - QByteArray bytes = jsonFile.readAll(); - jsonFile.close(); - QJsonParseError jsonParseError; - QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError); - if (jsonParseError.error != QJsonParseError::NoError) { - qWarning() << "Unable to open json document" << jsonParseError.errorString(); - return; - } - - QJsonObject json = doc.object(); - - int version = json.value(_versionJsonKey).toInt(); - if (version != 1) { - qWarning() << "Invalid version" << version; - return; - } + foreach (MAV_AUTOPILOT firmwareType, firmwareList) { + FirmwarePlugin* plugin = _toolbox->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR); - QJsonValue jsonValue = json.value(_mavCmdInfoJsonKey); - if (!jsonValue.isArray()) { - qWarning() << "mavCmdInfo not array"; - return; + plugin->missionCommandOverrides(overrideCommonJsonFilename, overrideFixedWingJsonFilename, overrideMultiRotorJsonFilename); + _autopilotToCommonMissionCommands[firmwareType] = new MissionCommandList(overrideCommonJsonFilename); + _autopilotToFixedWingMissionCommands[firmwareType] = new MissionCommandList(overrideFixedWingJsonFilename); + _autopilotToMultiRotorMissionCommands[firmwareType] = new MissionCommandList(overrideMultiRotorJsonFilename); } - QJsonArray jsonArray = jsonValue.toArray(); - foreach(QJsonValue info, jsonArray) { - if (!info.isObject()) { - qWarning() << "mavCmdArray should contain objects"; - return; - } - QJsonObject jsonObject = info.toObject(); - - // Make sure we have the required keys - QStringList requiredKeys; - requiredKeys << _idJsonKey << _rawNameJsonKey; - foreach (const QString &key, requiredKeys) { - if (!jsonObject.contains(key)) { - qWarning() << "Mission required key" << key; - return; - } - } - - // Validate key types + _createCategories(); +} - QStringList keys; - QList types; - keys << _idJsonKey << _rawNameJsonKey << _friendlyNameJsonKey << _descriptionJsonKey << _standaloneCoordinateJsonKey << _specifiesCoordinateJsonKey <<_friendlyEditJsonKey - << _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _categoryJsonKey; - types << QJsonValue::Double << QJsonValue::String << QJsonValue::String<< QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool << QJsonValue::Bool - << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::String; - if (!_validateKeyTypes(jsonObject, keys, types)) { - return; - } +/// Create category hierarchy for support commands +void MissionCommands::_createCategories(void) +{ + // FIXME: This isn't quite right since it's hardcoding the firmware providers. But ok for now. + QList firmwareList; + firmwareList << MAV_AUTOPILOT_GENERIC << MAV_AUTOPILOT_PX4 << MAV_AUTOPILOT_ARDUPILOTMEGA; - MavCmdInfo* mavCmdInfo = new MavCmdInfo(this); - - mavCmdInfo->_command = (MAV_CMD) jsonObject.value(_idJsonKey).toInt(); - mavCmdInfo->_category = jsonObject.value(_categoryJsonKey).toString("Advanced"); - mavCmdInfo->_rawName = jsonObject.value(_rawNameJsonKey).toString(); - mavCmdInfo->_friendlyName = jsonObject.value(_friendlyNameJsonKey).toString(QString()); - mavCmdInfo->_description = jsonObject.value(_descriptionJsonKey).toString(QString()); - mavCmdInfo->_standaloneCoordinate = jsonObject.value(_standaloneCoordinateJsonKey).toBool(false); - mavCmdInfo->_specifiesCoordinate = jsonObject.value(_specifiesCoordinateJsonKey).toBool(false); - mavCmdInfo->_friendlyEdit = jsonObject.value(_friendlyEditJsonKey).toBool(false); - - qCDebug(MissionCommandsLog) << "Command" - << mavCmdInfo->_command - << mavCmdInfo->_category - << mavCmdInfo->_rawName - << mavCmdInfo->_friendlyName - << mavCmdInfo->_description - << mavCmdInfo->_standaloneCoordinate - << mavCmdInfo->_specifiesCoordinate - << mavCmdInfo->_friendlyEdit; - - if (_mavCmdInfoMap.contains((MAV_CMD)mavCmdInfo->command())) { - qWarning() << "Duplicate command" << mavCmdInfo->command(); - return; - } + foreach (MAV_AUTOPILOT firmwareType, firmwareList) { + FirmwarePlugin* plugin = _toolbox->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR); - _mavCmdInfoMap[mavCmdInfo->_command] = mavCmdInfo; - - // Read params - - for (int i=1; i<=7; i++) { - QString paramKey = QString(_paramJsonKeyFormat).arg(i); - - if (jsonObject.contains(paramKey)) { - QJsonObject paramObject = jsonObject.value(paramKey).toObject(); - - // Validate key types - QStringList keys; - QList types; - keys << _defaultJsonKey << _decimalPlacesJsonKey << _enumStringsJsonKey << _enumValuesJsonKey << _labelJsonKey << _unitsJsonKey; - types << QJsonValue::Double << QJsonValue::Double << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::String; - if (!_validateKeyTypes(paramObject, keys, types)) { - return; - } - - mavCmdInfo->_friendlyEdit = true; // Assume friendly edit if we have params - - if (!paramObject.contains(_labelJsonKey)) { - qWarning() << "param object missing label key" << mavCmdInfo->rawName() << paramKey; - return; - } - - MavCmdParamInfo* paramInfo = new MavCmdParamInfo(this); - - paramInfo->_label = paramObject.value(_labelJsonKey).toString(); - paramInfo->_defaultValue = paramObject.value(_defaultJsonKey).toDouble(0.0); - paramInfo->_decimalPlaces = paramObject.value(_decimalPlacesJsonKey).toInt(FactMetaData::defaultDecimalPlaces); - paramInfo->_enumStrings = paramObject.value(_enumStringsJsonKey).toString().split(",", QString::SkipEmptyParts); - paramInfo->_param = i; - paramInfo->_units = paramObject.value(_unitsJsonKey).toString(); - - QStringList enumValues = paramObject.value(_enumValuesJsonKey).toString().split(",", QString::SkipEmptyParts); - foreach (const QString &enumValue, enumValues) { - bool convertOk; - double value = enumValue.toDouble(&convertOk); - - if (!convertOk) { - qWarning() << "Bad enumValue" << enumValue; - return; - } - - paramInfo->_enumValues << QVariant(value); - } - if (paramInfo->_enumValues.count() != paramInfo->_enumStrings.count()) { - qWarning() << "enum strings/values count mismatch" << paramInfo->_enumStrings.count() << paramInfo->_enumValues.count(); - return; - } - - qCDebug(MissionCommandsLog) << "Param" - << paramInfo->_label - << paramInfo->_defaultValue - << paramInfo->_decimalPlaces - << paramInfo->_param - << paramInfo->_units - << paramInfo->_enumStrings - << paramInfo->_enumValues; - - mavCmdInfo->_paramInfoMap[i] = paramInfo; - } + bool allCommandsSupported = false; + QList cmdList = plugin->supportedMissionCommands(); + if (cmdList.isEmpty()) { + allCommandsSupported = true; + cmdList = _commonMissionCommands.commandsIds(); } - // We don't add categories till down here, since friendly edit isn't valid till here - if (mavCmdInfo->_command != MAV_CMD_NAV_LAST) { - // Don't add fake home position command to categories + foreach (MAV_CMD command, cmdList) { + MavCmdInfo* mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command); if (mavCmdInfo->friendlyEdit()) { - // Only friendly edit commands go in category list. We use MAV_AUTOPILOT_GENERIC key to store full list. - if (!_categoryToMavCmdInfoListMap.contains(MAV_AUTOPILOT_GENERIC) || !_categoryToMavCmdInfoListMap[MAV_AUTOPILOT_GENERIC].contains(mavCmdInfo->category())) { - qCDebug(MissionCommandsLog) << "Adding new category"; - _categoryToMavCmdInfoListMap[MAV_AUTOPILOT_GENERIC][mavCmdInfo->category()] = new QmlObjectListModel(this); - } - _categoryToMavCmdInfoListMap[MAV_AUTOPILOT_GENERIC][mavCmdInfo->category()]->append(mavCmdInfo); - } - } - - if (mavCmdInfo->friendlyEdit()) { - if (mavCmdInfo->description().isEmpty()) { - qWarning() << "Missing description" << mavCmdInfo->rawName(); - return; - } - if (mavCmdInfo->rawName() == mavCmdInfo->friendlyName()) { - qWarning() << "Missing friendly name" << mavCmdInfo->rawName() << mavCmdInfo->friendlyName(); - return; + _categoryToMavCmdListMap[firmwareType][mavCmdInfo->category()].append(command); + } else if (!allCommandsSupported) { + qWarning() << "Attempt to add non friendly edit supported command"; } } } + } MAV_AUTOPILOT MissionCommands::_firmwareTypeFromVehicle(Vehicle* vehicle) const @@ -280,47 +103,71 @@ MAV_AUTOPILOT MissionCommands::_firmwareTypeFromVehicle(Vehicle* vehicle) const QString MissionCommands::categoryFromCommand(MavlinkQmlSingleton::Qml_MAV_CMD command) const { - return _mavCmdInfoMap[(MAV_CMD)command]->category(); + return _commonMissionCommands.getMavCmdInfo((MAV_CMD)command)->category(); } QVariant MissionCommands::getCommandsForCategory(Vehicle* vehicle, const QString& category) const { - return QVariant::fromValue(_categoryToMavCmdInfoListMap[_firmwareTypeFromVehicle(vehicle)][category]); + QmlObjectListModel* list = new QmlObjectListModel(); + QQmlEngine::setObjectOwnership(list, QQmlEngine::JavaScriptOwnership); + + foreach (MAV_CMD command, _categoryToMavCmdListMap[_firmwareTypeFromVehicle(vehicle)][category]) { + list->append(getMavCmdInfo(command, vehicle)); + } + + return QVariant::fromValue(list); } const QStringList MissionCommands::categories(Vehicle* vehicle) const { QStringList list; - foreach (const QString &category, _categoryToMavCmdInfoListMap[_firmwareTypeFromVehicle(vehicle)].keys()) { + foreach (const QString &category, _categoryToMavCmdListMap[_firmwareTypeFromVehicle(vehicle)].keys()) { list << category; } return list; } -void MissionCommands::_createFirmwareSpecificLists(void) +bool MissionCommands::contains(MAV_CMD command) const { - QList firmwareList; - - firmwareList << MAV_AUTOPILOT_PX4 << MAV_AUTOPILOT_ARDUPILOTMEGA; + return _commonMissionCommands.contains(command); +} - foreach (MAV_AUTOPILOT firmwareType, firmwareList) { - FirmwarePlugin* plugin = _toolbox->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR); +MavCmdInfo* MissionCommands::getMavCmdInfo(MAV_CMD command, Vehicle* vehicle) const +{ + if (!contains(command)) { + qWarning() << "Unknown command" << command; + return NULL; + } - QList cmdList = plugin->supportedMissionCommands(); - foreach (MAV_CMD command, cmdList) { - MavCmdInfo* mavCmdInfo = _mavCmdInfoMap[command]; + MavCmdInfo* mavCmdInfo = NULL; + MAV_AUTOPILOT firmwareType = _firmwareTypeFromVehicle(vehicle); - if (mavCmdInfo->friendlyEdit()) { - if (!_categoryToMavCmdInfoListMap.contains(firmwareType) || !_categoryToMavCmdInfoListMap[firmwareType].contains(mavCmdInfo->category())) { - qCDebug(MissionCommandsLog) << "Adding new category" << firmwareType; - _categoryToMavCmdInfoListMap[firmwareType][mavCmdInfo->category()] = new QmlObjectListModel(this); - } - _categoryToMavCmdInfoListMap[firmwareType][mavCmdInfo->category()]->append(mavCmdInfo); - } else { - qWarning() << "Attempt to add non friendly edit supported command"; + if (vehicle) { + if (vehicle->fixedWing()) { + if (_autopilotToFixedWingMissionCommands[firmwareType]->contains(command)) { + mavCmdInfo = _autopilotToFixedWingMissionCommands[firmwareType]->getMavCmdInfo(command); + } + } else if (vehicle->multiRotor()) { + if (_autopilotToMultiRotorMissionCommands[firmwareType]->contains(command)) { + mavCmdInfo = _autopilotToMultiRotorMissionCommands[firmwareType]->getMavCmdInfo(command); + } + } else { + if (_autopilotToCommonMissionCommands[firmwareType]->contains(command)) { + mavCmdInfo = _autopilotToCommonMissionCommands[firmwareType]->getMavCmdInfo(command); } } } + + if (!mavCmdInfo) { + mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command); + } + + return mavCmdInfo; +} + +QList MissionCommands::commandsIds(void) const +{ + return _commonMissionCommands.commandsIds(); } diff --git a/src/MissionManager/MissionCommands.h b/src/MissionManager/MissionCommands.h index e9fedb736..08b85edd3 100644 --- a/src/MissionManager/MissionCommands.h +++ b/src/MissionManager/MissionCommands.h @@ -25,104 +25,17 @@ #define MissionCommands_H #include "QGCToolbox.h" -#include "QGCMAVLink.h" -#include "QGCLoggingCategory.h" -#include "QmlObjectListModel.h" -#include "MavlinkQmlSingleton.h" - -#include -#include -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(MissionCommandsLog) - -class MissionCommands; -class Vehicle; - -class MavCmdParamInfo : public QObject { - - Q_OBJECT - -public: - MavCmdParamInfo(QObject* parent = NULL) - : QObject(parent) - { - - } - - Q_PROPERTY(int decimalPlaces READ decimalPlaces CONSTANT) - Q_PROPERTY(double defaultValue READ defaultValue CONSTANT) - Q_PROPERTY(QStringList enumStrings READ enumStrings CONSTANT) - Q_PROPERTY(QVariantList enumValues READ enumValues CONSTANT) - Q_PROPERTY(QString label READ label CONSTANT) - Q_PROPERTY(int param READ param CONSTANT) - Q_PROPERTY(QString units READ units CONSTANT) - - int decimalPlaces (void) const { return _decimalPlaces; } - double defaultValue (void) const { return _defaultValue; } - QStringList enumStrings (void) const { return _enumStrings; } - QVariantList enumValues (void) const { return _enumValues; } - QString label (void) const { return _label; } - int param (void) const { return _param; } - QString units (void) const { return _units; } - -private: - int _decimalPlaces; - double _defaultValue; - QStringList _enumStrings; - QVariantList _enumValues; - QString _label; - int _param; - QString _units; - - friend class MissionCommands; -}; - -class MavCmdInfo : public QObject { - Q_OBJECT - -public: - MavCmdInfo(QObject* parent = NULL) - : QObject(parent) - { - - } - - Q_PROPERTY(QString category READ category CONSTANT) - Q_PROPERTY(MavlinkQmlSingleton::Qml_MAV_CMD command READ command CONSTANT) - Q_PROPERTY(QString description READ description CONSTANT) - Q_PROPERTY(bool friendlyEdit READ friendlyEdit CONSTANT) - Q_PROPERTY(QString friendlyName READ friendlyName CONSTANT) - Q_PROPERTY(QString rawName READ rawName CONSTANT) - Q_PROPERTY(bool standaloneCoordinate READ standaloneCoordinate CONSTANT) - Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate CONSTANT) - - QString category (void) const { return _category; } - MavlinkQmlSingleton::Qml_MAV_CMD command(void) const { return (MavlinkQmlSingleton::Qml_MAV_CMD)_command; } - QString description (void) const { return _description; } - bool friendlyEdit (void) const { return _friendlyEdit; } - QString friendlyName (void) const { return _friendlyName; } - QString rawName (void) const { return _rawName; } - bool standaloneCoordinate(void) const { return _standaloneCoordinate; } - bool specifiesCoordinate (void) const { return _specifiesCoordinate; } - - const QMap& paramInfoMap(void) const { return _paramInfoMap; } - -private: - QString _category; - MAV_CMD _command; - QString _description; - bool _friendlyEdit; - QString _friendlyName; - QMap _paramInfoMap; - QString _rawName; - bool _standaloneCoordinate; - bool _specifiesCoordinate; - - friend class MissionCommands; -}; - +#include "MissionCommandList.h" + +/// Provides access to mission command information used for creating mission command ui editors. There is a base common set +/// of definitions. Individual commands can then be overriden depending on Vehicle information: +/// Common command definitions +/// MAV_AUTOPILOT common overrides +/// Fixed Wing +/// MAV_AUTOPILOT specific Fixed Wing overrides +/// Multi-Rotor +/// MAV_AUTOPILOT specific Multi Rotor overrides +/// The leaf nodes of the hierarchy take precedence over higher level branches class MissionCommands : public QGCTool { Q_OBJECT @@ -134,45 +47,29 @@ public: Q_INVOKABLE QString categoryFromCommand (MavlinkQmlSingleton::Qml_MAV_CMD command) const; Q_INVOKABLE QVariant getCommandsForCategory (Vehicle* vehicle, const QString& category) const; - const QMap& commandInfoMap(void) const { return _mavCmdInfoMap; }; + Q_INVOKABLE bool contains(MavlinkQmlSingleton::Qml_MAV_CMD command) const { return contains((MAV_CMD)command); } + bool contains(MAV_CMD command) const; + + Q_INVOKABLE QVariant getMavCmdInfo(MavlinkQmlSingleton::Qml_MAV_CMD command, Vehicle* vehicle) const { return QVariant::fromValue(getMavCmdInfo((MAV_CMD)command, vehicle)); } + MavCmdInfo* getMavCmdInfo(MAV_CMD command, Vehicle* vehicle) const; + + QList commandsIds(void) const; // Overrides from QGCTool virtual void setToolbox(QGCToolbox* toolbox); -signals: - private: - void _loadMavCmdInfoJson(void); - void _createFirmwareSpecificLists(void); - void _setupMetaData(void); - bool _validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList& types); + void _createCategories(void); MAV_AUTOPILOT _firmwareTypeFromVehicle(Vehicle* vehicle) const; private: - QMap > _categoryToMavCmdInfoListMap; - QMap _mavCmdInfoMap; + QMap > > _categoryToMavCmdListMap; + + MissionCommandList _commonMissionCommands; ///< Mission command definitions for common generic mavlink use case - static const QString _categoryJsonKey; - static const QString _decimalPlacesJsonKey; - static const QString _defaultJsonKey; - static const QString _descriptionJsonKey; - static const QString _enumStringsJsonKey; - static const QString _enumValuesJsonKey; - static const QString _friendlyNameJsonKey; - static const QString _friendlyEditJsonKey; - static const QString _idJsonKey; - static const QString _labelJsonKey; - static const QString _mavCmdInfoJsonKey; - static const QString _param1JsonKey; - static const QString _param2JsonKey; - static const QString _param3JsonKey; - static const QString _param4JsonKey; - static const QString _paramJsonKeyFormat; - static const QString _rawNameJsonKey; - static const QString _standaloneCoordinateJsonKey; - static const QString _specifiesCoordinateJsonKey; - static const QString _unitsJsonKey; - static const QString _versionJsonKey; + QMap _autopilotToCommonMissionCommands; ///< MAV_AUTOPILOT specific common overrides + QMap _autopilotToFixedWingMissionCommands; ///< MAV_AUTOPILOT specific fixed wing overrides + QMap _autopilotToMultiRotorMissionCommands; ///< MAV_AUTOPILOT specific multi rotor overrides }; #endif diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index beb56a4b5..dac7fbb6e 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -161,7 +161,7 @@ void MissionController::sendMissionItems(void) int MissionController::insertMissionItem(QGeoCoordinate coordinate, int i) { - MissionItem * newItem = new MissionItem(this); + MissionItem * newItem = new MissionItem(_activeVehicle, this); newItem->setSequenceNumber(_missionItems->count()); newItem->setCoordinate(coordinate); newItem->setCommand(MAV_CMD_NAV_WAYPOINT); @@ -258,7 +258,7 @@ void MissionController::loadMissionFromFile(void) if (versionOk) { while (!in.atEnd()) { - MissionItem* item = new MissionItem(); + MissionItem* item = new MissionItem(_activeVehicle, this); if (item->load(in)) { _missionItems->append(item); @@ -494,7 +494,7 @@ void MissionController::_initAllMissionItems(void) homeItem = qobject_cast(_missionItems->get(0)); } else { // Add the home position item to the front - homeItem = new MissionItem(this); + homeItem = new MissionItem(_activeVehicle, this); homeItem->setSequenceNumber(0); _missionItems->insert(0, homeItem); } diff --git a/src/MissionManager/MissionItem.cc b/src/MissionManager/MissionItem.cc index edf84c27f..c89981fbe 100644 --- a/src/MissionManager/MissionItem.cc +++ b/src/MissionManager/MissionItem.cc @@ -74,8 +74,9 @@ QDebug operator<<(QDebug dbg, const MissionItem* missionItem) return dbg; } -MissionItem::MissionItem(QObject* parent) +MissionItem::MissionItem(Vehicle* vehicle, QObject* parent) : QObject(parent) + , _vehicle(vehicle) , _rawEdit(false) , _dirty(false) , _sequenceNumber(0) @@ -107,7 +108,7 @@ MissionItem::MissionItem(QObject* parent) , _param7MetaData(FactMetaData::valueTypeDouble) , _syncingAltitudeRelativeToHomeAndFrame (false) , _syncingHeadingDegreesAndParam4 (false) - , _mavCmdInfoMap(qgcApp()->toolbox()->missionCommands()->commandInfoMap()) + , _missionCommands(qgcApp()->toolbox()->missionCommands()) { // Need a good command and frame before we start passing signals around _commandFact.setRawValue(MAV_CMD_NAV_WAYPOINT); @@ -121,7 +122,8 @@ MissionItem::MissionItem(QObject* parent) setDefaultsForCommand(); } -MissionItem::MissionItem(int sequenceNumber, +MissionItem::MissionItem(Vehicle* vehicle, + int sequenceNumber, MAV_CMD command, MAV_FRAME frame, double param1, @@ -135,6 +137,7 @@ MissionItem::MissionItem(int sequenceNumber, bool isCurrentItem, QObject* parent) : QObject(parent) + , _vehicle(vehicle) , _rawEdit(false) , _dirty(false) , _sequenceNumber(sequenceNumber) @@ -165,7 +168,7 @@ MissionItem::MissionItem(int sequenceNumber, , _param7MetaData(FactMetaData::valueTypeDouble) , _syncingAltitudeRelativeToHomeAndFrame (false) , _syncingHeadingDegreesAndParam4 (false) - , _mavCmdInfoMap(qgcApp()->toolbox()->missionCommands()->commandInfoMap()) + , _missionCommands(qgcApp()->toolbox()->missionCommands()) { // Need a good command and frame before we start passing signals around _commandFact.setRawValue(MAV_CMD_NAV_WAYPOINT); @@ -192,6 +195,7 @@ MissionItem::MissionItem(int sequenceNumber, MissionItem::MissionItem(const MissionItem& other, QObject* parent) : QObject(parent) + , _vehicle(NULL) , _rawEdit(false) , _dirty(false) , _sequenceNumber(0) @@ -219,7 +223,7 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent) , _param4MetaData(FactMetaData::valueTypeDouble) , _syncingAltitudeRelativeToHomeAndFrame (false) , _syncingHeadingDegreesAndParam4 (false) - , _mavCmdInfoMap(qgcApp()->toolbox()->missionCommands()->commandInfoMap()) + , _missionCommands(qgcApp()->toolbox()->missionCommands()) { // Need a good command and frame before we start passing signals around _commandFact.setRawValue(MAV_CMD_NAV_WAYPOINT); @@ -234,6 +238,8 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent) const MissionItem& MissionItem::operator=(const MissionItem& other) { + _vehicle = other._vehicle; + setCommand(other.command()); setFrame(other.frame()); setRawEdit(other._rawEdit); @@ -314,7 +320,8 @@ void MissionItem::_setupMetaData(void) enumStrings.clear(); enumValues.clear(); - foreach (const MavCmdInfo* mavCmdInfo, _mavCmdInfoMap) { + foreach (const MAV_CMD command, _missionCommands->commandsIds()) { + const MavCmdInfo* mavCmdInfo = _missionCommands->getMavCmdInfo(command, _vehicle); enumStrings.append(mavCmdInfo->rawName()); enumValues.append(QVariant(mavCmdInfo->command())); } @@ -488,8 +495,8 @@ void MissionItem::setParam7(double param) bool MissionItem::standaloneCoordinate(void) const { - if (_mavCmdInfoMap.contains((MAV_CMD)command())) { - return _mavCmdInfoMap[(MAV_CMD)command()]->standaloneCoordinate(); + if (_missionCommands->contains((MAV_CMD)command())) { + return _missionCommands->getMavCmdInfo((MAV_CMD)command(), _vehicle)->standaloneCoordinate(); } else { return false; } @@ -497,8 +504,8 @@ bool MissionItem::standaloneCoordinate(void) const bool MissionItem::specifiesCoordinate(void) const { - if (_mavCmdInfoMap.contains((MAV_CMD)command())) { - return _mavCmdInfoMap[(MAV_CMD)command()]->specifiesCoordinate(); + if (_missionCommands->contains((MAV_CMD)command())) { + return _missionCommands->getMavCmdInfo((MAV_CMD)command(), _vehicle)->specifiesCoordinate(); } else { return false; } @@ -506,8 +513,8 @@ bool MissionItem::specifiesCoordinate(void) const QString MissionItem::commandDescription(void) const { - if (_mavCmdInfoMap.contains((MAV_CMD)command())) { - return _mavCmdInfoMap[(MAV_CMD)command()]->description(); + if (_missionCommands->contains((MAV_CMD)command())) { + return _missionCommands->getMavCmdInfo((MAV_CMD)command(), _vehicle)->description(); } else { qWarning() << "Should not ask for command description on unknown command"; return QString(); @@ -561,7 +568,7 @@ QmlObjectListModel* MissionItem::textFieldFacts(void) FactMetaData* rgParamMetaData[7] = { &_param1MetaData, &_param2MetaData, &_param3MetaData, &_param4MetaData, &_param5MetaData, &_param6MetaData, &_param7MetaData }; for (int i=1; i<=7; i++) { - const QMap& paramInfoMap = _mavCmdInfoMap[command]->paramInfoMap(); + const QMap& paramInfoMap = _missionCommands->getMavCmdInfo(command, _vehicle)->paramInfoMap(); if (paramInfoMap.contains(i) && paramInfoMap[i]->enumStrings().count() == 0) { Fact* paramFact = rgParamFacts[i-1]; @@ -615,7 +622,7 @@ QmlObjectListModel* MissionItem::comboboxFacts(void) MAV_CMD command = (MAV_CMD)this->command(); for (int i=1; i<=7; i++) { - const QMap& paramInfoMap = _mavCmdInfoMap[command]->paramInfoMap(); + const QMap& paramInfoMap = _missionCommands->getMavCmdInfo(command, _vehicle)->paramInfoMap(); if (paramInfoMap.contains(i) && paramInfoMap[i]->enumStrings().count() != 0) { Fact* paramFact = rgParamFacts[i-1]; @@ -649,7 +656,7 @@ void MissionItem::setCoordinate(const QGeoCoordinate& coordinate) bool MissionItem::friendlyEditAllowed(void) const { - if (_mavCmdInfoMap.contains((MAV_CMD)command()) && _mavCmdInfoMap[(MAV_CMD)command()]->friendlyEdit()) { + if (_missionCommands->contains((MAV_CMD)command()) && _missionCommands->getMavCmdInfo((MAV_CMD)command(), _vehicle)->friendlyEdit()) { if (!autoContinue()) { return false; } @@ -752,8 +759,9 @@ void MissionItem::setDefaultsForCommand(void) // We set these global defaults first, then if there are param defaults they will get reset setParam7(defaultAltitude); - if (_mavCmdInfoMap.contains((MAV_CMD)command())) { - foreach (const MavCmdParamInfo* paramInfo, _mavCmdInfoMap[(MAV_CMD)command()]->paramInfoMap()) { + MAV_CMD command = (MAV_CMD)this->command(); + if (_missionCommands->contains(command)) { + foreach (const MavCmdParamInfo* paramInfo, _missionCommands->getMavCmdInfo(command, _vehicle)->paramInfoMap()) { Fact* rgParamFacts[7] = { &_param1Fact, &_param2Fact, &_param3Fact, &_param4Fact, &_param5Fact, &_param6Fact, &_param7Fact }; rgParamFacts[paramInfo->param()-1]->setRawValue(paramInfo->defaultValue()); @@ -782,11 +790,12 @@ void MissionItem::_sendCommandChanged(void) QString MissionItem::commandName(void) const { - if (_mavCmdInfoMap.contains((MAV_CMD)command())) { - const MavCmdInfo* mavCmdInfo = _mavCmdInfoMap[(MAV_CMD)command()]; + MAV_CMD command = (MAV_CMD)this->command(); + if (_missionCommands->contains(command)) { + const MavCmdInfo* mavCmdInfo = _missionCommands->getMavCmdInfo(command, _vehicle); return mavCmdInfo->friendlyName().isEmpty() ? mavCmdInfo->rawName() : mavCmdInfo->friendlyName(); } else { - return QString("Unknown: %1").arg(command()); + return QString("Unknown: %1").arg(command); } } diff --git a/src/MissionManager/MissionItem.h b/src/MissionManager/MissionItem.h index e9c7fc2aa..645ac90fe 100644 --- a/src/MissionManager/MissionItem.h +++ b/src/MissionManager/MissionItem.h @@ -46,9 +46,10 @@ class MissionItem : public QObject Q_OBJECT public: - MissionItem(QObject* parent = NULL); + MissionItem(Vehicle* vehicle, QObject* parent = NULL); - MissionItem(int sequenceNumber, + MissionItem(Vehicle* vehicle, + int sequenceNumber, MAV_CMD command, MAV_FRAME frame, double param1, @@ -212,6 +213,7 @@ private: void _setupMetaData(void); private: + Vehicle* _vehicle; ///< Vehicle associated with this item, NULL for offline mode bool _rawEdit; bool _dirty; int _sequenceNumber; @@ -257,7 +259,7 @@ private: bool _syncingAltitudeRelativeToHomeAndFrame; ///< true: already in a sync signal, prevents signal loop bool _syncingHeadingDegreesAndParam4; ///< true: already in a sync signal, prevents signal loop - const QMap& _mavCmdInfoMap; + const MissionCommands* _missionCommands; }; QDebug operator<<(QDebug dbg, const MissionItem& missionItem); diff --git a/src/MissionManager/MissionItemTest.cc b/src/MissionManager/MissionItemTest.cc index 1652868d3..dd6c24dce 100644 --- a/src/MissionManager/MissionItemTest.cc +++ b/src/MissionManager/MissionItemTest.cc @@ -103,7 +103,8 @@ void MissionItemTest::_test(void) qDebug() << "Command:" << info->command; - MissionItem* item = new MissionItem(1, + MissionItem* item = new MissionItem(NULL, // Vehicle + 1, info->command, info->frame, 10.1234567, @@ -158,7 +159,7 @@ void MissionItemTest::_test(void) QCOMPARE(factCount, expected->cFactValues); // Validate that loading is working correctly - MissionItem* loadedItem = new MissionItem(); + MissionItem* loadedItem = new MissionItem(NULL /* Vehicle */); QTextStream loadStream(&savedItemString, QIODevice::ReadOnly); QVERIFY(loadedItem->load(loadStream)); QCOMPARE(loadedItem->coordinate().latitude(), item->coordinate().latitude()); @@ -180,7 +181,7 @@ void MissionItemTest::_test(void) void MissionItemTest::_testDefaultValues(void) { - MissionItem item; + MissionItem item(NULL /* Vehicle */); item.setCommand(MAV_CMD_NAV_WAYPOINT); item.setFrame(MAV_FRAME_GLOBAL_RELATIVE_ALT); diff --git a/src/MissionManager/MissionManager.cc b/src/MissionManager/MissionManager.cc index dc24d6baf..249e76822 100644 --- a/src/MissionManager/MissionManager.cc +++ b/src/MissionManager/MissionManager.cc @@ -251,7 +251,8 @@ void MissionManager::_handleMissionItem(const mavlink_message_t& message) _requestItemRetryCount = 0; _itemIndicesToRead.removeOne(missionItem.seq); - MissionItem* item = new MissionItem(missionItem.seq, + MissionItem* item = new MissionItem(_vehicle, + missionItem.seq, (MAV_CMD)missionItem.command, (MAV_FRAME)missionItem.frame, missionItem.param1, diff --git a/src/MissionManager/MissionManagerTest.cc b/src/MissionManager/MissionManagerTest.cc index a449a3b5f..8e2368843 100644 --- a/src/MissionManager/MissionManagerTest.cc +++ b/src/MissionManager/MissionManagerTest.cc @@ -50,7 +50,7 @@ void MissionManagerTest::_writeItems(MockLinkMissionItemHandler::FailureMode_t f QmlObjectListModel* list = new QmlObjectListModel(); // Editor has a home position item on the front, so we do the same - MissionItem* homeItem = new MissionItem(this); + MissionItem* homeItem = new MissionItem(NULL /* Vehicle */, this); homeItem->setHomePositionSpecialCase(true); homeItem->setHomePositionValid(false); homeItem->setCommand(MavlinkQmlSingleton::MAV_CMD_NAV_WAYPOINT); @@ -61,7 +61,7 @@ void MissionManagerTest::_writeItems(MockLinkMissionItemHandler::FailureMode_t f for (size_t i=0; i<_cTestCases; i++) { const TestCase_t* testCase = &_rgTestCases[i]; - MissionItem* item = new MissionItem(list); + MissionItem* item = new MissionItem(NULL /* Vehicle */, list); QTextStream loadStream(testCase->itemStream, QIODevice::ReadOnly); QVERIFY(item->load(loadStream)); diff --git a/src/QGCLoggingCategory.cc b/src/QGCLoggingCategory.cc index 509c2e44e..e5f941302 100644 --- a/src/QGCLoggingCategory.cc +++ b/src/QGCLoggingCategory.cc @@ -29,6 +29,8 @@ // Add Global logging categories (not class specific) here using QGC_LOGGING_CATEGORY QGC_LOGGING_CATEGORY(FirmwareUpgradeLog, "FirmwareUpgradeLog") QGC_LOGGING_CATEGORY(FirmwareUpgradeVerboseLog, "FirmwareUpgradeVerboseLog") +QGC_LOGGING_CATEGORY(MissionCommandsLog, "MissionCommandsLog") + QGCLoggingCategoryRegister* _instance = NULL; diff --git a/src/QGCLoggingCategory.h b/src/QGCLoggingCategory.h index 947be2610..6dc19b4cf 100644 --- a/src/QGCLoggingCategory.h +++ b/src/QGCLoggingCategory.h @@ -33,6 +33,7 @@ // Add Global logging categories (not class specific) here using Q_DECLARE_LOGGING_CATEGORY Q_DECLARE_LOGGING_CATEGORY(FirmwareUpgradeLog) Q_DECLARE_LOGGING_CATEGORY(FirmwareUpgradeVerboseLog) +Q_DECLARE_LOGGING_CATEGORY(MissionCommandsLog) /// @def QGC_LOGGING_CATEGORY /// This is a QGC specific replacement for Q_LOGGING_CATEGORY. It will register the category name into a -- 2.22.0