From 0f18f587e5e341ff8bd0f173814439014fa4a617 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Sun, 27 Dec 2015 16:54:19 -0800 Subject: [PATCH] Automatic raw->cooked translation based on units --- src/FactSystem/Fact.cc | 93 ++++++--- src/FactSystem/Fact.h | 41 ++-- src/FactSystem/FactMetaData.cc | 191 ++++++++++++++---- src/FactSystem/FactMetaData.h | 61 ++++-- src/FactSystem/ParameterLoader.cc | 2 +- .../APM/APMParameterMetaData.cc | 12 +- .../PX4/PX4ParameterMetaData.cc | 18 +- src/MissionManager/MavCmdInfo.json | 6 +- src/MissionManager/MissionCommands.cc | 3 - src/MissionManager/MissionCommands.h | 3 - src/MissionManager/MissionItem.cc | 42 +--- src/MissionManager/MissionItem.h | 3 - 12 files changed, 314 insertions(+), 161 deletions(-) diff --git a/src/FactSystem/Fact.cc b/src/FactSystem/Fact.cc index abbd3d021..77a7331ae 100644 --- a/src/FactSystem/Fact.cc +++ b/src/FactSystem/Fact.cc @@ -80,7 +80,7 @@ void Fact::forceSetRawValue(const QVariant& value) QVariant typedValue; QString errorString; - if (_metaData->convertAndValidate(value, true /* convertOnly */, typedValue, errorString)) { + if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) { _rawValue.setValue(typedValue); emit valueChanged(cookedValue()); emit _containerRawValueChanged(rawValue()); @@ -96,7 +96,7 @@ void Fact::setRawValue(const QVariant& value) QVariant typedValue; QString errorString; - if (_metaData->convertAndValidate(value, true /* convertOnly */, typedValue, errorString)) { + if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) { if (typedValue != _rawValue) { _rawValue.setValue(typedValue); emit valueChanged(cookedValue()); @@ -242,27 +242,45 @@ QString Fact::_variantToString(const QVariant& variant) const return valueString; } -QString Fact::valueString(void) const +QString Fact::rawValueString(void) const +{ + return _variantToString(rawValue()); +} + +QString Fact::cookedValueString(void) const { return _variantToString(cookedValue()); } -QVariant Fact::defaultValue(void) const +QVariant Fact::rawDefaultValue(void) const +{ + if (_metaData) { + if (!_metaData->defaultValueAvailable()) { + qDebug() << "Access to unavailable default value"; + } + return _metaData->rawDefaultValue(); + } else { + qWarning() << "Meta data pointer missing"; + return QVariant(0); + } +} + +QVariant Fact::cookedDefaultValue(void) const { if (_metaData) { if (!_metaData->defaultValueAvailable()) { qDebug() << "Access to unavailable default value"; } - return _metaData->defaultValue(); + return _metaData->cookedDefaultValue(); } else { qWarning() << "Meta data pointer missing"; return QVariant(0); } } -QString Fact::defaultValueString(void) const +QString Fact::cookedDefaultValueString(void) const { - return _variantToString(defaultValue()); + return _variantToString(cookedDefaultValue()); } FactMetaData::ValueType_t Fact::type(void) const @@ -290,44 +308,74 @@ QString Fact::longDescription(void) const } } -QString Fact::units(void) const +QString Fact::rawUnits(void) const +{ + if (_metaData) { + return _metaData->rawUnits(); + } else { + qWarning() << "Meta data pointer missing"; + return QString(); + } +} + +QString Fact::cookedUnits(void) const { if (_metaData) { - return _metaData->units(); + return _metaData->cookedUnits(); } else { qWarning() << "Meta data pointer missing"; return QString(); } } -QVariant Fact::min(void) const +QVariant Fact::rawMin(void) const { if (_metaData) { - return _metaData->min(); + return _metaData->rawMin(); } else { qWarning() << "Meta data pointer missing"; return QVariant(0); } } -QString Fact::minString(void) const +QVariant Fact::cookedMin(void) const { - return _variantToString(min()); + if (_metaData) { + return _metaData->cookedMin(); + } else { + qWarning() << "Meta data pointer missing"; + return QVariant(0); + } } -QVariant Fact::max(void) const +QString Fact::cookedMinString(void) const +{ + return _variantToString(cookedMin()); +} + +QVariant Fact::rawMax(void) const { if (_metaData) { - return _metaData->max(); + return _metaData->rawMax(); } else { qWarning() << "Meta data pointer missing"; return QVariant(0); } } -QString Fact::maxString(void) const +QVariant Fact::cookedMax(void) const { - return _variantToString(max()); + if (_metaData) { + return _metaData->cookedMax(); + } else { + qWarning() << "Meta data pointer missing"; + return QVariant(0); + } +} + +QString Fact::cookedMaxString(void) const +{ + return _variantToString(cookedMax()); } bool Fact::minIsDefaultForType(void) const @@ -372,6 +420,8 @@ QString Fact::group(void) const void Fact::setMetaData(FactMetaData* metaData) { + // FIXME: Hack to stuff enums into APM parameters, wating on real APM metadata + static QStringList apmFlightModeParamList; static QStringList apmFlightModeEnumStrings; static QVariantList apmFlightModeEnumValues; @@ -380,8 +430,6 @@ void Fact::setMetaData(FactMetaData* metaData) static QStringList apmChannelOptEnumStrings; static QVariantList apmChannelOptEnumValues; - // FIXME: Hack to stuff enums into APM parameters, wating on real APM metadata - if (apmFlightModeEnumStrings.count() == 0) { apmFlightModeParamList << "FLTMODE1" << "FLTMODE2" << "FLTMODE3" << "FLTMODE4" << "FLTMODE5" << "FLTMODE6"; apmFlightModeEnumStrings << "Stabilize" << "Acro" << "AltHold" << "Auto" << "Guided" << "Loiter" << "RTL" << "Circle" @@ -415,7 +463,7 @@ bool Fact::valueEqualsDefault(void) const { if (_metaData) { if (_metaData->defaultValueAvailable()) { - return _metaData->defaultValue() == rawValue(); + return _metaData->rawDefaultValue() == rawValue(); } else { return false; } @@ -435,14 +483,13 @@ bool Fact::defaultValueAvailable(void) const } } -QString Fact::validate(const QString& value, bool convertOnly) +QString Fact::validate(const QString& cookedValue, bool convertOnly) { if (_metaData) { - QVariant typedValue; QString errorString; - _metaData->convertAndValidate(value, convertOnly, typedValue, errorString); + _metaData->convertAndValidateCooked(cookedValue, convertOnly, typedValue, errorString); return errorString; } else { diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h index 0c6e55fdf..b5e659b5c 100644 --- a/src/FactSystem/Fact.h +++ b/src/FactSystem/Fact.h @@ -48,8 +48,8 @@ public: Q_PROPERTY(int componentId READ componentId CONSTANT) Q_PROPERTY(int decimalPlaces READ decimalPlaces CONSTANT) - Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT) - Q_PROPERTY(QString defaultValueString READ defaultValueString CONSTANT) + Q_PROPERTY(QVariant defaultValue READ cookedDefaultValue CONSTANT) + Q_PROPERTY(QString defaultValueString READ cookedDefaultValueString CONSTANT) Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT) Q_PROPERTY(int enumIndex READ enumIndex WRITE setEnumIndex NOTIFY valueChanged) Q_PROPERTY(QStringList enumStrings READ enumStrings NOTIFY enumStringsChanged) @@ -57,48 +57,53 @@ public: Q_PROPERTY(QVariantList enumValues READ enumValues NOTIFY enumValuesChanged) Q_PROPERTY(QString group READ group CONSTANT) Q_PROPERTY(QString longDescription READ longDescription CONSTANT) - Q_PROPERTY(QVariant max READ max CONSTANT) - Q_PROPERTY(QString maxString READ maxString CONSTANT) + Q_PROPERTY(QVariant max READ cookedMax CONSTANT) + Q_PROPERTY(QString maxString READ cookedMaxString CONSTANT) Q_PROPERTY(bool maxIsDefaultForType READ maxIsDefaultForType CONSTANT) - Q_PROPERTY(QVariant min READ min CONSTANT) - Q_PROPERTY(QString minString READ minString CONSTANT) + Q_PROPERTY(QVariant min READ cookedMin CONSTANT) + Q_PROPERTY(QString minString READ cookedMinString CONSTANT) Q_PROPERTY(bool minIsDefaultForType READ minIsDefaultForType CONSTANT) Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT) Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT) - Q_PROPERTY(QString units READ units CONSTANT) + Q_PROPERTY(QString units READ cookedUnits CONSTANT) Q_PROPERTY(QVariant value READ cookedValue WRITE setCookedValue NOTIFY valueChanged) Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) - Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged) + Q_PROPERTY(QVariant valueString READ cookedValueString NOTIFY valueChanged) /// Convert and validate value /// @param convertOnly true: validate type conversion only, false: validate against meta data as well - Q_INVOKABLE QString validate(const QString& value, bool convertOnly); + Q_INVOKABLE QString validate(const QString& cookedValue, bool convertOnly); QVariant cookedValue (void) const; /// Value after translation + QVariant rawValue (void) const { return _rawValue; } /// value prior to translation, careful int componentId (void) const; int decimalPlaces (void) const; - QVariant defaultValue (void) const; + QVariant rawDefaultValue (void) const; + QVariant cookedDefaultValue (void) const; bool defaultValueAvailable (void) const; - QString defaultValueString (void) const; + QString cookedDefaultValueString(void) const; int enumIndex (void); // This is not const, since an unknown value can modify the enum lists QStringList enumStrings (void) const; QString enumStringValue (void); // This is not const, since an unknown value can modify the enum lists QVariantList enumValues (void) const; QString group (void) const; QString longDescription (void) const; - QVariant max (void) const; - QString maxString (void) const; + QVariant rawMax (void) const; + QVariant cookedMax (void) const; + QString cookedMaxString (void) const; bool maxIsDefaultForType (void) const; - QVariant min (void) const; - QString minString (void) const; + QVariant rawMin (void) const; + QVariant cookedMin (void) const; + QString cookedMinString (void) const; bool minIsDefaultForType (void) const; QString name (void) const; - QVariant rawValue (void) const { return _rawValue; } /// value prior to translation, careful QString shortDescription (void) const; FactMetaData::ValueType_t type (void) const; - QString units (void) const; - QString valueString (void) const; + QString cookedUnits (void) const; + QString rawUnits (void) const; + QString rawValueString (void) const; + QString cookedValueString (void) const; bool valueEqualsDefault (void) const; void setRawValue (const QVariant& value); diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc index 45a800eb4..15f9ac1ab 100644 --- a/src/FactSystem/FactMetaData.cc +++ b/src/FactSystem/FactMetaData.cc @@ -31,20 +31,26 @@ #include #include +#include + +const FactMetaData::BuiltInTranslation_s FactMetaData::_rgBuildInTranslations[] = { + { "centi-degrees", "degrees", FactMetaData::_centiDegreesToDegrees, FactMetaData::_degreesToCentiDegrees }, + { "radians", "degrees", FactMetaData::_radiansToDegrees, FactMetaData::_degreesToRadians }, +}; FactMetaData::FactMetaData(QObject* parent) : QObject(parent) , _type(valueTypeInt32) , _decimalPlaces(defaultDecimalPlaces) - , _defaultValue(0) + , _rawDefaultValue(0) , _defaultValueAvailable(false) , _group("*Default Group") - , _max(_maxForType()) + , _rawMax(_maxForType()) , _maxIsDefaultForType(true) - , _min(_minForType()) + , _rawMin(_minForType()) , _minIsDefaultForType(true) - , _rawTranslator(defaultTranslator) - , _cookedTranslator(defaultTranslator) + , _rawTranslator(_defaultTranslator) + , _cookedTranslator(_defaultTranslator) { } @@ -53,15 +59,15 @@ FactMetaData::FactMetaData(ValueType_t type, QObject* parent) : QObject(parent) , _type(type) , _decimalPlaces(defaultDecimalPlaces) - , _defaultValue(0) + , _rawDefaultValue(0) , _defaultValueAvailable(false) , _group("*Default Group") - , _max(_maxForType()) + , _rawMax(_maxForType()) , _maxIsDefaultForType(true) - , _min(_minForType()) + , _rawMin(_minForType()) , _minIsDefaultForType(true) - , _rawTranslator(defaultTranslator) - , _cookedTranslator(defaultTranslator) + , _rawTranslator(_defaultTranslator) + , _cookedTranslator(_defaultTranslator) { } @@ -75,66 +81,67 @@ FactMetaData::FactMetaData(const FactMetaData& other, QObject* parent) const FactMetaData& FactMetaData::operator=(const FactMetaData& other) { _decimalPlaces = other._decimalPlaces; - _defaultValue = other._defaultValue; + _rawDefaultValue = other._rawDefaultValue; _defaultValueAvailable = other._defaultValueAvailable; _enumStrings = other._enumStrings; _enumValues = other._enumValues; _group = other._group; _longDescription = other._longDescription; - _max = other._max; + _rawMax = other._rawMax; _maxIsDefaultForType = other._maxIsDefaultForType; - _min = other._min; + _rawMin = other._rawMin; _minIsDefaultForType = other._minIsDefaultForType; _name = other._name; _shortDescription = other._shortDescription; _type = other._type; - _units = other._units; + _rawUnits = other._rawUnits; + _cookedUnits = other._cookedUnits; _rawTranslator = other._rawTranslator; _cookedTranslator = other._cookedTranslator; return *this; } -QVariant FactMetaData::defaultValue(void) const +QVariant FactMetaData::rawDefaultValue(void) const { if (_defaultValueAvailable) { - return _defaultValue; + return _rawDefaultValue; } else { qWarning() << "Attempt to access unavailable default value"; return QVariant(0); } } -void FactMetaData::setDefaultValue(const QVariant& defaultValue) +void FactMetaData::setRawDefaultValue(const QVariant& rawDefaultValue) { - if (_min <= defaultValue && defaultValue <= _max) { - _defaultValue = defaultValue; + if (_rawMin <= rawDefaultValue && rawDefaultValue <= _rawMax) { + _rawDefaultValue = rawDefaultValue; _defaultValueAvailable = true; } else { qWarning() << "Attempt to set default value which is outside min/max range"; } } -void FactMetaData::setMin(const QVariant& min) +void FactMetaData::setRawMin(const QVariant& rawMin) { - if (min > _minForType()) { - _min = min; + if (rawMin > _minForType()) { + _rawMin = rawMin; _minIsDefaultForType = false; } else { qWarning() << "Attempt to set min below allowable value for fact: " << name() - << ", value attempted: " << min + << ", value attempted: " << rawMin << ", type: " << type() << ", min for type: " << _minForType(); - _min = _minForType(); + _rawMin = _minForType(); } } -void FactMetaData::setMax(const QVariant& max) +void FactMetaData::setRawMax(const QVariant& rawMax) { - if (max > _maxForType()) { + if (rawMax > _maxForType()) { qWarning() << "Attempt to set max above allowable value"; - _max = _maxForType(); + _rawMax = _maxForType(); } else { - _max = max; + _rawMax = rawMax; _maxIsDefaultForType = false; } } @@ -189,7 +196,7 @@ QVariant FactMetaData::_maxForType(void) const return QVariant(); } -bool FactMetaData::convertAndValidate(const QVariant& value, bool convertOnly, QVariant& typedValue, QString& errorString) +bool FactMetaData::convertAndValidateRaw(const QVariant& rawValue, bool convertOnly, QVariant& typedValue, QString& errorString) { bool convertOk = false; @@ -199,10 +206,10 @@ bool FactMetaData::convertAndValidate(const QVariant& value, bool convertOnly, Q case FactMetaData::valueTypeInt8: case FactMetaData::valueTypeInt16: case FactMetaData::valueTypeInt32: - typedValue = QVariant(value.toInt(&convertOk)); + typedValue = QVariant(rawValue.toInt(&convertOk)); if (!convertOnly && convertOk) { - if (min() > typedValue || typedValue > max()) { - errorString = QString("Value must be within %1 and %2").arg(min().toInt()).arg(max().toInt()); + if (rawMin() > typedValue || typedValue > rawMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toInt()).arg(cookedMax().toInt()); } } break; @@ -210,28 +217,28 @@ bool FactMetaData::convertAndValidate(const QVariant& value, bool convertOnly, Q case FactMetaData::valueTypeUint8: case FactMetaData::valueTypeUint16: case FactMetaData::valueTypeUint32: - typedValue = QVariant(value.toUInt(&convertOk)); + typedValue = QVariant(rawValue.toUInt(&convertOk)); if (!convertOnly && convertOk) { - if (min() > typedValue || typedValue > max()) { - errorString = QString("Value must be within %1 and %2").arg(min().toUInt()).arg(max().toUInt()); + if (rawMin() > typedValue || typedValue > rawMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toUInt()).arg(cookedMax().toUInt()); } } break; case FactMetaData::valueTypeFloat: - typedValue = QVariant(value.toFloat(&convertOk)); + typedValue = QVariant(rawValue.toFloat(&convertOk)); if (!convertOnly && convertOk) { - if (min() > typedValue || typedValue > max()) { - errorString = QString("Value must be within %1 and %2").arg(min().toFloat()).arg(max().toFloat()); + if (rawMin() > typedValue || typedValue > rawMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toFloat()).arg(cookedMax().toFloat()); } } break; case FactMetaData::valueTypeDouble: - typedValue = QVariant(value.toDouble(&convertOk)); + typedValue = QVariant(rawValue.toDouble(&convertOk)); if (!convertOnly && convertOk) { - if (min() > typedValue || typedValue > max()) { - errorString = QString("Value must be within %1 and %2").arg(min().toDouble()).arg(max().toDouble()); + if (rawMin() > typedValue || typedValue > rawMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toDouble()).arg(cookedMax().toDouble()); } } break; @@ -244,6 +251,61 @@ bool FactMetaData::convertAndValidate(const QVariant& value, bool convertOnly, Q return convertOk && errorString.isEmpty(); } +bool FactMetaData::convertAndValidateCooked(const QVariant& cookedValue, bool convertOnly, QVariant& typedValue, QString& errorString) +{ + bool convertOk = false; + + errorString.clear(); + + switch (type()) { + case FactMetaData::valueTypeInt8: + case FactMetaData::valueTypeInt16: + case FactMetaData::valueTypeInt32: + typedValue = QVariant(cookedValue.toInt(&convertOk)); + if (!convertOnly && convertOk) { + if (cookedMin() > typedValue || typedValue > cookedMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toInt()).arg(cookedMax().toInt()); + } + } + break; + + case FactMetaData::valueTypeUint8: + case FactMetaData::valueTypeUint16: + case FactMetaData::valueTypeUint32: + typedValue = QVariant(cookedValue.toUInt(&convertOk)); + if (!convertOnly && convertOk) { + if (cookedMin() > typedValue || typedValue > cookedMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toUInt()).arg(cookedMax().toUInt()); + } + } + break; + + case FactMetaData::valueTypeFloat: + typedValue = QVariant(cookedValue.toFloat(&convertOk)); + if (!convertOnly && convertOk) { + if (cookedMin() > typedValue || typedValue > cookedMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toFloat()).arg(cookedMax().toFloat()); + } + } + break; + + case FactMetaData::valueTypeDouble: + typedValue = QVariant(cookedValue.toDouble(&convertOk)); + if (!convertOnly && convertOk) { + if (cookedMin() > typedValue || typedValue > cookedMax()) { + errorString = QString("Value must be within %1 and %2").arg(cookedMin().toDouble()).arg(cookedMax().toDouble()); + } + } + break; + } + + if (!convertOk) { + errorString += "Invalid number"; + } + + return convertOk && errorString.isEmpty(); +} + void FactMetaData::setEnumInfo(const QStringList& strings, const QVariantList& values) { if (strings.count() != values.count()) { @@ -253,6 +315,7 @@ void FactMetaData::setEnumInfo(const QStringList& strings, const QVariantList& v _enumStrings = strings; _enumValues = values; + _setBuiltInTranslator(); } void FactMetaData::setTranslators(Translator rawTranslator, Translator cookedTranslator) @@ -261,8 +324,54 @@ void FactMetaData::setTranslators(Translator rawTranslator, Translator cookedTra _cookedTranslator = cookedTranslator; } +void FactMetaData::_setBuiltInTranslator(void) +{ + if (_enumStrings.count()) { + // No translation if enum + setTranslators(_defaultTranslator, _defaultTranslator); + _cookedUnits = _rawUnits; + } else { + for (size_t i=0; irawUnits == _rawUnits.toLower()) { + _cookedUnits = pBuiltInTranslation->cookedUnits; + setTranslators(pBuiltInTranslation->rawTranslator, pBuiltInTranslation->cookedTranslator); + } + } + } +} + void FactMetaData::addEnumInfo(const QString& name, const QVariant& value) { _enumStrings << name; _enumValues << value; } + +QVariant FactMetaData::_degreesToRadians(const QVariant& degrees) +{ + return QVariant(degrees.toDouble() * (M_PI / 180.0)); +} + +QVariant FactMetaData::_radiansToDegrees(const QVariant& radians) +{ + return QVariant(radians.toDouble() * (180 / M_PI)); +} + +QVariant FactMetaData::_centiDegreesToDegrees(const QVariant& centiDegrees) +{ + return QVariant(centiDegrees.toFloat() / 100.0f); +} + +QVariant FactMetaData::_degreesToCentiDegrees(const QVariant& degrees) +{ + return QVariant((uint32_t)(degrees.toFloat() * 100.0f)); +} + +void FactMetaData::setRawUnits(const QString& rawUnits) +{ + _rawUnits = rawUnits; + _cookedUnits = rawUnits; + + _setBuiltInTranslator(); +} diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h index 1d2a711df..c61a94f24 100644 --- a/src/FactSystem/FactMetaData.h +++ b/src/FactSystem/FactMetaData.h @@ -61,20 +61,24 @@ public: const FactMetaData& operator=(const FactMetaData& other); int decimalPlaces (void) const { return _decimalPlaces; } - QVariant defaultValue (void) const; + QVariant rawDefaultValue (void) const; + QVariant cookedDefaultValue (void) const { return _rawTranslator(rawDefaultValue()); } bool defaultValueAvailable (void) const { return _defaultValueAvailable; } QStringList enumStrings (void) const { return _enumStrings; } QVariantList enumValues (void) const { return _enumValues; } QString group (void) const { return _group; } QString longDescription (void) const { return _longDescription;} - QVariant max (void) const { return _max; } + QVariant rawMax (void) const { return _rawMax; } + QVariant cookedMax (void) const { return _rawTranslator(_rawMax); } bool maxIsDefaultForType (void) const { return _maxIsDefaultForType; } - QVariant min (void) const { return _min; } + QVariant rawMin (void) const { return _rawMin; } + QVariant cookedMin (void) const { return _rawTranslator(_rawMin); } bool minIsDefaultForType (void) const { return _minIsDefaultForType; } QString name (void) const { return _name; } QString shortDescription (void) const { return _shortDescription; } ValueType_t type (void) const { return _type; } - QString units (void) const { return _units; } + QString rawUnits (void) const { return _rawUnits; } + QString cookedUnits (void) const { return _cookedUnits; } Translator rawTranslator (void) const { return _rawTranslator; } Translator cookedTranslator (void) const { return _cookedTranslator; } @@ -83,50 +87,71 @@ public: void addEnumInfo(const QString& name, const QVariant& value); void setDecimalPlaces (int decimalPlaces) { _decimalPlaces = decimalPlaces; } - void setDefaultValue (const QVariant& defaultValue); + void setRawDefaultValue (const QVariant& rawDefaultValue); void setEnumInfo (const QStringList& strings, const QVariantList& values); void setGroup (const QString& group) { _group = group; } void setLongDescription (const QString& longDescription) { _longDescription = longDescription;} - void setMax (const QVariant& max); - void setMin (const QVariant& max); + void setRawMax (const QVariant& rawMax); + void setRawMin (const QVariant& rawMin); void setName (const QString& name) { _name = name; } void setShortDescription(const QString& shortDescription) { _shortDescription = shortDescription; } - void setUnits (const QString& units) { _units = units; } + void setRawUnits (const QString& rawUnits); void setTranslators(Translator rawTranslator, Translator cookedTranslator); - static QVariant defaultTranslator(const QVariant& from) { return from; } - /// Converts the specified value, validating against meta data - /// @param value Value to convert, can be string + /// Converts the specified raw value, validating against meta data + /// @param rawValue Value to convert, can be string /// @param convertOnly true: convert to correct type only, do not validate against meta data /// @param typeValue Converted value, correctly typed - /// @param errorString Error string if convert fails + /// @param errorString Error string if convert fails, values are cooked values since user visible /// @returns false: Convert failed, errorString set - bool convertAndValidate(const QVariant& value, bool convertOnly, QVariant& typedValue, QString& errorString); + bool convertAndValidateRaw(const QVariant& rawValue, bool convertOnly, QVariant& typedValue, QString& errorString); + + /// Same as convertAndValidateRaw except for cookedValue input + bool convertAndValidateCooked(const QVariant& cookedValue, bool convertOnly, QVariant& typedValue, QString& errorString); static const int defaultDecimalPlaces = 3; private: QVariant _minForType(void) const; QVariant _maxForType(void) const; - + void _setBuiltInTranslator(void); + + // Built in translators + static QVariant _defaultTranslator(const QVariant& from) { return from; } + static QVariant _degreesToRadians(const QVariant& degrees); + static QVariant _radiansToDegrees(const QVariant& radians); + static QVariant _centiDegreesToDegrees(const QVariant& centiDegrees); + static QVariant _degreesToCentiDegrees(const QVariant& degrees); + ValueType_t _type; // must be first for correct constructor init int _decimalPlaces; - QVariant _defaultValue; + QVariant _rawDefaultValue; bool _defaultValueAvailable; QStringList _enumStrings; QVariantList _enumValues; QString _group; QString _longDescription; - QVariant _max; + QVariant _rawMax; bool _maxIsDefaultForType; - QVariant _min; + QVariant _rawMin; bool _minIsDefaultForType; QString _name; QString _shortDescription; - QString _units; + QString _rawUnits; + QString _cookedUnits; Translator _rawTranslator; Translator _cookedTranslator; + + struct BuiltInTranslation_s { + const char* rawUnits; + const char* cookedUnits; + Translator rawTranslator; + Translator cookedTranslator; + + }; + + static const BuiltInTranslation_s _rgBuildInTranslations[]; }; #endif diff --git a/src/FactSystem/ParameterLoader.cc b/src/FactSystem/ParameterLoader.cc index 90bf32559..e9be6b724 100644 --- a/src/FactSystem/ParameterLoader.cc +++ b/src/FactSystem/ParameterLoader.cc @@ -721,7 +721,7 @@ void ParameterLoader::writeParametersToStream(QTextStream &stream) Fact* fact = _mapParameterName2Variant[componentId][paramName].value(); Q_ASSERT(fact); - stream << _vehicle->id() << "\t" << componentId << "\t" << paramName << "\t" << fact->valueString() << "\t" << QString("%1").arg(_factTypeToMavType(fact->type())) << "\n"; + stream << _vehicle->id() << "\t" << componentId << "\t" << paramName << "\t" << fact->rawValueString() << "\t" << QString("%1").arg(_factTypeToMavType(fact->type())) << "\n"; } } diff --git a/src/FirmwarePlugin/APM/APMParameterMetaData.cc b/src/FirmwarePlugin/APM/APMParameterMetaData.cc index 4a629774f..17b5ad670 100644 --- a/src/FirmwarePlugin/APM/APMParameterMetaData.cc +++ b/src/FirmwarePlugin/APM/APMParameterMetaData.cc @@ -434,14 +434,14 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType) } if (!rawMetaData->units.isEmpty()) { - metaData->setUnits(rawMetaData->units); + metaData->setRawUnits(rawMetaData->units); } if (!rawMetaData->min.isEmpty()) { QVariant varMin; QString errorString; - if (metaData->convertAndValidate(rawMetaData->min, false /* validate as well */, varMin, errorString)) { - metaData->setMin(varMin); + if (metaData->convertAndValidateRaw(rawMetaData->min, false /* validate as well */, varMin, errorString)) { + metaData->setRawMin(varMin); } else { qCDebug(APMParameterMetaDataLog) << "Invalid min value, name:" << metaData->name() << " type:" << metaData->type() << " min:" << rawMetaData->min @@ -452,8 +452,8 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType) if (!rawMetaData->max.isEmpty()) { QVariant varMax; QString errorString; - if (metaData->convertAndValidate(rawMetaData->max, false /* validate as well */, varMax, errorString)) { - metaData->setMax(varMax); + if (metaData->convertAndValidateRaw(rawMetaData->max, false /* validate as well */, varMax, errorString)) { + metaData->setRawMax(varMax); } else { qCDebug(APMParameterMetaDataLog) << "Invalid max value, name:" << metaData->name() << " type:" << metaData->type() << " max:" << rawMetaData->max @@ -470,7 +470,7 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType) QString errorString; QPair enumPair = rawMetaData->values[i]; - if (metaData->convertAndValidate(enumPair.first, false /* validate */, enumValue, errorString)) { + if (metaData->convertAndValidateRaw(enumPair.first, false /* validate */, enumValue, errorString)) { enumValues << enumValue; enumStrings << enumPair.second; } else { diff --git a/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc b/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc index 8d5dd4bcf..d8357f34a 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc +++ b/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc @@ -239,8 +239,8 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void) if (xml.attributes().hasAttribute("default") && !strDefault.isEmpty()) { QVariant varDefault; - if (metaData->convertAndValidate(strDefault, false, varDefault, errorString)) { - metaData->setDefaultValue(varDefault); + if (metaData->convertAndValidateRaw(strDefault, false, varDefault, errorString)) { + metaData->setRawDefaultValue(varDefault); } else { qCWarning(PX4ParameterMetaDataLog) << "Invalid default value, name:" << name << " type:" << type << " default:" << strDefault << " error:" << errorString; } @@ -275,8 +275,8 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void) qCDebug(PX4ParameterMetaDataLog) << "Min:" << text; QVariant varMin; - if (metaData->convertAndValidate(text, true /* convertOnly */, varMin, errorString)) { - metaData->setMin(varMin); + if (metaData->convertAndValidateRaw(text, true /* convertOnly */, varMin, errorString)) { + metaData->setRawMin(varMin); } else { qCWarning(PX4ParameterMetaDataLog) << "Invalid min value, name:" << metaData->name() << " type:" << metaData->type() << " min:" << text << " error:" << errorString; } @@ -287,8 +287,8 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void) qCDebug(PX4ParameterMetaDataLog) << "Max:" << text; QVariant varMax; - if (metaData->convertAndValidate(text, true /* convertOnly */, varMax, errorString)) { - metaData->setMax(varMax); + if (metaData->convertAndValidateRaw(text, true /* convertOnly */, varMax, errorString)) { + metaData->setRawMax(varMax); } else { qCWarning(PX4ParameterMetaDataLog) << "Invalid max value, name:" << metaData->name() << " type:" << metaData->type() << " max:" << text << " error:" << errorString; } @@ -297,7 +297,7 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void) Q_ASSERT(metaData); QString text = xml.readElementText(); qCDebug(PX4ParameterMetaDataLog) << "Unit:" << text; - metaData->setUnits(text); + metaData->setRawUnits(text); } else if (elementName == "decimal") { Q_ASSERT(metaData); @@ -325,8 +325,8 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void) if (metaData->defaultValueAvailable()) { QVariant var; - if (!metaData->convertAndValidate(metaData->defaultValue(), false /* convertOnly */, var, errorString)) { - qCWarning(PX4ParameterMetaDataLog) << "Invalid default value, name:" << metaData->name() << " type:" << metaData->type() << " default:" << metaData->defaultValue() << " error:" << errorString; + if (!metaData->convertAndValidateRaw(metaData->rawDefaultValue(), false /* convertOnly */, var, errorString)) { + qCWarning(PX4ParameterMetaDataLog) << "Invalid default value, name:" << metaData->name() << " type:" << metaData->type() << " default:" << metaData->rawDefaultValue() << " error:" << errorString; } } diff --git a/src/MissionManager/MavCmdInfo.json b/src/MissionManager/MavCmdInfo.json index ca24d058e..8110e0917 100644 --- a/src/MissionManager/MavCmdInfo.json +++ b/src/MissionManager/MavCmdInfo.json @@ -113,7 +113,7 @@ }, "param4": { "label": "Heading:", - "units": "degreesConvert", + "units": "radians", "default": 0.0, "decimalPlaces": 2 } @@ -128,13 +128,13 @@ "category": "Basic", "param1": { "label": "Pitch:", - "units": "degreesConvert", + "units": "radians", "default": 0.26179939, "decimalPlaces": 2 }, "param4": { "label": "Heading:", - "units": "degreesConvert", + "units": "radians", "default": 0.0, "decimalPlaces": 2 } diff --git a/src/MissionManager/MissionCommands.cc b/src/MissionManager/MissionCommands.cc index e9ced88ef..9ee58e5b8 100644 --- a/src/MissionManager/MissionCommands.cc +++ b/src/MissionManager/MissionCommands.cc @@ -58,9 +58,6 @@ const QString MissionCommands::_specifiesCoordinateJsonKey (QStringLiteral("spe const QString MissionCommands::_unitsJsonKey (QStringLiteral("units")); const QString MissionCommands::_versionJsonKey (QStringLiteral("version")); -const QString MissionCommands::_degreesConvertUnits (QStringLiteral("degreesConvert")); -const QString MissionCommands::_degreesUnits (QStringLiteral("degrees")); - MissionCommands::MissionCommands(QGCApplication* app) : QGCTool(app) { diff --git a/src/MissionManager/MissionCommands.h b/src/MissionManager/MissionCommands.h index 200b3e584..e9fedb736 100644 --- a/src/MissionManager/MissionCommands.h +++ b/src/MissionManager/MissionCommands.h @@ -139,9 +139,6 @@ public: // Overrides from QGCTool virtual void setToolbox(QGCToolbox* toolbox); - static const QString _degreesUnits; - static const QString _degreesConvertUnits; - signals: private: diff --git a/src/MissionManager/MissionItem.cc b/src/MissionManager/MissionItem.cc index 2cd3c699e..edf84c27f 100644 --- a/src/MissionManager/MissionItem.cc +++ b/src/MissionManager/MissionItem.cc @@ -309,7 +309,7 @@ void MissionItem::_setupMetaData(void) if (!_altitudeMetaData) { _altitudeMetaData = new FactMetaData(FactMetaData::valueTypeDouble); - _altitudeMetaData->setUnits("meters"); + _altitudeMetaData->setRawUnits("meters"); _altitudeMetaData->setDecimalPlaces(3); enumStrings.clear(); @@ -336,11 +336,11 @@ void MissionItem::_setupMetaData(void) _frameMetaData->setEnumInfo(enumStrings, enumValues); _latitudeMetaData = new FactMetaData(FactMetaData::valueTypeDouble); - _latitudeMetaData->setUnits("deg"); + _latitudeMetaData->setRawUnits("deg"); _latitudeMetaData->setDecimalPlaces(7); _longitudeMetaData = new FactMetaData(FactMetaData::valueTypeDouble); - _longitudeMetaData->setUnits("deg"); + _longitudeMetaData->setRawUnits("deg"); _longitudeMetaData->setDecimalPlaces(7); } @@ -516,18 +516,14 @@ QString MissionItem::commandDescription(void) const void MissionItem::_clearParamMetaData(void) { - _param1MetaData.setUnits(""); + _param1MetaData.setRawUnits(""); _param1MetaData.setDecimalPlaces(FactMetaData::defaultDecimalPlaces); - _param1MetaData.setTranslators(FactMetaData::defaultTranslator, FactMetaData::defaultTranslator); - _param2MetaData.setUnits(""); + _param2MetaData.setRawUnits(""); _param2MetaData.setDecimalPlaces(FactMetaData::defaultDecimalPlaces); - _param2MetaData.setTranslators(FactMetaData::defaultTranslator, FactMetaData::defaultTranslator); - _param3MetaData.setUnits(""); + _param3MetaData.setRawUnits(""); _param3MetaData.setDecimalPlaces(FactMetaData::defaultDecimalPlaces); - _param3MetaData.setTranslators(FactMetaData::defaultTranslator, FactMetaData::defaultTranslator); - _param4MetaData.setUnits(""); + _param4MetaData.setRawUnits(""); _param4MetaData.setDecimalPlaces(FactMetaData::defaultDecimalPlaces); - _param4MetaData.setTranslators(FactMetaData::defaultTranslator, FactMetaData::defaultTranslator); } QmlObjectListModel* MissionItem::textFieldFacts(void) @@ -575,12 +571,7 @@ QmlObjectListModel* MissionItem::textFieldFacts(void) paramFact->_setName(paramInfo->label()); paramMetaData->setDecimalPlaces(paramInfo->decimalPlaces()); paramMetaData->setEnumInfo(paramInfo->enumStrings(), paramInfo->enumValues()); - if (paramInfo->units() == MissionCommands::_degreesConvertUnits) { - paramMetaData->setTranslators(_radiansToDegrees, _degreesToRadians); - paramMetaData->setUnits(MissionCommands::_degreesUnits); - } else { - paramMetaData->setUnits(paramInfo->units()); - } + paramMetaData->setRawUnits(paramInfo->units()); paramFact->setMetaData(paramMetaData); model->append(paramFact); } @@ -634,12 +625,7 @@ QmlObjectListModel* MissionItem::comboboxFacts(void) paramFact->_setName(paramInfo->label()); paramMetaData->setDecimalPlaces(paramInfo->decimalPlaces()); paramMetaData->setEnumInfo(paramInfo->enumStrings(), paramInfo->enumValues()); - if (paramInfo->units() == MissionCommands::_degreesConvertUnits) { - paramMetaData->setTranslators(_radiansToDegrees, _degreesToRadians); - paramMetaData->setUnits(MissionCommands::_degreesUnits); - } else { - paramMetaData->setUnits(paramInfo->units()); - } + paramMetaData->setRawUnits(paramInfo->units()); paramFact->setMetaData(paramMetaData); model->append(paramFact); } @@ -804,16 +790,6 @@ QString MissionItem::commandName(void) const } } -QVariant MissionItem::_degreesToRadians(const QVariant& degrees) -{ - return QVariant(degrees.toDouble() * (M_PI / 180.0)); -} - -QVariant MissionItem::_radiansToDegrees(const QVariant& radians) -{ - return QVariant(radians.toDouble() * (180 / M_PI)); -} - void MissionItem::_sendFriendlyEditAllowedChanged(void) { emit friendlyEditAllowedChanged(friendlyEditAllowed()); diff --git a/src/MissionManager/MissionItem.h b/src/MissionManager/MissionItem.h index 31446d8cd..e9c7fc2aa 100644 --- a/src/MissionManager/MissionItem.h +++ b/src/MissionManager/MissionItem.h @@ -211,9 +211,6 @@ private: void _connectSignals(void); void _setupMetaData(void); - static QVariant _degreesToRadians(const QVariant& degrees); - static QVariant _radiansToDegrees(const QVariant& radians); - private: bool _rawEdit; bool _dirty; -- 2.22.0