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:
parent
a64cdc64ea
commit
20378f7b6b
57
ground/src/libs/uavobjgenerator/main.cpp
Normal file
57
ground/src/libs/uavobjgenerator/main.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
234
ground/src/libs/uavobjgenerator/uavobjectgenerator.cpp
Normal file
234
ground/src/libs/uavobjgenerator/uavobjectgenerator.cpp
Normal 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;
|
||||
}
|
||||
|
57
ground/src/libs/uavobjgenerator/uavobjectgenerator.h
Normal file
57
ground/src/libs/uavobjgenerator/uavobjectgenerator.h
Normal 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
|
593
ground/src/libs/uavobjgenerator/uavobjectparser.cpp
Normal file
593
ground/src/libs/uavobjgenerator/uavobjectparser.cpp
Normal 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;
|
||||
}
|
120
ground/src/libs/uavobjgenerator/uavobjectparser.h
Normal file
120
ground/src/libs/uavobjgenerator/uavobjectparser.h
Normal 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
|
14
ground/src/libs/uavobjgenerator/uavobjgenerator.pro
Normal file
14
ground/src/libs/uavobjgenerator/uavobjgenerator.pro
Normal 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
|
81
ground/src/plugins/uavobjects/exampleobject.cpp
Normal file
81
ground/src/plugins/uavobjects/exampleobject.cpp
Normal 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;
|
||||
}
|
64
ground/src/plugins/uavobjects/exampleobject.h
Normal file
64
ground/src/plugins/uavobjects/exampleobject.h
Normal 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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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) */
|
||||
|
@ -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() );
|
||||
}
|
||||
|
42
ground/src/plugins/uavobjects/uavobjectsinittemplate.cpp
Normal file
42
ground/src/plugins/uavobjects/uavobjectsinittemplate.cpp
Normal 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)
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
11
ground/src/shared/uavobjectdefinition/exampleobject.xml
Normal file
11
ground/src/shared/uavobjectdefinition/exampleobject.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user