1818#include < atomic>
1919#include < chrono>
2020#include < functional>
21+ #include < optional>
2122#include < memory>
2223#include < sstream>
2324#include < thread>
4344namespace rclcpp
4445{
4546
47+ struct TimerInfo
48+ {
49+ Time expected_call_time;
50+ Time actual_call_time;
51+ };
52+
4653class TimerBase
4754{
4855public:
@@ -101,16 +108,20 @@ class TimerBase
101108 * The multithreaded executor takes advantage of this to avoid scheduling
102109 * the callback multiple times.
103110 *
104- * \return `true` if the callback should be executed, `false` if the timer was canceled.
111+ * \return a valid shared_ptr if the callback should be executed,
112+ * an invalid shared_ptr (nullptr) if the timer was canceled.
105113 */
106114 RCLCPP_PUBLIC
107- virtual bool
115+ virtual std::shared_ptr< void >
108116 call () = 0 ;
109117
110118 // / Call the callback function when the timer signal is emitted.
119+ /* *
120+ * \param[in] data the pointer returned by the call function
121+ */
111122 RCLCPP_PUBLIC
112123 virtual void
113- execute_callback () = 0 ;
124+ execute_callback (const std::shared_ptr< void > & data ) = 0 ;
114125
115126 RCLCPP_PUBLIC
116127 std::shared_ptr<const rcl_timer_t >
@@ -198,16 +209,17 @@ class TimerBase
198209 set_on_reset_callback (rcl_event_callback_t callback, const void * user_data);
199210};
200211
201-
202212using VoidCallbackType = std::function<void ()>;
203213using TimerCallbackType = std::function<void (TimerBase &)>;
214+ using TimerInfoCallbackType = std::function<void (const TimerInfo &)>;
204215
205216// / Generic timer. Periodically executes a user-specified callback.
206217template <
207218 typename FunctorT,
208219 typename std::enable_if<
209220 rclcpp::function_traits::same_arguments<FunctorT, VoidCallbackType>::value ||
210- rclcpp::function_traits::same_arguments<FunctorT, TimerCallbackType>::value
221+ rclcpp::function_traits::same_arguments<FunctorT, TimerCallbackType>::value ||
222+ rclcpp::function_traits::same_arguments<FunctorT, TimerInfoCallbackType>::value
211223 >::type * = nullptr
212224>
213225class GenericTimer : public TimerBase
@@ -256,27 +268,28 @@ class GenericTimer : public TimerBase
256268 * \sa rclcpp::TimerBase::call
257269 * \throws std::runtime_error if it failed to notify timer that callback will occurr
258270 */
259- bool
271+ std::shared_ptr< void >
260272 call () override
261273 {
262- rcl_ret_t ret = rcl_timer_call (timer_handle_.get ());
274+ auto timer_call_info_ = std::make_shared<rcl_timer_call_info_t >();
275+ rcl_ret_t ret = rcl_timer_call_with_info (timer_handle_.get (), timer_call_info_.get ());
263276 if (ret == RCL_RET_TIMER_CANCELED) {
264- return false ;
277+ return nullptr ;
265278 }
266279 if (ret != RCL_RET_OK) {
267280 throw std::runtime_error (" Failed to notify timer that callback occurred" );
268281 }
269- return true ;
282+ return timer_call_info_ ;
270283 }
271284
272285 /* *
273286 * \sa rclcpp::TimerBase::execute_callback
274287 */
275288 void
276- execute_callback () override
289+ execute_callback (const std::shared_ptr< void > & data ) override
277290 {
278291 TRACETOOLS_TRACEPOINT (callback_start, reinterpret_cast <const void *>(&callback_), false );
279- execute_callback_delegate<>();
292+ execute_callback_delegate<>(* static_cast < rcl_timer_call_info_t *>(data. get ()) );
280293 TRACETOOLS_TRACEPOINT (callback_end, reinterpret_cast <const void *>(&callback_));
281294 }
282295
@@ -288,7 +301,7 @@ class GenericTimer : public TimerBase
288301 >::type * = nullptr
289302 >
290303 void
291- execute_callback_delegate ()
304+ execute_callback_delegate (const rcl_timer_call_info_t & )
292305 {
293306 callback_ ();
294307 }
@@ -300,11 +313,26 @@ class GenericTimer : public TimerBase
300313 >::type * = nullptr
301314 >
302315 void
303- execute_callback_delegate ()
316+ execute_callback_delegate (const rcl_timer_call_info_t & )
304317 {
305318 callback_ (*this );
306319 }
307320
321+
322+ template <
323+ typename CallbackT = FunctorT,
324+ typename std::enable_if<
325+ rclcpp::function_traits::same_arguments<CallbackT, TimerInfoCallbackType>::value
326+ >::type * = nullptr
327+ >
328+ void
329+ execute_callback_delegate (const rcl_timer_call_info_t & timer_call_info_)
330+ {
331+ const TimerInfo info{Time{timer_call_info_.expected_call_time , clock_->get_clock_type ()},
332+ Time{timer_call_info_.actual_call_time , clock_->get_clock_type ()}};
333+ callback_ (info);
334+ }
335+
308336 // / Is the clock steady (i.e. is the time between ticks constant?)
309337 /* * \return True if the clock used by this timer is steady. */
310338 bool
@@ -323,7 +351,8 @@ template<
323351 typename FunctorT,
324352 typename std::enable_if<
325353 rclcpp::function_traits::same_arguments<FunctorT, VoidCallbackType>::value ||
326- rclcpp::function_traits::same_arguments<FunctorT, TimerCallbackType>::value
354+ rclcpp::function_traits::same_arguments<FunctorT, TimerCallbackType>::value ||
355+ rclcpp::function_traits::same_arguments<FunctorT, TimerInfoCallbackType>::value
327356 >::type * = nullptr
328357>
329358class WallTimer : public GenericTimer <FunctorT>
0 commit comments