4 from sensor_msgs.msg
import Image
as msg_Image
5 from sensor_msgs.msg
import PointCloud2
as msg_PointCloud2
7 from sensor_msgs.msg
import Imu
as msg_Imu
9 from cv_bridge
import CvBridge, CvBridgeError
15 from theora_image_transport.msg
import Packet
as msg_theora
26 s = struct.pack(
'>f', rgb)
27 i = struct.unpack(
'>l', s)[0]
29 pack = ctypes.c_uint32(i).value
30 r = (pack & 0x00FF0000) >> 16
31 g = (pack & 0x0000FF00) >> 8
32 b = (pack & 0x000000FF)
33 return x, y, z, r, g, b
41 self.
timeout = params.get(
'timeout_secs', -1)
42 self.
seq = params.get(
'seq', -1)
43 self.
time = params.get(
'time',
None)
44 self.
node_name = params.get(
'node_name',
'rs2_listener')
51 self.
themes = {
'depthStream': {
'topic':
'/camera/depth/image_rect_raw',
'callback': self.
imageColorCallback,
'msg_type': msg_Image},
52 'colorStream': {
'topic':
'/camera/color/image_raw',
'callback': self.
imageColorCallback,
'msg_type': msg_Image},
53 'pointscloud': {
'topic':
'/camera/depth/color/points',
'callback': self.
pointscloudCallback,
'msg_type': msg_PointCloud2},
54 'alignedDepthInfra1': {
'topic':
'/camera/aligned_depth_to_infra1/image_raw',
'callback': self.
imageColorCallback,
'msg_type': msg_Image},
55 'alignedDepthColor': {
'topic':
'/camera/aligned_depth_to_color/image_raw',
'callback': self.
imageColorCallback,
'msg_type': msg_Image},
56 'static_tf': {
'topic':
'/camera/color/image_raw',
'callback': self.
imageColorCallback,
'msg_type': msg_Image},
57 'accelStream': {
'topic':
'/camera/accel/sample',
'callback': self.
imuCallback,
'msg_type': msg_Imu},
63 def _imuCallback(data):
67 self.
func_data[theme_name].setdefault(
'value', [])
68 self.
func_data[theme_name].setdefault(
'ros_value', [])
70 frame_id = data.header.frame_id
71 value = data.linear_acceleration
73 (trans,rot) = self.listener.lookupTransform(
'/camera_link', frame_id, rospy.Time(0))
74 quat = tf.transformations.quaternion_matrix(rot)
75 point = np.matrix([value.x, value.y, value.z, 1], dtype=
'float32')
79 rotated = np.array(rotated)[0][:3]
80 except Exception
as e:
83 self.
func_data[theme_name][
'value'].append(value)
84 self.
func_data[theme_name][
'ros_value'].append(rotated)
88 def _imageColorCallback(data):
90 self.
func_data[theme_name].setdefault(
'avg', [])
91 self.
func_data[theme_name].setdefault(
'ok_percent', [])
92 self.
func_data[theme_name].setdefault(
'num_channels', [])
93 self.
func_data[theme_name].setdefault(
'shape', [])
94 self.
func_data[theme_name].setdefault(
'reported_size', [])
97 cv_image = self.bridge.imgmsg_to_cv2(data, data.encoding)
98 except CvBridgeError
as e:
101 channels = cv_image.shape[2]
if len(cv_image.shape) > 2
else 1
102 pyimg = np.asarray(cv_image)
104 ok_number = (pyimg != 0).sum()
106 self.
func_data[theme_name][
'avg'].append(pyimg.sum() / ok_number)
107 self.
func_data[theme_name][
'ok_percent'].append(float(ok_number) / (pyimg.shape[0] * pyimg.shape[1]) / channels)
108 self.
func_data[theme_name][
'num_channels'].append(channels)
109 self.
func_data[theme_name][
'shape'].append(cv_image.shape)
110 self.
func_data[theme_name][
'reported_size'].append((data.width, data.height, data.step))
111 return _imageColorCallback
117 def _pointscloudCallback(data):
118 self.prev_time = time.time()
119 print (
'Got pointcloud: %d, %d' % (data.width, data.height))
121 self.func_data[theme_name].setdefault(
'frame_counter', 0)
122 self.func_data[theme_name].setdefault(
'avg', [])
123 self.func_data[theme_name].setdefault(
'size', [])
124 self.func_data[theme_name].setdefault(
'width', [])
125 self.func_data[theme_name].setdefault(
'height', [])
127 self.func_data[theme_name][
'frame_counter'] += 1
129 if self.func_data[theme_name][
'frame_counter'] == 1:
134 points = np.array([
pc2_to_xyzrgb(pp)
for pp
in pc2.read_points(data, skip_nans=
True, field_names=(
"x",
"y",
"z",
"rgb"))
if pp[0] > 0])
135 except Exception
as e:
138 self.func_data[theme_name][
'avg'].append(points.mean(0))
139 self.func_data[theme_name][
'size'].append(len(points))
140 self.func_data[theme_name][
'width'].append(data.width)
141 self.func_data[theme_name][
'height'].append(data.height)
142 return _pointscloudCallback
145 topic = params[
'topic']
146 print (
'connect to ROS with name: %s' % self.
node_name)
147 rospy.init_node(self.
node_name, anonymous=
True)
149 out_filename = params.get(
'filename',
None)
151 self.
fout = open(out_filename,
'w')
152 if msg_type
is msg_Imu:
154 print (
'Writing to file: %s' % out_filename)
155 columns = [
'frame_number',
'frame_time(sec)',
'accel.x',
'accel.y',
'accel.z',
'gyro.x',
'gyro.y',
'gyro.z']
156 line = (
'{:<%d}'*len(columns) % (col_w, col_w, col_w, col_w, col_w, col_w, col_w, col_w)).format(*columns) +
'\n' 157 sys.stdout.write(line)
158 self.fout.write(line)
160 rospy.loginfo(
'Subscribing on topic: %s' % topic)
164 break_timeout =
False 165 while not any([rospy.core.is_shutdown(), break_timeout, self.
result]):
166 rospy.rostime.wallsleep(0.5)
169 self.sub.unregister()
175 for test_name
in registers:
176 rospy.loginfo(
'Un-Subscribing test %s' % test_name)
177 registers[test_name][
'sub'].unregister()
181 self.
func_data =
dict([[theme_name, {}]
for theme_name
in themes])
183 print (
'connect to ROS with name: %s' % self.
node_name)
184 rospy.init_node(self.
node_name, anonymous=
True)
185 for theme_name
in themes:
186 theme = self.
themes[theme_name]
187 rospy.loginfo(
'Subscribing %s on topic: %s' % (theme_name, theme[
'topic']))
188 self.
func_data[theme_name][
'sub'] = rospy.Subscriber(theme[
'topic'], theme[
'msg_type'], theme[
'callback'](theme_name))
191 break_timeout =
False 192 while not any([rospy.core.is_shutdown(), break_timeout]):
193 rospy.rostime.wallsleep(0.5)
201 msg_time = data.header.stamp.secs + 1e-9 * data.header.stamp.nsecs
204 rospy.loginfo(
'Out of order: %.9f > %.9f' % (self.
prev_msg_time, msg_time))
205 if type(data) == msg_Imu:
207 frame_number = data.header.seq
208 accel = data.linear_acceleration
209 gyro = data.angular_velocity
210 line = (
'\n{:<%d}{:<%d.6f}{:<%d.4f}{:<%d.4f}{:<%d.4f}{:<%d.4f}{:<%d.4f}{:<%d.4f}' % (col_w, col_w, col_w, col_w, col_w, col_w, col_w, col_w)).format(frame_number, msg_time, accel.x, accel.y, accel.z, gyro.x, gyro.y, gyro.z)
211 sys.stdout.write(line)
213 self.fout.write(line)
219 if any([self.
seq > 0
and data.header.seq >= self.
seq,
220 self.
time and data.header.stamp.secs == self.
time[
'secs']
and data.header.stamp.nsecs == self.
time[
'nsecs']]):
222 self.sub.unregister()
227 if len(sys.argv) < 2
or '--help' in sys.argv
or '/?' in sys.argv:
230 print (
'rs2_listener.py <topic | theme> [Options]')
231 print (
'example: rs2_listener.py /camera/color/image_raw --time 1532423022.044515610 --timeout 3')
232 print (
'example: rs2_listener.py pointscloud')
234 print (
'Application subscribes on <topic>, wait for the first message matching [Options].')
235 print (
'When found, prints the timestamp.')
238 print (
'-s <sequential number>')
239 print (
'--time <secs.nsecs>')
240 print (
'--timeout <secs>')
241 print (
'--filename <filename> : write output to file')
247 wanted_topic = sys.argv[1]
249 if 'points' in wanted_topic:
250 msg_type = msg_PointCloud2
251 elif (
'imu' in wanted_topic)
or (
'gyro' in wanted_topic)
or (
'accel' in wanted_topic):
253 elif 'theora' in wanted_topic:
255 msg_type = msg_theora
256 except NameError
as e:
257 print (
'theora_image_transport is not installed. \nType "sudo apt-get install ros-kinetic-theora-image-transport" to enable registering on messages of type theora.')
262 for idx
in range(2, len(sys.argv)):
263 if sys.argv[idx] ==
'-s':
264 msg_params[
'seq'] = int(sys.argv[idx + 1])
265 if sys.argv[idx] ==
'--time':
266 msg_params[
'time'] =
dict(zip([
'secs',
'nsecs'], [int(part)
for part
in sys.argv[idx + 1].split(
'.')]))
267 if sys.argv[idx] ==
'--timeout':
268 msg_params[
'timeout_secs'] = int(sys.argv[idx + 1])
269 if sys.argv[idx] ==
'--filename':
270 msg_params[
'filename'] = sys.argv[idx+1]
273 if '/' in wanted_topic:
274 msg_params.setdefault(
'topic', wanted_topic)
275 res = msg_retriever.wait_for_message(msg_params, msg_type)
276 rospy.loginfo(
'Got message: %s' % res.header)
278 themes = [wanted_topic]
279 res = msg_retriever.wait_for_messages(themes)
283 if __name__ ==
'__main__':