Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 import os
00020 import sys
00021 import time
00022 import subprocess
00023
00024 from xml.etree import ElementTree
00025 from roslib.packages import get_pkg_dir
00026
00027 class Prefix:
00028
00029 KEY_FIND = 'find'
00030 KEY_ARG = 'arg'
00031
00032 @staticmethod
00033 def is_prefixed(path):
00034 if '$' in path:
00035 return True
00036 else:
00037 return False
00038
00039 @staticmethod
00040 def get_prefix(path):
00041
00042 if Prefix.is_prefixed(path):
00043 try:
00044
00045 path_split = path.split(")")
00046 prefix = path_split[0].split("(")[-1]
00047 prefix_args = prefix.split(' ')
00048 key = prefix_args[0]
00049 value = prefix_args[-1]
00050 rex = path_split[-1]
00051 return key, value, rex
00052 except :
00053 raise Exception("Bad prefix !")
00054 else:
00055 raise Exception("No profixed path !")
00056
00057 @staticmethod
00058 def find(path):
00059
00060 if Prefix.is_prefixed(path):
00061 try:
00062 key, value, rex = Prefix.get_prefix(path)
00063 if key == Prefix.KEY_FIND:
00064 return get_pkg_dir(value)+rex
00065 else:
00066 raise Exception("Bad prefixed key '%s'"%key)
00067 except Exception as ex:
00068 raise ex
00069 else:
00070 return path
00071
00072 @staticmethod
00073 def arg(exp, tree):
00074
00075 if Prefix.is_prefixed(exp):
00076 try:
00077 key, value, rex = Prefix.get_prefix(exp)
00078 if key == Prefix.KEY_ARG:
00079 node_arg = tree.find('%s[@name="%s"]'%(key,value))
00080 df = node_arg.attrib["default"]
00081 if Prefix.is_prefixed(df):
00082 Prefix.arg(df, tree)
00083 else:
00084 return node_arg.attrib["default"]+rex
00085 else:
00086 raise Exception("Bad prefixed key '%s'"%key)
00087 except Exception as ex:
00088 raise ex
00089 else:
00090 return exp
00091
00092 class RosLaunchDotGenerator:
00093
00094 def __init__(self):
00095
00096 self._launch_directory=""
00097 self._launch_list=[]
00098 self._dot_filename=""
00099
00100 def _parse(self, launch, dot):
00101
00102 self._launch_directory = launch
00103 launch_name = launch.split('/')[-1].split('.')[0]
00104
00105 root = None
00106 try:
00107 root = ElementTree.parse(self._launch_directory)
00108 except:
00109 raise Exception("Invalid launcher path from %s !"%self._launch_directory)
00110
00111 tree = root.getroot()
00112
00113 for elem in tree:
00114
00115 if elem.tag == 'include':
00116
00117 include_split = elem.attrib["file"].split(")")
00118 prefix = include_split[0]
00119 pkg_name = prefix.split(" ")[-1]
00120
00121 child = include_split[-1].split("/")[-1].split('.')[0]
00122
00123 dot.write('%s [shape=box, style=filled, color=lightgray];\n'%launch_name)
00124 dot.write('%s [shape=box, style=filled, color=lightgray];\n'%child)
00125 dot.write("%s -> %s\n"%(launch_name, child))
00126
00127 sub_launch = get_pkg_dir(pkg_name)+include_split[-1]
00128
00129 self._parse(sub_launch, dot)
00130
00131
00132 elif elem.tag == "node":
00133
00134 parent = launch_name
00135 child = Prefix.arg(elem.attrib["name"],tree)
00136 if parent == child:
00137 child += "_node"
00138
00139 dot.write('%s [shape=ellipse, style=filled, color=lightseagreen];\n'%child)
00140 dot.write("%s -> %s\n"%(parent,child))
00141
00142 def parse(self, launch, dot_filename):
00143
00144 self._dot_filename=dot_filename
00145
00146 dot_file = open(dot_filename,'w')
00147 dot_file.write("digraph LaunchDot {\n")
00148
00149 self._parse(launch, dot_file)
00150
00151 dot_file.write("}")
00152 dot_file.close()
00153
00154 def to_ps(self, ps_filename):
00155 cmd=["dot", "-Tps", self._dot_filename, "-o", "%s.ps"%ps_filename]
00156 subprocess.Popen(cmd)
00157
00158
00159
00160
00161
00162
00163 if __name__ == '__main__':
00164
00165 dep = RosLaunchDotGenerator()