2 Copyright (C) 1997-2017 JDERobot Developers Team 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Library General Public License for more details. 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, see <http://www.gnu.org/licenses/>. 17 Authors : Okan Asik (asik.okan@gmail.com) 22 from xml.dom
import minidom
24 from visualstates.gui.transition.transitiontype
import TransitionType
25 from visualstates.parsers.cppparser
import CPPParser
26 from visualstates.generators.basegenerator
import BaseGenerator
30 def __init__(self, libraries, config, states, globalNamespace):
31 BaseGenerator.__init__(self, libraries, config, states, globalNamespace)
35 if not os.path.exists(projectPath + os.sep +
'src'):
36 os.makedirs(projectPath + os.sep +
'src')
44 stringList.append(
'#endif')
45 sourceCode =
''.join(stringList)
46 fp = open(projectPath + os.sep +
'src' + os.sep + projectName +
'.h',
'w')
57 sourceCode =
''.join(stringList)
59 fp = open(projectPath + os.sep +
'src' + os.sep + projectName +
'.cpp',
'w')
65 sourceCode =
''.join(stringList)
66 fp = open(projectPath + os.sep + projectName +
'_runtime.py',
'w')
70 os.chmod(projectPath + os.sep + projectName +
'_runtime.py', stat.S_IEXEC | stat.S_IXOTH | stat.S_IWRITE | stat.S_IREAD)
74 cmakeString =
''.join(stringList)
75 fp = open(projectPath + os.sep +
'CMakeLists.txt',
'w')
80 xmlStr = xmlDoc.toprettyxml(indent=
' ')
81 with open(projectPath + os.sep +
'package.xml',
'w')
as f:
85 headers.append(
'#ifndef ' + projectName +
'_H\n')
86 headers.append(
'#define ' + projectName +
'_H\n\n')
88 headers.append(
'#include <ros/ros.h>\n')
89 headers.append(
'#include <visualstates/state.h>\n')
90 headers.append(
'#include <visualstates/temporaltransition.h>\n')
91 headers.append(
'#include <visualstates/conditionaltransition.h>\n')
93 for lib
in self.libraries:
94 headers.append(
'#include <')
95 headers.append(lib.strip(
'\n'))
100 for topic
in self.config.getTopics():
101 if topic[
'type']
not in typeSet:
102 headers.append(
'#include <' + topic[
'type'] +
'.h>\n')
103 typeSet.add(topic[
'type'])
110 classStr.append(
'class GlobalNamespace {\n')
111 classStr.append(
'private:\n')
112 classStr.append(
'\tros::NodeHandle nh;\n')
113 classStr.append(
'\tros::Rate rate;\n')
114 classStr.append(
'\tpthread_t thread;\n\n')
116 for topic
in config.getTopics():
117 varName = topic[
'name'].replace(
'/',
'_')
118 if varName[0] ==
'_':
119 varName = varName[1:]
121 if topic[
'opType'] ==
'Publish':
122 classStr.append(
'\tros::Publisher ' + varName +
'Pub;\n')
123 elif topic[
'opType'] ==
'Subscribe':
124 classStr.append(
'\tros::Subscriber ' + varName +
'Sub;\n')
126 types = type.split(
'/')
128 classStr.append(
'\t' + types[0] +
'::' + types[1] +
' last' + varName +
';\n')
129 classStr.append(
'\tvoid ' + varName +
'Callback(const ' + types[0] +
'::' + types[1] +
'& ' + varName +
');\n')
131 classStr.append(
'\t' + type +
' last' + varName +
';\n')
132 classStr.append(
'\tvoid ' + varName +
'Callback(const ' + type +
'& ' + varName +
');\n')
133 classStr.append(
'\n\n')
134 classStr.append(
'public:\n')
135 classStr.append(
'\tGlobalNamespace(int nodeRate);\n')
136 classStr.append(
'\tvoid startThread();\n')
137 classStr.append(
'\tstatic void* threadRunner(void*);\n')
138 classStr.append(
'\tvoid run();\n')
139 classStr.append(
'\tvoid join();\n')
140 classStr.append(
'\tvoid stop();\n\n')
142 for topic
in config.getTopics():
143 varName = topic[
'name'].replace(
'/',
'_')
144 if varName[0] ==
'_':
145 varName = varName[1:]
147 if topic[
'opType'] ==
'Subscribe':
149 types = type.split(
'/')
151 classStr.append(
'\t' + types[0] +
'::' + types[1] +
'& get' + varName +
'();\n')
153 classStr.append(
'\t' + type +
' get' + varName +
'();\n')
154 elif topic[
'opType'] ==
'Publish':
156 types = type.split(
'/')
158 classStr.append(
'\tvoid publish' + varName +
'(' + types[0] +
'::' + types[1] +
'& ' + varName +
');\n')
160 classStr.append(
'\tvoid publish' + varName +
'(' + type +
'& ' + varName +
');\n')
161 classStr.append(
'\n')
164 types, varNames, initialValues = CPPParser.parseVariables(globalNamespace.variables)
165 for i
in range(len(types)):
166 classStr.append(
'\t' + types[i] +
' ' + varNames[i] +
';\n')
167 classStr.append(
'\n')
169 returnTypes, funcNames, codes = CPPParser.parseFunctions(globalNamespace.functions)
170 for i
in range(len(returnTypes)):
171 classStr.append(
'\t' + returnTypes[i] +
' ' + funcNames[i] +
';\n')
173 classStr.append(
'};\n\n')
176 for state
in self.getAllStates():
177 classStr.append(
'class Namespace' + str(state.id) +
' {\n')
178 classStr.append(
'public:\n')
179 classStr.append(
'\tGlobalNamespace* globalNamespace;\n')
180 types, varNames, initialValues = CPPParser.parseVariables(state.getNamespace().variables)
181 for i
in range(len(types)):
182 classStr.append(types[i] +
' ' + varNames[i] +
';\n')
183 classStr.append(
'\n')
184 classStr.append(
'public:\n')
185 classStr.append(
'\tNamespace'+str(state.id)+
'(GlobalNamespace* _globalNamespace) {\n')
186 classStr.append(
'\t\tglobalNamespace = _globalNamespace;\n')
187 for i
in range(len(types)):
188 classStr.append(
'\t\t'+varNames[i] +
' = ' + initialValues[i] +
';\n')
189 classStr.append(
'\t}\n')
190 returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getNamespace().functions)
191 for i
in range(len(returnTypes)):
192 classStr.append(returnTypes[i] +
' ' + funcNames[i] +
';\n')
193 classStr.append(
'};\n\n')
196 for state
in self.getAllStates():
197 classStr.append(
'class State' + str(state.id) +
' : public State {\n')
198 classStr.append(
'public:\n')
199 classStr.append(
'\tGlobalNamespace* globalNamespace;\n')
200 if state.parent
is not None:
201 classStr.append(
'\tNamespace' + str(state.parent.id)+
'* stateNamespace;\n')
202 classStr.append(
'\tState' + str(state.id) +
'(int id, bool initial, GlobalNamespace* _globalNamespace,'\
203 ' Namespace'+str(state.parent.id)+
'* _stateNamespace, int cycleDuration, State* parent, RunTimeGui* gui):\n')
205 '\t\tState(id, initial, cycleDuration, parent, gui) {\nglobalNamespace = _globalNamespace;\nstateNamespace = _stateNamespace;\n}\n')
207 classStr.append(
'\tState' + str(state.id) +
'(int id, bool initial, GlobalNamespace* _globalNamespace,\ 208 int cycleDuration, State* parent, RunTimeGui* gui):\n')
210 '\t\tState(id, initial, cycleDuration, parent, gui) {\nglobalNamespace = _globalNamespace;\n}\n')
211 classStr.append(
'\tvirtual void runCode();\n')
212 classStr.append(
'};\n\n')
215 for state
in self.getAllStates():
216 stateStrList.append(
'void State' + str(state.id) +
'::runCode() {\n')
217 for codeLine
in state.getCode().split(
'\n'):
218 stateStrList.append(
'\t' + codeLine +
'\n')
219 stateStrList.append(
'}\n\n')
222 for tran
in self.getAllTransitions():
223 if tran.getType() == TransitionType.CONDITIONAL:
224 classStr.append(
'class Tran' + str(tran.id) +
' : public ConditionalTransition {\n')
225 classStr.append(
'\tpublic:\n')
226 classStr.append(
'\tGlobalNamespace* globalNamespace;\n')
227 if tran.origin.parent
is not None:
228 classStr.append(
'Namespace' + str(tran.origin.parent.id) +
'* stateNamespace;\n\n')
229 classStr.append(
'\tTran' + str(tran.id) +
'(int id, int destId, GlobalNamespace* _globalNamespace, \ 230 Namespace'+str(tran.origin.parent.id)+
'* _stateNamespace):\n')
231 classStr.append(
'ConditionalTransition(id, destId) {\nglobalNamespace = _globalNamespace;\n\ 232 stateNamespace = _stateNamespace;}\n')
234 classStr.append(
'\tTran' + str(tran.id) +
'(int id, int destId, GlobalNamespace* _globalNamespace):\n')
235 classStr.append(
'ConditionalTransition(id, destId) {globalNamespace = _globalNamespace;}\n')
236 classStr.append(
'\tvirtual void init();\n')
237 classStr.append(
'\tvirtual bool checkCondition();\n')
238 classStr.append(
'\tvirtual void runCode();\n')
239 classStr.append(
'};\n\n')
240 elif tran.getType() == TransitionType.TEMPORAL:
241 classStr.append(
'class Tran' + str(tran.id) +
' : public TemporalTransition {\n')
242 classStr.append(
'\tpublic:\n')
243 classStr.append(
'\tTran' + str(tran.id) +
'(int id, int destId, int elapsedTime):TemporalTransition(id, destId, elapsedTime) {}\n')
244 classStr.append(
'\tvirtual void runCode();\n')
245 classStr.append(
'};\n\n')
248 for tran
in self.getAllTransitions():
249 if tran.getType() == TransitionType.CONDITIONAL:
251 tranStr.append(
'void Tran' + str(tran.id) +
'::init() {\n')
252 tranStr.append(
'}\n\n')
253 tranStr.append(
'bool Tran' + str(tran.id) +
'::checkCondition() {\n')
254 for codeLine
in tran.getCondition().split(
'\n'):
255 tranStr.append(
'\t' + codeLine +
'\n')
256 tranStr.append(
'}\n')
258 tranStr.append(
'void Tran' + str(tran.id) +
'::runCode() {\n')
259 for codeLine
in tran.getCode().split(
'\n'):
260 tranStr.append(
'\t' + codeLine +
'\n')
261 tranStr.append(
'}\n\n')
264 headerStr.append(
'#include "' + projectName +
'.h"\n')
265 headerStr.append(
'#include <iostream>\n')
266 headerStr.append(
'#include <string>\n')
267 headerStr.append(
'#include <signal.h>\n')
268 headerStr.append(
'#include <visualstates/runtimegui.h>\n\n')
271 rosStr.append(
'GlobalNamespace::GlobalNamespace(int nodeRate):rate(nodeRate) {\n')
272 for topic
in config.getTopics():
273 varName = topic[
'name'].replace(
'/',
'_')
274 if varName[0] ==
'_':
275 varName = varName[1:]
278 types = type.split(
'/')
279 if topic[
'opType'] ==
'Publish':
281 rosStr.append(
'\t' + varName +
'Pub = nh.advertise<' + types[0] +
'::' + types[1] +
'>("' + topic[
'name'] +
'", 10);\n')
283 rosStr.append(
'\t' + varName +
'Pub = nh.advertise<' + type +
'>("' + topic[
284 'name'] +
'", 10);\n')
285 elif topic[
'opType'] ==
'Subscribe':
286 rosStr.append(
'\t' + varName +
'Sub = nh.subscribe("' + topic[
'name'] +
'", 10, &GlobalNamespace::'+varName+
'Callback, this);\n')
289 types, varNames, initialValues = CPPParser.parseVariables(globalNamespace.variables)
290 for i
in range(len(types)):
291 if initialValues[i]
is not None:
292 rosStr.append(
'\t' + varNames[i] +
' = ' + initialValues[i] +
';\n')
294 rosStr.append(
'}\n\n')
296 rosStr.append(
'void* GlobalNamespace::threadRunner(void* owner) {\n')
297 rosStr.append(
'\t((GlobalNamespace*)owner)->run();\n')
298 rosStr.append(
'}\n\n')
300 rosStr.append(
'void GlobalNamespace::startThread() {\n')
301 rosStr.append(
'\tpthread_create(&thread, NULL, &GlobalNamespace::threadRunner, this);\n')
302 rosStr.append(
'}\n\n')
304 rosStr.append(
'void GlobalNamespace::run() {\n')
305 rosStr.append(
'\twhile(nh.ok()) {\n')
306 rosStr.append(
'\t\tros::spinOnce();\n')
307 rosStr.append(
'\t\trate.sleep();\n')
308 rosStr.append(
'\t}\n')
309 rosStr.append(
'}\n\n')
311 rosStr.append(
'void GlobalNamespace::join() {\n')
312 rosStr.append(
'\tpthread_join(thread, NULL);\n')
313 rosStr.append(
'}\n\n')
315 rosStr.append(
'void GlobalNamespace::stop() {\n')
316 rosStr.append(
'\tnh.shutdown();\n')
317 rosStr.append(
'}\n\n')
319 for topic
in config.getTopics():
320 varName = topic[
'name'].replace(
'/',
'_')
321 if varName[0] ==
'_':
322 varName = varName[1:]
324 if topic[
'opType'] ==
'Subscribe':
326 types = type.split(
'/')
328 rosStr.append(
'void GlobalNamespace::' + varName +
'Callback(const ' + types[0] +
'::' + types[1] +
'& ' + varName +
') {\n')
330 rosStr.append(
'void GlobalNamespace::' + varName +
'Callback(const ' + type +
'& ' + varName +
') {\n')
331 rosStr.append(
'\tlast' + varName +
' = ' + varName +
';\n')
332 rosStr.append(
'}\n\n')
335 rosStr.append(types[0] +
'::' + types[1] +
'& GlobalNamespace::get' + varName +
'() {\n')
337 rosStr.append(type +
'& GlobalNamespace::get' + varName +
'() {\n')
338 rosStr.append(
'\treturn last' + varName +
';\n')
339 rosStr.append(
'}\n\n')
341 elif topic[
'opType'] ==
'Publish':
343 types = type.split(
'/')
345 rosStr.append(
'void GlobalNamespace::publish' + varName +
'(' + types[0] +
'::' + types[
346 1] +
'& ' + varName +
') {\n')
348 rosStr.append(
'void GlobalNamespace::publish' + varName +
'(' + type +
'& ' + varName +
') {\n')
349 rosStr.append(
'\t' + varName +
'Pub.publish(' + varName +
');\n')
350 rosStr.append(
'}\n\n')
352 returnTypes, funcNames, codes = CPPParser.parseFunctions(globalNamespace.functions)
353 for i
in range(len(returnTypes)):
354 rosStr.append(returnTypes[i] +
' GlobalNamespace::' + funcNames[i] +
'\n')
355 rosStr.append(codes[i])
356 rosStr.append(
'\n\n')
359 for state
in self.getAllStates():
360 namespace = state.getNamespace()
361 returnTypes, funcNames, codes = CPPParser.parseFunctions(namespace.functions)
362 for i
in range(len(returnTypes)):
363 strList.append(returnTypes[i] +
' Namespace'+str(state.id)+
'::' + funcNames[i] +
'\n')
364 strList.append(codes[i])
365 strList.append(
'\n\n')
368 if state.parent
is None:
371 return 'state'+str(state.parent.id)
374 for state
in self.states:
375 mainStr.append(
'State* state' + str(state.id) +
' = NULL;\n')
376 mainStr.append(
'GlobalNamespace* globalNamespace = NULL;\n\n')
378 mainStr.append(
'void signalCallback(int signum) {\n')
379 for state
in self.states:
380 mainStr.append(
'\tstate' + str(state.id) +
'->stop();\n')
381 mainStr.append(
'\tglobalNamespace->stop();\n')
382 mainStr.append(
'}\n\n')
384 mainStr.append(
'int main(int argc, char* argv[]) {\n')
385 mainStr.append(
'\tros::init(argc, argv,"' + projectName +
'_node");\n')
386 mainStr.append(
'\tRunTimeGui* runTimeGui = new RunTimeGui();\n\n')
387 mainStr.append(
'\tglobalNamespace = new GlobalNamespace(100);\n')
388 mainStr.append(
'\tglobalNamespace->startThread();\n\n')
390 for state
in self.getAllStates():
391 mainStr.append(
'\tNamespace' + str(state.id) +
' stateNamespace' + str(state.id) +
'(globalNamespace);\n')
392 if state.parent
is not None:
393 mainStr.append(
'\tState* state' + str(state.id) +
' = new State' + str(state.id) +
'(' +
394 str(state.id) +
', ' + str(state.initial).lower() +
', globalNamespace, &stateNamespace' + str(state.parent.id) +
', ' + str(
395 state.getTimeStep()) +
398 mainStr.append(
'\tstate' + str(state.id) +
' = new State' + str(state.id) +
'(' +
399 str(state.id) +
', ' + str(state.initial).lower() +
', globalNamespace, ' + str(state.getTimeStep()) +
404 for tran
in self.getAllTransitions():
405 if tran.getType() == TransitionType.CONDITIONAL:
406 mainStr.append(
'\tTransition* tran' + str(tran.id) +
' = new Tran' + str(tran.id) +
'(' + str(tran.id) +
407 ', ' + str(tran.destination.id) +
', globalNamespace, &stateNamespace'+str(tran.origin.parent.id)+
');\n')
408 elif tran.getType() == TransitionType.TEMPORAL:
409 mainStr.append(
'\tTransition* tran' + str(tran.id) +
' = new Tran' + str(tran.id) +
'(' + str(tran.id) +
410 ', ' + str(tran.destination.id) +
', ' + str(tran.getTemporalTime()) +
');\n')
412 mainStr.append(
'\tstate' + str(tran.origin.id) +
'->addTransition(tran' + str(tran.id) +
');\n')
415 for state
in self.states:
416 mainStr.append(
'\tstate' + str(state.id) +
'->startThread();\n')
419 mainStr.append(
'\tsignal(SIGINT, signalCallback);\n')
421 for state
in self.states:
422 mainStr.append(
'\tstate' + str(state.id) +
'->join();\n')
423 mainStr.append(
'\tglobalNamespace->join();\n')
424 mainStr.append(
'}\n')
427 guiStr.append(
'#!/usr/bin/python\n')
428 guiStr.append(
'# -*- coding: utf-8 -*-\n')
431 guiStr.append(
'import sys\n')
432 guiStr.append(
'from PyQt5.QtWidgets import QApplication\n')
433 guiStr.append(
'from visualstates.codegen.python.runtimegui import RunTimeGui\n')
434 guiStr.append(
'import rospy\n')
435 guiStr.append(
'from std_msgs.msg import String\n\n')
436 guiStr.append(
'gui = None\n\n')
437 guiStr.append(
'def callback(string_msg):\n')
438 guiStr.append(
'\tglobal gui\n')
439 guiStr.append(
'\tstate_id = int(string_msg.data)\n')
440 guiStr.append(
'\tgui.emitRunningStateById(state_id)\n\n\n')
441 guiStr.append(
'def runGui():\n')
442 guiStr.append(
'\tglobal gui\n')
443 guiStr.append(
'\trospy.init_node("runtime_gui", anonymous=True)\n')
444 guiStr.append(
'\trunningStateSubs = rospy.Subscriber("/runtime_gui", String, callback)\n\n')
445 guiStr.append(
'\tapp = QApplication(sys.argv)\n')
446 guiStr.append(
'\tgui = RunTimeGui()\n\n')
449 for state
in self.getAllStates():
450 guiStr.append(
'\tgui.addState(' + str(state.id) +
', "' + state.name +
451 '", ' + str(state.initial) +
', ' + str(state.x) +
', ' + str(state.y))
452 if state.parent
is None:
453 guiStr.append(
', None)\n')
455 guiStr.append(
', ' + str(state.parent.id) +
')\n')
458 for tran
in self.getAllTransitions():
459 guiStr.append(
'\tgui.addTransition(' + str(tran.id) +
', "' + tran.name +
'", ' +
460 str(tran.origin.id) +
', ' + str(tran.destination.id) +
461 ', ' + str(tran.x) +
', ' + str(tran.y) +
')\n')
464 guiStr.append(
'\tgui.emitLoadFromRoot()\n')
465 guiStr.append(
'\tgui.emitActiveStateById(0)\n')
466 guiStr.append(
'\tgui.show()\n')
467 guiStr.append(
'\tapp.exec_()\n\n')
469 guiStr.append(
'if __name__ == "__main__":\n')
470 guiStr.append(
'\trunGui()\n\n')
474 cmakeStr.append(
'project(')
475 cmakeStr.append(projectName)
476 cmakeStr.append(
')\n\n')
478 cmakeStr.append(
'cmake_minimum_required(VERSION 2.8.3)\n\n')
480 cmakeStr.append(
'find_package(catkin REQUIRED COMPONENTS roscpp visualstates\n')
481 for dep
in config.getBuildDependencies():
482 cmakeStr.append(
' ' + dep +
'\n')
483 cmakeStr.append(
')\n\n')
486 ${catkin_INCLUDE_DIRS} 490 cmakeStr.append(myStr)
492 cmakeStr.append(
'catkin_package()\n')
493 cmakeStr.append(
'add_executable(' + projectName +
' src/' + projectName +
'.cpp)\n')
494 cmakeStr.append(
'target_link_libraries(' + projectName +
' ${catkin_LIBRARIES} visualStatesRunTime)\n')
495 cmakeStr.append(
'install(TARGETS ' + projectName +
' RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})\n\n')
496 cmakeStr.append(
'catkin_install_python(PROGRAMS ' + projectName +
'_runtime.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})\n\n')
500 doc = minidom.Document()
501 root = doc.createElement(
'package')
502 nameElement = doc.createElement(
'name')
503 nameElement.appendChild(doc.createTextNode(projectName))
504 root.appendChild(nameElement)
505 versionElement = doc.createElement(
'version')
506 versionElement.appendChild(doc.createTextNode(
'0.0.0'))
507 root.appendChild(versionElement)
508 descElement = doc.createElement(
'description')
509 descElement.appendChild(doc.createTextNode(
'The ' + projectName +
' package'))
510 root.appendChild(descElement)
511 maintainerElement = doc.createElement(
'maintainer')
512 maintainerElement.setAttribute(
'email',
'todo@todo.todo')
513 maintainerElement.appendChild(doc.createTextNode(
'todo'))
514 root.appendChild(maintainerElement)
515 licenseElement = doc.createElement(
'license')
516 licenseElement.appendChild(doc.createTextNode(
'TODO (choose one: BSD, MIT, GPLv2, GPLv3 LGPLv3)'))
517 root.appendChild(licenseElement)
518 btoolDepElement = doc.createElement(
'buildtool_depend')
519 btoolDepElement.appendChild(doc.createTextNode(
'catkin'))
520 root.appendChild(btoolDepElement)
521 for bdep
in [
'visualstates']+config.getBuildDependencies():
522 bdepElement = doc.createElement(
'build_depend')
523 bdepElement.appendChild(doc.createTextNode(bdep))
524 root.appendChild(bdepElement)
526 for rdep
in [
'visualstates']+config.getRunDependencies():
527 rdepElement = doc.createElement(
'run_depend')
528 rdepElement.appendChild(doc.createTextNode(rdep))
529 root.appendChild(rdepElement)
531 exportElement = doc.createElement(
'export')
532 root.appendChild(exportElement)
533 doc.appendChild(root)
def generateRunTimeGui(self, guiStr)
def parentString(self, state)
def generatePackageXml(self, config, projectName)
def generateTranMethods(self, tranStr)
def generateHeadersForCpp(self, headerStr, projectName)
def generateTransitionClasses(self, classStr)
def generateStateNamespaceClass(self, classStr)
def generateMain(self, mainStr, projectName)
def generateStateClasses(self, classStr)
def generateGlobalNamespaceClass(self, classStr, config, globalNamespace)
def generate(self, projectPath, projectName)
def generateCmake(self, cmakeStr, projectName, config)
def generateHeaders(self, headers, projectName)
def generateStateNamespaceMethods(self, strList)
def generateGlobalNamespaceMethods(self, rosStr, config, globalNamespace)
def generateStateMethods(self, stateStrList)
def __init__(self, libraries, config, states, globalNamespace)