Robotics StackExchange | Archived questions

rospy.loginfo_throttle and _throttle_identical

A few simple logging questions:

  1. How does throttle decide that the message is the same and not a different log message? Is it simply by the call site?

  2. Also what are the units for throttle? The doc seems to imply that it is seconds but for me it's not doing any throttling.

  3. Finally, what exactly would throttleidentical do? How does it determine whether it's identical?

Thanks

Asked by pitosalas on 2019-07-28 13:05:21 UTC

Comments

Answers

I didn't know rospy.loginfo_throttle_identical() and the others existed until seeing this, it looks like it has been in the code for a few years (if not any documentation or open source ros projects). I'll have to start using it (check for C++ equivalents).

https://github.com/ros/ros_comm/blob/noetic-devel/clients/rospy/src/rospy/core.py#L273

https://github.com/ros/ros_comm/commit/60be2504d5341eb3bc80d86e5d16f1c53dc97ccd

From trying it out and looking at the code throttle_identical behaves like throttle except if the message text changes. The timer doesn't reset if the message changes, it will stay on the previous throttle phase.

This can be demonstrated on the python shell (every line must have the same caller id):

python
rospy.init_node('test')
rospy.loginfo_throttle_identical(10.0, "test1");
rospy.sleep(5.0);
rospy.loginfo_throttle_identical(10.0, "test1");  # doesn't log  'test1' == 'test1'
rospy.loginfo_throttle_identical(10.0, "test2");  # does log, 'test2' != 'test1'
rospy.loginfo_throttle_identical(10.0, "test1");  # does log, 'test1' != 'test2'
rospy.sleep(6.0);
rospy.loginfo_throttle_identical(10.0, "test1");  # does log, time elapsed since first log expired

Here it hashes on the message (as opposed to a string comparison) and uses the caller_id (probably source function + line number)

class LoggingIdentical(object):

    last_logging_msg_table = {}

    def __call__(self, caller_id, msg):
        """Do logging specified message only if distinct from last message.
        - caller_id (str): Id to identify the caller
        - msg (str): Contents of message to log
        """
        msg_hash = md5(msg).hexdigest()

        if msg_hash != self.last_logging_msg_table.get(caller_id):
            self.last_logging_msg_table[caller_id] = msg_hash
            return True
        return False

There's no loginfo_identical but the same could be accomplished with a very long throttle period loginfo_throttle_identical(1000000.0, ...).

(What I'd like is a throttle with an exponential falloff parameter, it would repeat but at an increasingly long period until reset. Also it would be nice to get a bool feedback from the log throttle call if a log occurred or not.)

Asked by lucasw on 2021-01-14 11:07:42 UTC

Comments