From 59a2cbbc858692ccb1369183300d1d43a2cdec91 Mon Sep 17 00:00:00 2001 From: tstellanova Date: Tue, 6 Aug 2013 07:43:45 -0700 Subject: [PATCH] Move more model code into the model class --- src/uas/UASParameterDataModel.cc | 218 +++++++++++++++++++++++++++++-- src/uas/UASParameterDataModel.h | 31 ++++- 2 files changed, 236 insertions(+), 13 deletions(-) diff --git a/src/uas/UASParameterDataModel.cc b/src/uas/UASParameterDataModel.cc index dbf461060..3269efd18 100644 --- a/src/uas/UASParameterDataModel.cc +++ b/src/uas/UASParameterDataModel.cc @@ -1,8 +1,13 @@ #include "UASParameterDataModel.h" +#include + #include +#include #include +#include "QGCMAVLink.h" + UASParameterDataModel::UASParameterDataModel(QObject *parent) : QObject(parent) { @@ -10,21 +15,43 @@ UASParameterDataModel::UASParameterDataModel(QObject *parent) : } -void UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + + +bool UASParameterDataModel::checkParameterChanged(int componentId, const QString& key, const QVariant &value) { + bool changed = true; addComponent(componentId); - QMap *existParams = getOnbardParametersForComponent(componentId); - QMap *pendParams = getPendingParametersForComponent(componentId); + QMap* existParams = getOnbardParametersForComponent(componentId); + + if (existParams->contains(key)) { + QVariant existValue = existParams->value(key); + QMap* pendParams = getPendingParametersForComponent(componentId); + if (pendParams->contains(key)) { + QVariant pendValue = pendParams->value(key); + if (existValue == pendValue) { + changed = false; + } + } + } - QVariant existValue = existParams->value(key); - QVariant pendValue = pendParams->value(key); - if (!(existValue == pendValue)) { + return changed; + +} + +bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key, QVariant &value) + +{ + bool changed = checkParameterChanged(componentId,key,value); + + if (changed ) { setPendingParameter(componentId,key,value); } + + return changed; } -void UASParameterDataModel::setPendingParameter(int componentId, QString& key, QVariant &value) +void UASParameterDataModel::setPendingParameter(int componentId, QString& key, const QVariant &value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -32,7 +59,7 @@ void UASParameterDataModel::setPendingParameter(int componentId, QString& key, params->insert(key,value); } -void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, QVariant& value) +void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, const QVariant& value) { //ensure we have a placeholder map for this component addComponent(componentId); @@ -40,6 +67,42 @@ void UASParameterDataModel::setOnboardParameter(int componentId, QString& key, params->insert(key,value); } +void UASParameterDataModel::setOnboardParameterWithType(int componentId, QString& key, QVariant& value) +{ + +// switch ((int)onboardParameters.value(componentId)->value(key).type()) + switch ((int)value.type()) + { + case QVariant::Int: + { + QVariant fixedValue(value.toInt()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QVariant::UInt: + { + QVariant fixedValue(value.toUInt()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QMetaType::Float: + { + QVariant fixedValue(value.toFloat()); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + case QMetaType::QChar: + { + QVariant fixedValue(QChar((unsigned char)value.toUInt())); + onboardParameters.value(componentId)->insert(key, fixedValue); + } + break; + default: + qCritical() << "ABORTED PARAM UPDATE, NO VALID QVARIANT TYPE"; + return; + } +} + void UASParameterDataModel::addComponent(int componentId) { if (!onboardParameters.contains(componentId)) { @@ -70,3 +133,142 @@ void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, setOnboardParameter(componentId,key, value); } + +bool UASParameterDataModel::getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const +{ + + if (onboardParameters.contains(componentId)) { + if (onboardParameters.value(componentId)->contains(key)) { + value = onboardParameters.value(componentId)->value(key); + return true; + } + } + + return false; +} + +void UASParameterDataModel::forgetAllOnboardParameters() +{ + onboardParameters.clear(); +} + +void UASParameterDataModel::readUpdateParametersFromStream(QTextStream& stream) +{ + + bool userWarned = false; + + while (!stream.atEnd()) { + QString line = stream.readLine(); + if (!line.startsWith("#")) { + QStringList wpParams = line.split("\t"); + int lineMavId = wpParams.at(0).toInt(); + if (wpParams.size() == 5) { + // Only load parameters for right mav + if (!userWarned && (uasId != lineMavId)) { + //TODO warn the user somehow + QString msg = tr("The parameters in the stream have been saved from system %1, but the currently selected system has the ID %2.").arg(lineMavId).arg(uasId); +// MainWindow::instance()->showCriticalMessage( +// tr("Parameter loading warning"), +// tr("The parameters from the file %1 have been saved from system %2, but the currently selected system has the ID %3. If this is unintentional, please click on to revert to the parameters that are currently onboard").arg(fileName).arg(wpParams.at(0).toInt()).arg(mav->getUASID())); + userWarned = true; + return; + } + + bool changed = false; + int componentId = wpParams.at(1).toInt(); + QString key = wpParams.at(2); + QString valStr = wpParams.at(3); + double dblVal = wpParams.at(3).toDouble(); + uint paramType = wpParams.at(4).toUInt(); + + + if (!onboardParameters.contains(componentId)) { + addComponent(componentId); + changed = true; + } + else { + if (fabs((static_cast(onboardParameters.value(componentId)->value(key, dblVal).toDouble())) - (dblVal)) > + 2.0f * FLT_EPSILON) { + changed = true; + qDebug() << "Changed" << key << "VAL" << dblVal; + } + } + + + if (changed) { + switch (paramType) + { + case MAV_PARAM_TYPE_REAL32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toFloat()); + setPendingParameter(componentId,key,QVariant(valStr.toFloat())); + //setParameter(componentId, key, valStr.toFloat()); + break; + case MAV_PARAM_TYPE_UINT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toUInt()); + setPendingParameter(componentId,key, QVariant(valStr.toUInt())); + //setParameter(componentId, key, QVariant(valStr.toUInt())); + break; + case MAV_PARAM_TYPE_INT32: + //receivedParameterUpdate(wpParams.at(0).toInt(), componentId, key, valStr.toInt()); + setPendingParameter(componentId,key,QVariant(valStr.toInt())); + //setParameter(componentId, key, QVariant(valStr.toInt())); + break; + default: + qDebug() << "FAILED LOADING PARAM" << key << "UNKNOWN DATA TYPE"; + } + + //TODO update display + + } + + + } + } + } + +} + +void UASParameterDataModel::writeOnboardParametersToStream(QTextStream& stream, const QString& name) +{ + stream << "# Onboard parameters for system " << name << "\n"; + stream << "#\n"; + stream << "# MAV ID COMPONENT ID PARAM NAME VALUE (FLOAT)\n"; + + // Iterate through all components, through all parameters and emit them + QMap*>::iterator i; + for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) { + // Iterate through the parameters of the component + int compid = i.key(); + QMap* comp = i.value(); + { + QMap::iterator j; + for (j = comp->begin(); j != comp->end(); ++j) + { + QString paramValue("%1"); + QString paramType("%1"); + switch ((int)j.value().type()) + { + case QVariant::Int: + paramValue = paramValue.arg(j.value().toInt()); + paramType = paramType.arg(MAV_PARAM_TYPE_INT32); + break; + case QVariant::UInt: + paramValue = paramValue.arg(j.value().toUInt()); + paramType = paramType.arg(MAV_PARAM_TYPE_UINT32); + break; + case QMetaType::Float: + // We store parameters as floats, with only 6 digits of precision guaranteed for decimal string conversion + // (see IEEE 754, 32 bit single-precision) + paramValue = paramValue.arg((double)j.value().toFloat(), 25, 'g', 6); + paramType = paramType.arg(MAV_PARAM_TYPE_REAL32); + break; + default: + qCritical() << "ABORTED PARAM WRITE TO FILE, NO VALID QVARIANT TYPE" << j.value(); + return; + } + stream << this->uasId << "\t" << compid << "\t" << j.key() << "\t" << paramValue << "\t" << paramType << "\n"; + stream.flush(); + } + } + } +} diff --git a/src/uas/UASParameterDataModel.h b/src/uas/UASParameterDataModel.h index b3e56b7a7..e38e06c8c 100644 --- a/src/uas/UASParameterDataModel.h +++ b/src/uas/UASParameterDataModel.h @@ -5,6 +5,8 @@ #include #include +class QTextStream; + class UASParameterDataModel : public QObject { Q_OBJECT @@ -15,14 +17,30 @@ public: virtual void addComponent(int componentId); /** @brief Write a new pending parameter value that may be eventually sent to the UAS */ - virtual void setPendingParameter(int componentId, QString& paramKey, QVariant& paramValue); - virtual void setOnboardParameter(int componentId, QString& key, QVariant &value); + virtual void setPendingParameter(int componentId, QString& key, const QVariant& value); + virtual void setOnboardParameter(int componentId, QString& key, const QVariant& value); + + /** @brief Save the onboard parameter with a the type specified in the QVariant as fixed */ + virtual void setOnboardParameterWithType(int componentId, QString& key, QVariant& value); + + /** @brief clears every parameter for every loaded component */ + virtual void forgetAllOnboardParameters(); + + /** + * @return true if the parameter has changed + */ + virtual bool checkParameterChanged(int componentId, const QString& key, const QVariant &value); - /** @brief add this parameter to pending list iff it has changed from onboard value */ - virtual void addPendingIfParameterChanged(int componentId, QString& key, QVariant &value); + /** @brief add this parameter to pending list iff it has changed from onboard value + * @return true if the parameter has changed + */ + virtual bool addPendingIfParameterChanged(int componentId, QString& key, QVariant& value); - void handleParameterUpdate(int componentId, QString& key, QVariant& value); + + virtual void handleParameterUpdate(int componentId, QString& key, QVariant& value); + + virtual bool getOnboardParameterValue(int componentId, const QString& key, QVariant& value) const; QMap* getPendingParametersForComponent(int componentId) { return pendingParameters.value(componentId); @@ -41,6 +59,9 @@ public: } + virtual void writeOnboardParametersToStream(QTextStream& stream, const QString& uasName); + virtual void readUpdateParametersFromStream(QTextStream& stream); + void setUASID(int anId) { this->uasId = anId; } signals: -- 2.22.0