15 #include "rclcpp/timer.hpp"
22 #include "rmw/impl/cpp/demangle.hpp"
24 #include "rclcpp/contexts/default_context.hpp"
25 #include "rclcpp/detail/cpp_callback_trampoline.hpp"
26 #include "rclcpp/exceptions.hpp"
27 #include "rclcpp/logging.hpp"
28 #include "rcutils/logging_macros.h"
33 rclcpp::Clock::SharedPtr clock,
34 std::chrono::nanoseconds period,
35 rclcpp::Context::SharedPtr context,
37 : clock_(clock), timer_handle_(nullptr)
39 if (
nullptr == context) {
40 context = rclcpp::contexts::get_global_default_context();
43 auto rcl_context = context->get_rcl_context();
45 timer_handle_ = std::shared_ptr<rcl_timer_t>(
49 std::lock_guard<std::mutex> clock_guard(clock->get_clock_mutex());
51 RCUTILS_LOG_ERROR_NAMED(
53 "Failed to clean up rcl timer handle: %s", rcl_get_error_string().str);
65 rcl_clock_t * clock_handle = clock_->get_clock_handle();
67 std::lock_guard<std::mutex> clock_guard(clock_->get_clock_mutex());
69 timer_handle_.get(), clock_handle, rcl_context.get(), period.count(),
72 rclcpp::exceptions::throw_from_rcl_error(ret,
"Couldn't initialize rcl timer handle");
87 rclcpp::exceptions::throw_from_rcl_error(ret,
"Couldn't cancel timer");
97 rclcpp::exceptions::throw_from_rcl_error(ret,
"Couldn't get timer cancelled state");
107 std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
111 rclcpp::exceptions::throw_from_rcl_error(ret,
"Couldn't reset timer");
121 rclcpp::exceptions::throw_from_rcl_error(ret,
"Failed to check timer");
126 std::chrono::nanoseconds
129 int64_t time_until_next_call = 0;
131 timer_handle_.get(), &time_until_next_call);
133 return std::chrono::nanoseconds::max();
135 rclcpp::exceptions::throw_from_rcl_error(ret,
"Timer could not get time until next call");
137 return std::chrono::nanoseconds(time_until_next_call);
140 std::shared_ptr<const rcl_timer_t>
141 TimerBase::get_timer_handle()
143 return timer_handle_;
149 return in_use_by_wait_set_.exchange(in_use_state);
156 throw std::invalid_argument(
157 "The callback passed to set_on_reset_callback "
162 [callback,
this](
size_t reset_calls) {
164 callback(reset_calls);
165 }
catch (
const std::exception & exception) {
168 "rclcpp::TimerBase@" <<
this <<
169 " caught " << rmw::impl::cpp::demangle(exception) <<
170 " exception in user-provided callback for the 'on reset' callback: " <<
175 "rclcpp::TimerBase@" <<
this <<
176 " caught unhandled exception in user-provided callback " <<
177 "for the 'on reset' callback");
181 std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
187 rclcpp::detail::cpp_callback_trampoline<
188 decltype(new_callback),
const void *,
size_t>,
189 static_cast<const void *
>(&new_callback));
192 on_reset_callback_ = new_callback;
196 rclcpp::detail::cpp_callback_trampoline<
197 decltype(on_reset_callback_),
const void *,
size_t>,
198 static_cast<const void *
>(&on_reset_callback_));
204 std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
206 if (on_reset_callback_) {
208 on_reset_callback_ =
nullptr;
218 rclcpp::exceptions::throw_from_rcl_error(ret,
"Failed to set timer on reset callback");
#define rcl_get_default_allocator
Return a properly initialized rcl_allocator_t with default values.
virtual RCLCPP_PUBLIC ~TimerBase()
TimerBase destructor.
RCLCPP_PUBLIC bool is_canceled()
Return the timer cancellation state.
RCLCPP_PUBLIC void reset()
Reset the timer.
RCLCPP_PUBLIC void clear_on_reset_callback()
Unset the callback registered for reset timer.
RCLCPP_PUBLIC bool exchange_in_use_by_wait_set_state(bool in_use_state)
Exchange the "in use by wait set" state for this timer.
RCLCPP_PUBLIC bool is_ready()
Check if the timer is ready to trigger the callback.
RCLCPP_PUBLIC void set_on_reset_callback(std::function< void(size_t)> callback)
Set a callback to be called when the timer is reset.
RCLCPP_PUBLIC std::chrono::nanoseconds time_until_trigger()
Check how long the timer has until its next scheduled callback.
RCLCPP_PUBLIC void cancel()
Cancel the timer.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Encapsulation of a time source.
Structure which encapsulates a ROS Timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_get_time_until_next_call(const rcl_timer_t *timer, int64_t *time_until_next_call)
Calculate and retrieve the time until the next call in nanoseconds.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_reset(rcl_timer_t *timer)
Reset a timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_set_on_reset_callback(const rcl_timer_t *timer, rcl_event_callback_t on_reset_callback, const void *user_data)
Set the on reset callback function for the timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_init2(rcl_timer_t *timer, rcl_clock_t *clock, rcl_context_t *context, int64_t period, const rcl_timer_callback_t callback, rcl_allocator_t allocator, bool autostart)
Initialize a timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_cancel(rcl_timer_t *timer)
Cancel a timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_timer_t rcl_get_zero_initialized_timer(void)
Return a zero initialized timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_fini(rcl_timer_t *timer)
Finalize a timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_is_canceled(const rcl_timer_t *timer, bool *is_canceled)
Retrieve the canceled state of a timer.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_timer_is_ready(const rcl_timer_t *timer, bool *is_ready)
Calculates whether or not the timer should be called.
#define RCL_RET_OK
Success return code.
#define RCL_RET_TIMER_CANCELED
Given timer was canceled return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.