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
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from __future__ import with_statement, print_function
00034
00035 import time
00036 import rospy
00037 import yaml
00038
00039
00040 class RosTfTreeDotcodeGenerator(object):
00041
00042 def __init__(self, initial_listen_duration=1):
00043 """
00044 :param initial_listen_duration: how many secs to listen to tf initially.
00045 """
00046 self.last_drawargs = None
00047 self.dotcode = None
00048 self.firstcall = True
00049 self.listen_duration = initial_listen_duration
00050 self.rank = None
00051 self.rankdir = None
00052 self.ranksep = None
00053 self.graph = None
00054 self.dotcode_factory = None
00055
00056 def generate_dotcode(self,
00057 dotcode_factory,
00058 tf2_frame_srv,
00059 timer=rospy.Time,
00060 yaml_parser=yaml,
00061 rank='same',
00062 ranksep=0.2,
00063 rankdir='TB',
00064 force_refresh=False):
00065 """
00066 :param force_refresh: if False, may return same dotcode as last time
00067 """
00068 if self.firstcall is True:
00069 self.firstcall = False
00070 force_refresh = True
00071
00072 drawing_args = {
00073 'dotcode_factory': dotcode_factory,
00074 "rank": rank,
00075 "rankdir": rankdir,
00076 "ranksep": ranksep}
00077
00078 selection_changed = False
00079 if self.last_drawargs != drawing_args:
00080 selection_changed = True
00081 self.last_drawargs = drawing_args
00082
00083 self.dotcode_factory = dotcode_factory
00084 self.rank = rank
00085 self.rankdir = rankdir
00086 self.ranksep = ranksep
00087
00088
00089 if force_refresh or self.dotcode is None or selection_changed:
00090 if self.listen_duration > 0:
00091 time.sleep(self.listen_duration)
00092
00093 self.listen_duration = 0
00094
00095 yaml_data = tf2_frame_srv().frame_yaml
00096 data = yaml_parser.load(yaml_data)
00097 self.graph = self.generate(data, timer.now().to_sec())
00098 self.dotcode = self.dotcode_factory.create_dot(self.graph)
00099
00100 return self.dotcode
00101
00102 def generate(self, data, timestamp):
00103 graph = self.dotcode_factory.get_graph(rank=self.rank,
00104 rankdir=self.rankdir,
00105 ranksep=self.ranksep)
00106
00107 if len(data) == 0:
00108 self.dotcode_factory.add_node_to_graph(graph, "No tf data received")
00109 return graph
00110
00111
00112 for frame_dict in data:
00113 tf_frame_values = data[frame_dict]
00114 if not tf_frame_values['parent'] in data:
00115 root = tf_frame_values['parent']
00116 self.dotcode_factory.add_node_to_graph(graph,
00117 tf_frame_values['parent'],
00118 shape='ellipse')
00119
00120 edge_label= '"Broadcaster: %s\\n' % str(tf_frame_values['broadcaster'])
00121 edge_label += 'Average rate: %s\\n' % str(tf_frame_values['rate'])
00122 edge_label += 'Buffer length: %s\\n' % str(tf_frame_values['buffer_length'])
00123 edge_label += 'Most recent transform: %s\\n' % str(tf_frame_values['most_recent_transform'])
00124 edge_label += 'Oldest transform: %s"' % str(tf_frame_values['oldest_transform'])
00125 self.dotcode_factory.add_edge_to_graph(graph,
00126 tf_frame_values['parent'],
00127 frame_dict,
00128 label=edge_label)
00129
00130
00131 legend_label = '"Recorded at time: %s"' % str(timestamp)
00132 self.dotcode_factory.add_node_to_graph(graph, legend_label)
00133 self.dotcode_factory.add_edge_to_graph(graph,
00134 legend_label,
00135 root,
00136 style='invis')
00137
00138
00139
00140
00141 return graph