How ROS Timers work
In this post we will explore some details about how ROS timers work.
Slow callbacks #
What happens if the callback duration is longer than the timer interval?
Lets create an example to check:
import rospy
def callback(timerevent):
rospy.sleep(5)
rospy.loginfo("Expected: %d", timerevent.current_expected.secs)
rospy.loginfo("Real : %d", timerevent.current_real.secs)
rospy.init_node('timer_example')
rospy.Timer(rospy.Duration(1), callback)
rospy.spin()
The output after 3 callbacks:
[INFO] [/timer_example] [1665856443.184161]: Expected: 1665856438
[INFO] [/timer_example] [1665856443.185529]: Real : 1665856438
[INFO] [/timer_example] [1665856448.192108]: Expected: 1665856439
[INFO] [/timer_example] [1665856448.193541]: Real : 1665856443
[INFO] [/timer_example] [1665856453.200060]: Expected: 1665856440
[INFO] [/timer_example] [1665856453.201459]: Real : 1665856448
The output tells us that the callback is executed every 5 seconds. This is equal to the time spent in the callback method. The timer is smart enough to realize that the callback is spending more time than the interval, and call the next callback immediately once the previous callback finishes.
Looking at the source code we see that it is indeed implemented as a loop with a Rate object controlling how long it sleeps.