Fact.cc 11.4 KB
Newer Older
Don Gagne's avatar
Don Gagne committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*=====================================================================
 
 QGroundControl Open Source Ground Control Station
 
 (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 
 This file is part of the QGROUNDCONTROL project
 
 QGROUNDCONTROL is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 QGROUNDCONTROL is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
 
 ======================================================================*/

/// @file
///     @author Don Gagne <don@thegagnes.com>

#include "Fact.h"
Don Gagne's avatar
Don Gagne committed
28
#include "QGCMAVLink.h"
Don Gagne's avatar
Don Gagne committed
29 30 31

#include <QtQml>

Don Gagne's avatar
Don Gagne committed
32 33 34
Fact::Fact(QObject* parent)
    : QObject(parent)
    , _componentId(-1)
35
    , _rawValue(0)
Don Gagne's avatar
Don Gagne committed
36 37
    , _type(FactMetaData::valueTypeInt32)
    , _metaData(NULL)
Don Gagne's avatar
Don Gagne committed
38 39 40 41 42
{    
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
}

Don Gagne's avatar
Don Gagne committed
43 44 45 46
Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent)
    : QObject(parent)
    , _name(name)
    , _componentId(componentId)
47
    , _rawValue(0)
Don Gagne's avatar
Don Gagne committed
48 49
    , _type(type)
    , _metaData(NULL)
Don Gagne's avatar
Don Gagne committed
50
{
Don Gagne's avatar
Don Gagne committed
51 52 53
    FactMetaData* metaData = new FactMetaData(_type, this);
    setMetaData(metaData);
}
Don Gagne's avatar
Don Gagne committed
54

Don Gagne's avatar
Don Gagne committed
55 56 57 58 59 60 61 62 63 64
Fact::Fact(const Fact& other, QObject* parent)
    : QObject(parent)
{
    *this = other;
}

const Fact& Fact::operator=(const Fact& other)
{
    _name           = other._name;
    _componentId    = other._componentId;
65
    _rawValue          = other._rawValue;
Don Gagne's avatar
Don Gagne committed
66 67 68 69 70 71 72 73 74
    _type           = other._type;
    
    if (_metaData && other._metaData) {
        *_metaData = *other._metaData;
    } else {
        _metaData = NULL;
    }
    
    return *this;
Don Gagne's avatar
Don Gagne committed
75 76
}

Don Gagne's avatar
Don Gagne committed
77
void Fact::forceSetRawValue(const QVariant& value)
78 79 80 81 82 83
{
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
        if (_metaData->convertAndValidate(value, true /* convertOnly */, typedValue, errorString)) {
Don Gagne's avatar
Don Gagne committed
84 85 86
            _rawValue.setValue(typedValue);
            emit valueChanged(cookedValue());
            emit _containerRawValueChanged(rawValue());
87 88 89 90 91 92
        }
    } else {
        qWarning() << "Meta data pointer missing";
    }
}

93
void Fact::setRawValue(const QVariant& value)
Don Gagne's avatar
Don Gagne committed
94
{
Don Gagne's avatar
Don Gagne committed
95 96 97 98 99
    if (_metaData) {
        QVariant    typedValue;
        QString     errorString;
        
        if (_metaData->convertAndValidate(value, true /* convertOnly */, typedValue, errorString)) {
100 101
            if (typedValue != _rawValue) {
                _rawValue.setValue(typedValue);
Don Gagne's avatar
Don Gagne committed
102 103
                emit valueChanged(cookedValue());
                emit _containerRawValueChanged(rawValue());
Don Gagne's avatar
Don Gagne committed
104 105 106 107
            }
        }
    } else {
        qWarning() << "Meta data pointer missing";
108
    }
Don Gagne's avatar
Don Gagne committed
109 110
}

Don Gagne's avatar
Don Gagne committed
111
void Fact::setCookedValue(const QVariant& value)
112 113 114 115 116 117 118 119 120 121 122 123 124
{
    if (_metaData) {
        setRawValue(_metaData->cookedTranslator()(value));
    } else {
        qWarning() << "Meta data pointer missing";
    }
}

void Fact::setEnumStringValue(const QString& value)
{
    if (_metaData) {
        int index = _metaData->enumStrings().indexOf(value);
        if (index != -1) {
Don Gagne's avatar
Don Gagne committed
125
            setCookedValue(_metaData->enumValues()[index]);
126 127 128 129 130 131 132 133 134
        }
    } else {
        qWarning() << "Meta data pointer missing";
    }
}

void Fact::setEnumIndex(int index)
{
    if (_metaData) {
Don Gagne's avatar
Don Gagne committed
135
        setCookedValue(_metaData->enumValues()[index]);
136 137 138 139 140
    } else {
        qWarning() << "Meta data pointer missing";
    }
}

Don Gagne's avatar
Don Gagne committed
141
void Fact::_containerSetRawValue(const QVariant& value)
Don Gagne's avatar
Don Gagne committed
142
{
143
    _rawValue = value;
Don Gagne's avatar
Don Gagne committed
144
    emit valueChanged(cookedValue());
145
    emit vehicleUpdated(_rawValue);
Don Gagne's avatar
Don Gagne committed
146
}
147 148 149 150 151 152

QString Fact::name(void) const
{
    return _name;
}

153 154 155 156 157
int Fact::componentId(void) const
{
    return _componentId;
}

Don Gagne's avatar
Don Gagne committed
158
QVariant Fact::cookedValue(void) const
159
{
160 161 162 163 164 165 166 167 168 169 170 171
    if (_metaData) {
        return _metaData->rawTranslator()(_rawValue);
    } else {
        qWarning() << "Meta data pointer missing";
        return _rawValue;
    }
}

QString Fact::enumStringValue(void) const
{
    if (_metaData) {
        int enumIndex = this->enumIndex();
Don Gagne's avatar
Don Gagne committed
172
        if (enumIndex >= 0 && enumIndex < _metaData->enumStrings().count()) {
173 174 175 176 177 178 179 180 181 182 183 184 185 186
            return _metaData->enumStrings()[enumIndex];
        }
    } else {
        qWarning() << "Meta data pointer missing";
    }

    return QString();
}

int Fact::enumIndex(void) const
{
    if (_metaData) {
        int index = 0;
        foreach (QVariant enumValue, _metaData->enumValues()) {
Don Gagne's avatar
Don Gagne committed
187
            if (enumValue == rawValue()) {
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
                return index;
            }
            index ++;
        }
    } else {
        qWarning() << "Meta data pointer missing";
    }

    return -1;
}

QStringList Fact::enumStrings(void) const
{
    if (_metaData) {
        return _metaData->enumStrings();
    } else {
        qWarning() << "Meta data pointer missing";
        return QStringList();
    }
}

QVariantList Fact::enumValues(void) const
{
    if (_metaData) {
        return _metaData->enumValues();
    } else {
        qWarning() << "Meta data pointer missing";
        return QVariantList();
    }
217 218
}

219
QString Fact::_variantToString(const QVariant& variant) const
220
{
221 222 223 224
    QString valueString;

    switch (type()) {
        case FactMetaData::valueTypeFloat:
225
            valueString = QString("%1").arg(variant.toFloat(), 0, 'f', decimalPlaces());
226 227
            break;
        case FactMetaData::valueTypeDouble:
228
            valueString = QString("%1").arg(variant.toDouble(), 0, 'f', decimalPlaces());
229 230
            break;
        default:
231
            valueString = variant.toString();
232 233 234 235
            break;
    }

    return valueString;
236 237
}

238 239
QString Fact::valueString(void) const
{
Don Gagne's avatar
Don Gagne committed
240
    return _variantToString(cookedValue());
241 242
}

243
QVariant Fact::defaultValue(void) const
244
{
Don Gagne's avatar
Don Gagne committed
245 246 247 248 249 250 251 252
    if (_metaData) {
        if (!_metaData->defaultValueAvailable()) {
            qDebug() << "Access to unavailable default value";
        }
        return _metaData->defaultValue();
    } else {
        qWarning() << "Meta data pointer missing";
        return QVariant(0);
253
    }
254 255
}

256 257 258 259 260
QString Fact::defaultValueString(void) const
{
    return _variantToString(defaultValue());
}

261
FactMetaData::ValueType_t Fact::type(void) const
262
{
263
    return _type;
264 265
}

266
QString Fact::shortDescription(void) const
267
{
Don Gagne's avatar
Don Gagne committed
268 269 270 271 272 273
    if (_metaData) {
        return _metaData->shortDescription();
    } else {
        qWarning() << "Meta data pointer missing";
        return QString();
    }
274 275
}

276
QString Fact::longDescription(void) const
277
{
Don Gagne's avatar
Don Gagne committed
278 279 280 281 282 283
    if (_metaData) {
        return _metaData->longDescription();
    } else {
        qWarning() << "Meta data pointer missing";
        return QString();
    }
284 285
}

286
QString Fact::units(void) const
287
{
Don Gagne's avatar
Don Gagne committed
288 289 290 291 292 293
    if (_metaData) {
        return _metaData->units();
    } else {
        qWarning() << "Meta data pointer missing";
        return QString();
    }
294 295
}

296
QVariant Fact::min(void) const
297
{
Don Gagne's avatar
Don Gagne committed
298 299 300 301 302 303
    if (_metaData) {
        return _metaData->min();
    } else {
        qWarning() << "Meta data pointer missing";
        return QVariant(0);
    }
304 305
}

306 307 308 309 310
QString Fact::minString(void) const
{
    return _variantToString(min());
}

311
QVariant Fact::max(void) const
312
{
Don Gagne's avatar
Don Gagne committed
313 314 315 316 317 318 319 320
    if (_metaData) {
        return _metaData->max();
    } else {
        qWarning() << "Meta data pointer missing";
        return QVariant(0);
    }
}

321 322 323 324 325
QString Fact::maxString(void) const
{
    return _variantToString(max());
}

326
bool Fact::minIsDefaultForType(void) const
Don Gagne's avatar
Don Gagne committed
327 328 329 330 331 332 333 334 335
{
    if (_metaData) {
        return _metaData->minIsDefaultForType();
    } else {
        qWarning() << "Meta data pointer missing";
        return false;
    }
}

336
bool Fact::maxIsDefaultForType(void) const
Don Gagne's avatar
Don Gagne committed
337 338 339 340 341 342 343
{
    if (_metaData) {
        return _metaData->maxIsDefaultForType();
    } else {
        qWarning() << "Meta data pointer missing";
        return false;
    }
344 345
}

346 347 348 349 350 351 352 353 354 355
int Fact::decimalPlaces(void) const
{
    if (_metaData) {
        return _metaData->decimalPlaces();
    } else {
        qWarning() << "Meta data pointer missing";
        return FactMetaData::defaultDecimalPlaces;
    }
}

356
QString Fact::group(void) const
357
{
Don Gagne's avatar
Don Gagne committed
358 359 360 361 362 363
    if (_metaData) {
        return _metaData->group();
    } else {
        qWarning() << "Meta data pointer missing";
        return QString();
    }
364 365
}

366 367
void Fact::setMetaData(FactMetaData* metaData)
{
Don Gagne's avatar
Don Gagne committed
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
    static QStringList  apmFlightModeParamList;
    static QStringList  apmFlightModeEnumStrings;
    static QVariantList apmFlightModeEnumValues;

    static QStringList  apmChannelOptParamList;
    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"
                                 << "Land" << "Drift" << "Sport" << "Flip" << "AutoTune" << "PosHold" << "Brake";
        for (int i=0; i<apmFlightModeEnumStrings.count(); i++) {
            apmFlightModeEnumValues << QVariant(i);
        }

        apmChannelOptParamList << "CH7_OPT" << "CH8_OPT" << "CH9_OPT" << "CH10_OPT" << "CH11_OPT" << "CH12_OPT";
        apmChannelOptEnumStrings << "Do Nothing" << "Flip" << "Simple Mode" << "RTL" << "Save Trim" << "Save WP" << "Camera Trigger" << "RangeFinder"
                                 << "Fence" << "ResetToArmedYaw" << "Super Simple Mode" << "Acro Trainer" << "Auto" << "AutoTune" << "Land" << "EPM"
                                 << "Parachute Enable" << "Parachute Release" << "Parachute 3pos" << "Auto Mission Reset" << "AttCon Feed Forward"
                                 << "AttCon Accel Limits" << "Retract Mount" << "Relay On/Off" << "Landing Gear" << "Lost Copter Sound"
                                 << "Motor Emergency Stop" << "Motor Interlock" << "Brake";
        for (int i=0; i<apmChannelOptEnumStrings.count(); i++) {
            apmChannelOptEnumValues << QVariant(i);
        }
    }

    if (apmFlightModeParamList.contains(name())) {
        metaData->setEnumInfo(apmFlightModeEnumStrings, apmFlightModeEnumValues);
    } else if (apmChannelOptParamList.contains(name())) {
        metaData->setEnumInfo(apmChannelOptEnumStrings, apmChannelOptEnumValues);
    }

403
    _metaData = metaData;
Don Gagne's avatar
Don Gagne committed
404
    emit valueChanged(cookedValue());
405
}
406

407
bool Fact::valueEqualsDefault(void) const
408
{
Don Gagne's avatar
Don Gagne committed
409 410
    if (_metaData) {
        if (_metaData->defaultValueAvailable()) {
Don Gagne's avatar
Don Gagne committed
411
            return _metaData->defaultValue() == rawValue();
Don Gagne's avatar
Don Gagne committed
412 413 414
        } else {
            return false;
        }
415
    } else {
Don Gagne's avatar
Don Gagne committed
416
        qWarning() << "Meta data pointer missing";
417 418 419 420
        return false;
    }
}

421
bool Fact::defaultValueAvailable(void) const
422
{
Don Gagne's avatar
Don Gagne committed
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
    if (_metaData) {
        return _metaData->defaultValueAvailable();
    } else {
        qWarning() << "Meta data pointer missing";
        return false;
    }
}

QString Fact::validate(const QString& value, bool convertOnly)
{
    if (_metaData) {
        
        QVariant    typedValue;
        QString     errorString;
        
        _metaData->convertAndValidate(value, convertOnly, typedValue, errorString);
        
        return errorString;
    } else {
        qWarning() << "Meta data pointer missing";
        return QString("Internal error: Meta data pointer missing");
    }
}