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)
Don Gagne's avatar
Don Gagne committed
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)
Don Gagne's avatar
Don Gagne committed
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;
Don Gagne's avatar
Don Gagne committed
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)
Don Gagne's avatar
Don Gagne committed
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());
Don Gagne's avatar
Don Gagne committed
87
88
89
90
91
92
        }
    } else {
        qWarning() << "Meta data pointer missing";
    }
}

Don Gagne's avatar
Don Gagne committed
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)) {
Don Gagne's avatar
Don Gagne committed
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)
Don Gagne's avatar
Don Gagne committed
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]);
Don Gagne's avatar
Don Gagne committed
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]);
Don Gagne's avatar
Don Gagne committed
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
{
Don Gagne's avatar
Don Gagne committed
143
    _rawValue = value;
Don Gagne's avatar
Don Gagne committed
144
    emit valueChanged(cookedValue());
Don Gagne's avatar
Don Gagne committed
145
    emit vehicleUpdated(_rawValue);
Don Gagne's avatar
Don Gagne committed
146
}
Don Gagne's avatar
Don Gagne committed
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
Don Gagne's avatar
Don Gagne committed
159
{
Don Gagne's avatar
Don Gagne committed
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()) {
Don Gagne's avatar
Don Gagne committed
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()) {
Don Gagne's avatar
Don Gagne committed
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();
    }
Don Gagne's avatar
Don Gagne committed
217
218
}

219
QString Fact::_variantToString(const QVariant& variant) const
Don Gagne's avatar
Don Gagne committed
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;
Don Gagne's avatar
Don Gagne committed
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
Don Gagne's avatar
Don Gagne committed
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);
Don Gagne's avatar
Don Gagne committed
253
    }
Don Gagne's avatar
Don Gagne committed
254
255
}

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

261
FactMetaData::ValueType_t Fact::type(void) const
Don Gagne's avatar
Don Gagne committed
262
{
263
    return _type;
Don Gagne's avatar
Don Gagne committed
264
265
}

266
QString Fact::shortDescription(void) const
Don Gagne's avatar
Don Gagne committed
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();
    }
Don Gagne's avatar
Don Gagne committed
274
275
}

276
QString Fact::longDescription(void) const
Don Gagne's avatar
Don Gagne committed
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();
    }
Don Gagne's avatar
Don Gagne committed
284
285
}

286
QString Fact::units(void) const
Don Gagne's avatar
Don Gagne committed
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();
    }
Don Gagne's avatar
Don Gagne committed
294
295
}

296
QVariant Fact::min(void) const
Don Gagne's avatar
Don Gagne committed
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);
    }
Don Gagne's avatar
Don Gagne committed
304
305
}

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

311
QVariant Fact::max(void) const
Don Gagne's avatar
Don Gagne committed
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;
    }
Don Gagne's avatar
Don Gagne committed
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
Don Gagne's avatar
Don Gagne committed
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();
    }
Don Gagne's avatar
Don Gagne committed
364
365
}

Don Gagne's avatar
Don Gagne committed
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);
    }

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

407
bool Fact::valueEqualsDefault(void) const
Don Gagne's avatar
Don Gagne committed
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;
        }
Don Gagne's avatar
Don Gagne committed
415
    } else {
Don Gagne's avatar
Don Gagne committed
416
        qWarning() << "Meta data pointer missing";
Don Gagne's avatar
Don Gagne committed
417
418
419
420
        return false;
    }
}

421
bool Fact::defaultValueAvailable(void) const
Don Gagne's avatar
Don Gagne committed
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");
    }
}