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

First release of the UAVObject generator application

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@397 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
vassilis 2010-03-27 03:22:43 +00:00 committed by vassilis
parent a64cdc64ea
commit 20378f7b6b
18 changed files with 1367 additions and 78 deletions

View File

@ -0,0 +1,57 @@
/**
******************************************************************************
*
* @file main.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief UAVObjectGenerator main.
*
* @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 <QtCore/QCoreApplication>
#include <QFile>
#include <QString>
#include <iostream>
#include "uavobjectgenerator.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString basepath;
// Get arguments
if (argc == 1)
{
basepath = QString("../../../../../");
}
else if (argc == 2)
{
basepath = QString(argv[1]);
}
else
{
std::cout << "Invalid arguments: uavobjectgenerator [base path to gcs and flight directories (as in svn)]" << std::endl;
}
// Start application
UAVObjectGenerator gen(basepath);
gen.processAll();
return 0;
}

View File

@ -0,0 +1,234 @@
/**
******************************************************************************
*
* @file uavobjectgenerator.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief UAVObjectGenerator, generates UAVObjects from XML files.
*
* @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
*/
/*
* The following is done by the object generator:
* - Read all XML files in the XML source directory
* - Process each XML and extract the information for all defined objects
* - Generate the unique objects IDs and check for collisions
* - Generate the GCS and Flight UAVObject code based on the supplied template source files
* - Update the object initialization source files for both the GCS and Flight code
*/
#include "uavobjectgenerator.h"
/**
* Constructor
* @param basepath The base directory where the 'flight' and 'gcs' folders are located (the SVN structure is expected)
* @param out The stdout file
*/
UAVObjectGenerator::UAVObjectGenerator(QString& basepath, FILE* out) :
basepath(basepath),
sout(out)
{
xmlPath = QDir( basepath + QString("ground/src/shared/uavobjectdefinition"));
flightCodePath = QDir( basepath + QString("flight/OpenPilot/UAVObjects"));
gcsCodePath = QDir( basepath + QString("ground/src/plugins/uavobjects"));
objectTemplateFilename = QString("uavobjecttemplate");
objectsInitTemplateFilename = QString("uavobjectsinittemplate");
objectsInitFilename = QString("uavobjectsinit");
sout << "- OpenPilot UAVObject Generator -" << endl;
}
/**
* Process all XML files and generate object code.
*/
bool UAVObjectGenerator::processAll()
{
// Read the template files
QString flightCodeTemplate = readFile( flightCodePath.absoluteFilePath(objectTemplateFilename + ".c") );
QString flightIncludeTemplate = readFile( flightCodePath.absoluteFilePath("inc/" + objectTemplateFilename + ".h") );
QString flightInitTemplate = readFile( flightCodePath.absoluteFilePath(objectsInitTemplateFilename + ".c") );
QString gcsCodeTemplate = readFile( gcsCodePath.absoluteFilePath(objectTemplateFilename + ".cpp") );
QString gcsIncludeTemplate = readFile( gcsCodePath.absoluteFilePath(objectTemplateFilename + ".h") );
QString gcsInitTemplate = readFile( gcsCodePath.absoluteFilePath(objectsInitTemplateFilename + ".cpp") );
if ( flightCodeTemplate.isNull() || flightIncludeTemplate.isNull() ||
gcsCodeTemplate.isNull() || gcsIncludeTemplate.isNull() ||
flightInitTemplate.isNull() || gcsInitTemplate.isNull() )
{
sout << "Error: Could not open template files." << endl;
return false;
}
// Get all XML files
QStringList filters;
filters.append("*.xml");
xmlPath.setNameFilters(filters);
QFileInfoList xmlList = xmlPath.entryInfoList();
// Read in each XML file and parse it
QList<UAVObjectParser*> parsers;
for (int n = 0; n < xmlList.length(); ++n)
{
QFileInfo fileinfo = xmlList[n];
QString filename = fileinfo.fileName();
QString xmlstr = readFile(fileinfo.absoluteFilePath());
UAVObjectParser* parser = new UAVObjectParser();
sout << "Parsing XML file: " << fileinfo.fileName() << endl;
QString res = parser->parseXML(xmlstr, filename);
if (!res.isNull())
{
sout << "Error: " << res << endl;
return false;
}
parsers.append(parser);
}
// Generate the code for each object and write it to the destination directory
QList<quint32> objIDList;
QString objInc;
QString flightObjInit;
QString gcsObjInit;
bool res;
for (int parseridx = 0; parseridx < parsers.length(); ++ parseridx)
{
UAVObjectParser* parser = parsers[parseridx];
for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx)
{
QString name = parser->getObjectName(objidx);
QString namelc = name.toLower();
sout << "Generating code for object: " << name << endl;
// Check for object ID conflicts
quint32 id = parser->getObjectID(objidx);
if ( objIDList.contains(id) )
{
sout << "Error: Object ID collision found in object " << name << ", modify object name" << endl;
return false;
}
else
{
objIDList.append(id);
}
// Generate the flight code
QString flightCode;
QString flightInclude;
res = parser->generateFlightObject(objidx, flightIncludeTemplate, flightCodeTemplate,
flightInclude, flightCode);
if (!res)
{
sout << "Error: Improperly formatted flight object template file" << endl;
return false;
}
// Generate the GCS code
QString gcsCode;
QString gcsInclude;
res = parser->generateGCSObject(objidx, gcsIncludeTemplate, gcsCodeTemplate,
gcsInclude, gcsCode);
if (!res)
{
sout << "Error: Improperly formatted GCS object template file" << endl;
return false;
}
// Write the flight code
// TODO: Only write file if modified
res = writeFile( flightCodePath.absolutePath() + "/" + namelc + ".c", flightCode );
if (!res)
{
sout << "Error: Could not write output files" << endl;
return false;
}
res = writeFile( flightCodePath.absolutePath() + "/inc/" + namelc + ".h", flightInclude );
if (!res)
{
sout << "Error: Could not write output files" << endl;
return false;
}
// Write the GCS code
// TODO: Only write file if modified
res = writeFile( gcsCodePath.absolutePath() + "/" + namelc + ".cpp", gcsCode );
if (!res)
{
sout << "Error: Could not write output files" << endl;
return false;
}
res = writeFile( gcsCodePath.absolutePath() + "/" + namelc + ".h", gcsInclude );
if (!res)
{
sout << "Error: Could not write output files" << endl;
return false;
}
// Update strings for the object initialization
objInc.append("#include \"" + namelc + ".h\"\n");
flightObjInit.append(" " + name + "Initialize();\n");
gcsObjInit.append(" objMngr->registerObject( new " + name + "() );");
}
}
// Write the flight object inialization files
sout << "Updating object initialization files" << endl;
flightInitTemplate.replace( QString("$(OBJINC)"), objInc);
flightInitTemplate.replace( QString("$(OBJINIT)"), flightObjInit);
res = writeFile( flightCodePath.absolutePath() + "/" + objectsInitFilename + ".c",
flightInitTemplate );
if (!res)
{
sout << "Error: Could not write output files" << endl;
return false;
}
// Write the gcs object inialization files
gcsInitTemplate.replace( QString("$(OBJINC)"), objInc);
gcsInitTemplate.replace( QString("$(OBJINIT)"), gcsObjInit);
res = writeFile( gcsCodePath.absolutePath() + "/" + objectsInitFilename + ".cpp",
gcsInitTemplate );
if (!res)
{
sout << "Error: Could not write output files" << endl;
return false;
}
// Done
sout << "Done: processed " << xmlList.length() << " XML files and generated "
<< objIDList.length() << " objects with no ID collisions." << endl;
return true;
}
/**
* Read a file and return its contents as a string
*/
QString UAVObjectGenerator::readFile(QString name)
{
QFile file(name);
if (!file.open(QFile::ReadOnly)) return QString();
QTextStream fileStr(&file);
QString str = fileStr.readAll();
file.close();
return str;
}
/**
* Write contents of string to file
*/
bool UAVObjectGenerator::writeFile(QString name, QString& str)
{
QFile file(name);
if (!file.open(QFile::WriteOnly)) return false;
QTextStream fileStr(&file);
fileStr << str;
file.close();
return true;
}

View File

@ -0,0 +1,57 @@
/**
******************************************************************************
*
* @file uavobjectgenerator.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief UAVObjectGenerator, generates UAVObjects from XML files.
*
* @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 UAVOBJECTGENERATOR_H
#define UAVOBJECTGENERATOR_H
#include <QTextStream>
#include <QString>
#include <QDir>
#include <QFile>
#include "uavobjectparser.h"
class UAVObjectGenerator
{
public:
UAVObjectGenerator(QString& basepath, FILE* out = stdout);
bool processAll();
private:
QDir basepath;
QTextStream sout;
QDir xmlPath;
QDir flightCodePath;
QDir gcsCodePath;
QString objectTemplateFilename;
QString objectsInitTemplateFilename;
QString objectsInitFilename;
QString readFile(QString name);
bool writeFile(QString name, QString& str);
};
#endif // UAVOBJECTGENERATOR_H

View File

@ -0,0 +1,593 @@
/**
******************************************************************************
*
* @file uavobjectparser.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Parses XML files and extracts object information.
*
* @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 "uavobjectparser.h"
#include <QByteArray>
const char* UAVObjectParser::FieldTypeStr[] = {"FIELDTYPE_INT8", "FIELDTYPE_INT16", "FIELDTYPE_INT32", "FIELDTYPE_FLOAT32", "FIELDTYPE_CHAR"};
const char* UAVObjectParser::FieldTypeStrC[] = {"int8_t", "int16_t", "int32_t", "float", "char"};
const char* UAVObjectParser::FieldTypeStrCPP[] = {"qint8", "qint16", "qint32", "float", "char"};
const char* UAVObjectParser::UpdateModeStr[] = {"UPDATEMODE_PERIODIC", "UPDATEMODE_ONCHANGE", "UPDATEMODE_MANUAL", "UPDATEMODE_NEVER"};
/**
* Constructor
*/
UAVObjectParser::UAVObjectParser()
{
}
/**
* Get number of objects
*/
int UAVObjectParser::getNumObjects()
{
return objInfo.length();
}
/**
* Get the detailed object information
*/
QList<UAVObjectParser::ObjectInfo*> UAVObjectParser::getObjectInfo()
{
return objInfo;
}
/**
* Get the name of the object
*/
QString UAVObjectParser::getObjectName(int objIndex)
{
ObjectInfo* info = objInfo[objIndex];
if (info == NULL)
{
return QString();
}
else
{
return info->name;
}
}
/**
* Get the ID of the object
*/
quint32 UAVObjectParser::getObjectID(int objIndex)
{
ObjectInfo* info = objInfo[objIndex];
if (info == NULL)
{
return 0;
}
else
{
return info->id;
}
}
/**
* Parse supplied XML file
* @param xml The xml text
* @param filename The xml filename
* @returns Null QString() on success, error message on failure
*/
QString UAVObjectParser::parseXML(QString& xml, QString& filename)
{
this->filename = filename;
// Create DOM document and parse it
QDomDocument doc("UAVObjects");
bool parsed = doc.setContent(xml);
if (!parsed) return QString("Improperly formated XML file");
// Read all objects contained in the XML file, creating an new ObjectInfo for each
QDomElement docElement = doc.documentElement();
QDomNode node = docElement.firstChild();
while ( !node.isNull() )
{
// Create new object entry
ObjectInfo* info = new ObjectInfo;
// Process object attributes
QString status = processObjectAttributes(node, info);
if (!status.isNull())
{
return status;
}
// Process child elements (fields and metadata)
QDomNode childNode = node.firstChild();
while ( !childNode.isNull() )
{
// Process element depending on its type
if ( childNode.nodeName().compare(QString("field")) == 0 )
{
QString status = processObjectFields(childNode, info);
if (!status.isNull())
{
return status;
}
}
else if ( childNode.nodeName().compare(QString("telemetrygcs")) == 0 )
{
QString status = processObjectMetadata(childNode, &info->gcsTelemetryUpdateMode,
&info->gcsTelemetryUpdatePeriod, &info->gcsTelemetryAcked);
if (!status.isNull())
{
return status;
}
}
else if ( childNode.nodeName().compare(QString("telemetryflight")) == 0 )
{
QString status = processObjectMetadata(childNode, &info->flightTelemetryUpdateMode,
&info->flightTelemetryUpdatePeriod, &info->flightTelemetryAcked);
if (!status.isNull())
{
return status;
}
}
else if ( childNode.nodeName().compare(QString("logging")) == 0 )
{
QString status = processObjectMetadata(childNode, &info->loggingUpdateMode,
&info->loggingUpdatePeriod, NULL);
if (!status.isNull())
{
return status;
}
}
else
{
return QString("Unknown object element");
}
// Get next element
childNode = childNode.nextSibling();
}
// Calculate ID
calculateID(info);
// Add object
objInfo.append(info);
// Get next object
node = node.nextSibling();
}
// Done, return null string
return QString();
}
/**
* Calculate the unique object ID based on the object information.
* The ID will change if the object definition changes, this is intentional
* and is used to avoid connecting objects with incompatible configurations.
*/
void UAVObjectParser::calculateID(ObjectInfo* info)
{
// Hash object name
quint32 hash = updateHash(info->name, 0);
// Hash object attributes
hash = updateHash(info->type, hash);
hash = updateHash(info->isSingleInst, hash);
// Hash field information
for (int n = 0; n < info->fields.length(); ++n)
{
hash = updateHash(info->fields[n]->name, hash);
hash = updateHash(info->fields[n]->numElements, hash);
hash = updateHash(info->fields[n]->type, hash);
}
// Done
info->id = hash;
}
/**
* Shift-Add-XOR hash implementation. LSB is set to zero, it is reserved
* for the ID of the metaobject.
*
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
*/
quint32 UAVObjectParser::updateHash(quint32 value, quint32 hash)
{
return (hash ^ ((hash<<5) + (hash>>2) + value)) & 0xFFFFFFFE;
}
/**
* Update the hash given a string
*/
quint32 UAVObjectParser::updateHash(QString& value, quint32 hash)
{
QByteArray bytes = value.toAscii();
quint32 hashout = hash;
for (int n = 0; n < bytes.length(); ++n)
{
hashout = updateHash(bytes[n], hashout);
}
return hashout;
}
/**
* Process the metadata part of the XML
*/
QString UAVObjectParser::processObjectMetadata(QDomNode& childNode, UpdateMode* mode, int* period, bool* acked)
{
// Get updatemode attribute
QDomNamedNodeMap elemAttributes = childNode.attributes();
QDomNode elemAttr = elemAttributes.namedItem("updatemode");
if ( elemAttr.isNull() )
{
return QString("Object:telemetrygcs:updatemode attribute is missing");
}
else
{
if ( elemAttr.nodeValue().compare(QString("periodic")) == 0 )
{
*mode = UPDATEMODE_PERIODIC;
}
else if ( elemAttr.nodeValue().compare(QString("onchange")) == 0 )
{
*mode = UPDATEMODE_ONCHANGE;
}
else if ( elemAttr.nodeValue().compare(QString("manual")) == 0 )
{
*mode = UPDATEMODE_MANUAL;
}
else if ( elemAttr.nodeValue().compare(QString("never")) == 0 )
{
*mode = UPDATEMODE_NEVER;
}
else
{
return QString("Object:telemetrygcs:updatemode attribute value is invalid");
}
}
// Get period attribute
elemAttr = elemAttributes.namedItem("period");
if ( elemAttr.isNull() )
{
return QString("Object:telemetrygcs:period attribute is missing");
}
else
{
*period = elemAttr.nodeValue().toInt();
}
// Get acked attribute (only if acked parameter is not null, not applicable for logging metadata)
if ( acked != NULL)
{
elemAttr = elemAttributes.namedItem("acked");
if ( elemAttr.isNull())
{
return QString("Object:telemetrygcs:acked attribute is missing");
}
else
{
if ( elemAttr.nodeValue().compare(QString("true")) == 0 )
{
*acked = true;
}
else if ( elemAttr.nodeValue().compare(QString("false")) == 0 )
{
*acked = false;
}
else
{
return QString("Object:telemetrygcs:acked attribute value is invalid");
}
}
}
// Done
return QString();
}
/**
* Process the object fields of the XML
*/
QString UAVObjectParser::processObjectFields(QDomNode& childNode, ObjectInfo* info)
{
// Create field
FieldInfo* field = new FieldInfo;
// Get name attribute
QDomNamedNodeMap elemAttributes = childNode.attributes();
QDomNode elemAttr = elemAttributes.namedItem("name");
if ( elemAttr.isNull() )
{
return QString("Object:field:name attribute is missing");
}
else
{
field->name = elemAttr.nodeValue();
}
// Get units attribute
elemAttr = elemAttributes.namedItem("units");
if ( elemAttr.isNull() )
{
return QString("Object:field:units attribute is missing");
}
else
{
field->units = elemAttr.nodeValue();
}
// Get type attribute
elemAttr = elemAttributes.namedItem("type");
if ( elemAttr.isNull() )
{
return QString("Object:field:type attribute is missing");
}
else
{
if ( elemAttr.nodeValue().compare(QString("int8")) == 0 )
{
field->type = FIELDTYPE_INT8;
}
else if ( elemAttr.nodeValue().compare(QString("int16")) == 0 )
{
field->type = FIELDTYPE_INT16;
}
else if ( elemAttr.nodeValue().compare(QString("int32")) == 0 )
{
field->type = FIELDTYPE_INT32;
}
else if ( elemAttr.nodeValue().compare(QString("float")) == 0 )
{
field->type = FIELDTYPE_FLOAT32;
}
else if ( elemAttr.nodeValue().compare(QString("char")) == 0 )
{
field->type = FIELDTYPE_CHAR;
}
else
{
return QString("Object:field:type attribute value is invalid");
}
}
// Get numelements attribute
elemAttr = elemAttributes.namedItem("elements");
if ( elemAttr.isNull() )
{
return QString("Object:field:elements attribute is missing");
}
else
{
field->numElements = elemAttr.nodeValue().toInt();
}
// Add field to object
info->fields.append(field);
// Done
return QString();
}
/**
* Process the object attributes from the XML
*/
QString UAVObjectParser::processObjectAttributes(QDomNode& node, ObjectInfo* info)
{
// Get name attribute
QDomNamedNodeMap attributes = node.attributes();
QDomNode attr = attributes.namedItem("name");
if ( attr.isNull() )
{
return QString("Object:name attribute is missing");
}
else
{
info->name = attr.nodeValue();
}
// Get singleinstance attribute
attr = attributes.namedItem("singleinstance");
if ( attr.isNull() )
{
return QString("Object:singleinstance attribute is missing");
}
else
{
if ( attr.nodeValue().compare(QString("true")) == 0 )
{
info->isSingleInst = true;
}
else if ( attr.nodeValue().compare(QString("false")) == 0 )
{
info->isSingleInst = false;
}
else
{
return QString("Object:singleinstance attribute value is invalid");
}
}
// Get type attribute
attr = attributes.namedItem("type");
if ( attr.isNull() )
{
return QString("Object:type attribute is missing");
}
else
{
if ( attr.nodeValue().compare(QString("data")) == 0 )
{
info->type = OBJTYPE_DATA;
}
else if ( attr.nodeValue().compare(QString("settings")) == 0 )
{
info->type = OBJTYPE_SETTINGS;
}
else
{
return QString("Object:type attribute value is invalid");
}
}
// Done
return QString();
}
/**
* Replace all the common tags from the template file with actual object
* information.
*/
void UAVObjectParser::replaceCommonTags(QString& out, ObjectInfo* info)
{
QString value;
// Replace $(XMLFILE) tag
out.replace(QString("$(XMLFILE)"), filename);
// Replace $(NAME) tag
out.replace(QString("$(NAME)"), info->name);
// Replace $(NAMELC) tag
out.replace(QString("$(NAMELC)"), info->name.toLower());
// Replace $(NAMEUC) tag
out.replace(QString("$(NAMEUC)"), info->name.toUpper());
// Replace $(OBJID) tag
out.replace(QString("$(OBJID)"), QString().setNum(info->id));
// Replace $(SINGLEINST) tag
value = boolToString( info->isSingleInst );
out.replace(QString("$(SINGLEINST)"), value);
// Replace $(FLIGHTTELEM_ACKED) tag
value = boolToString( info->flightTelemetryAcked );
out.replace(QString("$(FLIGHTTELEM_ACKED)"), value);
// Replace $(FLIGHTTELEM_UPDATEMODE) tag
value = UpdateModeStr[info->flightTelemetryUpdateMode];
out.replace(QString("$(FLIGHTTELEM_UPDATEMODE)"), value);
// Replace $(FLIGHTTELEM_UPDATEPERIOD) tag
out.replace(QString("$(FLIGHTTELEM_UPDATEPERIOD)"), QString().setNum(info->flightTelemetryUpdatePeriod));
// Replace $(GCSTELEM_ACKED) tag
value = boolToString( info->gcsTelemetryAcked );
out.replace(QString("$(GCSTELEM_ACKED)"), value);
// Replace $(GCSTELEM_UPDATEMODE) tag
value = UpdateModeStr[info->gcsTelemetryUpdateMode];
out.replace(QString("$(GCSTELEM_UPDATEMODE)"), value);
// Replace $(GCSTELEM_UPDATEPERIOD) tag
out.replace(QString("$(GCSTELEM_UPDATEPERIOD)"), QString().setNum(info->gcsTelemetryUpdatePeriod));
// Replace $(LOGGING_UPDATEMODE) tag
value = UpdateModeStr[info->loggingUpdateMode];
out.replace(QString("$(LOGGING_UPDATEMODE)"), value);
// Replace $(LOGGING_UPDATEPERIOD) tag
out.replace(QString("$(LOGGING_UPDATEPERIOD)"), QString().setNum(info->loggingUpdatePeriod));
}
/**
* Convert a boolean to string
*/
QString UAVObjectParser::boolToString(bool value)
{
if ( value )
{
return QString("1");
}
else
{
return QString("0");
}
}
/**
* Generate the flight object files
*/
bool UAVObjectParser::generateFlightObject(int objIndex, const QString& templateInclude, const QString& templateCode,
QString& outInclude, QString& outCode)
{
// Get object
ObjectInfo* info = objInfo[objIndex];
if (info == NULL) return false;
// Prepare output strings
outInclude = templateInclude;
outCode = templateCode;
// Replace common tags
replaceCommonTags(outInclude, info);
replaceCommonTags(outCode, info);
// Replace the $(DATAFIELDS) tag
QString type;
QString fields;
for (int n = 0; n < info->fields.length(); ++n)
{
// Determine type
type = FieldTypeStrC[info->fields[n]->type];
// Append field
if ( info->fields[n]->numElements > 1 )
{
fields.append( QString(" %1 %2[%3];\n").arg(type)
.arg(info->fields[n]->name).arg(info->fields[n]->numElements) );
}
else
{
fields.append( QString(" %1 %2;\n").arg(type).arg(info->fields[n]->name) );
}
}
outInclude.replace(QString("$(DATAFIELDS)"), fields);
// Done
return true;
}
/**
* Generate the GCS object files
*/
bool UAVObjectParser::generateGCSObject(int objIndex, const QString& templateInclude, const QString& templateCode,
QString& outInclude, QString& outCode)
{
// Get object
ObjectInfo* info = objInfo[objIndex];
if (info == NULL) return false;
// Prepare output strings
outInclude = templateInclude;
outCode = templateCode;
// Replace common tags
replaceCommonTags(outInclude, info);
replaceCommonTags(outCode, info);
// Replace the $(DATAFIELDS) tag
QString type;
QString fields;
for (int n = 0; n < info->fields.length(); ++n)
{
// Determine type
type = FieldTypeStrCPP[info->fields[n]->type];
// Append field
if ( info->fields[n]->numElements > 1 )
{
fields.append( QString(" %1 %2[%3];\n").arg(type).arg(info->fields[n]->name)
.arg(info->fields[n]->numElements) );
}
else
{
fields.append( QString(" %1 %2;\n").arg(type).arg(info->fields[n]->name) );
}
}
outInclude.replace(QString("$(DATAFIELDS)"), fields);
// Replace the $(FIELDSINIT) tag
QString finit;
for (int n = 0; n < info->fields.length(); ++n)
{
finit.append( QString(" fields.append(new UAVObjectField(QString(\"%1\"), QString(\"%2\"), UAVObjectField::%3, %4));\n")
.arg(info->fields[n]->name)
.arg(info->fields[n]->units)
.arg(FieldTypeStr[info->fields[n]->type])
.arg(info->fields[n]->numElements) );
}
outCode.replace(QString("$(FIELDSINIT)"), finit);
// Done
return true;
}

View File

@ -0,0 +1,120 @@
/**
******************************************************************************
*
* @file uavobjectparser.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Parses XML files and extracts object information.
*
* @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 UAVOBJECTPARSER_H
#define UAVOBJECTPARSER_H
#include <QString>
#include <QList>
#include <QDomDocument>
#include <QDomElement>
#include <QDomNode>
class UAVObjectParser
{
public:
// Types
typedef enum {
OBJTYPE_DATA = 0,
OBJTYPE_SETTINGS
} ObjectType;
typedef enum {
FIELDTYPE_INT8 = 0,
FIELDTYPE_INT16,
FIELDTYPE_INT32,
FIELDTYPE_FLOAT32,
FIELDTYPE_CHAR
} FieldType;
/**
* Object update mode
*/
typedef enum {
UPDATEMODE_PERIODIC = 0, /** Automatically update object at periodic intervals */
UPDATEMODE_ONCHANGE, /** Only update object when its data changes */
UPDATEMODE_MANUAL, /** Manually update object, by calling the updated() function */
UPDATEMODE_NEVER /** Object is never updated */
} UpdateMode;
typedef struct {
QString name;
QString units;
FieldType type;
int numElements;
} FieldInfo;
typedef struct {
QString name;
quint32 id;
ObjectType type;
bool isSingleInst;
bool flightTelemetryAcked;
UpdateMode flightTelemetryUpdateMode; /** Update mode used by the autopilot (UpdateMode) */
int flightTelemetryUpdatePeriod; /** Update period used by the autopilot (only if telemetry mode is PERIODIC) */
bool gcsTelemetryAcked;
UpdateMode gcsTelemetryUpdateMode; /** Update mode used by the GCS (UpdateMode) */
int gcsTelemetryUpdatePeriod; /** Update period used by the GCS (only if telemetry mode is PERIODIC) */
UpdateMode loggingUpdateMode; /** Update mode used by the logging module (UpdateMode) */
int loggingUpdatePeriod; /** Update period used by the logging module (only if logging mode is PERIODIC) */
QList<FieldInfo*> fields;
} ObjectInfo;
// Constants
static const char* FieldTypeStr[];
static const char* FieldTypeStrC[];
static const char* FieldTypeStrCPP[];
static const char* UpdateModeStr[];
// Functions
UAVObjectParser();
QString parseXML(QString& xml, QString& filename);
int getNumObjects();
QList<ObjectInfo*> getObjectInfo();
QString getObjectName(int objIndex);
quint32 getObjectID(int objIndex);
bool generateFlightObject(int objIndex, const QString& templateInclude, const QString& templateCode,
QString& outInclude, QString& outCode);
bool generateGCSObject(int objIndex, const QString& templateInclude, const QString& templateCode,
QString& outInclude, QString& outCode);
private:
QList<ObjectInfo*> objInfo;
QString filename;
QString processObjectAttributes(QDomNode& node, ObjectInfo* info);
QString processObjectFields(QDomNode& childNode, ObjectInfo* info);
QString processObjectMetadata(QDomNode& childNode, UpdateMode* mode, int* period, bool* acked);
void calculateID(ObjectInfo* info);
quint32 updateHash(quint32 value, quint32 hash);
quint32 updateHash(QString& value, quint32 hash);
QString boolToString(bool value);
QString updateModeToString(UpdateMode mode);
void replaceCommonTags(QString& out, ObjectInfo* info);
};
#endif // UAVOBJECTPARSER_H

View File

@ -0,0 +1,14 @@
# -------------------------------------------------
# Project created by QtCreator 2010-03-21T20:44:17
# -------------------------------------------------
QT += xml
QT -= gui
TARGET = uavobjgenerator
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
uavobjectparser.cpp \
uavobjectgenerator.cpp
HEADERS += uavobjectparser.h \
uavobjectgenerator.h

View File

@ -0,0 +1,81 @@
/**
******************************************************************************
*
* @file exampleobject.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the ExampleObject object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: exampleobject.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 "exampleobject.h"
const QString ExampleObject::NAME = QString("ExampleObject");
ExampleObject::ExampleObject(): UAVDataObject(OBJID, SINGLEINST, NAME)
{
// Create fields
QList<UAVObjectField*> fields;
fields.append(new UAVObjectField(QString("field1"), QString("unit1"), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("field2"), QString("unit2"), UAVObjectField::FIELDTYPE_INT16, 1));
fields.append(new UAVObjectField(QString("field3"), QString("unit3"), UAVObjectField::FIELDTYPE_FLOAT32, 4));
fields.append(new UAVObjectField(QString("field4"), QString("unit4"), UAVObjectField::FIELDTYPE_INT32, 1));
// Initialize object
initializeFields(fields, (quint8*)&data, NUMBYTES);
}
UAVObject::Metadata ExampleObject::getDefaultMetadata()
{
UAVObject::Metadata metadata;
metadata.gcsTelemetryAcked = 1;
metadata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
metadata.gcsTelemetryUpdatePeriod = 100;
metadata.flightTelemetryAcked = 1;
metadata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
metadata.flightTelemetryUpdatePeriod = 0;
metadata.loggingUpdateMode = UAVObject::UPDATEMODE_NEVER;
metadata.loggingUpdatePeriod = 0;
return metadata;
}
ExampleObject::DataFields ExampleObject::getData()
{
QMutexLocker locker(mutex);
return data;
}
void ExampleObject::setData(DataFields& data)
{
QMutexLocker locker(mutex);
this->data = data;
emit objectUpdatedAuto(this); // trigger object updated event
emit objectUpdated(this);
}
UAVDataObject* ExampleObject::clone(quint32 instID)
{
ExampleObject* obj = new ExampleObject();
obj->initialize(instID, this->getMetaObject());
return obj;
}

View File

@ -0,0 +1,64 @@
/**
******************************************************************************
*
* @file exampleobject.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the ExampleObject object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: exampleobject.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 EXAMPLEOBJECT_H
#define EXAMPLEOBJECT_H
#include "uavdataobject.h"
class ExampleObject: public UAVDataObject
{
public:
typedef struct {
qint8 field1;
qint16 field2;
float field3[4];
qint32 field4;
} __attribute__((packed)) DataFields;
static const quint32 OBJID = 3048370380U;
static const QString NAME;
static const bool SINGLEINST = 0;
static const quint32 NUMBYTES = sizeof(DataFields);
ExampleObject();
DataFields getData();
void setData(DataFields& data);
Metadata getDefaultMetadata();
UAVDataObject* clone(quint32 instID);
private:
DataFields data;
};
#endif // EXAMPLEOBJECT_H

View File

@ -19,9 +19,10 @@ UAVObject::Metadata TestObject1::getDefaultMetadata()
{
// Create metadata
UAVObject::Metadata metadata;
metadata.ackRequired = true;
metadata.gcsTelemetryAcked = true;
metadata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
metadata.gcsTelemetryUpdatePeriod = 200;
metadata.flightTelemetryAcked = true;
metadata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_NEVER;
metadata.flightTelemetryUpdatePeriod = 0;
metadata.loggingUpdateMode = UAVObject::UPDATEMODE_NEVER;

View File

@ -13,11 +13,13 @@ SOURCES += main.cpp \
../uavmetaobject.cpp \
../uavdataobject.cpp \
testobject1.cpp \
uavobjectstest.cpp
uavobjectstest.cpp \
../exampleobject.cpp
HEADERS += ../uavobjectmanager.h \
../uavobjectfield.h \
../uavobject.h \
../uavmetaobject.h \
../uavdataobject.h \
testobject1.h \
uavobjectstest.h
uavobjectstest.h \
../exampleobject.h

View File

@ -35,18 +35,20 @@ UAVMetaObject::UAVMetaObject(quint32 objID, const QString& name, UAVObject* pare
{
this->parent = parent;
// Setup default metadata of metaobject (can not be changed)
ownMetadata.ackRequired = 1;
ownMetadata.flightTelemetryAcked = 1;
ownMetadata.flightTelemetryUpdateMode = UPDATEMODE_ONCHANGE;
ownMetadata.flightTelemetryUpdatePeriod = 0;
ownMetadata.gcsTelemetryAcked = 1;
ownMetadata.gcsTelemetryUpdateMode = UPDATEMODE_ONCHANGE;
ownMetadata.gcsTelemetryUpdatePeriod = 0;
ownMetadata.loggingUpdateMode = UPDATEMODE_ONCHANGE;
ownMetadata.loggingUpdatePeriod = 0;
// Setup fields
QList<UAVObjectField*> fields;
fields.append(new UAVObjectField(QString("AckRequired"), QString(""), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("FlightTelemetryAcked"), QString(""), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("FlightTelemetryUpdateMode"), QString(""), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("FlightTelemetryUpdatePeriod"), QString("ms"), UAVObjectField::FIELDTYPE_INT32, 1));
fields.append(new UAVObjectField(QString("GCSTelemetryAcked"), QString(""), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("GCSTelemetryUpdateMode"), QString(""), UAVObjectField::FIELDTYPE_INT8, 1));
fields.append(new UAVObjectField(QString("GCSTelemetryUpdatePeriod"), QString("ms"), UAVObjectField::FIELDTYPE_INT32, 1));
fields.append(new UAVObjectField(QString("LoggingUpdateMode"), QString(""), UAVObjectField::FIELDTYPE_INT8, 1));

View File

@ -60,9 +60,10 @@ public:
* properties for each object and can be used by multiple modules (e.g. telemetry and logger)
*/
typedef struct {
quint8 ackRequired; /** Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) */
quint8 flightTelemetryAcked; /** Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) */
quint8 flightTelemetryUpdateMode; /** Update mode used by the autopilot (UpdateMode) */
qint32 flightTelemetryUpdatePeriod; /** Update period used by the autopilot (only if telemetry mode is PERIODIC) */
quint8 gcsTelemetryAcked; /** Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) */
quint8 gcsTelemetryUpdateMode; /** Update mode used by the GCS (UpdateMode) */
qint32 gcsTelemetryUpdatePeriod; /** Update period used by the GCS (only if telemetry mode is PERIODIC) */
quint8 loggingUpdateMode; /** Update mode used by the logging module (UpdateMode) */

View File

@ -4,7 +4,11 @@
* @file uavobjectsinit.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @brief
* @brief Initialize all objects.
* Automatically generated by the UAVObjectGenerator.
*
* @note This is an automatically generated file.
* DO NOT modify manually.
* @see The GNU Public License (GPL) Version 3
* @defgroup uavobjects_plugin
* @{
@ -26,12 +30,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "uavobjectsinit.h"
#include "exampleobject.h"
/**
* Static function used to initialize the first instance of each object.
* For each object class an entry should be made here.
* Function used to initialize the first instance of each object.
* This file is automatically updated by the UAVObjectGenerator.
*/
void UAVObjectsInitialize(UAVObjectManager* objMngr)
{
//objMngr->registerObject( new TestObject() );
objMngr->registerObject( new ExampleObject() );
}

View File

@ -0,0 +1,42 @@
/**
******************************************************************************
*
* @file uavobjectsinit.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @brief Initialize all objects.
* Automatically generated by the UAVObjectGenerator.
*
* @note This is an automatically generated file.
* DO NOT modify manually.
* @see The GNU Public License (GPL) Version 3
* @defgroup uavobjects_plugin
* @{
*
*****************************************************************************/
/*
* 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 "uavobjectsinit.h"
$(OBJINC)
/**
* Function used to initialize the first instance of each object.
* This file is automatically updated by the UAVObjectGenerator.
*/
void UAVObjectsInitialize(UAVObjectManager* objMngr)
{
$(OBJINIT)
}

View File

@ -1,14 +1,17 @@
/**
******************************************************************************
*
* @file uavobjecttemplate.cpp
* @file $(NAMELC).cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup
* @{
* @brief Implementation of the $(NAME) object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: $(XMLFILE).
* 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
@ -25,52 +28,50 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "$(NAMELC).h"
const QString $(NAME)::NAME = QString("$(NAME)");
$(NAME)::$(NAME)(): UAVDataObject(OBJID, SINGLEINST, NAME)
{
// Create fields
QList<UAVObjectField*> fields;
$(FIELDS)
// fields.append(new UAVObjectField(QString("$(FIELD_NAME)"), QString("$(FIELD_UNITS)", UAVObjectField::$(FIELD_TYPE), $(FIELD_NUMELEM));
// Initialize object
initializeFields(fields, (quint8*)&data, NUMBYTES);
}
UAVObject::Metadata $(NAME)::getDefaultMetadata()
{
UAVObject::Metadata metadata;
metadata.ackRequired = $(ACK);
metadata.gcsTelemetryUpdateMode = UAVObject::$(GCSTELEM_UPDATEMODE);
metadata.gcsTelemetryUpdatePeriod = $(GCSTELEM_UPDATEPERIOD);
metadata.flightTelemetryUpdateMode = UAVObject::$(FLIGHTTELEM_UPDATEMODE);
metadata.flightTelemetryUpdatePeriod = $(FLIGHTTELEM_UPDATEPERIOD);
metadata.loggingUpdateMode = UAVObject::$(LOGGING_UPDATEMODE);
metadata.loggingUpdatePeriod = $(LOGGING_UPDATEPERIOD);
return metadata;
}
$(NAME)::DataFields $(NAME)::getData()
{
QMutexLocker locker(mutex);
return data;
}
void $(NAME)::setData(DataFields& data)
{
QMutexLocker locker(mutex);
this->data = data;
emit objectUpdatedAuto(this); // trigger object updated event
emit objectUpdated(this);
}
UAVDataObject* $(NAME)::clone(quint32 instID)
{
$(NAME)* obj = new $(NAME)();
obj->initialize(instID, this->getMetaObject());
return obj;
}
#include "$(NAMELC).h"
const QString $(NAME)::NAME = QString("$(NAME)");
$(NAME)::$(NAME)(): UAVDataObject(OBJID, SINGLEINST, NAME)
{
// Create fields
QList<UAVObjectField*> fields;
$(FIELDSINIT)
// Initialize object
initializeFields(fields, (quint8*)&data, NUMBYTES);
}
UAVObject::Metadata $(NAME)::getDefaultMetadata()
{
UAVObject::Metadata metadata;
metadata.gcsTelemetryAcked = $(GCSTELEM_ACKED);
metadata.gcsTelemetryUpdateMode = UAVObject::$(GCSTELEM_UPDATEMODE);
metadata.gcsTelemetryUpdatePeriod = $(GCSTELEM_UPDATEPERIOD);
metadata.flightTelemetryAcked = $(FLIGHTTELEM_ACKED);
metadata.flightTelemetryUpdateMode = UAVObject::$(FLIGHTTELEM_UPDATEMODE);
metadata.flightTelemetryUpdatePeriod = $(FLIGHTTELEM_UPDATEPERIOD);
metadata.loggingUpdateMode = UAVObject::$(LOGGING_UPDATEMODE);
metadata.loggingUpdatePeriod = $(LOGGING_UPDATEPERIOD);
return metadata;
}
$(NAME)::DataFields $(NAME)::getData()
{
QMutexLocker locker(mutex);
return data;
}
void $(NAME)::setData(DataFields& data)
{
QMutexLocker locker(mutex);
this->data = data;
emit objectUpdatedAuto(this); // trigger object updated event
emit objectUpdated(this);
}
UAVDataObject* $(NAME)::clone(quint32 instID)
{
$(NAME)* obj = new $(NAME)();
obj->initialize(instID, this->getMetaObject());
return obj;
}

View File

@ -1,14 +1,17 @@
/**
******************************************************************************
*
* @file uavobjecttemplate.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup
* @{
*
******************************************************************************
*
* @file $(NAMELC).h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the $(NAME) object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: $(XMLFILE).
* 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
@ -34,10 +37,10 @@ class $(NAME): public UAVDataObject
{
public:
typedef struct {
$(DATAFIELDS)
$(DATAFIELDS)
} __attribute__((packed)) DataFields;
static const quint32 OBJID = $(OBJID);
static const quint32 OBJID = $(OBJID)U;
static const QString NAME;
static const bool SINGLEINST = $(SINGLEINST);
static const quint32 NUMBYTES = sizeof(DataFields);

View File

@ -216,7 +216,7 @@ void Telemetry::processObjectUpdates(UAVObject* obj, EventMask event, bool allIn
retries = 0;
while(retries < MAX_RETRIES && !success)
{
success = utalk->sendObject(obj, metadata.ackRequired, REQ_TIMEOUT_MS, allInstances); // call blocks until ack is received or timeout
success = utalk->sendObject(obj, metadata.gcsTelemetryAcked, REQ_TIMEOUT_MS, allInstances); // call blocks until ack is received or timeout
++retries;
}
}

View File

@ -0,0 +1,11 @@
<xml>
<object name="ExampleObject" singleinstance="false" type="data">
<field name="field1" units="unit1" type="int8" elements="1"/>
<field name="field2" units="unit2" type="int16" elements="1"/>
<field name="field3" units="unit3" type="float" elements="4"/>
<field name="field4" units="unit4" type="int32" elements="1"/>
<telemetrygcs acked="true" updatemode="periodic" period="100"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>
<logging updatemode="never" period="0"/>
</object>
</xml>