From 95726c7cf3f909e24c5cc5e8cd3ece56a564dff1 Mon Sep 17 00:00:00 2001 From: John Aughey Date: Sat, 16 May 2015 23:32:50 -0500 Subject: [PATCH 1/4] Adding a json object generator --- .../FlightPlan/lib/uavobject.json.template | 7 ++ .../json/uavobjectgeneratorjson.cpp | 118 ++++++++++++++++++ .../generators/json/uavobjectgeneratorjson.h | 44 +++++++ ground/uavobjgenerator/main.cpp | 12 +- ground/uavobjgenerator/uavobjgenerator.pro | 2 + 5 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 flight/modules/FlightPlan/lib/uavobject.json.template create mode 100644 ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp create mode 100644 ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.h diff --git a/flight/modules/FlightPlan/lib/uavobject.json.template b/flight/modules/FlightPlan/lib/uavobject.json.template new file mode 100644 index 00000000000..ec1daf46935 --- /dev/null +++ b/flight/modules/FlightPlan/lib/uavobject.json.template @@ -0,0 +1,7 @@ +{ + "name": "$(NAME)", + "object_id": $(UOBJID), + "fields": [ + $(DATAFIELDS) + ] +} \ No newline at end of file diff --git a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp new file mode 100644 index 00000000000..0c7eb1a76ef --- /dev/null +++ b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * + * @file uavobjectgeneratorjson.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief produce json code for uavobjects + * + * @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 "uavobjectgeneratorjson.h" +using namespace std; + +bool UAVObjectGeneratorJson::generate(UAVObjectParser *parser, QString templatepath, QString outputpath) +{ + // Load template and setup output directory + jsonCodePath = QDir(templatepath + QString("flight/modules/FlightPlan/lib")); + jsonOutputPath = QDir(outputpath + QString("json")); + jsonOutputPath.mkpath(jsonOutputPath.absolutePath()); + jsonCodeTemplate = readFile(jsonCodePath.absoluteFilePath("uavobject.json.template")); + if (jsonCodeTemplate.isEmpty()) { + std::cerr << "Problem reading json templates" << endl; + return false; + } + + // Process each object + for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) { + ObjectInfo *info = parser->getObjectByIndex(objidx); + process_object(info); + } + + return true; // if we come here everything should be fine +} + +/** + * Generate the json object files + */ +bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) +{ + if (info == NULL) { + return false; + } + + // Prepare output strings + QString outCode = jsonCodeTemplate; + + // Replace common tags + replaceCommonTags(outCode, info); + + // Replace the ($DATAFIELDS) tag + QStringList datafields; + for (int n = 0; n < info->fields.length(); ++n) { + QString f = "{\n"; + // Class header + f.append(QString(" \"name\": \"%1\",\n").arg(info->fields[n]->name)); + f.append(QString(" \"type\": %1,\n").arg(info->fields[n]->type)); + f.append(QString(" \"numElements\": %1\n").arg(info->fields[n]->numElements)); + // Only for enum types + if (info->fields[n]->type == FIELDTYPE_ENUM) { + /* + datafields.append(QString(" # Enumeration options\n")); + // Go through each option + QStringList options = info->fields[n]->options; + for (int m = 0; m < options.length(); ++m) { + QString name = options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), ""); + if (name[0].isDigit()) { + name = QString("N%1").arg(name); + } + datafields.append(QString(" %1 = %2\n").arg(name).arg(m)); + } + */ + } + // Generate element names (only if field has more than one element) + if (info->fields[n]->numElements > 1 && !info->fields[n]->defaultElementNames) { + /* + datafields.append(QString(" # Array element names\n")); + // Go through the element names + QStringList elemNames = info->fields[n]->elementNames; + for (int m = 0; m < elemNames.length(); ++m) { + QString name = elemNames[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), ""); + if (name[0].isDigit()) { + name = QString("N%1").arg(name); + } + datafields.append(QString(" %1 = %2\n").arg(name).arg(m)); + } + */ + } + f.append("}"); + datafields.append(f); + } + outCode.replace(QString("$(DATAFIELDS)"), datafields.join(",\n")); + + + // Write the Json code + bool res = writeFileIfDiffrent(jsonOutputPath.absolutePath() + "/" + info->namelc + ".json", outCode); + if (!res) { + cout << "Error: Could not write Json output files" << endl; + return false; + } + + return true; +} diff --git a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.h b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.h new file mode 100644 index 00000000000..221b96bfe9f --- /dev/null +++ b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.h @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * + * @file uavobjectgeneratorjson.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief produce json code for uavobjects + * + * @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 UAVOBJECTGENERATORJSON_H +#define UAVOBJECTGENERATORJSON_H + +#include "../generator_common.h" + +class UAVObjectGeneratorJson { +public: + bool generate(UAVObjectParser *gen, QString templatepath, QString outputpath); + +private: + bool process_object(ObjectInfo *info); + + QString jsonCodeTemplate; + QDir jsonCodePath; + QDir jsonOutputPath; +}; + +#endif diff --git a/ground/uavobjgenerator/main.cpp b/ground/uavobjgenerator/main.cpp index 55de04f3dac..d143ff6c887 100644 --- a/ground/uavobjgenerator/main.cpp +++ b/ground/uavobjgenerator/main.cpp @@ -34,6 +34,7 @@ #include "generators/gcs/uavobjectgeneratorgcs.h" #include "generators/matlab/uavobjectgeneratormatlab.h" #include "generators/python/uavobjectgeneratorpython.h" +#include "generators/json/uavobjectgeneratorjson.h" #include "generators/wireshark/uavobjectgeneratorwireshark.h" #define RETURN_ERR_USAGE 1 @@ -53,6 +54,7 @@ void usage() cout << "\t-flight build flight code" << endl; cout << "\t-java build java code" << endl; cout << "\t-python build python code" << endl; + cout << "\t-json build json code" << endl; cout << "\t-matlab build matlab code" << endl; cout << "\t-wireshark build wireshark plugin" << endl; cout << "\tIf no language is specified ( and not -none ) -> all are built." << endl; @@ -107,11 +109,12 @@ int main(int argc, char *argv[]) bool do_flight = (arguments_stringlist.removeAll("-flight") > 0); bool do_java = (arguments_stringlist.removeAll("-java") > 0); bool do_python = (arguments_stringlist.removeAll("-python") > 0); + bool do_json = (arguments_stringlist.removeAll("-json") > 0); bool do_matlab = (arguments_stringlist.removeAll("-matlab") > 0); bool do_wireshark = (arguments_stringlist.removeAll("-wireshark") > 0); bool do_none = (arguments_stringlist.removeAll("-none") > 0); // - bool do_all = ((do_gcs || do_flight || do_java || do_python || do_matlab) == false); + bool do_all = ((do_gcs || do_flight || do_java || do_python || do_json || do_matlab) == false); bool do_allObjects = true; if (arguments_stringlist.length() >= 2) { @@ -237,6 +240,13 @@ int main(int argc, char *argv[]) pygen.generate(parser, templatepath, outputpath); } + // generate json code if wanted + if (do_json | do_all) { + cout << "generating json code" << endl; + UAVObjectGeneratorJson pygen; + pygen.generate(parser, templatepath, outputpath); + } + // generate matlab code if wanted if (do_matlab | do_all) { cout << "generating matlab code" << endl; diff --git a/ground/uavobjgenerator/uavobjgenerator.pro b/ground/uavobjgenerator/uavobjgenerator.pro index d3a06d92a41..b0001c87c01 100644 --- a/ground/uavobjgenerator/uavobjgenerator.pro +++ b/ground/uavobjgenerator/uavobjgenerator.pro @@ -20,6 +20,7 @@ SOURCES += main.cpp \ generators/gcs/uavobjectgeneratorgcs.cpp \ generators/matlab/uavobjectgeneratormatlab.cpp \ generators/python/uavobjectgeneratorpython.cpp \ + generators/json/uavobjectgeneratorjson.cpp \ generators/wireshark/uavobjectgeneratorwireshark.cpp \ generators/generator_common.cpp HEADERS += uavobjectparser.h \ @@ -28,5 +29,6 @@ HEADERS += uavobjectparser.h \ generators/gcs/uavobjectgeneratorgcs.h \ generators/matlab/uavobjectgeneratormatlab.h \ generators/python/uavobjectgeneratorpython.h \ + generators/json/uavobjectgeneratorjson.h \ generators/wireshark/uavobjectgeneratorwireshark.h \ generators/generator_common.h From 2845deae98e7517fc6be8ef3ad4a23f42d989811 Mon Sep 17 00:00:00 2001 From: John Aughey Date: Sat, 16 May 2015 23:51:03 -0500 Subject: [PATCH 2/4] Fixing indent spacing for OC reasons. --- flight/modules/FlightPlan/lib/uavobject.json.template | 10 +++++----- .../generators/json/uavobjectgeneratorjson.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/flight/modules/FlightPlan/lib/uavobject.json.template b/flight/modules/FlightPlan/lib/uavobject.json.template index ec1daf46935..2bd93a5f23e 100644 --- a/flight/modules/FlightPlan/lib/uavobject.json.template +++ b/flight/modules/FlightPlan/lib/uavobject.json.template @@ -1,7 +1,7 @@ { - "name": "$(NAME)", - "object_id": $(UOBJID), - "fields": [ - $(DATAFIELDS) - ] + "name": "$(NAME)", + "object_id": $(UOBJID), + "fields": [ +$(DATAFIELDS) + ] } \ No newline at end of file diff --git a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp index 0c7eb1a76ef..0b2ee72cb71 100644 --- a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp +++ b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp @@ -66,11 +66,11 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) // Replace the ($DATAFIELDS) tag QStringList datafields; for (int n = 0; n < info->fields.length(); ++n) { - QString f = "{\n"; + QString f = " {\n"; // Class header - f.append(QString(" \"name\": \"%1\",\n").arg(info->fields[n]->name)); - f.append(QString(" \"type\": %1,\n").arg(info->fields[n]->type)); - f.append(QString(" \"numElements\": %1\n").arg(info->fields[n]->numElements)); + f.append(QString(" \"name\": \"%1\",\n").arg(info->fields[n]->name)); + f.append(QString(" \"type\": %1,\n").arg(info->fields[n]->type)); + f.append(QString(" \"numElements\": %1\n").arg(info->fields[n]->numElements)); // Only for enum types if (info->fields[n]->type == FIELDTYPE_ENUM) { /* @@ -101,7 +101,7 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) } */ } - f.append("}"); + f.append(" }"); datafields.append(f); } outCode.replace(QString("$(DATAFIELDS)"), datafields.join(",\n")); From 884ef8e9a17b1fc336b337ce45d5e15eab84a5b1 Mon Sep 17 00:00:00 2001 From: John Aughey Date: Sun, 17 May 2015 00:06:13 -0500 Subject: [PATCH 3/4] adding an unpackstr field --- .../FlightPlan/lib/uavobject.json.template | 1 + .../json/uavobjectgeneratorjson.cpp | 36 +++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/flight/modules/FlightPlan/lib/uavobject.json.template b/flight/modules/FlightPlan/lib/uavobject.json.template index 2bd93a5f23e..4432ff3da4b 100644 --- a/flight/modules/FlightPlan/lib/uavobject.json.template +++ b/flight/modules/FlightPlan/lib/uavobject.json.template @@ -1,6 +1,7 @@ { "name": "$(NAME)", "object_id": $(UOBJID), + "unpackstr": "$(UNPACKSTR)", "fields": [ $(DATAFIELDS) ] diff --git a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp index 0b2ee72cb71..cb0fd1c24e5 100644 --- a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp +++ b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp @@ -65,14 +65,35 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) // Replace the ($DATAFIELDS) tag QStringList datafields; - for (int n = 0; n < info->fields.length(); ++n) { - QString f = " {\n"; + QString unpackstr = "<"; + Q_FOREACH(const FieldInfo *field, info->fields) { + QString f = " {\n"; // Class header - f.append(QString(" \"name\": \"%1\",\n").arg(info->fields[n]->name)); - f.append(QString(" \"type\": %1,\n").arg(info->fields[n]->type)); - f.append(QString(" \"numElements\": %1\n").arg(info->fields[n]->numElements)); + f.append(QString(" \"name\": \"%1\",\n").arg(field->name)); + f.append(QString(" \"type\": %1,\n").arg(field->type)); + f.append(QString(" \"numElements\": %1\n").arg(field->numElements)); + if(field->type == FIELDTYPE_INT8) { + unpackstr.append("b"); + } else if(field->type == FIELDTYPE_INT16) { + unpackstr.append("h"); + } else if(field->type == FIELDTYPE_INT32) { + unpackstr.append("i"); + } else if(field->type == FIELDTYPE_UINT8) { + unpackstr.append("B"); + } else if(field->type == FIELDTYPE_UINT16) { + unpackstr.append("H"); + } else if(field->type == FIELDTYPE_UINT32) { + unpackstr.append("I"); + } else if(field->type == FIELDTYPE_FLOAT32) { + unpackstr.append("f"); + } else if(field->type == FIELDTYPE_ENUM) { + unpackstr.append("B"); + } else { + std::cerr << "json object generator: Unknown field type " << field->type << std::endl; + } + unpackstr.append("(").append(field->name).append(")"); // Only for enum types - if (info->fields[n]->type == FIELDTYPE_ENUM) { + if (field->type == FIELDTYPE_ENUM) { /* datafields.append(QString(" # Enumeration options\n")); // Go through each option @@ -87,7 +108,7 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) */ } // Generate element names (only if field has more than one element) - if (info->fields[n]->numElements > 1 && !info->fields[n]->defaultElementNames) { + if (field->numElements > 1 && !field->defaultElementNames) { /* datafields.append(QString(" # Array element names\n")); // Go through the element names @@ -105,6 +126,7 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) datafields.append(f); } outCode.replace(QString("$(DATAFIELDS)"), datafields.join(",\n")); + outCode.replace(QString("$(UNPACKSTR)"), unpackstr); // Write the Json code From dadb39a32771cb0b11fc56b9990b072586d3c809 Mon Sep 17 00:00:00 2001 From: John Aughey Date: Sun, 17 May 2015 00:09:18 -0500 Subject: [PATCH 4/4] adding a size output for json --- flight/modules/FlightPlan/lib/uavobject.json.template | 1 + .../uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/flight/modules/FlightPlan/lib/uavobject.json.template b/flight/modules/FlightPlan/lib/uavobject.json.template index 4432ff3da4b..15ffd2bea32 100644 --- a/flight/modules/FlightPlan/lib/uavobject.json.template +++ b/flight/modules/FlightPlan/lib/uavobject.json.template @@ -1,6 +1,7 @@ { "name": "$(NAME)", "object_id": $(UOBJID), + "size": $(SIZE), "unpackstr": "$(UNPACKSTR)", "fields": [ $(DATAFIELDS) diff --git a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp index cb0fd1c24e5..8b78aa04671 100644 --- a/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp +++ b/ground/uavobjgenerator/generators/json/uavobjectgeneratorjson.cpp @@ -66,7 +66,9 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) // Replace the ($DATAFIELDS) tag QStringList datafields; QString unpackstr = "<"; + unsigned int bytecount = 0; Q_FOREACH(const FieldInfo *field, info->fields) { + bytecount += field->numBytes; QString f = " {\n"; // Class header f.append(QString(" \"name\": \"%1\",\n").arg(field->name)); @@ -127,6 +129,7 @@ bool UAVObjectGeneratorJson::process_object(ObjectInfo *info) } outCode.replace(QString("$(DATAFIELDS)"), datafields.join(",\n")); outCode.replace(QString("$(UNPACKSTR)"), unpackstr); + outCode.replace(QString("$(SIZE)"), QString("%1").arg(bytecount)); // Write the Json code