3 from rs2_listener
import CWaitForMessage
6 from cv_bridge
import CvBridge, CvBridgeError
25 res[
'max_diff'] = [0,0,0]
26 for topic, msg, t
in bag.read_messages(topics=topic):
27 value = np.array([msg.linear_acceleration.x, msg.linear_acceleration.y, msg.linear_acceleration.z])
28 if res[
'value']
is None:
31 diff = abs(value - res[
'value'])
32 res[
'max_diff'] = [max(diff[x], res[
'max_diff'][x])
for x
in range(len(diff))]
33 res[
'max_diff'] = np.array(res[
'max_diff'])
37 return ImuGetData(rec_filename,
'/device_0/sensor_2/Accel_0/imu/data')
41 gt_data[
'ros_value'] = np.array([0.63839424, 0.05380408, 9.85343552])
42 gt_data[
'ros_max_diff'] = np.array([1.97013582e-02, 4.65862500e-09, 4.06165277e-02])
49 v_data = np.array([data[
'value'][0].x, data[
'value'][0].y, data[
'value'][0].z])
50 v_gt_data = gt_data[
'value']
51 diff = v_data - v_gt_data
52 max_diff = abs(diff).max()
53 msg =
'original accel: Expect max diff of %.3f. Got %.3f.' % (gt_data[
'max_diff'].max(), max_diff)
55 if max_diff > gt_data[
'max_diff'].max():
58 v_data = data[
'ros_value'][0]
59 v_gt_data = gt_data[
'ros_value']
60 diff = v_data - v_gt_data
61 max_diff = abs(diff).max()
62 msg =
'rotated to ROS: Expect max diff of %.3f. Got %.3f.' % (gt_data[
'ros_max_diff'].max(), max_diff)
64 if max_diff > gt_data[
'ros_max_diff'].max():
66 except Exception
as e:
68 print (
'Test Failed: %s' % msg)
79 for topic, msg, t
in bag.read_messages(topics=topic):
81 cv_image = bridge.imgmsg_to_cv2(msg, msg.encoding)
82 except CvBridgeError
as e:
85 pyimg = np.asarray(cv_image)
86 ok_number = (pyimg != 0).sum()
87 ok_percent.append(float(ok_number) / (pyimg.shape[0] * pyimg.shape[1]))
88 all_avg.append(pyimg.sum() / ok_number)
90 all_avg = np.array(all_avg)
91 channels = cv_image.shape[2]
if len(cv_image.shape) > 2
else 1
92 res[
'num_channels'] = channels
93 res[
'shape'] = cv_image.shape
94 res[
'avg'] = all_avg.mean()
95 res[
'ok_percent'] = {
'value': (np.array(ok_percent).mean()) / channels,
'epsilon': 0.01}
96 res[
'epsilon'] = max(all_avg.max() - res[
'avg'], res[
'avg'] - all_avg.min())
97 res[
'reported_size'] = [msg.width, msg.height, msg.step]
103 return ImageGetData(rec_filename,
'/device_0/sensor_1/Color_0/image/data')
107 return ImageGetData(rec_filename,
'/device_0/sensor_0/Depth_0/image/data')
113 gt_data[
'shape'] = color_data[
'shape'][:2]
114 gt_data[
'reported_size'] = color_data[
'reported_size']
115 gt_data[
'reported_size'][2] = gt_data[
'reported_size'][0]*2
116 gt_data[
'ok_percent'][
'epsilon'] *= 3
121 gt_data[
'shape'] = [x/2
for x
in gt_data[
'shape']]
122 gt_data[
'reported_size'] = [x/2
for x
in gt_data[
'reported_size']]
123 gt_data[
'epsilon'] *= 3
130 channels =
list(
set(data[
'num_channels']))
131 msg =
'Expect %d channels. Got %d channels.' % (gt_data[
'num_channels'], channels[0])
133 if len(channels) > 1
or channels[0] != gt_data[
'num_channels']:
135 msg =
'Expected all received images to be the same shape. Got %s' %
str(
set(data[
'shape']))
137 if len(
set(data[
'shape'])) > 1:
139 msg =
'Expected shape to be %s. Got %s' % (gt_data[
'shape'],
list(
set(data[
'shape']))[0])
141 if (np.array(
list(
set(data[
'shape']))[0]) != np.array(gt_data[
'shape'])).any():
143 msg =
'Expected header [width, height, step] to be %s. Got %s' % (gt_data[
'reported_size'],
list(
set(data[
'reported_size']))[0])
145 if (np.array(
list(
set(data[
'reported_size']))[0]) != np.array(gt_data[
'reported_size'])).any():
147 msg =
'Expect average of %.3f (+-%.3f). Got average of %.3f.' % (gt_data[
'avg'].mean(), gt_data[
'epsilon'], np.array(data[
'avg']).mean())
149 if abs(np.array(data[
'avg']).mean() - gt_data[
'avg'].mean()) > gt_data[
'epsilon']:
152 msg =
'Expect no holes percent > %.3f. Got %.3f.' % (gt_data[
'ok_percent'][
'value']-gt_data[
'ok_percent'][
'epsilon'], np.array(data[
'ok_percent']).mean())
154 if np.array(data[
'ok_percent']).mean() < gt_data[
'ok_percent'][
'value']-gt_data[
'ok_percent'][
'epsilon']:
157 except Exception
as e:
159 print (
'Test Failed: %s' % msg)
165 gt_data[
'epsilon'] *= 3
170 return (
not res[0], res[1])
173 width = np.array(data[
'width']).mean()
174 height = np.array(data[
'height']).mean()
175 msg =
'Expect image size %d(+-%d), %d. Got %d, %d.' % (gt_data[
'width'][0], gt_data[
'width'][1], gt_data[
'height'][0], width, height)
177 if abs(width - gt_data[
'width'][0]) > gt_data[
'width'][1]
or height != gt_data[
'height'][0]:
179 mean_pos = np.array([xx[:3]
for xx
in data[
'avg']]).mean(0)
180 msg =
'Expect average position of %s (+-%.3f). Got average of %s.' % (gt_data[
'avg'][0][:3], gt_data[
'epsilon'][0], mean_pos)
182 if abs(mean_pos - gt_data[
'avg'][0][:3]).max() > gt_data[
'epsilon'][0]:
184 mean_col = np.array([xx[3:]
for xx
in data[
'avg']]).mean(0)
185 msg =
'Expect average color of %s (+-%.3f). Got average of %s.' % (gt_data[
'avg'][0][3:], gt_data[
'epsilon'][1], mean_col)
187 if abs(mean_col - gt_data[
'avg'][0][3:]).max() > gt_data[
'epsilon'][1]:
194 for couple
in gt_data.keys():
195 if data[couple]
is None:
196 msg =
'Tf is None for couple %s' %
'->'.join(couple)
198 if any(abs((np.array(data[couple][0]) - np.array(gt_data[couple][0]))) > 1e-5)
or \
199 any(abs((np.array(data[couple][1]) - np.array(gt_data[couple][1]))) > 1e-5):
200 msg =
'Tf is changed for couple %s' %
'->'.join(couple)
204 test_types = {
'vis_avg': {
'listener_theme':
'colorStream',
205 'data_func': ImageColorGetData,
206 'test_func': ImageColorTest},
207 'depth_avg': {
'listener_theme':
'depthStream',
208 'data_func': ImageDepthGetData,
209 'test_func': ImageColorTest},
210 'no_file': {
'listener_theme':
'colorStream',
211 'data_func':
lambda x:
None,
212 'test_func': NotImageColorTest},
213 'pointscloud_avg': {
'listener_theme':
'pointscloud',
214 'data_func':
lambda x: {
'width': [660353, 2300],
'height': [1],
'avg': [np.array([ 1.28251814, -0.15839984, 4.82235184, 80, 160, 240])],
'epsilon': [0.04, 5]},
215 'test_func': PointCloudTest},
216 'align_depth_ir1': {
'listener_theme':
'alignedDepthInfra1',
217 'data_func': ImageDepthGetData,
218 'test_func': ImageColorTest},
219 'align_depth_color': {
'listener_theme':
'alignedDepthColor',
220 'data_func': ImageDepthInColorShapeGetData,
221 'test_func': ImageColorTest_3epsilon},
222 'depth_avg_decimation': {
'listener_theme':
'depthStream',
223 'data_func': ImageDepthGetData_decimation,
224 'test_func': ImageColorTest},
225 'align_depth_ir1_decimation': {
'listener_theme':
'alignedDepthInfra1',
226 'data_func': ImageDepthGetData,
227 'test_func': ImageColorTest},
228 'static_tf': {
'listener_theme':
'static_tf',
229 'data_func':
lambda x: {(
'camera_link',
'camera_color_frame'): ([-0.00010158783697988838, 0.014841210097074509, -0.00022671300393994898], [-0.0008337442995980382, 0.0010442184284329414, -0.0009920650627464056, 0.9999986290931702]),
230 (
'camera_link',
'camera_depth_frame'): ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0]),
231 (
'camera_link',
'camera_infra1_frame'): ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0]),
232 (
'camera_depth_frame',
'camera_infra1_frame'): ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0]),
233 (
'camera_depth_frame',
'camera_color_frame'): ([-0.00010158783697988838, 0.014841210097074509, -0.00022671300393994898], [-0.0008337442995980382, 0.0010442184284329414, -0.0009920650627464056, 0.9999986290931702]),
234 (
'camera_infra1_frame',
'camera_color_frame'): ([-0.00010158783697988838, 0.014841210097074509, -0.00022671300393994898], [-0.0008337442995980382, 0.0010442184284329414, -0.0009920650627464056, 0.9999986290931702])}
236 'test_func': staticTFTest},
237 'accel_up': {
'listener_theme':
'accelStream',
238 'data_func': AccelGetDataDeviceStandStraight,
239 'test_func': ImuTest},
246 test_type = test_types[test[
'type']]
247 gt_data = test_type[
'data_func'](test[
'params'][
'rosbag_filename'])
248 return test_type[
'test_func'](listener_res[test_type[
'listener_theme']], gt_data)
252 title =
'TEST RESULTS' 253 headers = [
'index',
'test name',
'score',
'message']
254 col_0_width = len(headers[0]) + 1
255 col_1_width = max([len(headers[1])] + [len(test[0])
for test
in results]) + 1
256 col_2_width = max([len(headers[2]), len(
'OK'), len(
'FAILED')]) + 1
257 col_3_width = max([len(headers[3])] + [len(test[1][1])
for test
in results]) + 1
258 total_width = col_0_width + col_1_width + col_2_width + col_3_width
260 print ((
'{:^%ds}'%total_width).format(title))
261 print (
'-'*total_width)
262 print ((
'{:<%ds}{:<%ds}{:>%ds} : {:<%ds}' % (col_0_width, col_1_width, col_2_width, col_3_width)).format(*headers))
263 print (
'-'*(col_0_width-1) +
' '*1 +
'-'*(col_1_width-1) +
' '*2 +
'-'*(col_2_width-1) +
' '*3 +
'-'*(col_3_width-1))
264 print (
'\n'.join([(
'{:<%dd}{:<%ds}{:>%ds} : {:<s}' % (col_0_width, col_1_width, col_2_width)).format(idx, test[0],
'OK' if test[1][0]
else 'FAILED', test[1][1])
for idx, test
in enumerate(results)]))
271 start_time = time.time()
273 tf_listener.waitForTransform(from_id, to_id, rospy.Time(), rospy.Duration(tf_timeout))
274 res = tf_listener.lookupTransform(from_id, to_id, rospy.Time())
275 except Exception
as e:
278 waited_for = time.time() - start_time
279 tf_timeout = max(0.0, tf_timeout - waited_for)
284 msg_params = {
'timeout_secs': 5}
286 params_strs =
set([test[
'params_str']
for test
in tests])
287 for params_str
in params_strs:
288 rec_tests = [test
for test
in tests
if test[
'params_str'] == params_str]
289 themes = [test_types[test[
'type']][
'listener_theme']
for test
in rec_tests]
292 print (
'Running the following tests: %s' % (
'\n' +
'\n'.join([test[
'name']
for test
in rec_tests])))
296 for run_no
in range(num_of_startups):
298 print (
'*'*8 +
' Starting ROS ' +
'*'*8)
299 print (
'running node (%d/%d)' % (run_no, num_of_startups))
300 cmd_params = [
'roslaunch',
'realsense2_camera',
'rs_from_file.launch'] + params_str.split(
' ')
301 print (
'running command: ' +
' '.join(cmd_params))
302 p_wrapper = subprocess.Popen(cmd_params, stdout=
None, stderr=
None)
304 service_list = rosservice.get_service_list()
305 is_node_up = len([service
for service
in service_list
if 'realsense2_camera/' in service]) > 0
309 print (
'Node is NOT UP')
310 print (
'*'*8 +
' Killing ROS ' +
'*'*9)
311 p_wrapper.terminate()
316 listener_res = msg_retriever.wait_for_messages(themes)
317 if 'static_tf' in [test[
'type']
for test
in rec_tests]:
318 print (
'Gathering static transforms')
319 frame_ids = [
'camera_link',
'camera_depth_frame',
'camera_infra1_frame',
'camera_infra2_frame',
'camera_color_frame',
'camera_fisheye_frame',
'camera_pose']
321 listener_res[
'static_tf'] =
dict([(xx,
get_tf(tf_listener, xx[0], xx[1]))
for xx
in itertools.combinations(frame_ids, 2)])
322 print (
'*'*8 +
' Killing ROS ' +
'*'*9)
323 p_wrapper.terminate()
326 listener_res =
dict([[theme_name, {}]
for theme_name
in themes])
332 for test
in rec_tests:
335 except Exception
as e:
336 print (
'Test %s Failed: %s' % (test[
'name'], e))
337 res =
False,
'%s' % e
338 results.append([test[
'name'], res])
344 outdoors_filename =
'./records/outdoors_1color.bag' 345 all_tests = [{
'name':
'non_existent_file',
'type':
'no_file',
'params': {
'rosbag_filename':
'/home/non_existent_file.txt'}},
346 {
'name':
'vis_avg_2',
'type':
'vis_avg',
'params': {
'rosbag_filename': outdoors_filename}},
347 {
'name':
'depth_avg_1',
'type':
'depth_avg',
'params': {
'rosbag_filename': outdoors_filename}},
348 {
'name':
'depth_w_cloud_1',
'type':
'depth_avg',
'params': {
'rosbag_filename': outdoors_filename,
'enable_pointcloud':
'true'}},
352 {
'name':
'depth_avg_decimation_1',
'type':
'depth_avg_decimation',
'params': {
'rosbag_filename': outdoors_filename,
'filters':
'decimation'}},
359 for test
in all_tests:
360 test[
'params'][
'rosbag_filename'] = os.path.abspath(test[
'params'][
'rosbag_filename'])
361 test[
'params_str'] =
' '.join([key +
':=' + test[
'params'][key]
for key
in sorted(test[
'params'].keys())])
363 if len(sys.argv) < 2
or '--help' in sys.argv
or '/?' in sys.argv:
366 print (
'rs2_test.py --all | <test_name> [<test_name> [...]]')
368 print (
'Available tests are:')
369 print (
'\n'.join([test[
'name']
for test
in all_tests]))
372 if '--all' in sys.argv[1:]:
373 tests_to_run = all_tests
375 tests_to_run = [test
for test
in all_tests
if test[
'name']
in sys.argv[1:]]
380 res = int(all([result[1][0]
for result
in results])) - 1
381 print (
'exit (%d)' % res)
384 if __name__ ==
'__main__':
def ImageGetData(rec_filename, topic)
def run_test(test, listener_res)
def ImageDepthGetData_decimation(rec_filename)
def ImuTest(data, gt_data)
def ImageColorGetData(rec_filename)
def staticTFTest(data, gt_data)
def PointCloudTest(data, gt_data)
def ImageDepthInColorShapeGetData(rec_filename)
def print_results(results)
def get_tf(tf_listener, from_id, to_id)
def ImageColorTest(data, gt_data)
def ImageColorTest_3epsilon(data, gt_data)
def NotImageColorTest(data, gt_data)
def ImuGetData(rec_filename, topic)
def AccelGetData(rec_filename)
def AccelGetDataDeviceStandStraight(rec_filename)
def ImageDepthGetData(rec_filename)