Merged in f5soh/librepilot/LP-607_world_mag_model_2015v2 (pull request #526)
[librepilot.git] / ground / uavobjgenerator / generators / python / uavobjectgeneratorpython.cpp
blob80c3883bad70a3c8380caeacbcdc94953e0c0b61
1 /**
2 ******************************************************************************
4 * @file uavobjectgeneratorpython.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @brief produce python code for uavobjects
8 * @see The GNU Public License (GPL) Version 3
10 *****************************************************************************/
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "uavobjectgeneratorpython.h"
28 using namespace std;
30 bool UAVObjectGeneratorPython::generate(UAVObjectParser *parser, QString templatepath, QString outputpath)
32 // Load template and setup output directory
33 pythonCodePath = QDir(templatepath + QString("flight/modules/FlightPlan/lib"));
34 pythonOutputPath = QDir(outputpath);
35 pythonOutputPath.mkpath(pythonOutputPath.absolutePath());
36 pythonCodeTemplate = readFile(pythonCodePath.absoluteFilePath("uavobject.pyt.template"));
37 if (pythonCodeTemplate.isEmpty()) {
38 std::cerr << "Problem reading python templates" << endl;
39 return false;
42 // Process each object
43 for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) {
44 ObjectInfo *info = parser->getObjectByIndex(objidx);
45 process_object(info);
48 return true; // if we come here everything should be fine
51 /**
52 * Generate the python object files
54 bool UAVObjectGeneratorPython::process_object(ObjectInfo *info)
56 if (info == NULL) {
57 return false;
60 // Prepare output strings
61 QString outCode = pythonCodeTemplate;
63 // Replace common tags
64 replaceCommonTags(outCode, info);
66 // Replace the ($DATAFIELDS) tag
67 QString datafields;
68 for (int n = 0; n < info->fields.length(); ++n) {
69 // Class header
70 datafields.append(QString("# Field %1 definition\n").arg(info->fields[n]->name));
71 datafields.append(QString("class %1Field(UAVObjectField):\n").arg(info->fields[n]->name));
72 // Only for enum types
73 if (info->fields[n]->type == FIELDTYPE_ENUM) {
74 datafields.append(QString(" # Enumeration options\n"));
75 // Go through each option
76 QStringList options = info->fields[n]->options;
77 for (int m = 0; m < options.length(); ++m) {
78 QString name = options[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), "");
79 if (name[0].isDigit()) {
80 name = QString("N%1").arg(name);
82 datafields.append(QString(" %1 = %2\n").arg(name).arg(m));
85 // Generate element names (only if field has more than one element)
86 if (info->fields[n]->numElements > 1 && !info->fields[n]->defaultElementNames) {
87 datafields.append(QString(" # Array element names\n"));
88 // Go through the element names
89 QStringList elemNames = info->fields[n]->elementNames;
90 for (int m = 0; m < elemNames.length(); ++m) {
91 QString name = elemNames[m].toUpper().replace(QRegExp(ENUM_SPECIAL_CHARS), "");
92 if (name[0].isDigit()) {
93 name = QString("N%1").arg(name);
95 datafields.append(QString(" %1 = %2\n").arg(name).arg(m));
98 // Constructor
99 datafields.append(QString(" def __init__(self):\n"));
100 datafields.append(QString(" UAVObjectField.__init__(self, %1, %2)\n\n").arg(info->fields[n]->type).arg(info->fields[n]->numElements));
102 outCode.replace(QString("$(DATAFIELDS)"), datafields);
104 // Replace the $(DATAFIELDINIT) tag
105 QString fields;
106 for (int n = 0; n < info->fields.length(); ++n) {
107 fields.append(QString(" self.%1 = %1Field()\n").arg(info->fields[n]->name));
108 fields.append(QString(" self.addField(self.%1)\n").arg(info->fields[n]->name));
110 outCode.replace(QString("$(DATAFIELDINIT)"), fields);
112 // Write the Python code
113 bool res = writeFileIfDifferent(pythonOutputPath.absolutePath() + "/" + info->namelc + ".py", outCode);
114 if (!res) {
115 cout << "Error: Could not write Python output files" << endl;
116 return false;
119 return true;