/*=================================================================== 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; }