From badf509d1dcf750e885d8610a5d8e7a95bf7e518 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 15 May 2012 18:21:27 +0200 Subject: [PATCH 1/5] UAVObjects: switched around order of update modes to give each bit semantic meaning - important to allow usage of a bitfield type later --- flight/UAVObjects/inc/uavobjectmanager.h | 8 ++++---- ground/openpilotgcs/src/plugins/uavobjects/uavobject.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/flight/UAVObjects/inc/uavobjectmanager.h b/flight/UAVObjects/inc/uavobjectmanager.h index 20f7b1f6e..735581011 100644 --- a/flight/UAVObjects/inc/uavobjectmanager.h +++ b/flight/UAVObjects/inc/uavobjectmanager.h @@ -59,10 +59,10 @@ typedef void* UAVObjHandle; * Object update mode, used by multiple modules (e.g. telemetry and logger) */ typedef enum { - UPDATEMODE_PERIODIC = 0, /** Automatically update object at periodic intervals */ - UPDATEMODE_ONCHANGE = 1, /** Only update object when its data changes */ - UPDATEMODE_THROTTLED = 2, /** Object is updated on change, but not more often than the interval time */ - UPDATEMODE_MANUAL = 3 /** Manually update object, by calling the updated() function */ + UPDATEMODE_MANUAL = 0, /** Manually update object, by calling the updated() function */ + UPDATEMODE_PERIODIC = 1, /** Automatically update object at periodic intervals */ + UPDATEMODE_ONCHANGE = 2, /** Only update object when its data changes */ + UPDATEMODE_THROTTLED = 3 /** Object is updated on change, but not more often than the interval time */ } UAVObjUpdateMode; /** diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h index e1264a607..773863993 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h @@ -58,10 +58,10 @@ public: * Object update mode */ typedef enum { - UPDATEMODE_PERIODIC = 0, /** Automatically update object at periodic intervals */ - UPDATEMODE_ONCHANGE = 1, /** Only update object when its data changes */ - UPDATEMODE_THROTTLED = 2, /** Object is updated on change, but not more often than the interval time */ - UPDATEMODE_MANUAL = 3 /** Manually update object, by calling the updated() function */ + UPDATEMODE_MANUAL = 0, /** Manually update object, by calling the updated() function */ + UPDATEMODE_PERIODIC = 1, /** Automatically update object at periodic intervals */ + UPDATEMODE_ONCHANGE = 2, /** Only update object when its data changes */ + UPDATEMODE_THROTTLED = 3 /** Object is updated on change, but not more often than the interval time */ } UpdateMode; /** From 31fd30b1086588a6d47d4aea6af0a41499b40eb1 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 15 May 2012 18:22:36 +0200 Subject: [PATCH 2/5] UABOBJECTS: Made GCS aware of new BITFIELD type in UAVObjects - so far not used by UAVObjectgenerator, but can be used (hardcoded) in metadata objects --- .../uavobjectbrowser/uavobjecttreemodel.cpp | 1 + .../src/plugins/uavobjects/uavobjectfield.cpp | 63 ++++++++++++++++--- .../src/plugins/uavobjects/uavobjectfield.h | 3 +- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp b/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp index ac2e4bcee..4ba78a51b 100644 --- a/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp @@ -166,6 +166,7 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt FieldTreeItem *item; UAVObjectField::FieldType type = field->getType(); switch (type) { + case UAVObjectField::BITFIELD: case UAVObjectField::ENUM: { QStringList options = field->getOptions(); QVariant value = field->getValue(); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp index f5df52396..97a8978a5 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp @@ -86,6 +86,9 @@ void UAVObjectField::constructorInitialize(const QString& name, const QString& u case ENUM: numBytesPerElement = sizeof(quint8); break; + case BITFIELD: + numBytesPerElement = sizeof(quint8); + break; case STRING: numBytesPerElement = sizeof(quint8); break; @@ -477,7 +480,15 @@ UAVObject* UAVObjectField::getObject() void UAVObjectField::clear() { QMutexLocker locker(obj->getMutex()); - memset(&data[offset], 0, numBytesPerElement*numElements); + switch (type) + { + case BITFIELD: + memset(&data[offset], 0, numBytesPerElement*((quint32)(numElements/8))); + break; + default: + memset(&data[offset], 0, numBytesPerElement*numElements); + break; + } } QString UAVObjectField::getName() @@ -507,7 +518,15 @@ quint32 UAVObjectField::getDataOffset() quint32 UAVObjectField::getNumBytes() { - return numBytesPerElement * numElements; + switch (type) + { + case BITFIELD: + return numBytesPerElement * ((quint32) (numElements/8)); + break; + default: + return numBytesPerElement * numElements; + break; + } } QString UAVObjectField::toString() @@ -584,6 +603,12 @@ qint32 UAVObjectField::pack(quint8* dataOut) dataOut[numBytesPerElement*index] = data[offset + numBytesPerElement*index]; } break; + case BITFIELD: + for (quint32 index = 0; index < (quint32)(numElements/8); ++index) + { + dataOut[numBytesPerElement*index] = data[offset + numBytesPerElement*index]; + } + break; case STRING: memcpy(dataOut, &data[offset], numElements); break; @@ -653,6 +678,12 @@ qint32 UAVObjectField::unpack(const quint8* dataIn) data[offset + numBytesPerElement*index] = dataIn[numBytesPerElement*index]; } break; + case BITFIELD: + for (quint32 index = 0; index < (quint32)(numElements/8); ++index) + { + data[offset + numBytesPerElement*index] = dataIn[numBytesPerElement*index]; + } + break; case STRING: memcpy(&data[offset], dataIn, numElements); break; @@ -661,11 +692,6 @@ qint32 UAVObjectField::unpack(const quint8* dataIn) return getNumBytes(); } -quint32 UAVObjectField::getNumBytesElement() -{ - return numBytesPerElement; -} - bool UAVObjectField::isNumeric() { switch (type) @@ -694,6 +720,9 @@ bool UAVObjectField::isNumeric() case ENUM: return false; break; + case BITFIELD: + return false; + break; case STRING: return false; break; @@ -730,6 +759,9 @@ bool UAVObjectField::isText() case ENUM: return true; break; + case BITFIELD: + return true; + break; case STRING: return true; break; @@ -810,6 +842,14 @@ QVariant UAVObjectField::getValue(quint32 index) return QVariant( options[tmpenum] ); break; } + case BITFIELD: + { + quint8 tmpbitfield; + memcpy(&tmpbitfield, &data[offset + numBytesPerElement*((quint32)(index/8))], numBytesPerElement); + tmpbitfield = (tmpbitfield >> (index % 8)) & 1; + return QVariant( tmpbitfield ); + break; + } case STRING: { data[offset + numElements - 1] = '\0'; @@ -845,6 +885,7 @@ bool UAVObjectField::checkValue(const QVariant& value, quint32 index) case UINT32: case FLOAT32: case STRING: + case BITFIELD: return true; break; case ENUM: @@ -926,6 +967,14 @@ void UAVObjectField::setValue(const QVariant& value, quint32 index) memcpy(&data[offset + numBytesPerElement*index], &tmpenum, numBytesPerElement); break; } + case BITFIELD: + { + quint8 tmpbitfield; + memcpy(&tmpbitfield, &data[offset + numBytesPerElement*((quint32)(index/8))], numBytesPerElement); + tmpbitfield = tmpbitfield | ( (value.toUInt()!=0?1:0) << (index % 8) ); + memcpy(&data[offset + numBytesPerElement*((quint32)(index/8))], &tmpbitfield, numBytesPerElement); + break; + } case STRING: { QString str = value.toString(); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h index faad2e568..c99db17a2 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.h @@ -42,7 +42,7 @@ class UAVOBJECTS_EXPORT UAVObjectField: public QObject Q_OBJECT public: - typedef enum { INT8 = 0, INT16, INT32, UINT8, UINT16, UINT32, FLOAT32, ENUM, STRING } FieldType; + typedef enum { INT8 = 0, INT16, INT32, UINT8, UINT16, UINT32, FLOAT32, ENUM, BITFIELD, STRING } FieldType; typedef enum { EQUAL,NOT_EQUAL,BETWEEN,BIGGER,SMALLER } LimitType; typedef struct { @@ -70,7 +70,6 @@ public: void setDouble(double value, quint32 index = 0); quint32 getDataOffset(); quint32 getNumBytes(); - quint32 getNumBytesElement(); bool isNumeric(); bool isText(); QString toString(); From 8fc471463d4c7bab8ce3265ac6478084242f2c02 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 15 May 2012 18:23:25 +0200 Subject: [PATCH 3/5] UAVOBJECTS: On GCS side, handle Mode Bitfield in UAVOBJECT Metadata as a type BITFIELD. This has no effect on flight side, since the serialized form is identical to an UINT8 that's interpreted as a bitfield which is used there, so that can change later if necessary --- .../src/plugins/uavobjects/uavmetaobject.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp index bb45495f5..3a526377c 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp @@ -39,16 +39,14 @@ UAVMetaObject::UAVMetaObject(quint32 objID, const QString& name, UAVObject* pare UAVObject::MetadataInitialize(ownMetadata); // Setup fields QStringList boolEnum; - boolEnum << tr("False") << tr("True"); - QStringList updateModeEnum; - updateModeEnum << tr("Periodic") << tr("On Change") << tr("Manual") << tr("Never"); - QStringList accessModeEnum; - accessModeEnum << tr("Read/Write") << tr("Read Only"); + boolEnum << tr("0") << tr("1"); + QStringList modesBitField; + modesBitField << tr("FlightReadOnly") << tr("GCSReadOnly") << tr("FlightTelemetryAcked") << tr("GCSTelemetryAcked") << tr("FlightUpdatePeriodic") << tr("FlightUpdateOnChange") << tr("GCSUpdatePeriodic") << tr("GCSUpdateOnChange"); QList fields; - fields.append( new UAVObjectField(tr("Modes"), tr(""), UAVObjectField::UINT8, 1, accessModeEnum) ); - fields.append( new UAVObjectField(tr("Flight Telemetry Update Period"), tr(""), UAVObjectField::UINT16, 1, QStringList()) ); - fields.append( new UAVObjectField(tr("GCS Telemetry Update Period"), tr(""), UAVObjectField::UINT16, 1, QStringList()) ); - fields.append( new UAVObjectField(tr("Logging Update Period"), tr(""), UAVObjectField::UINT16, 1, QStringList()) ); + fields.append( new UAVObjectField(tr("Modes"), tr("boolean"), UAVObjectField::BITFIELD, modesBitField, boolEnum) ); + fields.append( new UAVObjectField(tr("Flight Telemetry Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()) ); + fields.append( new UAVObjectField(tr("GCS Telemetry Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()) ); + fields.append( new UAVObjectField(tr("Logging Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()) ); // Initialize parent UAVObject::initialize(0); UAVObject::initializeFields(fields, (quint8*)&parentMetadata, sizeof(Metadata)); From aa7788d04cb195e4ba3949f171b4feb451608380 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 15 May 2012 19:01:32 +0200 Subject: [PATCH 4/5] UAVObjects: Bugfixes to BITFIELD type --- .../src/plugins/uavobjects/uavobjectfield.cpp | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp index 97a8978a5..4281682e0 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp @@ -136,14 +136,15 @@ void UAVObjectField::limitsInitialize(const QString &limits) QString value=_value.trimmed(); switch (type) { + case UINT8: + case UINT16: + case UINT32: + case BITFIELD: + lstruc.values.append((quint32)value.toULong()); + break; case INT8: case INT16: case INT32: - case UINT8: - lstruc.values.append((quint32)value.toULong()); - break; - case UINT16: - case UINT32: lstruc.values.append((qint32)value.toLong()); break; case FLOAT32: @@ -193,6 +194,7 @@ bool UAVObjectField::isWithinLimits(QVariant var,quint32 index) case UINT8: case UINT16: case UINT32: + case BITFIELD: foreach (QVariant vars, struc.values) { if(var.toUInt()==vars.toUInt()) return true; @@ -233,6 +235,7 @@ bool UAVObjectField::isWithinLimits(QVariant var,quint32 index) case UINT8: case UINT16: case UINT32: + case BITFIELD: foreach (QVariant vars, struc.values) { if(var.toUInt()==vars.toUInt()) return false; @@ -278,6 +281,7 @@ bool UAVObjectField::isWithinLimits(QVariant var,quint32 index) case UINT8: case UINT16: case UINT32: + case BITFIELD: if(!(var.toUInt()>=struc.values.at(0).toUInt() && var.toUInt()<=struc.values.at(1).toUInt())) return false; return true; @@ -319,6 +323,7 @@ bool UAVObjectField::isWithinLimits(QVariant var,quint32 index) case UINT8: case UINT16: case UINT32: + case BITFIELD: if(!(var.toUInt()>=struc.values.at(0).toUInt())) return false; return true; @@ -353,6 +358,7 @@ bool UAVObjectField::isWithinLimits(QVariant var,quint32 index) case UINT8: case UINT16: case UINT32: + case BITFIELD: if(!(var.toUInt()<=struc.values.at(0).toUInt())) return false; return true; @@ -460,6 +466,8 @@ QString UAVObjectField::getTypeAsString() return "float32"; case UAVObjectField::ENUM: return "enum"; + case UAVObjectField::BITFIELD: + return "bitfield"; case UAVObjectField::STRING: return "string"; default: @@ -721,7 +729,7 @@ bool UAVObjectField::isNumeric() return false; break; case BITFIELD: - return false; + return true; break; case STRING: return false; @@ -760,7 +768,7 @@ bool UAVObjectField::isText() return true; break; case BITFIELD: - return true; + return false; break; case STRING: return true; @@ -971,7 +979,7 @@ void UAVObjectField::setValue(const QVariant& value, quint32 index) { quint8 tmpbitfield; memcpy(&tmpbitfield, &data[offset + numBytesPerElement*((quint32)(index/8))], numBytesPerElement); - tmpbitfield = tmpbitfield | ( (value.toUInt()!=0?1:0) << (index % 8) ); + tmpbitfield = (tmpbitfield & ~(1 << (index % 8))) | ( (value.toUInt()!=0?1:0) << (index % 8) ); memcpy(&data[offset + numBytesPerElement*((quint32)(index/8))], &tmpbitfield, numBytesPerElement); break; } From 80f53b185c67d475ead43df97c4a62bcc36d7d90 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 15 May 2012 19:40:58 +0200 Subject: [PATCH 5/5] GCS: BITFIELD: Set lists of options hardcoded in uavobjectfield.cpp (can only be "0" or "1" ) --- ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp | 4 +--- ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp index 3a526377c..e190b4f27 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp @@ -38,12 +38,10 @@ UAVMetaObject::UAVMetaObject(quint32 objID, const QString& name, UAVObject* pare // Setup default metadata of metaobject (can not be changed) UAVObject::MetadataInitialize(ownMetadata); // Setup fields - QStringList boolEnum; - boolEnum << tr("0") << tr("1"); QStringList modesBitField; modesBitField << tr("FlightReadOnly") << tr("GCSReadOnly") << tr("FlightTelemetryAcked") << tr("GCSTelemetryAcked") << tr("FlightUpdatePeriodic") << tr("FlightUpdateOnChange") << tr("GCSUpdatePeriodic") << tr("GCSUpdateOnChange"); QList fields; - fields.append( new UAVObjectField(tr("Modes"), tr("boolean"), UAVObjectField::BITFIELD, modesBitField, boolEnum) ); + fields.append( new UAVObjectField(tr("Modes"), tr("boolean"), UAVObjectField::BITFIELD, modesBitField, QStringList()) ); fields.append( new UAVObjectField(tr("Flight Telemetry Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()) ); fields.append( new UAVObjectField(tr("GCS Telemetry Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()) ); fields.append( new UAVObjectField(tr("Logging Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()) ); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp index 4281682e0..79590fad8 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjectfield.cpp @@ -88,6 +88,7 @@ void UAVObjectField::constructorInitialize(const QString& name, const QString& u break; case BITFIELD: numBytesPerElement = sizeof(quint8); + this->options = QStringList()<