UASParameterDataModel.cc 9.78 KB
Newer Older
1 2
#include "UASParameterDataModel.h"

3 4
#include <float.h>

5
#include <QDebug>
6
#include <QStringList>
7 8
#include <QVariant>

9 10
#include "QGCMAVLink.h"

11 12 13 14 15
UASParameterDataModel::UASParameterDataModel(QObject *parent) :
    QObject(parent)
{


16
}
17

18 19 20


bool UASParameterDataModel::checkParameterChanged(int componentId, const QString& key,  const QVariant &value)
21
{
22
    bool changed = true;
23
    addComponent(componentId);
24 25 26 27 28 29 30 31 32 33 34 35
    QMap<QString, QVariant>* existParams = getOnbardParametersForComponent(componentId);

    if (existParams->contains(key)) {
        QVariant existValue = existParams->value(key);
        QMap<QString, QVariant>* pendParams = getPendingParametersForComponent(componentId);
        if (pendParams->contains(key)) {
            QVariant pendValue = pendParams->value(key);
            if (existValue == pendValue) {
                changed = false;
            }
        }
    }
36

37 38 39 40 41 42 43 44 45 46
    return changed;

}

bool UASParameterDataModel::addPendingIfParameterChanged(int componentId, QString& key,  QVariant &value)

{
    bool changed = checkParameterChanged(componentId,key,value);

    if (changed ) {
47 48
        setPendingParameter(componentId,key,value);
    }
49 50

    return changed;
51
}
52 53


54
void UASParameterDataModel::setPendingParameter(int componentId, QString& key,  const QVariant &value)
55 56 57 58 59
{
    //ensure we have a placeholder map for this component
    addComponent(componentId);
    QMap<QString, QVariant> *params = getPendingParametersForComponent(componentId);
    params->insert(key,value);
60 61
}

62
void UASParameterDataModel::setOnboardParameter(int componentId, QString& key,  const QVariant& value)
63 64 65 66 67 68
{
    //ensure we have a placeholder map for this component
    addComponent(componentId);
    QMap<QString, QVariant> *params = getOnbardParametersForComponent(componentId);
    params->insert(key,value);
}
69

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
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;
    }
}

106
void UASParameterDataModel::addComponent(int componentId)
107
{
108 109 110 111 112
    if (!onboardParameters.contains(componentId)) {
        onboardParameters.insert(componentId, new QMap<QString, QVariant>());
    }
    if (!pendingParameters.contains(componentId)) {
        pendingParameters.insert(componentId, new QMap<QString, QVariant>());
113 114
    }
}
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135


void UASParameterDataModel::handleParameterUpdate(int componentId, QString& key, QVariant& value)
{
    //verify that the value requested by the user matches the set value
    //if it doesn't match, leave the pending parameter in the pending list!
    if (pendingParameters.contains(componentId)) {
        QMap<QString , QVariant> *pendingParams = pendingParameters.value(componentId);
        if ((NULL != pendingParams) && pendingParams->contains(key)) {
            QVariant reqVal = pendingParams->value(key);
            if (reqVal == value) {
                pendingParams->remove(key);
            }
            else {
                qDebug() << "Pending commit for " << key << " want: " << reqVal << " got: " << value;
            }
        }
    }

    setOnboardParameter(componentId,key, value);
}
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274

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 <READ> 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<float>(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<int, QMap<QString, QVariant>*>::iterator i;
    for (i = onboardParameters.begin(); i != onboardParameters.end(); ++i) {
        // Iterate through the parameters of the component
        int compid = i.key();
        QMap<QString, QVariant>* comp = i.value();
        {
            QMap<QString, QVariant>::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();
            }
        }
    }
}