Timer callbacks can be delayed when using simulation time
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 805
- Forks
- 564
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 27
Description
This is a breakout of the issue described in https://github.com/ros2/rclcpp/issues/2532#issuecomment-2125015383.
Timer processing when using simulation time is a two step process (e.g. requires two waits of the wait set), so it's possible that subscription callbacks can get called before the timer callback when using simulation time. As timers have higher priority than subscriptions (as documented in the Scheduling semantics), one may expect that timers driven via the /clock topic would also have that same higher-priority and expect that timer callbacks driven by the /clock topic would execute before subscription callbacks for messages that were transmitted after the /clock message. Because of the two-step process, this is not necessarily the case.
A potential change to consider would be to have the clock jump handler registered by the timer call the timer callback directly instead of triggering the guard condition. This would only be applicable if the clock thread has been disabled or the default callback group has been configured to be reentrant (though that may be confusing when using the SingleThreadedExecutor, but would actually be consistent with the execute_timers_separate_thread option to the EventsExecutor).
It should be noted that due to the issue described in https://github.com/ros2/rclcpp/issues/2532, an implementation of the above suggestion would likely require that the executor have an explicit processing step for the /clock topic subscription before processing other subscriptions to ensure that the timers are executed before the other subscriptions, Prior to Jazzy, the /clock subscription is always handled first because it was internally registered by the TimeSource before any other application subscriptions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the timer clock jump handler and the executor's processing of the /clock subscription, then compare the SingleThreadedExecutor and EventsExecutor paths described in the issue. Trace how the TimeSource and timer interact with guard conditions. Done means the intended callback ordering is defined and covered by tests for simulation time without breaking the stated executor configurations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- robotics
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100