cpprosgenerator.py
Go to the documentation of this file.
1 '''
2  Copyright (C) 1997-2017 JDERobot Developers Team
3 
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.
8 
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.
13 
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/>.
16 
17  Authors : Okan Asik (asik.okan@gmail.com)
18 
19  '''
20 import os
21 import stat
22 from xml.dom import minidom
23 
24 from visualstates.gui.transition.transitiontype import TransitionType
25 from visualstates.parsers.cppparser import CPPParser
26 from visualstates.generators.basegenerator import BaseGenerator
27 
28 
29 class CppRosGenerator(BaseGenerator):
30  def __init__(self, libraries, config, states, globalNamespace):
31  BaseGenerator.__init__(self, libraries, config, states, globalNamespace)
32 
33  def generate(self, projectPath, projectName):
34  # create source dir if not exists
35  if not os.path.exists(projectPath + os.sep + 'src'):
36  os.makedirs(projectPath + os.sep + 'src')
37 
38  stringList = []
39  self.generateHeaders(stringList, projectName)
40  self.generateGlobalNamespaceClass(stringList, self.config, self.globalNamespace)
41  self.generateStateNamespaceClass(stringList)
42  self.generateStateClasses(stringList)
43  self.generateTransitionClasses(stringList)
44  stringList.append('#endif')
45  sourceCode = ''.join(stringList)
46  fp = open(projectPath + os.sep + 'src' + os.sep + projectName + '.h', 'w')
47  fp.write(sourceCode)
48  fp.close()
49 
50  stringList = []
51  self.generateHeadersForCpp(stringList, projectName)
52  self.generateStateMethods(stringList)
53  self.generateTranMethods(stringList)
54  self.generateGlobalNamespaceMethods(stringList, self.config, self.globalNamespace)
55  self.generateStateNamespaceMethods(stringList)
56  self.generateMain(stringList, projectName)
57  sourceCode = ''.join(stringList)
58 
59  fp = open(projectPath + os.sep + 'src' + os.sep + projectName + '.cpp', 'w')
60  fp.write(sourceCode)
61  fp.close()
62 
63  stringList = []
64  self.generateRunTimeGui(stringList)
65  sourceCode = ''.join(stringList)
66  fp = open(projectPath + os.sep + projectName + '_runtime.py', 'w')
67  fp.write(sourceCode)
68  fp.close()
69  # make runtime gui python file executable
70  os.chmod(projectPath + os.sep + projectName + '_runtime.py', stat.S_IEXEC | stat.S_IXOTH | stat.S_IWRITE | stat.S_IREAD)
71 
72  stringList = []
73  self.generateCmake(stringList, projectName, self.config)
74  cmakeString = ''.join(stringList)
75  fp = open(projectPath + os.sep + 'CMakeLists.txt', 'w')
76  fp.write(cmakeString)
77  fp.close()
78 
79  xmlDoc = self.generatePackageXml(self.config, projectName)
80  xmlStr = xmlDoc.toprettyxml(indent=' ')
81  with open(projectPath + os.sep + 'package.xml', 'w') as f:
82  f.write(xmlStr)
83 
84  def generateHeaders(self, headers, projectName):
85  headers.append('#ifndef ' + projectName + '_H\n')
86  headers.append('#define ' + projectName + '_H\n\n')
87 
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')
92 
93  for lib in self.libraries:
94  headers.append('#include <')
95  headers.append(lib.strip('\n'))
96  headers.append('>\n')
97 
98  # generate ros message headers
99  typeSet = {''} # create set
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'])
104 
105  headers.append('\n')
106 
107  return headers
108 
109  def generateGlobalNamespaceClass(self, classStr, config, globalNamespace):
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')
115 
116  for topic in config.getTopics():
117  varName = topic['name'].replace('/', '_')
118  if varName[0] == '_':
119  varName = varName[1:]
120 
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')
125  type = topic['type']
126  types = type.split('/')
127  if len(types) == 2:
128  classStr.append('\t' + types[0] + '::' + types[1] + ' last' + varName + ';\n')
129  classStr.append('\tvoid ' + varName + 'Callback(const ' + types[0] + '::' + types[1] + '& ' + varName + ');\n')
130  else:
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')
141 
142  for topic in config.getTopics():
143  varName = topic['name'].replace('/', '_')
144  if varName[0] == '_':
145  varName = varName[1:]
146 
147  if topic['opType'] == 'Subscribe':
148  type = topic['type']
149  types = type.split('/')
150  if len(types) == 2:
151  classStr.append('\t' + types[0] + '::' + types[1] + '& get' + varName + '();\n')
152  else:
153  classStr.append('\t' + type + ' get' + varName + '();\n')
154  elif topic['opType'] == 'Publish':
155  type = topic['type']
156  types = type.split('/')
157  if len(types) == 2:
158  classStr.append('\tvoid publish' + varName + '(' + types[0] + '::' + types[1] + '& ' + varName + ');\n')
159  else:
160  classStr.append('\tvoid publish' + varName + '(' + type + '& ' + varName + ');\n')
161  classStr.append('\n')
162 
163  # define variables
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')
168 
169  returnTypes, funcNames, codes = CPPParser.parseFunctions(globalNamespace.functions)
170  for i in range(len(returnTypes)):
171  classStr.append('\t' + returnTypes[i] + ' ' + funcNames[i] + ';\n')
172 
173  classStr.append('};\n\n')
174 
175  def generateStateNamespaceClass(self, classStr):
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')
194 
195  def generateStateClasses(self, classStr):
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')
204  classStr.append(
205  '\t\tState(id, initial, cycleDuration, parent, gui) {\nglobalNamespace = _globalNamespace;\nstateNamespace = _stateNamespace;\n}\n')
206  else:
207  classStr.append('\tState' + str(state.id) + '(int id, bool initial, GlobalNamespace* _globalNamespace,\
208 int cycleDuration, State* parent, RunTimeGui* gui):\n')
209  classStr.append(
210  '\t\tState(id, initial, cycleDuration, parent, gui) {\nglobalNamespace = _globalNamespace;\n}\n')
211  classStr.append('\tvirtual void runCode();\n')
212  classStr.append('};\n\n')
213 
214  def generateStateMethods(self, stateStrList):
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')
220 
221  def generateTransitionClasses(self, classStr):
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')
233  else:
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')
246 
247  def generateTranMethods(self, tranStr):
248  for tran in self.getAllTransitions():
249  if tran.getType() == TransitionType.CONDITIONAL:
250  #todo: currently user does not provide init method
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')
257 
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')
262 
263  def generateHeadersForCpp(self, headerStr, projectName):
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')
269 
270  def generateGlobalNamespaceMethods(self, rosStr, config, globalNamespace):
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:]
276 
277  type = topic['type']
278  types = type.split('/')
279  if topic['opType'] == 'Publish':
280  if len(types) == 2:
281  rosStr.append('\t' + varName + 'Pub = nh.advertise<' + types[0] + '::' + types[1] + '>("' + topic['name'] + '", 10);\n')
282  else:
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')
287 
288  # set inital values of variables
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')
293 
294  rosStr.append('}\n\n')
295 
296  rosStr.append('void* GlobalNamespace::threadRunner(void* owner) {\n')
297  rosStr.append('\t((GlobalNamespace*)owner)->run();\n')
298  rosStr.append('}\n\n')
299 
300  rosStr.append('void GlobalNamespace::startThread() {\n')
301  rosStr.append('\tpthread_create(&thread, NULL, &GlobalNamespace::threadRunner, this);\n')
302  rosStr.append('}\n\n')
303 
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')
310 
311  rosStr.append('void GlobalNamespace::join() {\n')
312  rosStr.append('\tpthread_join(thread, NULL);\n')
313  rosStr.append('}\n\n')
314 
315  rosStr.append('void GlobalNamespace::stop() {\n')
316  rosStr.append('\tnh.shutdown();\n')
317  rosStr.append('}\n\n')
318 
319  for topic in config.getTopics():
320  varName = topic['name'].replace('/', '_')
321  if varName[0] == '_':
322  varName = varName[1:]
323 
324  if topic['opType'] == 'Subscribe':
325  type = topic['type']
326  types = type.split('/')
327  if len(types) == 2:
328  rosStr.append('void GlobalNamespace::' + varName + 'Callback(const ' + types[0] + '::' + types[1] + '& ' + varName + ') {\n')
329  else:
330  rosStr.append('void GlobalNamespace::' + varName + 'Callback(const ' + type + '& ' + varName + ') {\n')
331  rosStr.append('\tlast' + varName + ' = ' + varName + ';\n')
332  rosStr.append('}\n\n')
333 
334  if len(types) == 2:
335  rosStr.append(types[0] + '::' + types[1] + '& GlobalNamespace::get' + varName + '() {\n')
336  else:
337  rosStr.append(type + '& GlobalNamespace::get' + varName + '() {\n')
338  rosStr.append('\treturn last' + varName + ';\n')
339  rosStr.append('}\n\n')
340 
341  elif topic['opType'] == 'Publish':
342  type = topic['type']
343  types = type.split('/')
344  if len(types) == 2:
345  rosStr.append('void GlobalNamespace::publish' + varName + '(' + types[0] + '::' + types[
346  1] + '& ' + varName + ') {\n')
347  else:
348  rosStr.append('void GlobalNamespace::publish' + varName + '(' + type + '& ' + varName + ') {\n')
349  rosStr.append('\t' + varName + 'Pub.publish(' + varName + ');\n')
350  rosStr.append('}\n\n')
351 
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')
357 
358  def generateStateNamespaceMethods(self, strList):
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')
366 
367  def parentString(self, state):
368  if state.parent is None:
369  return 'NULL'
370  else:
371  return 'state'+str(state.parent.id)
372 
373  def generateMain(self, mainStr, projectName):
374  for state in self.states:
375  mainStr.append('State* state' + str(state.id) + ' = NULL;\n')
376  mainStr.append('GlobalNamespace* globalNamespace = NULL;\n\n')
377 
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')
383 
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')
389  # create state instances
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()) +
396  ', ' + self.parentString(state) + ', runTimeGui);\n')
397  else:
398  mainStr.append('\tstate' + str(state.id) + ' = new State' + str(state.id) + '(' +
399  str(state.id) + ', ' + str(state.initial).lower() + ', globalNamespace, ' + str(state.getTimeStep()) +
400  ', ' + self.parentString(state) + ', runTimeGui);\n')
401  mainStr.append('\n')
402 
403  # create transition instances
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')
411 
412  mainStr.append('\tstate' + str(tran.origin.id) + '->addTransition(tran' + str(tran.id) + ');\n')
413  mainStr.append('\n')
414 
415  for state in self.states:
416  mainStr.append('\tstate' + str(state.id) + '->startThread();\n')
417  mainStr.append('\n')
418 
419  mainStr.append('\tsignal(SIGINT, signalCallback);\n')
420 
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')
425 
426  def generateRunTimeGui(self, guiStr):
427  guiStr.append('#!/usr/bin/python\n')
428  guiStr.append('# -*- coding: utf-8 -*-\n')
429  #guiStr.append('import visualstates.codegen.python\n')
430 
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')
447 
448  # create runtime state code
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')
454  else:
455  guiStr.append(', ' + str(state.parent.id) + ')\n')
456  guiStr.append('\n')
457 
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')
462  guiStr.append('\n')
463 
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')
468 
469  guiStr.append('if __name__ == "__main__":\n')
470  guiStr.append('\trunGui()\n\n')
471 
472 
473  def generateCmake(self, cmakeStr, projectName, config):
474  cmakeStr.append('project(')
475  cmakeStr.append(projectName)
476  cmakeStr.append(')\n\n')
477 
478  cmakeStr.append('cmake_minimum_required(VERSION 2.8.3)\n\n')
479 
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')
484  myStr = '''
485 include_directories(
486  ${catkin_INCLUDE_DIRS}
487 )
488 
489 '''
490  cmakeStr.append(myStr)
491 
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')
497  return cmakeStr
498 
499  def generatePackageXml(self, config, projectName):
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)
525 
526  for rdep in ['visualstates']+config.getRunDependencies():
527  rdepElement = doc.createElement('run_depend')
528  rdepElement.appendChild(doc.createTextNode(rdep))
529  root.appendChild(rdepElement)
530 
531  exportElement = doc.createElement('export')
532  root.appendChild(exportElement)
533  doc.appendChild(root)
534 
535  return doc
def generateGlobalNamespaceClass(self, classStr, config, globalNamespace)
def generateCmake(self, cmakeStr, projectName, config)
def generateGlobalNamespaceMethods(self, rosStr, config, globalNamespace)
def __init__(self, libraries, config, states, globalNamespace)


visualstates
Author(s):
autogenerated on Thu Apr 1 2021 02:42:20