@@ -424,10 +424,12 @@ def _str_params(self):
424424class DeduplicateTF (DeserializedMessageFilter ):
425425 """Discard all messages except each first changed."""
426426
427- def __init__ (self , max_ignored_duration = None , include_topics = None , * args , ** kwargs ):
427+ def __init__ (self , max_ignored_duration = None , cache_size = 1 , include_topics = None , * args , ** kwargs ):
428428 """
429429 :param float max_ignored_duration: If set, a duplicate will pass if its stamp is further from the last passed
430430 message than the given duration (in seconds).
431+ :param int cache_size: Number of previous messages to remember for each TF
432+ (duplicates are searched in this cache).
431433 :param list include_topics: Topics to work on (defaults to standard TF topics).
432434 :param args: Standard include/exclude and stamp args.
433435 :param kwargs: Standard include/exclude and stamp kwargs.
@@ -436,6 +438,7 @@ def __init__(self, max_ignored_duration=None, include_topics=None, *args, **kwar
436438 include_topics = ['tf' , 'tf_static' ] if include_topics is None else include_topics ,
437439 include_types = [TFMessage ._type ], * args , ** kwargs ) # noqa
438440 self ._max_ignored_duration = rospy .Duration (max_ignored_duration ) if max_ignored_duration is not None else None
441+ self ._cache_size = max (1 , cache_size )
439442 self ._last_msgs = {}
440443
441444 def filter (self , topic , msg , stamp , header , tags ):
@@ -445,23 +448,27 @@ def filter(self, topic, msg, stamp, header, tags):
445448
446449 for i in reversed (range (len (tfs ))):
447450 key = "%s@%s@%s" % (topic , tfs [i ].header .frame_id , tfs [i ].child_frame_id )
451+ msg_stamp = tfs [i ].header .stamp
448452
449453 if key not in self ._last_msgs :
450- self ._last_msgs [key ] = tfs [i ], stamp , copy .deepcopy (tags )
454+ self ._last_msgs [key ] = deque (maxlen = self ._cache_size )
455+ self ._last_msgs [key ].append ((msg_stamp , stamp , copy .deepcopy (tags )))
451456 continue
452457
453- last_msg , last_msg_stamp , last_tags = self ._last_msgs [key ]
454-
455- stamp_ok = tfs [i ].header .stamp == last_msg .header .stamp
458+ same_msgs = [(ms , s , t ) for ms , s , t in self ._last_msgs [key ] if ms == msg_stamp ]
459+ has_seen_this_stamp = len (same_msgs ) > 0
456460
457461 stamp_diff_ok = True
458462 if self ._max_ignored_duration is not None :
463+ _ , last_msg_stamp , _ = max (same_msgs , key = lambda x : x [1 ])
464+ # if stamp would somehow be before last_msg_stamp, we want to succeed
465+ last_msg_stamp = min (stamp , last_msg_stamp )
459466 stamp_diff_ok = stamp - last_msg_stamp < self ._max_ignored_duration
460467
461- if stamp_ok and stamp_diff_ok :
468+ if has_seen_this_stamp and stamp_diff_ok :
462469 del tfs [i ]
463470 else :
464- self ._last_msgs [key ] = tfs [ i ] , stamp , copy .deepcopy (tags )
471+ self ._last_msgs [key ]. append (( msg_stamp , stamp , copy .deepcopy (tags )) )
465472
466473 if len (tfs ) == 0 :
467474 return None
0 commit comments