55
66import copy
77import sys
8- from collections import deque
98
109import genpy
1110import rosbag .bag
11+ import rospy
12+ from cras import Heap
1213
1314from .bag_utils import BagWrapper , MultiBag
1415from .message_filter import MessageFilter , Passthrough , filter_message
@@ -66,14 +67,18 @@ def filter_bag(bags, out, bag_filter=Passthrough(), params=None, start_time=None
6667 # apply connection filters
6768 topics = [c .topic for c in bags ._get_connections (topics , bag_filter .connection_filter )] # noqa
6869
69- queue = deque ()
70+ get_stamp_fn = lambda x : x [2 ] # get stamp from the tuple
71+ heap = Heap (initial = list (bag_filter .extra_initial_messages ()), key = get_stamp_fn )
72+
7073 connection_filter = bag_filter .connection_filter
74+ _stamp = rospy .Time (0 )
7175 for topic , msg , stamp , connection_header in bags .read_messages (
7276 topics = topics , start_time = time_ranges , end_time = extra_time_ranges , return_connection_header = True ,
7377 raw = bag_filter .is_raw , connection_filter = connection_filter ):
74- queue .append ((topic , msg , stamp , connection_header ))
75- while len (queue ) > 0 :
76- _topic , _msg , _stamp , _connection_header = queue .popleft ()
78+ heap .push ((topic , msg , stamp , connection_header ))
79+ # For each bag message, process the whole heap up to the stamp of the bag message
80+ while len (heap ) > 0 and _stamp <= stamp :
81+ _topic , _msg , _stamp , _connection_header = heap .pop ()
7782 _connection_header = copy .copy (_connection_header ) # Prevent modifying connection records from in bag
7883 is_from_extra_time_ranges = False
7984 if extra_time_ranges is not None and time_ranges is not None :
@@ -82,10 +87,31 @@ def filter_bag(bags, out, bag_filter=Passthrough(), params=None, start_time=None
8287 if not isinstance (ret , list ):
8388 ret = [ret ]
8489 for data in ret [1 :]:
85- queue . append (data )
90+ heap . push (data )
8691 if ret [0 ] is None :
8792 continue
8893 _topic , _raw_msg , _stamp , _connection_header = ret [0 ]
8994 out .write (_topic , _raw_msg , _stamp , connection_header = _connection_header , raw = True )
9095
96+ # Push all final messages before processing the rest of the heap
97+ for m in bag_filter .extra_final_messages ():
98+ heap .push (m )
99+
100+ # Finish the rest of the heap if there is something left (messages with stamp higher than last message from bag)
101+ while len (heap ) > 0 :
102+ _topic , _msg , _stamp , _connection_header = heap .pop ()
103+ _connection_header = copy .copy (_connection_header ) # Prevent modifying connection records from in bag
104+ is_from_extra_time_ranges = False
105+ if extra_time_ranges is not None and time_ranges is not None :
106+ is_from_extra_time_ranges = _stamp in extra_time_ranges and _stamp not in time_ranges
107+ ret = filter_message (_topic , _msg , _stamp , _connection_header , bag_filter , True , is_from_extra_time_ranges )
108+ if not isinstance (ret , list ):
109+ ret = [ret ]
110+ for data in ret [1 :]:
111+ heap .push (data )
112+ if ret [0 ] is None :
113+ continue
114+ _topic , _raw_msg , _stamp , _connection_header = ret [0 ]
115+ out .write (_topic , _raw_msg , _stamp , connection_header = _connection_header , raw = True )
116+
91117 bag_filter .reset ()
0 commit comments