Commit 89285b12 authored by DonLakeFlyer's avatar DonLakeFlyer

parent 4450945e
......@@ -683,6 +683,9 @@ HEADERS += \
src/SHPFileHelper.h \
src/Terrain/TerrainQuery.h \
src/TerrainTile.h \
src/Vehicle/CompInfo.h \
src/Vehicle/CompInfoParam.h \
src/Vehicle/CompInfoVersion.h \
src/Vehicle/ComponentInformationManager.h \
src/Vehicle/FTPManager.h \
src/Vehicle/GPSRTKFactGroup.h \
......@@ -899,6 +902,9 @@ SOURCES += \
src/SHPFileHelper.cc \
src/Terrain/TerrainQuery.cc \
src/TerrainTile.cc\
src/Vehicle/CompInfo.cc \
src/Vehicle/CompInfoParam.cc \
src/Vehicle/CompInfoVersion.cc \
src/Vehicle/ComponentInformationManager.cc \
src/Vehicle/FTPManager.cc \
src/Vehicle/GPSRTKFactGroup.cc \
......
......@@ -131,6 +131,9 @@ const char* FactMetaData::_maxJsonKey = "max";
const char* FactMetaData::_incrementJsonKey = "increment";
const char* FactMetaData::_hasControlJsonKey = "control";
const char* FactMetaData::_qgcRebootRequiredJsonKey = "qgcRebootRequired";
const char* FactMetaData::_categoryJsonKey = "category";
const char* FactMetaData::_groupJsonKey = "group";
const char* FactMetaData::_volatileJsonKey = "volatile";
FactMetaData::FactMetaData(QObject* parent)
: QObject (parent)
......@@ -1233,14 +1236,6 @@ FactMetaData* FactMetaData::createFromJsonObject(const QJsonObject& json, QMap<Q
{
QString errorString;
// Make sure we have the required keys
QStringList requiredKeys;
requiredKeys << _nameJsonKey << _typeJsonKey;
if (!JsonHelper::validateRequiredKeys(json, requiredKeys, errorString)) {
qWarning() << errorString;
return new FactMetaData(valueTypeUint32, metaDataParent);
}
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ _nameJsonKey, QJsonValue::String, true },
{ _typeJsonKey, QJsonValue::String, true },
......@@ -1252,6 +1247,9 @@ FactMetaData* FactMetaData::createFromJsonObject(const QJsonObject& json, QMap<Q
{ _maxJsonKey, QJsonValue::Double, false },
{ _hasControlJsonKey, QJsonValue::Bool, false },
{ _qgcRebootRequiredJsonKey, QJsonValue::Bool, false },
{ _categoryJsonKey, QJsonValue::String, false },
{ _groupJsonKey, QJsonValue::String, false },
{ _volatileJsonKey, QJsonValue::Bool, false },
};
if (!JsonHelper::validateKeys(json, keyInfoList, errorString)) {
qWarning() << errorString;
......@@ -1361,16 +1359,30 @@ FactMetaData* FactMetaData::createFromJsonObject(const QJsonObject& json, QMap<Q
}
}
bool hasControlJsonKey = true;
if (json.contains(_hasControlJsonKey)) {
metaData->setHasControl(json[_hasControlJsonKey].toBool());
} else {
metaData->setHasControl(true);
hasControlJsonKey = json[_hasControlJsonKey].toBool();
}
metaData->setHasControl(hasControlJsonKey);
bool qgcRebootRequired = false;
if (json.contains(_qgcRebootRequiredJsonKey)) {
metaData->setQGCRebootRequired(json[_qgcRebootRequiredJsonKey].toBool());
} else {
metaData->setQGCRebootRequired(false);
qgcRebootRequired = json[_qgcRebootRequiredJsonKey].toBool();
}
metaData->setQGCRebootRequired(qgcRebootRequired);
bool volatileValue = false;
if (json.contains(_volatileJsonKey)) {
volatileValue = json[_volatileJsonKey].toBool();
}
metaData->setVolatileValue(volatileValue);
if (json.contains(_groupJsonKey)) {
metaData->setGroup(json[_groupJsonKey].toString());
}
if (json.contains(_categoryJsonKey)) {
metaData->setCategory(json[_categoryJsonKey].toString());
}
return metaData;
......
......@@ -47,6 +47,8 @@ public:
// @return Error string for failed validation explanation to user. Empty string indicates no error.
typedef QString (*CustomCookedValidator)(const QVariant& cookedValue);
typedef QMap<QString /* param Name */, FactMetaData*> NameToMetaDataMap_t;
FactMetaData(QObject* parent = nullptr);
FactMetaData(ValueType_t type, QObject* parent = nullptr);
FactMetaData(ValueType_t type, const QString name, QObject* parent = nullptr);
......@@ -359,6 +361,9 @@ private:
static const char* _incrementJsonKey;
static const char* _hasControlJsonKey;
static const char* _qgcRebootRequiredJsonKey;
static const char* _categoryJsonKey;
static const char* _groupJsonKey;
static const char* _volatileJsonKey;
static const char* _jsonMetaDataDefinesName;
static const char* _jsonMetaDataFactsName;
......
......@@ -15,6 +15,8 @@
#include "FirmwarePlugin.h"
#include "UAS.h"
#include "JsonHelper.h"
#include "ComponentInformationManager.h"
#include "CompInfoParam.h"
#include <QEasingCurve>
#include <QFile>
......@@ -63,7 +65,6 @@ const QHash<int, QString> _mavlinkCompIdHash {
{ MAV_COMP_ID_GPS2, "GPS2" }
};
const char* ParameterManager::_cachedMetaDataFilePrefix = "ParameterFactMetaData";
const char* ParameterManager::_jsonParametersKey = "parameters";
const char* ParameterManager::_jsonCompIdKey = "compId";
const char* ParameterManager::_jsonParamNameKey = "name";
......@@ -82,7 +83,6 @@ ParameterManager::ParameterManager(Vehicle* vehicle)
, _metaDataAddedToFacts (false)
, _logReplay (vehicle->priorityLink() && vehicle->priorityLink()->isLogReplay())
, _parameterSetMajorVersion (-1)
, _parameterMetaData (nullptr)
, _prevWaitingReadParamIndexCount (0)
, _prevWaitingReadParamNameCount (0)
, _prevWaitingWriteParamNameCount (0)
......@@ -114,11 +114,6 @@ ParameterManager::ParameterManager(Vehicle* vehicle)
QFileInfo(QSettings().fileName()).dir().mkdir("ParamCache");
}
ParameterManager::~ParameterManager()
{
delete _parameterMetaData;
}
void ParameterManager::_updateProgressBar(void)
{
int waitingReadParamIndexCount = 0;
......@@ -937,20 +932,12 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian
if (cacheMap.contains(_versionParam)) {
_parameterSetMajorVersion = cacheMap[_versionParam].second.toInt();
}
_loadMetaData();
_vehicle->compInfoManager()->compInfoParam(MAV_COMP_ID_AUTOPILOT1)->_parameterMajorVersionKnown(_parameterSetMajorVersion);
/* compute the crc of the local cache to check against the remote */
FirmwarePlugin* firmwarePlugin = _vehicle->firmwarePlugin();
for (const QString& name: cacheMap.keys()) {
bool volatileValue = false;
FactMetaData* metaData = firmwarePlugin->getMetaDataForFact(_parameterMetaData, name, _vehicle->vehicleType());
if (metaData) {
volatileValue = metaData->volatileValue();
}
if (volatileValue) {
if (_vehicle->compInfoManager()->compInfoParam(MAV_COMP_ID_AUTOPILOT1)->_isParameterVolatile(name)) {
// Does not take part in CRC
qCDebug(ParameterManagerLog) << "Volatile parameter" << name;
} else {
......@@ -1015,7 +1002,6 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian
} else {
// Cache parameter version may differ from vehicle parameter version so we can't trust information loaded from cache parameter version number
_parameterSetMajorVersion = -1;
_clearMetaData();
qCInfo(ParameterManagerLog) << "Parameters cache match failed" << qPrintable(QFileInfo(cacheFile).absoluteFilePath());
if (ParameterManagerDebugCacheFailureLog().isDebugEnabled()) {
_debugCacheCRC[componentId] = true;
......@@ -1025,6 +1011,7 @@ void ParameterManager::_tryCacheHashLoad(int vehicleId, int componentId, QVarian
}
qgcApp()->showAppMessage(tr("Parameter cache CRC match failed"));
}
_vehicle->compInfoManager()->compInfoParam(MAV_COMP_ID_AUTOPILOT1)->_clearPX4ParameterMetaData();
}
}
......@@ -1193,42 +1180,23 @@ FactMetaData::ValueType_t ParameterManager::_mavTypeToFactType(MAV_PARAM_TYPE ma
}
}
void ParameterManager::_clearMetaData(void)
{
if (_parameterMetaData) {
_parameterMetaData->deleteLater();
_parameterMetaData = nullptr;
}
}
void ParameterManager::_loadMetaData(void)
{
if (_parameterMetaData) {
return;
}
QString metaDataFile;
int majorVersion, minorVersion;
// Load best parameter meta data set
metaDataFile = parameterMetaDataFile(_vehicle, _vehicle->firmwareType(), _parameterSetMajorVersion, majorVersion, minorVersion);
qCDebug(ParameterManagerLog) << "Loading meta data file:major:minor" << metaDataFile << majorVersion << minorVersion;
_parameterMetaData = _vehicle->firmwarePlugin()->loadParameterMetaData(metaDataFile);
}
void ParameterManager::_addMetaDataToDefaultComponent(void)
{
_loadMetaData();
if (_metaDataAddedToFacts) {
return;
}
_metaDataAddedToFacts = true;
// Loop over all parameters in default component adding meta data
QVariantMap& factMap = _mapParameterName2Variant[_vehicle->defaultComponentId()];
for (const QString& key: factMap.keys()) {
_vehicle->firmwarePlugin()->addMetaDataToFact(_parameterMetaData, factMap[key].value<Fact*>(), _vehicle->vehicleType());
_vehicle->compInfoManager()->compInfoParam(MAV_COMP_ID_AUTOPILOT1)->_parameterMajorVersionKnown(_parameterSetMajorVersion);
if (_mapParameterName2Variant.contains(MAV_COMP_ID_AUTOPILOT1)) {
// Loop over all parameters in autopilot component adding meta data
QVariantMap& factMap = _mapParameterName2Variant[MAV_COMP_ID_AUTOPILOT1];
for (const QString& key: factMap.keys()) {
Fact* fact = factMap[key].value<Fact*>();
FactMetaData* factMetaData = _vehicle->compInfoManager()->compInfoParam(MAV_COMP_ID_AUTOPILOT1)->factMetaDataForName(key, fact->type());
fact->setMetaData(factMetaData);
}
}
}
......@@ -1319,152 +1287,6 @@ void ParameterManager::_initialRequestTimeout(void)
}
}
QString ParameterManager::parameterMetaDataFile(Vehicle* vehicle, MAV_AUTOPILOT firmwareType, int wantedMajorVersion, int& majorVersion, int& minorVersion)
{
bool cacheHit = false;
FirmwarePlugin* plugin = _anyVehicleTypeFirmwarePlugin(firmwareType);
// Cached files are stored in settings location
QSettings settings;
QDir cacheDir = QFileInfo(settings.fileName()).dir();
// First look for a direct cache hit
int cacheMinorVersion, cacheMajorVersion;
QFile cacheFile(cacheDir.filePath(QString("%1.%2.%3.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType).arg(wantedMajorVersion)));
if (cacheFile.exists()) {
plugin->getParameterMetaDataVersionInfo(cacheFile.fileName(), cacheMajorVersion, cacheMinorVersion);
if (wantedMajorVersion != cacheMajorVersion) {
qWarning() << "Parameter meta data cache corruption:" << cacheFile.fileName() << "major version does not match file name" << "actual:excepted" << cacheMajorVersion << wantedMajorVersion;
} else {
qCDebug(ParameterManagerLog) << "Direct cache hit on file:major:minor" << cacheFile.fileName() << cacheMajorVersion << cacheMinorVersion;
cacheHit = true;
}
}
if (!cacheHit) {
// No direct hit, look for lower param set version
QString wildcard = QString("%1.%2.*.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType);
QStringList cacheHits = cacheDir.entryList(QStringList(wildcard), QDir::Files, QDir::Name);
// Find the highest major version number which is below the vehicles major version number
int cacheHitIndex = -1;
cacheMajorVersion = -1;
QRegExp regExp(QString("%1\\.%2\\.(\\d*)\\.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType));
for (int i=0; i< cacheHits.count(); i++) {
if (regExp.exactMatch(cacheHits[i]) && regExp.captureCount() == 1) {
int majorVersion = regExp.capturedTexts()[0].toInt();
if (majorVersion > cacheMajorVersion && majorVersion < wantedMajorVersion) {
cacheMajorVersion = majorVersion;
cacheHitIndex = i;
}
}
}
if (cacheHitIndex != -1) {
// We have a cache hit on a lower major version, read minor version as well
int majorVersion;
cacheFile.setFileName(cacheDir.filePath(cacheHits[cacheHitIndex]));
plugin->getParameterMetaDataVersionInfo(cacheFile.fileName(), majorVersion, cacheMinorVersion);
if (majorVersion != cacheMajorVersion) {
qWarning() << "Parameter meta data cache corruption:" << cacheFile.fileName() << "major version does not match file name" << "actual:excepted" << majorVersion << cacheMajorVersion;
cacheHit = false;
} else {
qCDebug(ParameterManagerLog) << "Indirect cache hit on file:major:minor:want" << cacheFile.fileName() << cacheMajorVersion << cacheMinorVersion << wantedMajorVersion;
cacheHit = true;
}
}
}
int internalMinorVersion, internalMajorVersion;
QString internalMetaDataFile = plugin->internalParameterMetaDataFile(vehicle);
plugin->getParameterMetaDataVersionInfo(internalMetaDataFile, internalMajorVersion, internalMinorVersion);
qCDebug(ParameterManagerLog) << "Internal meta data file:major:minor" << internalMetaDataFile << internalMajorVersion << internalMinorVersion;
if (cacheHit) {
// Cache hit is available, we need to check if internal meta data is a better match, if so use internal version
if (internalMajorVersion == wantedMajorVersion) {
if (cacheMajorVersion == wantedMajorVersion) {
// Both internal and cache are direct hit on major version, Use higher minor version number
cacheHit = cacheMinorVersion > internalMinorVersion;
} else {
// Direct internal hit, but not direct hit in cache, use internal
cacheHit = false;
}
} else {
if (cacheMajorVersion == wantedMajorVersion) {
// Direct hit on cache, no direct hit on internal, use cache
cacheHit = true;
} else {
// No direct hit anywhere, use internal
cacheHit = false;
}
}
}
QString metaDataFile;
if (cacheHit && !qgcApp()->runningUnitTests()) {
majorVersion = cacheMajorVersion;
minorVersion = cacheMinorVersion;
metaDataFile = cacheFile.fileName();
} else {
majorVersion = internalMajorVersion;
minorVersion = internalMinorVersion;
metaDataFile = internalMetaDataFile;
}
qCDebug(ParameterManagerLog) << "ParameterManager::parameterMetaDataFile file:major:minor" << metaDataFile << majorVersion << minorVersion;
return metaDataFile;
}
FirmwarePlugin* ParameterManager::_anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT firmwareType)
{
// There are cases where we need a FirmwarePlugin but we don't have a vehicle. In those specified case the plugin for any of the supported vehicle types will do.
MAV_TYPE anySupportedVehicleType = qgcApp()->toolbox()->firmwarePluginManager()->supportedVehicleTypes(firmwareType)[0];
return qgcApp()->toolbox()->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, anySupportedVehicleType);
}
void ParameterManager::cacheMetaDataFile(const QString& metaDataFile, MAV_AUTOPILOT firmwareType)
{
FirmwarePlugin* plugin = _anyVehicleTypeFirmwarePlugin(firmwareType);
int newMajorVersion, newMinorVersion;
plugin->getParameterMetaDataVersionInfo(metaDataFile, newMajorVersion, newMinorVersion);
qCDebug(ParameterManagerLog) << "ParameterManager::cacheMetaDataFile file:firmware:major;minor" << metaDataFile << firmwareType << newMajorVersion << newMinorVersion;
// Find the cache hit closest to this new file
int cacheMajorVersion, cacheMinorVersion;
QString cacheHit = ParameterManager::parameterMetaDataFile(nullptr, firmwareType, newMajorVersion, cacheMajorVersion, cacheMinorVersion);
qCDebug(ParameterManagerLog) << "ParameterManager::cacheMetaDataFile cacheHit file:firmware:major;minor" << cacheHit << cacheMajorVersion << cacheMinorVersion;
bool cacheNewFile = false;
if (cacheHit.isEmpty()) {
// No cache hits, store the new file
cacheNewFile = true;
} else if (cacheMajorVersion == newMajorVersion) {
// Direct hit on major version in cache:
// Cache new file if newer/equal minor version. We cache if equal to allow flashing test builds with new parameter metadata.
// Also delete older cache file.
if (newMinorVersion >= cacheMinorVersion) {
cacheNewFile = true;
QFile::remove(cacheHit);
}
} else {
// Indirect hit in cache, store new file
cacheNewFile = true;
}
if (cacheNewFile) {
// Cached files are stored in settings location. Copy from current file to cache naming.
QSettings settings;
QDir cacheDir = QFileInfo(settings.fileName()).dir();
QFile cacheFile(cacheDir.filePath(QString("%1.%2.%3.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType).arg(newMajorVersion)));
qCDebug(ParameterManagerLog) << "ParameterManager::cacheMetaDataFile caching file:" << cacheFile.fileName();
QFile newFile(metaDataFile);
newFile.copy(cacheFile.fileName());
}
}
/// Remap a parameter from one firmware version to another
QString ParameterManager::_remapParamNameToVersion(const QString& paramName)
{
......@@ -1583,118 +1405,12 @@ void ParameterManager::_loadOfflineEditingParams(void)
_mapParameterName2Variant[defaultComponentId][paramName] = QVariant::fromValue(fact);
}
_addMetaDataToDefaultComponent();
_setupDefaultComponentCategoryMap();
_parametersReady = true;
_initialLoadComplete = true;
_debugCacheCRC.clear();
}
void ParameterManager::saveToJson(int componentId, const QStringList& paramsToSave, QJsonObject& saveObject)
{
QList<int> rgCompIds;
QStringList rgParamNames;
if (componentId == MAV_COMP_ID_ALL) {
rgCompIds = _mapParameterName2Variant.keys();
} else {
rgCompIds.append(_actualComponentId(componentId));
}
QJsonArray rgParams;
// Loop over all requested component ids
for (int i=0; i<rgCompIds.count(); i++) {
int compId = rgCompIds[i];
if (!_mapParameterName2Variant.contains(compId)) {
qCDebug(ParameterManagerLog) << "ParameterManager::saveToJson no params for compId" << compId;
continue;
}
// Build list of parameter names if not specified
if (paramsToSave.count() == 0) {
rgParamNames = parameterNames(compId);
} else {
rgParamNames = paramsToSave;
}
// Loop over parameter names adding each to json array
for (int j=0; j<rgParamNames.count(); j++) {
QString paramName = rgParamNames[j];
if (!parameterExists(compId, paramName)) {
qCDebug(ParameterManagerLog) << "ParameterManager::saveToJson param not found compId:param" << compId << paramName;
continue;
}
QJsonObject paramJson;
Fact* fact = getParameter(compId, paramName);
paramJson.insert(_jsonCompIdKey, QJsonValue(compId));
paramJson.insert(_jsonParamNameKey, QJsonValue(fact->name()));
paramJson.insert(_jsonParamValueKey, QJsonValue(fact->rawValue().toDouble()));
rgParams.append(QJsonValue(paramJson));
}
}
saveObject.insert(_jsonParametersKey, QJsonValue(rgParams));
}
bool ParameterManager::loadFromJson(const QJsonObject& json, bool required, QString& errorString)
{
QList<QJsonValue::Type> keyTypes;
errorString.clear();
if (required) {
if (!JsonHelper::validateRequiredKeys(json, QStringList(_jsonParametersKey), errorString)) {
return false;
}
} else if (!json.contains(_jsonParametersKey)) {
return true;
}
keyTypes = { QJsonValue::Array };
if (!JsonHelper::validateKeyTypes(json, QStringList(_jsonParametersKey), keyTypes, errorString)) {
return false;
}
QJsonArray rgParams = json[_jsonParametersKey].toArray();
for (int i=0; i<rgParams.count(); i++) {
QJsonValueRef paramValue = rgParams[i];
if (!paramValue.isObject()) {
errorString = tr("%1 key is not a json object").arg(_jsonParametersKey);
return false;
}
QJsonObject param = paramValue.toObject();
QStringList requiredKeys = { _jsonCompIdKey, _jsonParamNameKey, _jsonParamValueKey };
if (!JsonHelper::validateRequiredKeys(param, requiredKeys, errorString)) {
return false;
}
keyTypes = { QJsonValue::Double, QJsonValue::String, QJsonValue::Double };
if (!JsonHelper::validateKeyTypes(param, requiredKeys, keyTypes, errorString)) {
return false;
}
int compId = param[_jsonCompIdKey].toInt();
QString name = param[_jsonParamNameKey].toString();
double value = param[_jsonParamValueKey].toDouble();
if (!parameterExists(compId, name)) {
qCDebug(ParameterManagerLog) << "ParameterManager::loadFromJson param not found compId:param" << compId << name;
continue;
}
Fact* fact = getParameter(compId, name);
fact->setRawValue(value);
}
return true;
}
void ParameterManager::resetAllParametersToDefaults()
{
_vehicle->sendMavCommand(MAV_COMP_ID_ALL,
......
......@@ -33,8 +33,7 @@ class ParameterManager : public QObject
public:
/// @param uas Uas which this set of facts is associated with
ParameterManager (Vehicle* vehicle);
~ParameterManager ();
ParameterManager(Vehicle* vehicle);
Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged) ///< true: Parameters are ready for use
Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged) ///< true: Parameters are missing from firmware response, false: all parameters received from firmware
......@@ -91,29 +90,6 @@ public:
/// Returns the version number for the parameter set, -1 if not known
int parameterSetVersion(void) { return _parameterSetMajorVersion; }
/// Returns the newest available parameter meta data file (from cache or internal) for the specified information.
/// @param wantedMajorVersion Major version you are looking for
/// @param[out] majorVersion Major version for found meta data
/// @param[out] minorVersion Minor version for found meta data
/// @return Meta data file name of best match, emptyString is none found
static QString parameterMetaDataFile(Vehicle* vehicle, MAV_AUTOPILOT firmwareType, int wantedMajorVersion, int& majorVersion, int& minorVersion);
/// If this file is newer than anything in the cache, cache it as the latest version
static void cacheMetaDataFile(const QString& metaDataFile, MAV_AUTOPILOT firmwareType);
/// Saves the specified param set to the json object.
/// @param componentId Component id which contains params, MAV_COMP_ID_ALL to save all components
/// @param paramsToSave List of params names to save, empty to save all for component
/// @param saveObject Json object to save to
void saveToJson(int componentId, const QStringList& paramsToSave, QJsonObject& saveObject);
/// Load a parameter set from json
/// @param json Json object to load from
/// @param required true: no parameters in object will generate error
/// @param errorString Error string if return is false
/// @return true: success, false: failure (errorString set)
bool loadFromJson(const QJsonObject& json, bool required, QString& errorString);
bool pendingWrites(void);
Vehicle* vehicle(void) { return _vehicle; }
......@@ -128,32 +104,31 @@ protected:
Vehicle* _vehicle;
MAVLinkProtocol* _mavlink;
void _parameterUpdate(int vehicleId, int componentId, QString parameterName, int parameterCount, int parameterId, int mavType, QVariant value);
void _valueUpdated(const QVariant& value);
void _waitingParamTimeout(void);
void _tryCacheLookup(void);
void _initialRequestTimeout(void);
void _parameterUpdate (int vehicleId, int componentId, QString parameterName, int parameterCount, int parameterId, int mavType, QVariant value);
void _valueUpdated (const QVariant& value);
void _waitingParamTimeout (void);
void _tryCacheLookup (void);
void _initialRequestTimeout (void);
private:
static QVariant _stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool failOk = false);
static FirmwarePlugin* _anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT firmwareType);
int _actualComponentId(int componentId);
void _setupComponentCategoryMap(int componentId);
void _setupDefaultComponentCategoryMap(void);
void _readParameterRaw(int componentId, const QString& paramName, int paramIndex);
void _writeParameterRaw(int componentId, const QString& paramName, const QVariant& value);
void _writeLocalParamCache(int vehicleId, int componentId);
void _tryCacheHashLoad(int vehicleId, int componentId, QVariant hash_value);
void _loadMetaData(void);
void _clearMetaData(void);
void _addMetaDataToDefaultComponent(void);
QString _remapParamNameToVersion(const QString& paramName);
void _loadOfflineEditingParams(void);
QString _logVehiclePrefix(int componentId);
void _setLoadProgress(double loadProgress);
bool _fillIndexBatchQueue(bool waitingParamTimeout);
void _updateProgressBar(void);
int _actualComponentId (int componentId);
void _setupComponentCategoryMap (int componentId);
void _setupDefaultComponentCategoryMap (void);
void _readParameterRaw (int componentId, const QString& paramName, int paramIndex);
void _writeParameterRaw (int componentId, const QString& paramName, const QVariant& value);
void _writeLocalParamCache (int vehicleId, int componentId);
void _tryCacheHashLoad (int vehicleId, int componentId, QVariant hash_value);
void _loadMetaData (void);
void _clearMetaData (void);
void _addMetaDataToDefaultComponent (void);
QString _remapParamNameToVersion (const QString& paramName);
void _loadOfflineEditingParams (void);
QString _logVehiclePrefix (int componentId);
void _setLoadProgress (double loadProgress);
bool _fillIndexBatchQueue (bool waitingParamTimeout);
void _updateProgressBar (void);
MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType);
FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType);
......@@ -178,7 +153,6 @@ private:
bool _logReplay; ///< true: running with log replay link
QString _versionParam; ///< Parameter which contains parameter set version
int _parameterSetMajorVersion; ///< Version for parameter set, -1 if not known
QObject* _parameterMetaData; ///< Opaque data from FirmwarePlugin::loadParameterMetaDataCall
typedef QPair<int /* FactMetaData::ValueType_t */, QVariant /* Fact::rawValue */> ParamTypeVal;
typedef QMap<QString /* parameter name */, ParamTypeVal> CacheMapName2ParamTypeVal;
......@@ -222,7 +196,6 @@ private:
Fact _defaultFact; ///< Used to return default fact, when parameter not found
static const char* _cachedMetaDataFilePrefix;
static const char* _jsonParametersKey;
static const char* _jsonCompIdKey;
static const char* _jsonParamNameKey;
......
......@@ -702,15 +702,17 @@ bool APMFirmwarePlugin::sendHomePositionToVehicle(void)
return true;
}
void APMFirmwarePlugin::addMetaDataToFact(QObject* parameterMetaData, Fact* fact, MAV_TYPE vehicleType)
FactMetaData* APMFirmwarePlugin::_getMetaDataForFact(QObject* parameterMetaData, const QString& name, FactMetaData::ValueType_t type, MAV_TYPE vehicleType)
{
APMParameterMetaData* apmMetaData = qobject_cast<APMParameterMetaData*>(parameterMetaData);
if (apmMetaData) {
apmMetaData->addMetaDataToFact(fact, vehicleType);
return apmMetaData->getMetaDataForFact(name, vehicleType, type);
} else {
qWarning() << "Internal error: pointer passed to APMFirmwarePlugin::addMetaDataToFact not APMParameterMetaData";
}
return nullptr;
}
QList<MAV_CMD> APMFirmwarePlugin::supportedMissionCommands(void)
......@@ -771,7 +773,7 @@ QString APMFirmwarePlugin::missionCommandOverrides(MAV_TYPE vehicleType) const
}
}
QObject* APMFirmwarePlugin::loadParameterMetaData(const QString& metaDataFile)
QObject* APMFirmwarePlugin::_loadParameterMetaData(const QString& metaDataFile)
{
Q_UNUSED(metaDataFile);
......@@ -806,7 +808,7 @@ void APMFirmwarePlugin::_artooSocketError(QAbstractSocket::SocketError socketErr
qgcApp()->showAppMessage(tr("Error during Solo video link setup: %1").arg(socketError));
}
QString APMFirmwarePlugin::internalParameterMetaDataFile(Vehicle* vehicle)
QString APMFirmwarePlugin::_internalParameterMetaDataFile(Vehicle* vehicle)
{
switch (vehicle->vehicleType()) {
case MAV_TYPE_QUADROTOR:
......
......@@ -97,12 +97,12 @@ public:
virtual void initializeStreamRates (Vehicle* vehicle);
void initializeVehicle (Vehicle* vehicle) override;
bool sendHomePositionToVehicle (void) override;
void addMetaDataToFact (QObject* parameterMetaData, Fact* fact, MAV_TYPE vehicleType) override;
QString missionCommandOverrides (MAV_TYPE vehicleType) const override;
QString getVersionParam (void) override { return QStringLiteral("SYSID_SW_MREV"); }
QString internalParameterMetaDataFile (Vehicle* vehicle) override;
void getParameterMetaDataVersionInfo (const QString& metaDataFile, int& majorVersion, int& minorVersion) override { APMParameterMetaData::getParameterMetaDataVersionInfo(metaDataFile, majorVersion, minorVersion); }
QObject* loadParameterMetaData (const QString& metaDataFile) override;
QString _internalParameterMetaDataFile (Vehicle* vehicle) override;
FactMetaData* _getMetaDataForFact (QObject* parameterMetaData, const QString& name, FactMetaData::ValueType_t type, MAV_TYPE vehicleType) override;
void _getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion) override { APMParameterMetaData::getParameterMetaDataVersionInfo(metaDataFile, majorVersion, minorVersion); }
QObject* _loadParameterMetaData (const QString& metaDataFile) override;
QString brandImageIndoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/APM/BrandImage"); }
QString brandImageOutdoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/APM/BrandImage"); }
......
......@@ -425,27 +425,26 @@ bool APMParameterMetaData::parseParameterAttributes(QXmlStreamReader& xml, APMFa
return true;
}
void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
FactMetaData* APMParameterMetaData::getMetaDataForFact(const QString& name, MAV_TYPE vehicleType, FactMetaData::ValueType_t type)
{
const QString mavTypeString = mavTypeToString(vehicleType);
APMFactMetaDataRaw* rawMetaData = nullptr;
// check if we have metadata for fact, use generic otherwise
if (_vehicleTypeToParametersMap[mavTypeString].contains(fact->name())) {
rawMetaData = _vehicleTypeToParametersMap[mavTypeString][fact->name()];
} else if (_vehicleTypeToParametersMap["libraries"].contains(fact->name())) {
rawMetaData = _vehicleTypeToParametersMap["libraries"][fact->name()];
if (_vehicleTypeToParametersMap[mavTypeString].contains(name)) {
rawMetaData = _vehicleTypeToParametersMap[mavTypeString][name];
} else if (_vehicleTypeToParametersMap["libraries"].contains(name)) {
rawMetaData = _vehicleTypeToParametersMap["libraries"][name];
}
FactMetaData *metaData = new FactMetaData(fact->type(), fact);
FactMetaData *metaData = new FactMetaData(type, this);
// we don't have data for this fact
if (!rawMetaData) {
metaData->setCategory(QStringLiteral("Advanced"));
metaData->setGroup(_groupFromParameterName(fact->name()));
fact->setMetaData(metaData);
qCDebug(APMParameterMetaDataLog) << "No metaData for " << fact->name() << "using generic metadata";
return;
metaData->setGroup(_groupFromParameterName(name));
qCDebug(APMParameterMetaDataLog) << "No metaData for " << name << "using generic metadata";
return metaData;
}
metaData->setName(rawMetaData->name);
......@@ -531,7 +530,7 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
QVariant typedBitSet;
switch (fact->type()) {
switch (type) {
case FactMetaData::valueTypeInt8:
typedBitSet = QVariant((signed char)bitSet);
break;
......@@ -599,15 +598,15 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
}
// ArduPilot does not yet support decimal places meta data. So for P/I/D parameters we force to 6 places
if ((fact->name().endsWith(QStringLiteral("_P")) ||
fact->name().endsWith(QStringLiteral("_I")) ||
fact->name().endsWith(QStringLiteral("_D"))) &&
(fact->type() == FactMetaData::valueTypeFloat ||
fact->type() == FactMetaData::valueTypeDouble)) {
if ((name.endsWith(QStringLiteral("_P")) ||
name.endsWith(QStringLiteral("_I")) ||
name.endsWith(QStringLiteral("_D"))) &&
(type == FactMetaData::valueTypeFloat ||
type == FactMetaData::valueTypeDouble)) {
metaData->setDecimalPlaces(6);
}
fact->setMetaData(metaData);
return metaData;
}
void APMParameterMetaData::getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion)
......
......@@ -58,7 +58,7 @@ class APMParameterMetaData : public QObject
public:
APMParameterMetaData(void);
void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType);
FactMetaData* getMetaDataForFact(const QString& name, MAV_TYPE vehicleType, FactMetaData::ValueType_t type);
void loadParameterFactMetaDataFile(const QString& metaDataFile);
static void getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion);
......@@ -83,8 +83,9 @@ private:
QString mavTypeToString(MAV_TYPE vehicleTypeEnum);
QString _groupFromParameterName(const QString& name);
bool _parameterMetaDataLoaded; ///< true: parameter meta data already loaded
QMap<QString, ParameterNametoFactMetaDataMap> _vehicleTypeToParametersMap; ///< Maps from a vehicle type to paramametertoFactMeta map>
bool _parameterMetaDataLoaded = false; ///< true: parameter meta data already loaded
// FIXME: metadata is vehicle type specific now
QMap<QString, ParameterNametoFactMetaDataMap> _vehicleTypeToParametersMap; ///< Maps from a vehicle type to paramametertoFactMeta map>
};
#endif
......@@ -203,7 +203,7 @@ QString FirmwarePlugin::missionCommandOverrides(MAV_TYPE vehicleType) const
}
}
void FirmwarePlugin::getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion)
void FirmwarePlugin::_getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion)
{
Q_UNUSED(metaDataFile);
majorVersion = -1;
......
......@@ -214,24 +214,28 @@ public:
/// Returns the parameter set version info pulled from inside the meta data file. -1 if not found.
/// Note: The implementation for this must not vary by vehicle type.
virtual void getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion);
/// Important: Only CompInfoParam code should use this method
virtual void _getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion);
/// Returns the internal resource parameter meta date file.
virtual QString internalParameterMetaDataFile(Vehicle* /*vehicle*/) { return QString(); }
/// Important: Only CompInfoParam code should use this method
virtual QString _internalParameterMetaDataFile(Vehicle* /*vehicle*/) { return QString(); }
/// Loads the specified parameter meta data file.
/// @return Opaque parameter meta data information which must be stored with Vehicle. Vehicle is responsible to
/// call deleteParameterMetaData when no longer needed.
virtual QObject* loadParameterMetaData(const QString& /*metaDataFile*/) { return nullptr; }
/// Important: Only CompInfoParam code should use this method
virtual QObject* _loadParameterMetaData(const QString& /*metaDataFile*/) { return nullptr; }
/// Returns the FactMetaData associated with the parameter name
/// @param opaqueParameterMetaData Opaque pointer returned from loadParameterMetaData
/// @param name Parameter name
virtual FactMetaData* getMetaDataForFact(QObject* /*parameterMetaData*/, const QString& /*name*/, MAV_TYPE /*vehicleType*/) { return nullptr; }
/// 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; }
/// Adds the parameter meta data to the Fact
/// Returns the FactMetaData associated with the parameter name
/// @param opaqueParameterMetaData Opaque pointer returned from loadParameterMetaData
virtual void addMetaDataToFact(QObject* /*parameterMetaData*/, Fact* /*fact*/, MAV_TYPE /*vehicleType*/) { return; }
/// Important: Only CompInfoParam code should use this method
virtual bool _isParameterVolatile(QObject* /*parameterMetaData*/, const QString& /*name*/, MAV_TYPE /*vehicleType*/) { return false; }
/// List of supported mission commands. Empty list for all commands supported.
virtual QList<MAV_CMD> supportedMissionCommands(void);
......
......@@ -250,12 +250,12 @@ bool PX4FirmwarePlugin::sendHomePositionToVehicle(void)
return false;
}
FactMetaData* PX4FirmwarePlugin::getMetaDataForFact(QObject* parameterMetaData, const QString& name, MAV_TYPE vehicleType)
FactMetaData* PX4FirmwarePlugin::_getMetaDataForFact(QObject* parameterMetaData, const QString& name, FactMetaData::ValueType_t type, MAV_TYPE vehicleType)
{
PX4ParameterMetaData* px4MetaData = qobject_cast<PX4ParameterMetaData*>(parameterMetaData);
if (px4MetaData) {
return px4MetaData->getMetaDataForFact(name, vehicleType);
return px4MetaData->getMetaDataForFact(name, vehicleType, type);
} else {
qWarning() << "Internal error: pointer passed to PX4FirmwarePlugin::getMetaDataForFact not PX4ParameterMetaData";
}
......@@ -263,18 +263,7 @@ FactMetaData* PX4FirmwarePlugin::getMetaDataForFact(QObject* parameterMetaData,
return nullptr;
}
void PX4FirmwarePlugin::addMetaDataToFact(QObject* parameterMetaData, Fact* fact, MAV_TYPE vehicleType)
{
PX4ParameterMetaData* px4MetaData = qobject_cast<PX4ParameterMetaData*>(parameterMetaData);
if (px4MetaData) {
px4MetaData->addMetaDataToFact(fact, vehicleType);
} else {
qWarning() << "Internal error: pointer passed to PX4FirmwarePlugin::addMetaDataToFact not PX4ParameterMetaData";
}
}
void PX4FirmwarePlugin::getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion)
void PX4FirmwarePlugin::_getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion)
{
return PX4ParameterMetaData::getParameterMetaDataVersionInfo(metaDataFile, majorVersion, minorVersion);
}
......@@ -329,7 +318,7 @@ QString PX4FirmwarePlugin::missionCommandOverrides(MAV_TYPE vehicleType) const
}
}
QObject* PX4FirmwarePlugin::loadParameterMetaData(const QString& metaDataFile)
QObject* PX4FirmwarePlugin::_loadParameterMetaData(const QString& metaDataFile)
{
PX4ParameterMetaData* metaData = new PX4ParameterMetaData;
if (!metaDataFile.isEmpty()) {
......
......@@ -55,15 +55,14 @@ public:
bool isGuidedMode (const Vehicle* vehicle) const override;
void initializeVehicle (Vehicle* vehicle) override;
bool sendHomePositionToVehicle (void) override;
void addMetaDataToFact (QObject* parameterMetaData, Fact* fact, MAV_TYPE vehicleType) override;
FactMetaData* getMetaDataForFact (QObject* parameterMetaData, const QString& name, MAV_TYPE vehicleType) override;
QString missionCommandOverrides (MAV_TYPE vehicleType) const override;
QString getVersionParam (void) override { return QString("SYS_PARAM_VER"); }
QString internalParameterMetaDataFile (Vehicle* vehicle) override { Q_UNUSED(vehicle); return QString(":/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml"); }
void getParameterMetaDataVersionInfo (const QString& metaDataFile, int& majorVersion, int& minorVersion) override;
QObject* loadParameterMetaData (const QString& metaDataFile) final;
FactMetaData* _getMetaDataForFact (QObject* parameterMetaData, const QString& name, FactMetaData::ValueType_t type, MAV_TYPE vehicleType) override;
QString _internalParameterMetaDataFile (Vehicle* vehicle) override { Q_UNUSED(vehicle); return QString(":/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml"); }
void _getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion) override;
QObject* _loadParameterMetaData (const QString& metaDataFile) final;
bool adjustIncomingMavlinkMessage (Vehicle* vehicle, mavlink_message_t* message) override;
QString offlineEditingParamFile(Vehicle* vehicle) override { Q_UNUSED(vehicle); return QStringLiteral(":/FirmwarePlugin/PX4/PX4.OfflineEditing.params"); }
QString offlineEditingParamFile (Vehicle* vehicle) override { Q_UNUSED(vehicle); return QStringLiteral(":/FirmwarePlugin/PX4/PX4.OfflineEditing.params"); }
QString brandImageIndoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/PX4/BrandImage"); }
QString brandImageOutdoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/PX4/BrandImage"); }
QString autoDisarmParameter (Vehicle* vehicle) override { Q_UNUSED(vehicle); return QStringLiteral("COM_DISARM_LAND"); }
......
......@@ -25,7 +25,6 @@ static const char* kInvalidConverstion = "Internal Error: No support for string
QGC_LOGGING_CATEGORY(PX4ParameterMetaDataLog, "PX4ParameterMetaDataLog")
PX4ParameterMetaData::PX4ParameterMetaData(void)
: _parameterMetaDataLoaded(false)
{
}
......@@ -480,7 +479,7 @@ void PX4ParameterMetaData::_generateParameterJson()
if (metaData->volatileValue()) {
_jsonWriteLine(jsonFile, indentLevel, "\"volatile\": true,");
}
_jsonWriteLine(jsonFile, indentLevel, QStringLiteral("\"decimalPlaces\": \"%1\",").arg(metaData->decimalPlaces()));
_jsonWriteLine(jsonFile, indentLevel, QStringLiteral("\"decimalPlaces\": %1,").arg(metaData->decimalPlaces()));
_jsonWriteLine(jsonFile, indentLevel, QStringLiteral("\"minValue\": %1,").arg(metaData->rawMin().toDouble()));
_jsonWriteLine(jsonFile, indentLevel, QStringLiteral("\"maxValue\": %1").arg(metaData->rawMax().toDouble()));
_jsonWriteLine(jsonFile, --indentLevel, QStringLiteral("}%1").arg(++keyIndex == _mapParameterName2FactMetaData.keys().count() ? "" : ","));
......@@ -491,24 +490,17 @@ void PX4ParameterMetaData::_generateParameterJson()
}
#endif
FactMetaData* PX4ParameterMetaData::getMetaDataForFact(const QString& name, MAV_TYPE vehicleType)
FactMetaData* PX4ParameterMetaData::getMetaDataForFact(const QString& name, MAV_TYPE vehicleType, FactMetaData::ValueType_t type)
{
Q_UNUSED(vehicleType)
if (_mapParameterName2FactMetaData.contains(name)) {
return _mapParameterName2FactMetaData[name];
} else {
return nullptr;
if (!_mapParameterName2FactMetaData.contains(name)) {
qCDebug(PX4ParameterMetaDataLog) << "No metaData for " << name << "using generic metadata";
FactMetaData* metaData = new FactMetaData(type, this);
_mapParameterName2FactMetaData[name] = metaData;
}
}
void PX4ParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
{
Q_UNUSED(vehicleType)
if (_mapParameterName2FactMetaData.contains(fact->name())) {
fact->setMetaData(_mapParameterName2FactMetaData[fact->name()]);
}
return _mapParameterName2FactMetaData[name];
}
void PX4ParameterMetaData::getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion)
......
......@@ -36,8 +36,7 @@ public:
PX4ParameterMetaData(void);
void loadParameterFactMetaDataFile (const QString& metaDataFile);
FactMetaData* getMetaDataForFact (const QString& name, MAV_TYPE vehicleType);
void addMetaDataToFact (Fact* fact, MAV_TYPE vehicleType);
FactMetaData* getMetaDataForFact (const QString& name, MAV_TYPE vehicleType, FactMetaData::ValueType_t type);
static void getParameterMetaDataVersionInfo(const QString& metaDataFile, int& majorVersion, int& minorVersion);
......@@ -58,8 +57,8 @@ private:
void _generateParameterJson();
#endif
bool _parameterMetaDataLoaded; ///< true: parameter meta data already loaded
QMap<QString, FactMetaData*> _mapParameterName2FactMetaData; ///< Maps from a parameter name to FactMetaData
bool _parameterMetaDataLoaded = false; ///< true: parameter meta data already loaded
FactMetaData::NameToMetaDataMap_t _mapParameterName2FactMetaData; ///< Maps from a parameter name to FactMetaData
};
#endif
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "CompInfo.h"
CompInfo::CompInfo(COMP_METADATA_TYPE type, uint8_t compId, Vehicle* vehicle, QObject* parent)
: QObject (parent)
, type (type)
, vehicle (vehicle)
, compId (compId)
{
}
void CompInfo::setMessage(const mavlink_message_t& message)
{
mavlink_component_information_t componentInformation;
mavlink_msg_component_information_decode(&message, &componentInformation);
available = true;
uidMetaData = componentInformation.metadata_uid;
uidTranslation = componentInformation.translation_uid;
uriMetaData = componentInformation.metadata_uri;
uriTranslation = componentInformation.translation_uri;
}
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include "QGCMAVLink.h"
#include "QGCLoggingCategory.h"
#include "FactMetaData.h"
#include <QObject>
class FactMetaData;
class Vehicle;
class FirmwarePlugin;
/// Base class for all CompInfo types
class CompInfo : public QObject
{
Q_OBJECT
public:
CompInfo(COMP_METADATA_TYPE type, uint8_t compId, Vehicle* vehicle, QObject* parent = nullptr);
/// Called to pass the COMPONENT_INFORMATION message in
void setMessage(const mavlink_message_t& message);
virtual void setJson(const QString& metaDataJsonFileName, const QString& translationJsonFileName) = 0;
COMP_METADATA_TYPE type;
Vehicle* vehicle = nullptr;
uint8_t compId = MAV_COMP_ID_ALL;
bool available = false;
uint32_t uidMetaData = 0;
uint32_t uidTranslation = 0;
QString uriMetaData;
QString uriTranslation;
};
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "CompInfoParam.h"
#include "JsonHelper.h"
#include "FactMetaData.h"
#include "FirmwarePlugin.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include <QStandardPaths>
#include <QJsonDocument>
#include <QJsonArray>
QGC_LOGGING_CATEGORY(CompInfoParamLog, "CompInfoParamLog")
const char* CompInfoParam::_jsonScopeKey = "scope";
const char* CompInfoParam::_jsonParametersKey = "parameters";
const char* CompInfoParam::_cachedMetaDataFilePrefix = "ParameterFactMetaData";
CompInfoParam::CompInfoParam(uint8_t compId, Vehicle* vehicle, QObject* parent)
: CompInfo(COMP_METADATA_TYPE_PARAMETER, compId, vehicle, parent)
{
}
void CompInfoParam::setJson(const QString& metadataJsonFileName, const QString& /*translationJsonFileName*/)
{
if (metadataJsonFileName.isEmpty()) {
// This will fall back to using the old FirmwarePlugin mechanism for parameter meta data.
// In this case paramter metadata is loaded through the _parameterMajorVersionKnown call which happens after parameter are downloaded
return;
}
QString errorString;
QJsonDocument jsonDoc;
_noJsonMetadata = false;
if (!JsonHelper::isJsonFile(metadataJsonFileName, jsonDoc, errorString)) {
qCWarning(CompInfoParamLog) << "Metadata json file open failed: compid:" << compId << errorString;
return;
}
QJsonObject jsonObj = jsonDoc.object();
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ JsonHelper::jsonVersionKey, QJsonValue::Double, true },
{ _jsonScopeKey, QJsonValue::String, true },
{ _jsonParametersKey, QJsonValue::Array, true },
};
if (!JsonHelper::validateKeys(jsonObj, keyInfoList, errorString)) {
qCWarning(CompInfoParamLog) << "Metadata json validation failed: compid:" << compId << errorString;
return;
}
int version = jsonObj[JsonHelper::jsonVersionKey].toInt();
if (version != 1) {
qCWarning(CompInfoParamLog) << "Metadata json unsupported version" << version;
return;
}
QJsonArray rgParameters = jsonObj[_jsonParametersKey].toArray();
for (const QJsonValue& parameterValue: rgParameters) {
QMap<QString, QString> emptyDefineMap;
if (!parameterValue.isObject()) {
qCWarning(CompInfoParamLog) << "Metadata json read failed: compid:" << compId << "parameters array contains non-object";
return;
}
FactMetaData* newMetaData = FactMetaData::createFromJsonObject(parameterValue.toObject(), emptyDefineMap, this);
_nameToMetaDataMap[newMetaData->name()] = newMetaData;
}
}
FactMetaData* CompInfoParam::factMetaDataForName(const QString& name, FactMetaData::ValueType_t type)
{
if (_opaqueParameterMetaData) {
return vehicle->firmwarePlugin()->_getMetaDataForFact(_opaqueParameterMetaData, name, type, vehicle->vehicleType());
} else {
if (!_nameToMetaDataMap.contains(name)) {
_nameToMetaDataMap[name] = new FactMetaData(type, this);
}
return _nameToMetaDataMap[name];
}
}
bool CompInfoParam::_isParameterVolatile(const QString& name)
{
if (_opaqueParameterMetaData) {
return vehicle->firmwarePlugin()->_isParameterVolatile(_opaqueParameterMetaData, name, vehicle->vehicleType());
} else {
return _nameToMetaDataMap.contains(name) ? _nameToMetaDataMap[name]->volatileValue() : false;
}
}
FirmwarePlugin* CompInfoParam::_anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT firmwareType)
{
FirmwarePluginManager* pluginMgr = qgcApp()->toolbox()->firmwarePluginManager();
MAV_TYPE anySupportedVehicleType = pluginMgr->supportedVehicleTypes(firmwareType)[0];
return pluginMgr->firmwarePluginForAutopilot(firmwareType, anySupportedVehicleType);
}
QString CompInfoParam::_parameterMetaDataFile(Vehicle* vehicle, MAV_AUTOPILOT firmwareType, int wantedMajorVersion, int& majorVersion, int& minorVersion)
{
bool cacheHit = false;
FirmwarePlugin* plugin = _anyVehicleTypeFirmwarePlugin(firmwareType);
if (firmwareType != MAV_AUTOPILOT_PX4) {
return plugin->_internalParameterMetaDataFile(vehicle);
} else {
// Only PX4 support the old style cached metadata
QSettings settings;
QDir cacheDir = QFileInfo(settings.fileName()).dir();
// First look for a direct cache hit
int cacheMinorVersion, cacheMajorVersion;
QFile cacheFile(cacheDir.filePath(QString("%1.%2.%3.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType).arg(wantedMajorVersion)));
if (cacheFile.exists()) {
plugin->_getParameterMetaDataVersionInfo(cacheFile.fileName(), cacheMajorVersion, cacheMinorVersion);
if (wantedMajorVersion != cacheMajorVersion) {
qWarning() << "Parameter meta data cache corruption:" << cacheFile.fileName() << "major version does not match file name" << "actual:excepted" << cacheMajorVersion << wantedMajorVersion;
} else {
qCDebug(CompInfoParamLog) << "Direct cache hit on file:major:minor" << cacheFile.fileName() << cacheMajorVersion << cacheMinorVersion;
cacheHit = true;
}
}
if (!cacheHit) {
// No direct hit, look for lower param set version
QString wildcard = QString("%1.%2.*.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType);
QStringList cacheHits = cacheDir.entryList(QStringList(wildcard), QDir::Files, QDir::Name);
// Find the highest major version number which is below the vehicles major version number
int cacheHitIndex = -1;
cacheMajorVersion = -1;
QRegExp regExp(QString("%1\\.%2\\.(\\d*)\\.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType));
for (int i=0; i< cacheHits.count(); i++) {
if (regExp.exactMatch(cacheHits[i]) && regExp.captureCount() == 1) {
int majorVersion = regExp.capturedTexts()[0].toInt();
if (majorVersion > cacheMajorVersion && majorVersion < wantedMajorVersion) {
cacheMajorVersion = majorVersion;
cacheHitIndex = i;
}
}
}
if (cacheHitIndex != -1) {
// We have a cache hit on a lower major version, read minor version as well
int majorVersion;
cacheFile.setFileName(cacheDir.filePath(cacheHits[cacheHitIndex]));
plugin->_getParameterMetaDataVersionInfo(cacheFile.fileName(), majorVersion, cacheMinorVersion);
if (majorVersion != cacheMajorVersion) {
qWarning() << "Parameter meta data cache corruption:" << cacheFile.fileName() << "major version does not match file name" << "actual:excepted" << majorVersion << cacheMajorVersion;
cacheHit = false;
} else {
qCDebug(CompInfoParamLog) << "Indirect cache hit on file:major:minor:want" << cacheFile.fileName() << cacheMajorVersion << cacheMinorVersion << wantedMajorVersion;
cacheHit = true;
}
}
}
int internalMinorVersion, internalMajorVersion;
QString internalMetaDataFile = plugin->_internalParameterMetaDataFile(vehicle);
plugin->_getParameterMetaDataVersionInfo(internalMetaDataFile, internalMajorVersion, internalMinorVersion);
qCDebug(CompInfoParamLog) << "Internal metadata file:major:minor" << internalMetaDataFile << internalMajorVersion << internalMinorVersion;
if (cacheHit) {
// Cache hit is available, we need to check if internal meta data is a better match, if so use internal version
if (internalMajorVersion == wantedMajorVersion) {
if (cacheMajorVersion == wantedMajorVersion) {
// Both internal and cache are direct hit on major version, Use higher minor version number
cacheHit = cacheMinorVersion > internalMinorVersion;
} else {
// Direct internal hit, but not direct hit in cache, use internal
cacheHit = false;
}
} else {
if (cacheMajorVersion == wantedMajorVersion) {
// Direct hit on cache, no direct hit on internal, use cache
cacheHit = true;
} else {
// No direct hit anywhere, use internal
cacheHit = false;
}
}
}
QString metaDataFile;
if (cacheHit && !qgcApp()->runningUnitTests()) {
majorVersion = cacheMajorVersion;
minorVersion = cacheMinorVersion;
metaDataFile = cacheFile.fileName();
} else {
majorVersion = internalMajorVersion;
minorVersion = internalMinorVersion;
metaDataFile = internalMetaDataFile;
}
qCDebug(CompInfoParamLog) << "_parameterMetaDataFile returning file:major:minor" << metaDataFile << majorVersion << minorVersion;
return metaDataFile;
}
}
void CompInfoParam::_cachePX4MetaDataFile(const QString& metaDataFile)
{
FirmwarePlugin* plugin = _anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT_PX4);
int newMajorVersion, newMinorVersion;
plugin->_getParameterMetaDataVersionInfo(metaDataFile, newMajorVersion, newMinorVersion);
qCDebug(CompInfoParamLog) << "ParameterManager::cacheMetaDataFile file:major;minor" << metaDataFile << newMajorVersion << newMinorVersion;
// Find the cache hit closest to this new file
int cacheMajorVersion, cacheMinorVersion;
QString cacheHit = _parameterMetaDataFile(nullptr, MAV_AUTOPILOT_PX4, newMajorVersion, cacheMajorVersion, cacheMinorVersion);
qCDebug(CompInfoParamLog) << "ParameterManager::cacheMetaDataFile cacheHit file:firmware:major;minor" << cacheHit << cacheMajorVersion << cacheMinorVersion;
bool cacheNewFile = false;
if (cacheHit.isEmpty()) {
// No cache hits, store the new file
cacheNewFile = true;
} else if (cacheMajorVersion == newMajorVersion) {
// Direct hit on major version in cache:
// Cache new file if newer/equal minor version. We cache if equal to allow flashing test builds with new parameter metadata.
// Also delete older cache file.
if (newMinorVersion >= cacheMinorVersion) {
cacheNewFile = true;
QFile::remove(cacheHit);
}
} else {
// Indirect hit in cache, store new file
cacheNewFile = true;
}
if (cacheNewFile) {
// Cached files are stored in settings location. Copy from current file to cache naming.
QSettings settings;
QDir cacheDir = QFileInfo(settings.fileName()).dir();
QFile cacheFile(cacheDir.filePath(QString("%1.%2.%3.xml").arg(_cachedMetaDataFilePrefix).arg(MAV_AUTOPILOT_PX4).arg(newMajorVersion)));
qCDebug(CompInfoParamLog) << "ParameterManager::cacheMetaDataFile caching file:" << cacheFile.fileName();
QFile newFile(metaDataFile);
newFile.copy(cacheFile.fileName());
}
}
void CompInfoParam::_parameterMajorVersionKnown(int wantedMajorVersion)
{
if (_noJsonMetadata) {
if (_opaqueParameterMetaData) {
return;
}
QString metaDataFile;
int majorVersion, minorVersion;
// Load best parameter meta data set
metaDataFile = _parameterMetaDataFile(vehicle, vehicle->firmwareType(), wantedMajorVersion, majorVersion, minorVersion);
qCDebug(CompInfoParamLog) << "Loading meta data the old way file:major:minor" << metaDataFile << majorVersion << minorVersion;
_opaqueParameterMetaData = vehicle->firmwarePlugin()->_loadParameterMetaData(metaDataFile);
}
}
void CompInfoParam::_clearPX4ParameterMetaData (void)
{
if (_opaqueParameterMetaData) {
qCDebug(CompInfoParamLog) << "_clearPX4ParameterMetaData";
_opaqueParameterMetaData->deleteLater();
_opaqueParameterMetaData = nullptr;
}
}
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include "CompInfo.h"
#include "QGCMAVLink.h"
#include "QGCLoggingCategory.h"
#include "FactMetaData.h"
#include <QObject>
class FactMetaData;
class Vehicle;
class FirmwarePlugin;
Q_DECLARE_LOGGING_CATEGORY(CompInfoParamLog)
class CompInfoParam : public CompInfo
{
Q_OBJECT
public:
CompInfoParam(uint8_t compId, Vehicle* vehicle, QObject* parent = nullptr);
FactMetaData* factMetaDataForName(const QString& name, FactMetaData::ValueType_t type);
// Overrides from CompInfo
void setJson(const QString& metadataJsonFileName, const QString& translationJsonFileName) override;
// The following methods are used to support the old non-COMPONENT_INFORMATION based mechanism to get parameter meta data
bool _isParameterVolatile (const QString& name);
void _parameterMajorVersionKnown(int wantedMajorVersion);
void _clearPX4ParameterMetaData (void);
static void _cachePX4MetaDataFile(const QString& metaDataFile);
private:
static FirmwarePlugin* _anyVehicleTypeFirmwarePlugin (MAV_AUTOPILOT firmwareType);
static QString _parameterMetaDataFile (Vehicle* vehicle, MAV_AUTOPILOT firmwareType, int wantedMajorVersion, int& majorVersion, int& minorVersion);
bool _noJsonMetadata = true;
FactMetaData::NameToMetaDataMap_t _nameToMetaDataMap;
QObject* _opaqueParameterMetaData = nullptr;
static const char* _cachedMetaDataFilePrefix;
static const char* _jsonScopeKey;
static const char* _jsonParametersKey;
};
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "CompInfoVersion.h"
#include "JsonHelper.h"
#include "FactMetaData.h"
#include "FirmwarePlugin.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include <QStandardPaths>
#include <QJsonDocument>
#include <QJsonArray>
QGC_LOGGING_CATEGORY(CompInfoVersionLog, "CompInfoVersionLog")
const char* CompInfoVersion::_jsonSupportedCompMetadataTypesKey = "supportedCompMetadataTypes";
CompInfoVersion::CompInfoVersion(uint8_t compId, Vehicle* vehicle, QObject* parent)
: CompInfo (COMP_METADATA_TYPE_VERSION, compId, vehicle, parent)
{
}
void CompInfoVersion::setJson(const QString& metadataJsonFileName, const QString& /*translationJsonFileName*/)
{
if (metadataJsonFileName.isEmpty()) {
return;
}
QString errorString;
QJsonDocument jsonDoc;
if (!JsonHelper::isJsonFile(metadataJsonFileName, jsonDoc, errorString)) {
qCWarning(CompInfoVersionLog) << "Metadata json file open failed: compid:" << compId << errorString;
return;
}
QJsonObject jsonObj = jsonDoc.object();
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ JsonHelper::jsonVersionKey, QJsonValue::Double, true },
{ _jsonSupportedCompMetadataTypesKey, QJsonValue::Array, true },
};
if (!JsonHelper::validateKeys(jsonObj, keyInfoList, errorString)) {
qCWarning(CompInfoVersionLog) << "Metadata json validation failed: compid:" << compId << errorString;
return;
}
int version = jsonObj[JsonHelper::jsonVersionKey].toInt();
if (version != 1) {
qCWarning(CompInfoVersionLog) << "Metadata json unsupported version" << version;
return;
}
QJsonArray rgSupportedTypes = jsonObj[_jsonSupportedCompMetadataTypesKey].toArray();
for (const QJsonValue& typeValue: rgSupportedTypes) {
_supportedTypes.append(static_cast<COMP_METADATA_TYPE>(typeValue.toInt()));
}
}
/****************************************************************************
*
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#pragma once
#include "CompInfo.h"
#include "QGCMAVLink.h"
#include "QGCLoggingCategory.h"
#include "FactMetaData.h"
#include <QObject>
class FactMetaData;
class Vehicle;
class FirmwarePlugin;
Q_DECLARE_LOGGING_CATEGORY(CompInfoVersionLog)
class CompInfoVersion : public CompInfo
{
Q_OBJECT
public:
CompInfoVersion(uint8_t compId, Vehicle* vehicle, QObject* parent = nullptr);
bool isMetaDataTypeSupported(COMP_METADATA_TYPE type) { return _supportedTypes.contains(type); }
// Overrides from CompInfo
void setJson(const QString& metadataJsonFileName, const QString& translationJsonFileName) override;
private:
QList<COMP_METADATA_TYPE> _supportedTypes;
static const char* _jsonSupportedCompMetadataTypesKey;
};
......@@ -12,6 +12,8 @@
#include "FTPManager.h"
#include "QGCZlib.h"
#include "JsonHelper.h"
#include "CompInfoVersion.h"
#include "CompInfoParam.h"
#include <QStandardPaths>
#include <QJsonDocument>
......@@ -19,9 +21,6 @@
QGC_LOGGING_CATEGORY(ComponentInformationManagerLog, "ComponentInformationManagerLog")
const char* ComponentInformationManager::_jsonVersionKey = "version";
const char* ComponentInformationManager::_jsonSupportedCompMetadataTypesKey = "supportedCompMetadataTypes";
ComponentInformationManager::StateFn ComponentInformationManager::_rgStates[]= {
ComponentInformationManager::_stateRequestCompInfoVersion,
ComponentInformationManager::_stateRequestCompInfoParam,
......@@ -43,7 +42,8 @@ ComponentInformationManager::ComponentInformationManager(Vehicle* vehicle)
: _vehicle (vehicle)
, _requestTypeStateMachine (this)
{
_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_VERSION] = new CompInfoVersion (MAV_COMP_ID_AUTOPILOT1, vehicle, this);
_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_PARAMETER] = new CompInfoParam (MAV_COMP_ID_AUTOPILOT1, vehicle, this);
}
int ComponentInformationManager::stateCount(void) const
......@@ -66,7 +66,7 @@ void ComponentInformationManager::requestAllComponentInformation(RequestAllCompl
void ComponentInformationManager::_stateRequestCompInfoVersion(StateMachine* stateMachine)
{
ComponentInformationManager* compMgr = static_cast<ComponentInformationManager*>(stateMachine);
compMgr->_requestTypeStateMachine.request(COMP_METADATA_TYPE_VERSION);
compMgr->_requestTypeStateMachine.request(compMgr->_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_VERSION]);
}
void ComponentInformationManager::_stateRequestCompInfoComplete(void)
......@@ -79,9 +79,10 @@ void ComponentInformationManager::_stateRequestCompInfoParam(StateMachine* state
ComponentInformationManager* compMgr = static_cast<ComponentInformationManager*>(stateMachine);
if (compMgr->_isCompTypeSupported(COMP_METADATA_TYPE_PARAMETER)) {
compMgr->_requestTypeStateMachine.request(COMP_METADATA_TYPE_PARAMETER);
compMgr->_requestTypeStateMachine.request(compMgr->_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_PARAMETER]);
} else {
qCDebug(ComponentInformationManagerLog) << "_stateRequestCompInfoParam skipping, not supported";
compMgr->advance();
}
}
......@@ -93,39 +94,19 @@ void ComponentInformationManager::_stateRequestAllCompInfoComplete(StateMachine*
compMgr->_requestAllCompleteFnData = nullptr;
}
void ComponentInformationManager::_compInfoJsonAvailable(const QString& metadataJsonFileName, const QString& translationsJsonFileName)
bool ComponentInformationManager::_isCompTypeSupported(COMP_METADATA_TYPE type)
{
qCDebug(ComponentInformationManagerLog) << "_compInfoJsonAvailable metadata:translation" << metadataJsonFileName << translationsJsonFileName;
if (!metadataJsonFileName.isEmpty()) {
QString errorString;
QJsonDocument jsonDoc;
if (!JsonHelper::isJsonFile(metadataJsonFileName, jsonDoc, errorString)) {
qCWarning(ComponentInformationManagerLog) << "Version json file read failed" << errorString;
return;
}
QJsonObject jsonObj = jsonDoc.object();
if (currentState() == _stateRequestCompInfoVersion) {
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ _jsonVersionKey, QJsonValue::Double, true },
{ _jsonSupportedCompMetadataTypesKey, QJsonValue::Array, true },
};
if (!JsonHelper::validateKeys(jsonObj, keyInfoList, errorString)) {
qCWarning(ComponentInformationManagerLog) << "Version json validation failed:" << errorString;
return;
}
return qobject_cast<CompInfoVersion*>(_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_VERSION])->isMetaDataTypeSupported(type);
}
for (const QJsonValue& idValue: jsonObj[_jsonSupportedCompMetadataTypesKey].toArray()) {
_supportedMetaDataTypes.append(static_cast<COMP_METADATA_TYPE>(idValue.toInt()));
}
}
}
CompInfoParam* ComponentInformationManager::compInfoParam(uint8_t compId)
{
return _compInfoMap.contains(compId) && _compInfoMap[compId].contains(COMP_METADATA_TYPE_PARAMETER) ? qobject_cast<CompInfoParam*>(_compInfoMap[compId][COMP_METADATA_TYPE_PARAMETER]) : nullptr;
}
bool ComponentInformationManager::_isCompTypeSupported(COMP_METADATA_TYPE type)
CompInfoVersion* ComponentInformationManager::compInfoVersion(uint8_t compId)
{
return _supportedMetaDataTypes.contains(type);
return _compInfoMap.contains(compId) && _compInfoMap[compId].contains(COMP_METADATA_TYPE_VERSION) ? qobject_cast<CompInfoVersion*>(_compInfoMap[compId][COMP_METADATA_TYPE_VERSION]) : nullptr;
}
RequestMetaDataTypeStateMachine::RequestMetaDataTypeStateMachine(ComponentInformationManager* compMgr)
......@@ -134,11 +115,10 @@ RequestMetaDataTypeStateMachine::RequestMetaDataTypeStateMachine(ComponentInform
}
void RequestMetaDataTypeStateMachine::request(COMP_METADATA_TYPE type)
void RequestMetaDataTypeStateMachine::request(CompInfo* compInfo)
{
_compInfoAvailable = false;
_type = type;
_stateIndex = -1;
_compInfo = compInfo;
_stateIndex = -1;
_jsonMetadataFileName.clear();
_jsonTranslationFileName.clear();
......@@ -162,19 +142,7 @@ void RequestMetaDataTypeStateMachine::statesCompleted(void) const
QString RequestMetaDataTypeStateMachine::typeToString(void)
{
return _type == COMP_METADATA_TYPE_VERSION ? "COMP_METADATA_TYPE_VERSION" : "COMP_METADATA_TYPE_PARAM";
}
void RequestMetaDataTypeStateMachine::handleComponentInformation(const mavlink_message_t& message)
{
mavlink_component_information_t componentInformation;
mavlink_msg_component_information_decode(&message, &componentInformation);
_compInfo.metadataUID = componentInformation.metadata_uid;
_compInfo.metadataURI = componentInformation.metadata_uri;
_compInfo.translationUID = componentInformation.translation_uid;
_compInfo.translationURI = componentInformation.translation_uri;
_compInfoAvailable = true;
return _compInfo->type == COMP_METADATA_TYPE_VERSION ? "COMP_METADATA_TYPE_VERSION" : "COMP_METADATA_TYPE_PARAM";
}
static void _requestMessageResultHandler(void* resultHandlerData, MAV_RESULT result, Vehicle::RequestMessageResultHandlerFailureCode_t failureCode, const mavlink_message_t &message)
......@@ -182,7 +150,7 @@ static void _requestMessageResultHandler(void* resultHandlerData, MAV_RESULT res
RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(resultHandlerData);
if (result == MAV_RESULT_ACCEPTED) {
requestMachine->handleComponentInformation(message);
requestMachine->compInfo()->setMessage(message);
} else {
switch (failureCode) {
case Vehicle::RequestMessageFailureCommandError:
......@@ -217,7 +185,7 @@ void RequestMetaDataTypeStateMachine::_stateRequestCompInfo(StateMachine* stateM
stateMachine,
MAV_COMP_ID_AUTOPILOT1,
MAVLINK_MSG_ID_COMPONENT_INFORMATION,
requestMachine->_type);
requestMachine->_compInfo->type);
}
}
......@@ -260,7 +228,7 @@ void RequestMetaDataTypeStateMachine::_downloadCompleteTranslationJson(const QSt
jsonTranslationFileName = _downloadCompleteJsonWorker(fileName, "translation.json");
}
_compMgr->_compInfoJsonAvailable(_jsonMetadataFileName, jsonTranslationFileName);
_compInfo->setJson(_jsonMetadataFileName, jsonTranslationFileName);
advance();
}
......@@ -268,22 +236,20 @@ void RequestMetaDataTypeStateMachine::_downloadCompleteTranslationJson(const QSt
void RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson(StateMachine* stateMachine)
{
RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine);
Vehicle* vehicle = requestMachine->_compMgr->vehicle();
FTPManager* ftpManager = vehicle->ftpManager();
CompInfo* compInfo = requestMachine->compInfo();
FTPManager* ftpManager = compInfo->vehicle->ftpManager();
if (requestMachine->_compInfoAvailable) {
ComponentInformation_t& compInfo = requestMachine->_compInfo;
qCDebug(ComponentInformationManagerLog) << "Downloading metadata json" << compInfo.metadataURI;
if (_uriIsFTP(compInfo.metadataURI)) {
if (compInfo->available) {
qCDebug(ComponentInformationManagerLog) << "Downloading metadata json" << compInfo->uriMetaData;
if (_uriIsFTP(compInfo->uriMetaData)) {
connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_downloadCompleteMetaDataJson);
ftpManager->download(compInfo.metadataURI, QStandardPaths::writableLocation(QStandardPaths::TempLocation));
ftpManager->download(compInfo->uriMetaData, QStandardPaths::writableLocation(QStandardPaths::TempLocation));
} else {
// FIXME: NYI
qCDebug(ComponentInformationManagerLog) << "Skipping metadata json download. http download NYI";
}
} else {
qCDebug(ComponentInformationManagerLog) << "Skipping metadata json download. Component informatiom not available";
qCDebug(ComponentInformationManagerLog) << "Skipping metadata json download. Component information not available";
requestMachine->advance();
}
}
......@@ -291,26 +257,25 @@ void RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson(StateMachine* st
void RequestMetaDataTypeStateMachine::_stateRequestTranslationJson(StateMachine* stateMachine)
{
RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine);
Vehicle* vehicle = requestMachine->_compMgr->vehicle();
FTPManager* ftpManager = vehicle->ftpManager();
CompInfo* compInfo = requestMachine->compInfo();
FTPManager* ftpManager = compInfo->vehicle->ftpManager();
if (requestMachine->_compInfoAvailable) {
ComponentInformation_t& compInfo = requestMachine->_compInfo;
if (compInfo.translationURI.isEmpty()) {
if (compInfo->available) {
if (compInfo->uriTranslation.isEmpty()) {
qCDebug(ComponentInformationManagerLog) << "Skipping translation json download. No translation json specified";
requestMachine->advance();
} else {
qCDebug(ComponentInformationManagerLog) << "Downloading translation json" << compInfo.translationURI;
if (_uriIsFTP(compInfo.translationURI)) {
qCDebug(ComponentInformationManagerLog) << "Downloading translation json" << compInfo->uriTranslation;
if (_uriIsFTP(compInfo->uriTranslation)) {
connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_downloadCompleteTranslationJson);
ftpManager->download(compInfo.metadataURI, QStandardPaths::writableLocation(QStandardPaths::TempLocation));
ftpManager->download(compInfo->uriTranslation, QStandardPaths::writableLocation(QStandardPaths::TempLocation));
} else {
// FIXME: NYI
qCDebug(ComponentInformationManagerLog) << "Skipping translation json download. http download NYI";
}
}
} else {
qCDebug(ComponentInformationManagerLog) << "Skipping translation json download. Component informatiom not available";
qCDebug(ComponentInformationManagerLog) << "Skipping translation json download. Component information not available";
requestMachine->advance();
}
}
......@@ -318,8 +283,9 @@ void RequestMetaDataTypeStateMachine::_stateRequestTranslationJson(StateMachine*
void RequestMetaDataTypeStateMachine::_stateRequestComplete(StateMachine* stateMachine)
{
RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine);
CompInfo* compInfo = requestMachine->compInfo();
requestMachine->compMgr()->_compInfoJsonAvailable(requestMachine->_jsonMetadataFileName, requestMachine->_jsonTranslationFileName);
compInfo->setJson(requestMachine->_jsonMetadataFileName, requestMachine->_jsonTranslationFileName);
requestMachine->advance();
}
......
......@@ -17,13 +17,9 @@ Q_DECLARE_LOGGING_CATEGORY(ComponentInformationManagerLog)
class Vehicle;
class ComponentInformationManager;
typedef struct {
uint32_t metadataUID;
QString metadataURI;
uint32_t translationUID;
QString translationURI;
} ComponentInformation_t;
class CompInfo;
class CompInfoParam;
class CompInfoVersion;
class RequestMetaDataTypeStateMachine : public StateMachine
{
......@@ -32,10 +28,9 @@ class RequestMetaDataTypeStateMachine : public StateMachine
public:
RequestMetaDataTypeStateMachine(ComponentInformationManager* compMgr);
void request (COMP_METADATA_TYPE type);
QString typeToString (void);
ComponentInformationManager* compMgr (void) { return _compMgr; }
void handleComponentInformation (const mavlink_message_t& message);
void request (CompInfo* compInfo);
QString typeToString(void);
CompInfo* compInfo (void) { return _compInfo; }
// Overrides from StateMachine
int stateCount (void) const final;
......@@ -55,15 +50,13 @@ private:
static bool _uriIsFTP (const QString& uri);
ComponentInformationManager* _compMgr;
COMP_METADATA_TYPE _type = COMP_METADATA_TYPE_VERSION;
bool _compInfoAvailable = false;
ComponentInformation_t _compInfo;
ComponentInformationManager* _compMgr = nullptr;
CompInfo* _compInfo = nullptr;
QString _jsonMetadataFileName;
QString _jsonTranslationFileName;
static StateFn _rgStates[];
static int _cStates;
static StateFn _rgStates[];
static int _cStates;
};
class ComponentInformationManager : public StateMachine
......@@ -75,8 +68,10 @@ public:
typedef void (*RequestAllCompleteFn)(void* requestAllCompleteFnData);
void requestAllComponentInformation (RequestAllCompleteFn requestAllCompletFn, void * requestAllCompleteFnData);
Vehicle* vehicle (void) { return _vehicle; }
void requestAllComponentInformation (RequestAllCompleteFn requestAllCompletFn, void * requestAllCompleteFnData);
Vehicle* vehicle (void) { return _vehicle; }
CompInfoParam* compInfoParam (uint8_t compId);
CompInfoVersion* compInfoVersion (uint8_t compId);
// Overrides from StateMachine
int stateCount (void) const final;
......@@ -84,7 +79,6 @@ public:
private:
void _stateRequestCompInfoComplete (void);
void _compInfoJsonAvailable (const QString& metadataJsonFileName, const QString& translationsJsonFileName);
bool _isCompTypeSupported (COMP_METADATA_TYPE type);
static void _stateRequestCompInfoVersion (StateMachine* stateMachine);
......@@ -93,19 +87,13 @@ private:
Vehicle* _vehicle = nullptr;
RequestMetaDataTypeStateMachine _requestTypeStateMachine;
bool _versionCompInfoAvailable = false;
ComponentInformation_t _versionCompInfo;
bool _paramCompInfoAvailable = false;
ComponentInformation_t _parameterCompInfo;
QList<COMP_METADATA_TYPE> _supportedMetaDataTypes;
RequestAllCompleteFn _requestAllCompleteFn = nullptr;
void* _requestAllCompleteFnData = nullptr;
QMap<uint8_t /* compId */, QMap<COMP_METADATA_TYPE, CompInfo*>> _compInfoMap;
static StateFn _rgStates[];
static int _cStates;
static const char* _jsonVersionKey;
static const char* _jsonSupportedCompMetadataTypesKey;
friend class RequestMetaDataTypeStateMachine;
};
......@@ -462,13 +462,13 @@ void Vehicle::_commonInit()
connect(_missionManager, &MissionManager::sendComplete, _trajectoryPoints, &TrajectoryPoints::clear);
connect(_missionManager, &MissionManager::newMissionItemsAvailable, _trajectoryPoints, &TrajectoryPoints::clear);
_parameterManager = new ParameterManager(this);
connect(_parameterManager, &ParameterManager::parametersReadyChanged, this, &Vehicle::_parametersReady);
_componentInformationManager = new ComponentInformationManager (this);
_initialConnectStateMachine = new InitialConnectStateMachine (this);
_ftpManager = new FTPManager (this);
_parameterManager = new ParameterManager(this);
connect(_parameterManager, &ParameterManager::parametersReadyChanged, this, &Vehicle::_parametersReady);
_objectAvoidance = new VehicleObjectAvoidance(this, this);
// GeoFenceManager needs to access ParameterManager so make sure to create after
......
......@@ -1007,9 +1007,10 @@ public:
void setConnectionLostEnabled(bool connectionLostEnabled);
ParameterManager* parameterManager () { return _parameterManager; }
ParameterManager* parameterManager () const { return _parameterManager; }
FTPManager* ftpManager () { return _ftpManager; }
ParameterManager* parameterManager () { return _parameterManager; }
ParameterManager* parameterManager () const { return _parameterManager; }
FTPManager* ftpManager () { return _ftpManager; }
ComponentInformationManager* compInfoManager () { return _componentInformationManager; }
VehicleObjectAvoidance* objectAvoidance () { return _objectAvoidance; }
static const int cMaxRcChannels = 18;
......
......@@ -7,18 +7,13 @@
*
****************************************************************************/
/// @file
/// @brief Support for Intel Hex firmware file
/// @author Don Gagne <don@thegagnes.com>
#include "FirmwareImage.h"
#include "QGCLoggingCategory.h"
#include "JsonHelper.h"
#include "QGCMAVLink.h"
#include "QGCApplication.h"
#include "FirmwarePlugin.h"
#include "ParameterManager.h"
#include "CompInfoParam.h"
#include "Bootloader.h"
#include <QDebug>
......@@ -292,7 +287,7 @@ bool FirmwareImage::_px4Load(const QString& imageFilename)
}
// Cache this file with the system
ParameterManager::cacheMetaDataFile(parameterFilename, firmwareType);
CompInfoParam::_cachePX4MetaDataFile(parameterFilename);
}
// Decompress the airframe xml and save to file
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment