Skip to content

Commit d3024b5

Browse files
author
Enrique Fernández Perdomo
committed
Merge pull request #2 from clearpathrobotics/check_drop
Add check_drop.py (check msg dropping and time stamps)
2 parents 6d5a54c + 9b1b3c1 commit d3024b5

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

bag_tools/scripts/check_drop.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/python
2+
"""
3+
Copyright (c) 2015,
4+
Enrique Fernandez Perdomo
5+
Clearpath Robotics, Inc.
6+
All rights reserved.
7+
8+
Redistribution and use in source and binary forms, with or without
9+
modification, are permitted provided that the following conditions are met:
10+
* Redistributions of source code must retain the above copyright
11+
notice, this list of conditions and the following disclaimer.
12+
* Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
* Neither the name of Systems, Robotics and Vision Group, University of
16+
the Balearican Islands nor the names of its contributors may be used to
17+
endorse or promote products derived from this software without specific
18+
prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
24+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
"""
31+
32+
import rospy
33+
import rosbag
34+
35+
import numpy
36+
import argparse
37+
38+
import matplotlib.pyplot as plt
39+
40+
def check_drop(inbags):
41+
# Retrieve msg time, bag time and sequence number for all topics and messages:
42+
msg_time = {}
43+
bag_time = {}
44+
seq = {}
45+
46+
for inbag in inbags:
47+
rospy.loginfo(' Processing input bagfile: %s', inbag)
48+
for topic, msg, t in rosbag.Bag(inbag,'r').read_messages():
49+
if topic == "/tf":
50+
for transform in msg.transforms:
51+
key = "/tf: " + transform.header.frame_id + " -> " + transform.child_frame_id
52+
if key not in msg_time:
53+
msg_time[key] = []
54+
bag_time[key] = []
55+
seq[key] = []
56+
else:
57+
msg_time[key].append(transform.header.stamp.to_sec())
58+
bag_time[key].append(t.to_sec())
59+
seq[key].append(transform.header.seq)
60+
elif msg._has_header:
61+
key = topic
62+
if key not in msg_time:
63+
msg_time[key] = []
64+
bag_time[key] = []
65+
seq[key] = []
66+
else:
67+
msg_time[key].append(msg.header.stamp.to_sec())
68+
bag_time[key].append(t.to_sec())
69+
seq[key].append(msg.header.seq)
70+
71+
# Convert lists to numpy.arrays:
72+
for key in msg_time.iterkeys():
73+
msg_time[key] = numpy.array(msg_time[key])
74+
bag_time[key] = numpy.array(bag_time[key])
75+
seq[key] = numpy.array(seq[key])
76+
77+
# Compute differences:
78+
msg_time_diff = {}
79+
bag_time_diff = {}
80+
seq_diff = {}
81+
82+
for key in msg_time.iterkeys():
83+
msg_time_diff[key] = numpy.diff(msg_time[key])
84+
bag_time_diff[key] = numpy.diff(bag_time[key])
85+
seq_diff[key] = numpy.diff(seq[key])
86+
87+
# Compute min, max and mean differences:
88+
basename = inbags[0].replace('.bag', '')
89+
90+
max_len = max(len(topic) for topic in msg_time_diff.keys())
91+
topics = msg_time_diff.keys()
92+
topics.sort()
93+
94+
for topic in topics:
95+
msg_time_diff_topic = msg_time_diff[topic]
96+
bag_time_diff_topic = bag_time_diff[topic]
97+
seq_diff_topic = seq_diff[topic]
98+
99+
msg_time_diff_min = numpy.min(msg_time_diff_topic)
100+
msg_time_diff_max = numpy.max(msg_time_diff_topic)
101+
msg_time_diff_mean = numpy.mean(msg_time_diff_topic)
102+
msg_time_diff_median = numpy.median(msg_time_diff_topic)
103+
104+
bag_time_diff_min = numpy.min(bag_time_diff_topic)
105+
bag_time_diff_max = numpy.max(bag_time_diff_topic)
106+
bag_time_diff_mean = numpy.mean(bag_time_diff_topic)
107+
bag_time_diff_median = numpy.median(bag_time_diff_topic)
108+
109+
seq_diff_min = numpy.min(seq_diff_topic)
110+
seq_diff_max = numpy.max(seq_diff_topic)
111+
seq_diff_mean = numpy.mean(seq_diff_topic)
112+
seq_diff_median = numpy.median(seq_diff_topic)
113+
114+
rospy.loginfo('%s message time: mean = %s, min = %s, max = %s, median = %s', topic.ljust(max_len + 2), msg_time_diff_mean, msg_time_diff_min, msg_time_diff_max, msg_time_diff_median)
115+
rospy.loginfo('%s bag time: mean = %s, min = %s, max = %s, median = %s', topic.ljust(max_len + 2), bag_time_diff_mean, bag_time_diff_min, bag_time_diff_max, bag_time_diff_median)
116+
rospy.loginfo('%s seq: mean = %s, min = %s, max = %s, median = %s', topic.ljust(max_len + 2), seq_diff_mean, seq_diff_min, seq_diff_max, seq_diff_median)
117+
118+
# Create and save plots:
119+
N = len(msg_time_diff_topic)
120+
x = numpy.array([0, N - 1])
121+
122+
fig = plt.figure()
123+
fig.set_size_inches(20, 15)
124+
125+
plt.subplot(311)
126+
plt.title(topic + ' - Message time difference [s]')
127+
plt.plot(msg_time_diff_topic, 'b')
128+
plt.plot(x, numpy.array([msg_time_diff_min, msg_time_diff_min]), 'r--')
129+
plt.plot(x, numpy.array([msg_time_diff_max, msg_time_diff_max]), 'r--')
130+
plt.plot(x, numpy.array([msg_time_diff_mean, msg_time_diff_mean]), 'g')
131+
132+
plt.subplot(312)
133+
plt.title(topic + ' - Bag time difference [s]')
134+
plt.plot(bag_time_diff_topic, 'b')
135+
plt.plot(x, numpy.array([bag_time_diff_min, bag_time_diff_min]), 'r--')
136+
plt.plot(x, numpy.array([bag_time_diff_max, bag_time_diff_max]), 'r--')
137+
plt.plot(x, numpy.array([bag_time_diff_mean, bag_time_diff_mean]), 'g')
138+
139+
plt.subplot(313)
140+
plt.title(topic + ' - Sequence number difference')
141+
plt.plot(seq_diff_topic, 'b')
142+
plt.plot(x, numpy.array([seq_diff_min, seq_diff_min]), 'r--')
143+
plt.plot(x, numpy.array([seq_diff_max, seq_diff_max]), 'r--')
144+
plt.plot(x, numpy.array([seq_diff_mean, seq_diff_mean]), 'g')
145+
146+
plt.savefig(basename + topic.replace('/', '_').replace(' ', '_').replace(':', '_') + '.png')
147+
148+
if __name__ == "__main__":
149+
rospy.init_node('check_drop', anonymous=True)
150+
151+
parser = argparse.ArgumentParser(
152+
description='Checks the header.seq and header.stamp difference to detect '
153+
'message dropping in a bagfile. Prints out min, max and mean '
154+
'differences and all values are shown on a plot.')
155+
parser.add_argument('inbag', help='input bagfile(s)', nargs='+')
156+
args = parser.parse_args()
157+
try:
158+
check_drop(args.inbag)
159+
except Exception, e:
160+
import traceback
161+
traceback.print_exc()

0 commit comments

Comments
 (0)