1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

GCS/UAVObjects: Added support for saving and loading of objects

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@407 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
vassilis 2010-03-28 22:22:19 +00:00 committed by vassilis
parent df573fdad5
commit 37cec4c7fd
16 changed files with 360 additions and 38 deletions

View File

@ -32,7 +32,7 @@
const QString ExampleObject::NAME = QString("ExampleObject");
ExampleObject::ExampleObject(): UAVDataObject(OBJID, SINGLEINST, NAME)
ExampleObject::ExampleObject(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTINGS, NAME)
{
// Create fields
QList<UAVObjectField*> fields;

View File

@ -46,7 +46,8 @@ public:
static const quint32 OBJID = 3048370380U;
static const QString NAME;
static const bool SINGLEINST = 0;
static const bool ISSINGLEINST = 0;
static const bool ISSETTINGS = 0;
static const quint32 NUMBYTES = sizeof(DataFields);
ExampleObject();

View File

@ -0,0 +1,81 @@
/**
******************************************************************************
*
* @file examplesettings.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the ExampleSettings object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: examplesettings.xml.
* This is an automatically generated file.
* DO NOT modify manually.
*
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "examplesettings.h"
const QString ExampleSettings::NAME = QString("ExampleSettings");
ExampleSettings::ExampleSettings(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTINGS, NAME)
{
// Create fields
QList<UAVObjectField*> fields;
fields.append(new UAVObjectField(QString("setting1"), QString("unit1"), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("setting2"), QString("unit2"), UAVObjectField::FIELDTYPE_INT16, 1));
fields.append(new UAVObjectField(QString("setting3"), QString("unit3"), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("setting4"), QString("unit4"), UAVObjectField::FIELDTYPE_INT32, 1));
// Initialize object
initializeFields(fields, (quint8*)&data, NUMBYTES);
}
UAVObject::Metadata ExampleSettings::getDefaultMetadata()
{
UAVObject::Metadata metadata;
metadata.gcsTelemetryAcked = 1;
metadata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
metadata.gcsTelemetryUpdatePeriod = 0;
metadata.flightTelemetryAcked = 1;
metadata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
metadata.flightTelemetryUpdatePeriod = 0;
metadata.loggingUpdateMode = UAVObject::UPDATEMODE_NEVER;
metadata.loggingUpdatePeriod = 0;
return metadata;
}
ExampleSettings::DataFields ExampleSettings::getData()
{
QMutexLocker locker(mutex);
return data;
}
void ExampleSettings::setData(DataFields& data)
{
QMutexLocker locker(mutex);
this->data = data;
emit objectUpdatedAuto(this); // trigger object updated event
emit objectUpdated(this);
}
UAVDataObject* ExampleSettings::clone(quint32 instID)
{
ExampleSettings* obj = new ExampleSettings();
obj->initialize(instID, this->getMetaObject());
return obj;
}

View File

@ -0,0 +1,65 @@
/**
******************************************************************************
*
* @file examplesettings.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the ExampleSettings object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: examplesettings.xml.
* This is an automatically generated file.
* DO NOT modify manually.
*
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EXAMPLESETTINGS_H
#define EXAMPLESETTINGS_H
#include "uavdataobject.h"
class ExampleSettings: public UAVDataObject
{
public:
typedef struct {
qint8 setting1;
qint16 setting2;
qint8 setting3;
qint32 setting4;
} __attribute__((packed)) DataFields;
static const quint32 OBJID = 3555345034U;
static const QString NAME;
static const bool ISSINGLEINST = 1;
static const bool ISSETTINGS = 1;
static const quint32 NUMBYTES = sizeof(DataFields);
ExampleSettings();
DataFields getData();
void setData(DataFields& data);
Metadata getDefaultMetadata();
UAVDataObject* clone(quint32 instID);
private:
DataFields data;
};
#endif // EXAMPLESETTINGS_H

View File

@ -8,7 +8,7 @@ UAVObjectsTest::UAVObjectsTest(): sout(stdout), done(false)
connect(objMngr, SIGNAL(newInstance(UAVObject*)), this, SLOT(newInstance(UAVObject*)));
// Create test objects
obj1 = new TestObject1();
obj1 = new ExampleObject();
connect(obj1, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(objectUpdated(UAVObject*)));
connect(obj1, SIGNAL(objectUpdatedAuto(UAVObject*)), this, SLOT(objectUpdatedAuto(UAVObject*)));
connect(obj1, SIGNAL(objectUpdatedManual(UAVObject*)), this, SLOT(objectUpdatedManual(UAVObject*)));
@ -62,16 +62,16 @@ void UAVObjectsTest::runTest()
if (!done)
{
// Create a new instance
TestObject1* obj2 = new TestObject1();
ExampleObject* obj2 = new ExampleObject();
objMngr->registerObject(obj2);
// Set data
TestObject1::DataFields data = obj1->getData();
ExampleObject::DataFields data = obj1->getData();
data.field1 = 1;
data.field2[0] = 2.1;
data.field2[1] = 2.2;
data.field2[2] = 2.3;
data.field3 = 3;
data.field3[0] = 2.1;
data.field3[1] = 2.2;
data.field3[2] = 2.3;
data.field2 = 3;
data.field4 = 4;
obj1->setData(data);
@ -93,16 +93,27 @@ void UAVObjectsTest::runTest()
quint8* buf = new quint8[obj1->getNumBytes()];
obj1->pack(buf);
data.field1 = 10;
data.field2[0] = 20.1;
data.field2[1] = 20.2;
data.field2[2] = 20.3;
data.field3 = 30;
data.field3[0] = 20.1;
data.field3[1] = 20.2;
data.field3[2] = 20.3;
data.field2 = 30;
data.field4 = 40;
obj1->setData(data);
obj1->unpack(buf);
// Save, load testing
obj1->save();
data.field1 = 10;
data.field3[0] = 20.1;
data.field3[1] = 20.2;
data.field3[2] = 20.3;
data.field2 = 30;
data.field4 = 40;
obj1->setData(data);
obj1->load();
// Get all instances
QList<UAVObject*> objs = objMngr->getObjectInstances(TestObject1::OBJID);
QList<UAVObject*> objs = objMngr->getObjectInstances(ExampleObject::OBJID);
for (int n = 0; n < objs.length(); ++n)
{
sout << "[Printing object instances]\n";

View File

@ -1,8 +1,8 @@
#ifndef UAVOBJECTSTEST_H
#define UAVOBJECTSTEST_H
#include "..\UAVObjectManager.h"
#include "testobject1.h"
#include "..\uavobjectmanager.h"
#include "..\exampleobject.h"
#include <QTimer>
#include <QTextStream>
@ -26,7 +26,7 @@ private slots:
private:
UAVObjectManager* objMngr;
TestObject1* obj1;
ExampleObject* obj1;
QTimer* timer;
QTextStream sout;
bool done;

View File

@ -12,7 +12,6 @@ SOURCES += main.cpp \
../uavobject.cpp \
../uavmetaobject.cpp \
../uavdataobject.cpp \
testobject1.cpp \
uavobjectstest.cpp \
../exampleobject.cpp
HEADERS += ../uavobjectmanager.h \
@ -20,6 +19,5 @@ HEADERS += ../uavobjectmanager.h \
../uavobject.h \
../uavmetaobject.h \
../uavdataobject.h \
testobject1.h \
uavobjectstest.h \
../exampleobject.h

View File

@ -30,10 +30,11 @@
/**
* Constructor
*/
UAVDataObject::UAVDataObject(quint32 objID, bool isSingleInst, const QString& name):
UAVDataObject::UAVDataObject(quint32 objID, bool isSingleInst, bool isSet,const QString& name):
UAVObject(objID, isSingleInst, name)
{
mobj = NULL;
this->isSet = isSet;
}
/**
@ -55,6 +56,14 @@ void UAVDataObject::initialize(UAVMetaObject* mobj)
this->mobj = mobj;
}
/**
* Returns true if this is a data object holding module settings
*/
bool UAVDataObject::isSettings()
{
return isSet;
}
/**
* Set the object's metadata
*/

View File

@ -39,9 +39,10 @@ class UAVOBJECTS_EXPORT UAVDataObject: public UAVObject
Q_OBJECT
public:
UAVDataObject(quint32 objID, bool isSingleInst, const QString& name);
UAVDataObject(quint32 objID, bool isSingleInst, bool isSet, const QString& name);
void initialize(quint32 instID, UAVMetaObject* mobj);
void initialize(UAVMetaObject* mobj);
bool isSettings();
void setMetadata(const Metadata& mdata);
Metadata getMetadata();
UAVMetaObject* getMetaObject();
@ -49,6 +50,7 @@ public:
private:
UAVMetaObject* mobj;
bool isSet;
};

View File

@ -26,6 +26,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "uavobject.h"
#include <QtEndian>
/**
* Constructor
@ -242,6 +243,151 @@ qint32 UAVObject::unpack(const quint8* dataIn)
return numBytes;
}
/**
* Save the object data to the file.
* The file will be created in the current directory
* and its name will be the same as the object with
* the .uavobj extension.
* @returns True on success, false on failure
*/
bool UAVObject::save()
{
QMutexLocker locker(mutex);
// Open file
QFile file(name + ".uavobj");
if (!file.open(QFile::WriteOnly))
{
return false;
}
// Write object
if ( !save(file) )
{
return false;
}
// Close file
file.close();
return true;
}
/**
* Save the object data to the file.
* The file is expected to be already open for writting.
* The data will be appended and the file will not be closed.
* @returns True on success, false on failure
*/
bool UAVObject::save(QFile& file)
{
QMutexLocker locker(mutex);
quint8 buffer[numBytes];
quint8 tmpId[4];
// Write the object ID
qToBigEndian<quint32>(objID, tmpId);
if ( file.write((const char*)tmpId, 4) == -1 )
{
return false;
}
// Write the instance ID
if (!isSingleInst)
{
qToBigEndian<quint16>(instID, tmpId);
if ( file.write((const char*)tmpId, 2) == -1 )
{
return false;
}
}
// Write the data
pack(buffer);
if ( file.write((const char*)buffer, numBytes) == -1 )
{
return false;
}
// Done
return true;
}
/**
* Load the object data from a file.
* The file will be openned in the current directory
* and its name will be the same as the object with
* the .uavobj extension.
* @returns True on success, false on failure
*/
bool UAVObject::load()
{
QMutexLocker locker(mutex);
// Open file
QFile file(name + ".uavobj");
if (!file.open(QFile::ReadOnly))
{
return false;
}
// Load object
if ( !load(file) )
{
return false;
}
// Close file
file.close();
return true;
}
/**
* Load the object data from file.
* The file is expected to be already open for reading.
* The data will be read and the file will not be closed.
* @returns True on success, false on failure
*/
bool UAVObject::load(QFile& file)
{
QMutexLocker locker(mutex);
quint8 buffer[numBytes];
quint8 tmpId[4];
// Read the object ID
if ( file.read((char*)tmpId, 4) != 4 )
{
return false;
}
// Check that the IDs match
if (qFromBigEndian<quint32>(tmpId) != objID)
{
return false;
}
// Read the instance ID
if ( file.read((char*)tmpId, 2) != 2 )
{
return false;
}
// Check that the IDs match
if (qFromBigEndian<quint16>(tmpId) != instID)
{
return false;
}
// Read and unpack the data
if ( file.read((char*)buffer, numBytes) != numBytes )
{
return false;
}
unpack(buffer);
// Done
return true;
}
/**
* Return a string with the object information
*/

View File

@ -35,6 +35,7 @@
#include <QMutexLocker>
#include <QString>
#include <QList>
#include <QFile>
#include "uavobjectfield.h"
class UAVObjectField;
@ -78,8 +79,12 @@ public:
bool isSingleInstance();
QString getName();
quint32 getNumBytes();
virtual qint32 pack(quint8* dataOut);
virtual qint32 unpack(const quint8* dataIn);
qint32 pack(quint8* dataOut);
qint32 unpack(const quint8* dataIn);
bool save();
bool save(QFile& file);
bool load();
bool load(QFile& file);
virtual void setMetadata(const Metadata& mdata) = 0;
virtual Metadata getMetadata() = 0;
virtual Metadata getDefaultMetadata() = 0;

View File

@ -1,9 +1,7 @@
TEMPLATE = lib
TARGET = UAVObjects
include(../../openpilotgcsplugin.pri)
include(uavobjects_dependencies.pri)
HEADERS += uavobjects_global.h \
uavobject.h \
uavmetaobject.h \
@ -11,15 +9,17 @@ HEADERS += uavobjects_global.h \
uavdataobject.h \
uavobjectfield.h \
uavobjectsinit.h \
uavobjectsplugin.h
uavobjectsplugin.h \
examplesettings.h \
exampleobject.h
SOURCES += uavobject.cpp \
uavmetaobject.cpp \
uavobjectmanager.cpp \
uavdataobject.cpp \
uavobjectfield.cpp \
uavobjectsinit.cpp \
uavobjectsplugin.cpp
uavobjectsplugin.cpp \
examplesettings.cpp \
exampleobject.cpp
DEFINES += UAVOBJECTS_LIBRARY
OTHER_FILES += UAVObjects.pluginspec

View File

@ -31,6 +31,7 @@
*/
#include "uavobjectsinit.h"
#include "exampleobject.h"
#include "examplesettings.h"
/**
@ -40,4 +41,6 @@
void UAVObjectsInitialize(UAVObjectManager* objMngr)
{
objMngr->registerObject( new ExampleObject() );
objMngr->registerObject( new ExampleSettings() );
}

View File

@ -32,7 +32,7 @@
const QString $(NAME)::NAME = QString("$(NAME)");
$(NAME)::$(NAME)(): UAVDataObject(OBJID, SINGLEINST, NAME)
$(NAME)::$(NAME)(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTINGS, NAME)
{
// Create fields
QList<UAVObjectField*> fields;

View File

@ -42,7 +42,8 @@ $(DATAFIELDS)
static const quint32 OBJID = $(OBJID)U;
static const QString NAME;
static const bool SINGLEINST = $(SINGLEINST);
static const bool ISSINGLEINST = $(ISSINGLEINST);
static const bool ISSETTINGS = $(ISSETTINGS);
static const quint32 NUMBYTES = sizeof(DataFields);
$(NAME)();

View File

@ -160,7 +160,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
if (rxCount == 4)
{
// Search for object, if not found reset state machine
rxObjId = (qint32)qFromBigEndian<qint32>(rxTmpBuffer);
rxObjId = (qint32)qFromBigEndian<quint32>(rxTmpBuffer);
UAVObject* rxObj = objMngr->getObject(rxObjId);
if (rxObj == NULL)
{
@ -214,7 +214,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
rxTmpBuffer[rxCount++] = rxbyte;
if (rxCount == 2)
{
rxInstId = (qint16)qFromBigEndian<qint16>(rxTmpBuffer);
rxInstId = (qint16)qFromBigEndian<quint16>(rxTmpBuffer);
rxCS = updateChecksum(rxCS, rxTmpBuffer, 2);
rxCount = 0;
// If there is a payload get it, otherwise receive checksum
@ -241,7 +241,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
rxTmpBuffer[rxCount++] = rxbyte;
if (rxCount == 2)
{
rxCSPacket = (qint16)qFromBigEndian<qint16>(rxTmpBuffer);
rxCSPacket = (qint16)qFromBigEndian<quint16>(rxTmpBuffer);
if (rxCS == rxCSPacket)
{
mutex->lock();
@ -491,7 +491,7 @@ bool UAVTalk::transmitSingleObject(UAVObject* obj, quint8 type, bool allInstance
// Setup type and object id fields
objId = obj->getObjID();
txBuffer[0] = type;
qToBigEndian<qint32>(objId, &txBuffer[1]);
qToBigEndian<quint32>(objId, &txBuffer[1]);
// Setup instance ID if one is required
if ( obj->isSingleInstance() )
@ -503,12 +503,12 @@ bool UAVTalk::transmitSingleObject(UAVObject* obj, quint8 type, bool allInstance
// Check if all instances are requested
if (allInstances)
{
qToBigEndian<qint16>(allInstId, &txBuffer[5]);
qToBigEndian<quint16>(allInstId, &txBuffer[5]);
}
else
{
instId = obj->getInstID();
qToBigEndian<qint16>(instId, &txBuffer[5]);
qToBigEndian<quint16>(instId, &txBuffer[5]);
}
dataOffset = 7;
}
@ -541,7 +541,7 @@ bool UAVTalk::transmitSingleObject(UAVObject* obj, quint8 type, bool allInstance
// Calculate checksum
cs = 0;
cs = updateChecksum(cs, txBuffer, dataOffset+length);
qToBigEndian<qint16>(cs, &txBuffer[dataOffset+length]);
qToBigEndian<quint16>(cs, &txBuffer[dataOffset+length]);
// Send buffer
io->write((const char*)txBuffer, dataOffset+length+CHECKSUM_LENGTH);