silverhammer_util.py
Go to the documentation of this file.
1 from StringIO import StringIO
2 from struct import Struct, pack, unpack
3 import re
4 import rospy
5 import roslib
6 import roslib.message
7 
8 # utility function
9 def parseMessageType(field_string):
10  match = re.match("(.*)\[([\d]*)\]", field_string)
11  if match:
12  num_string = match.group(2)
13  return (match.group(1), int(num_string))
14  else:
15  return (field_string, 1)
16 def fieldToTopic(field):
17  field.replace("__", "/")
18 
20  slots = list(msg.__slots__) #copy
21  slot_types = list(msg._slot_types)
22  fmt_stream = StringIO()
23  fmt_stream.write("!")
24  for slot, slot_type in zip(slots, slot_types):
25  parsed_type = parseMessageType(slot_type)
26  field_type = parsed_type[0]
27  field_length = parsed_type[1]
28  if field_type == "char":
29  fmt_stream.write("c" * field_length)
30  elif field_type == "bool":
31  fmt_stream.write("?" * field_length)
32  elif field_type == "int8":
33  fmt_stream.write("b" * field_length)
34  elif field_type == "uint8":
35  fmt_stream.write("B" * field_length)
36  elif field_type == "int16":
37  raise Exception("int16 is not supported")
38  elif field_type == "uint16":
39  fmt_stream.write("H" * field_length)
40  elif field_type == "int32":
41  fmt_stream.write("i" * field_length)
42  elif field_type == "uint32":
43  fmt_stream.write("I" * field_length)
44  elif field_type == "int64":
45  fmt_stream.write("q" * field_length)
46  elif field_type == "uint64":
47  fmt_stream.write("Q" * field_length)
48  elif field_type == "float32":
49  fmt_stream.write("f" * field_length)
50  elif field_type == "float64":
51  fmt_stream.write("d" * field_length)
52  elif field_type == "string":
53  raise Excception("string is not supported!, please use char[static_length]")
54  elif field_type == "duration" or field_type == "time":
55  raise Excception("duration and time are not supported")
56  return fmt_stream.getvalue()
57 
58 def packableValue(value, value_type):
59  if value_type == "uint8":
60  return ord(value)
61  else:
62  return value
63 
64 def packMessage(msg, fmt):
65  data = []
66  for slot, slot_type in zip(msg.__slots__, msg._slot_types):
67  slot_value = getattr(msg, slot)
68  parsed_type = parseMessageType(slot_type)
69  field_type = parsed_type[0]
70  if hasattr(slot_value, "__len__"): #array
71  for i in range(len(slot_value)):
72  data.append(packableValue(slot_value[i], field_type))
73  else:
74  #data.append(packableValue(slot_value, field_type))
75  data.append(slot_value)
76  packed = pack(fmt, *data)
77  return packed
78 
79 def unpackArrayValue(array, field_type):
80  if field_type == "bool":
81  return [v == 1 for v in array]
82  else:
83  return array
84 
85 def unpackValue(val, field_type):
86  if field_type == "bool":
87  return val == 1
88  else:
89  return val
90 
91 def unpackMessage(data, fmt, message_class):
92  unpacked_data = unpack(fmt, data)
93  msg = message_class()
94  counter = 0
95  for slot, slot_type in zip(msg.__slots__, msg._slot_types):
96  slot_value = getattr(msg, slot)
97  parsed_type = parseMessageType(slot_type)
98  field_type = parsed_type[0]
99  field_length = parsed_type[1]
100  target_data = unpacked_data[counter:counter + field_length]
101  if hasattr(slot_value, "__len__"): #array
102  setattr(msg, slot, unpackArrayValue(target_data, field_type))
103  else:
104  setattr(msg, slot, unpackValue(target_data[0], field_type))
105  counter = counter + field_length
106  return msg
107 
108 def publishersFromMessage(msg, prefix="", latch=False):
109  ret = []
110  for slot, slot_type in zip(msg.__slots__, msg._slot_types):
111  topic_name = prefix + "/" + slot.replace("__", "/")
112  try:
113  msg_class = roslib.message.get_message_class(slot_type)
114  except:
115  raise Exception("invalid topic type: %s"%slot_type)
116  ret.append(rospy.Publisher(topic_name, msg_class, latch=latch))
117  return ret
118 
119 def decomposeLargeMessage(msg, prefix=""):
120  ret = dict()
121  for slot, slot_type in zip(msg.__slots__, msg._slot_types):
122  topic_name = prefix + "/" + slot.replace("__", "/")
123  ret[topic_name] = getattr(msg, slot)
124  return ret
125 
126 
128  ret = []
129  for slot, slot_type in zip(msg.__slots__, msg._slot_types):
130  topic_name = "/" + slot.replace("__", "/")
131  try:
132  msg_class = roslib.message.get_message_class(slot_type)
133  except:
134  raise Exception("invalid topic type: %s"%slot_type)
135  ret.append((topic_name, msg_class))
136  return ret
137 
138 #################################################w
139 # Packet definition for Large Data
140 # |SeqID(4byte)|ID(4byte)|NUM_PACKET(4byte)|data.... |
141 #################################################w
143  def __init__(self, seq_id, id, num, data, packet_size):
144  self.id = id
145  self.seq_id = seq_id
146  self.num = num
147  self.data = data
148  self.packet_size = packet_size
149  def pack(self):
150  return pack("!III%ds" % (len(self.data)),
151  self.seq_id, self.id, self.num, self.data)
152  #def pack(self):
153  @classmethod
154  def headerSize(cls):
155  return 4 + 4 + 4
156  @classmethod
157  def fromData(cls, data, packet_size):
158  unpacked = unpack("!III%ds" % (len(data) - cls.headerSize()), data)
159  ret = cls(unpacked[0], unpacked[1], unpacked[2], unpacked[3],
160  packet_size)
161  #print "buffer length", len(unpacked[3])
162  return ret
163 
164 def separateBufferIntoPackets(seq_id, buffer, packet_size):
165  buffer_packet_size = packet_size - LargeDataUDPPacket.headerSize()
166  num_packet = len(buffer) / buffer_packet_size
167  if len(buffer) % buffer_packet_size != 0:
168  num_packet = num_packet + 1
169  packets = []
170  for i in range(num_packet):
171  packets.append(LargeDataUDPPacket(seq_id, i, num_packet,
172  buffer[i*buffer_packet_size:(i+1)*buffer_packet_size],
173  packet_size))
174  #print "buffer length", len(buffer[i*num_packet:(i+1)*num_packet])
175  return packets
def unpackMessage(data, fmt, message_class)
def packableValue(value, value_type)
def separateBufferIntoPackets(seq_id, buffer, packet_size)
def unpackArrayValue(array, field_type)
w Packet definition for Large Data |SeqID(4byte)|ID(4byte)|NUM_PACKET(4byte)|data....
def __init__(self, seq_id, id, num, data, packet_size)
def publishersFromMessage(msg, prefix="", latch=False)


jsk_network_tools
Author(s): Yusuke Furuta
autogenerated on Tue Feb 6 2018 03:45:07