subtopic_repub.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import sys
4 import rospy
5 import roslib
6 import rosgraph
7 import std_msgs.msg
8 from rostopic import get_topic_class, ROSTopicException
9 
10 """
11 Republish a subfield of a topic as another topic.
12 Useful for graph_rviz_plugin.
13 Based on rostopic echo (rostopic/__init__.py)
14 
15 Usage:
16 subtopic_repub.py /topic/subtopic/field /my_republished_field [queue_size (default 10)]
17 
18 Examples:
19 ./subtopic_repub.py /imu/angular_velocity/x /angular_velocity_x
20 ./subtopic_repub.py /hullbot/sensors/bno055/imu/angular_velocity_covariance[0] /angular_velocity_covariance_0
21 
22 Author: Sammy Pfeiffer <sam.pfeiffer at hullbot.com>
23 """
24 
25 
26 def rostopic_republish(input_subtopic, republish_topic, queue_size=10):
27  """
28  Republish new message on subtopic.
29 
30  :param subtopic: topic name, ``str``
31  """
32  # Getting all available topics to find our real topic
33  published_topics = rospy.get_published_topics()
34  real_topic = ""
35  for t_name, t_type in published_topics:
36  if t_name in input_subtopic:
37  real_topic = t_name
38  if not real_topic:
39  raise ROSTopicException("Didn't find real topic, is it published?")
40  msg_class, _, msg_eval = get_topic_class(input_subtopic, blocking=True)
41  rospy.loginfo("Input topic is of type: {}".format(msg_class._type))
42 
43  basic_types = {
44  'bool': std_msgs.msg.Bool,
45 
46  'float32': std_msgs.msg.Float32,
47  'float64': std_msgs.msg.Float64,
48 
49  'int8': std_msgs.msg.Int8,
50  'int16': std_msgs.msg.Int16,
51  'int32': std_msgs.msg.Int32,
52  'int64': std_msgs.msg.Int64,
53 
54  'uint8': std_msgs.msg.UInt8,
55  'uint16': std_msgs.msg.UInt16,
56  'uint32': std_msgs.msg.UInt32,
57  'uint64': std_msgs.msg.UInt64,
58 
59  'string': std_msgs.msg.String,
60  'char': std_msgs.msg.Char,
61  'time': std_msgs.msg.Time,
62  }
63 
64  # Get the type of the subfield
65  if len(input_subtopic) > len(real_topic):
66  subtopic = input_subtopic[len(real_topic):]
67  subtopic = subtopic.strip('/')
68  user_array_index = None
69  # If the user added [X] to the field, we get the array index
70  if '[' in subtopic.split('/')[-1]:
71  # Capture the user specified array index, e.g., /topic[5] '5'
72  user_array_index = subtopic.split('/')[-1].split('[')[1]
73  user_array_index = int(user_array_index.replace(']', ''))
74  if subtopic:
75  fields = subtopic.split('/')
76  submsg_class = msg_class
77  indexes = []
78  for field in fields:
79  if '[' in field:
80  if '[' in input_subtopic:
81  size_array = int(field.split(
82  '[')[1].replace(']', ''))
83  field = field.replace(
84  '[' + str(size_array) + ']', '')
85  else:
86  raise ROSTopicException(
87  "The topic has an array member, not implemented.")
88  # Store the index in the slots to later on access the subfields
89  index = submsg_class.__slots__.index(field)
90  indexes.append(index)
91 
92  type_information = submsg_class._slot_types[index]
93  # Deal with array types
94  if '[' in type_information:
95  if '[' in input_subtopic:
96  size_array = int(type_information.split(
97  '[')[1].replace(']', ''))
98  type_information = type_information.replace(
99  '[' + str(size_array) + ']', '')
100  else:
101  raise ROSTopicException(
102  "The topic has an array member, not implemented. You may want to add [0] or another element.")
103  if type_information in basic_types:
104  submsg_class = basic_types[type_information]
105  else:
106  submsg_class = roslib.message.get_message_class(
107  type_information)
108  else:
109  raise ROSTopicException(
110  "You didn't provide a subtopic, you may want to use 'rostun topictools relay' instead")
111 
112  rospy.loginfo("Got submsg of type: {}".format(submsg_class._type))
113  if user_array_index is not None:
114  rospy.loginfo("Got an array index: {}".format(user_array_index))
115  pub = rospy.Publisher(republish_topic, submsg_class,
116  queue_size=queue_size)
117 
118  def republish_callback(msg):
119  # access subfield
120  submsg = msg
121  for i in indexes:
122  submsg = submsg.__getattribute__(submsg.__slots__[i])
123  if user_array_index is not None:
124  try:
125  submsg = submsg[user_array_index]
126  except IndexError as e:
127  rospy.logwarn_throttle(1.0,
128  "Exception on access array at pos {}, reported array size: {}, Exception: {}, raw array: {}".format(
129  user_array_index, len(submsg), e, submsg))
130  pub.publish(submsg)
131 
132  sub = rospy.Subscriber(real_topic, msg_class, republish_callback)
133  rospy.spin()
134 
135 
136 def usage():
137  print("Usage:")
138  print(
139  sys.argv[0] + "/topic/subtopic/field /my_republished_field [queue_size (default 10)]")
140  exit(0)
141 
142 
143 if __name__ == '__main__':
144  args = rospy.myargv()
145  if len(args) < 3:
146  usage()
147  subtopic = args[1]
148  repub_topic = args[2]
149  queue_size = 10
150  if len(args) == 4:
151  queue_size = args[3]
152  rospy.init_node('subtopic_repub', anonymous=True)
153  rospy.loginfo("Republishing subtopic: {} into topic: {} (with queue_size: {})".format(
154  subtopic, repub_topic, queue_size))
155  rostopic_republish(subtopic, repub_topic, queue_size=queue_size)
def rostopic_republish(input_subtopic, republish_topic, queue_size=10)


graph_rviz_plugin
Author(s): Édouard Pronier, Victor Lamoine - Institut Maupertuis
autogenerated on Mon Feb 28 2022 22:27:30