15 #ifndef RCLCPP__CREATE_TIMER_HPP_
16 #define RCLCPP__CREATE_TIMER_HPP_
24 #include "rclcpp/duration.hpp"
25 #include "rclcpp/node_interfaces/get_node_base_interface.hpp"
26 #include "rclcpp/node_interfaces/get_node_timers_interface.hpp"
27 #include "rclcpp/node_interfaces/node_base_interface.hpp"
28 #include "rclcpp/node_interfaces/node_clock_interface.hpp"
29 #include "rclcpp/node_interfaces/node_timers_interface.hpp"
44 template<
typename DurationRepT,
typename DurationT>
45 std::chrono::nanoseconds
46 safe_cast_to_period_in_ns(std::chrono::duration<DurationRepT, DurationT> period)
48 if (period < std::chrono::duration<DurationRepT, DurationT>::zero()) {
49 throw std::invalid_argument{
"timer period cannot be negative"};
54 constexpr
auto maximum_safe_cast_ns =
55 std::chrono::nanoseconds::max() - std::chrono::duration<DurationRepT, DurationT>(1);
64 constexpr
auto ns_max_as_double =
65 std::chrono::duration_cast<std::chrono::duration<double, std::chrono::nanoseconds::period>>(
66 maximum_safe_cast_ns);
67 if (period > ns_max_as_double) {
68 throw std::invalid_argument{
69 "timer period must be less than std::chrono::nanoseconds::max()"};
72 const auto period_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(period);
73 if (period_ns < std::chrono::nanoseconds::zero()) {
74 throw std::runtime_error{
75 "Casting timer period to nanoseconds resulted in integer overflow."};
84 template<
typename CallbackT>
85 typename rclcpp::TimerBase::SharedPtr
87 std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
88 std::shared_ptr<node_interfaces::NodeTimersInterface> node_timers,
89 rclcpp::Clock::SharedPtr clock,
91 CallbackT && callback,
92 rclcpp::CallbackGroup::SharedPtr group =
nullptr,
93 bool autostart =
true)
97 period.
to_chrono<std::chrono::nanoseconds>(),
98 std::forward<CallbackT>(callback),
106 template<
typename NodeT,
typename CallbackT>
107 typename rclcpp::TimerBase::SharedPtr
110 rclcpp::Clock::SharedPtr clock,
112 CallbackT && callback,
113 rclcpp::CallbackGroup::SharedPtr group =
nullptr,
114 bool autostart =
true)
118 period.
to_chrono<std::chrono::nanoseconds>(),
119 std::forward<CallbackT>(callback),
121 rclcpp::node_interfaces::get_node_base_interface(node).get(),
122 rclcpp::node_interfaces::get_node_timers_interface(node).get(),
143 template<
typename DurationRepT,
typename DurationT,
typename CallbackT>
146 rclcpp::Clock::SharedPtr clock,
147 std::chrono::duration<DurationRepT, DurationT> period,
149 rclcpp::CallbackGroup::SharedPtr group,
152 bool autostart =
true)
154 if (clock ==
nullptr) {
155 throw std::invalid_argument{
"clock cannot be null"};
157 if (node_base ==
nullptr) {
158 throw std::invalid_argument{
"input node_base cannot be null"};
160 if (node_timers ==
nullptr) {
161 throw std::invalid_argument{
"input node_timers cannot be null"};
164 const std::chrono::nanoseconds period_ns = detail::safe_cast_to_period_in_ns(period);
168 std::move(clock), period_ns, std::move(callback), node_base->
get_context(), autostart);
188 template<
typename DurationRepT,
typename DurationT,
typename CallbackT>
191 std::chrono::duration<DurationRepT, DurationT> period,
193 rclcpp::CallbackGroup::SharedPtr group,
196 bool autostart =
true)
198 if (node_base ==
nullptr) {
199 throw std::invalid_argument{
"input node_base cannot be null"};
202 if (node_timers ==
nullptr) {
203 throw std::invalid_argument{
"input node_timers cannot be null"};
206 const std::chrono::nanoseconds period_ns = detail::safe_cast_to_period_in_ns(period);
210 period_ns, std::move(callback), node_base->
get_context(), autostart);
DurationT to_chrono() const
Convert Duration into a std::chrono::Duration.
Generic timer. Periodically executes a user-specified callback.
Pure virtual interface class for the NodeBase part of the Node API.
virtual RCLCPP_PUBLIC rclcpp::Context::SharedPtr get_context()=0
Return the context of the node.
Pure virtual interface class for the NodeTimers part of the Node API.
virtual RCLCPP_PUBLIC void add_timer(rclcpp::TimerBase::SharedPtr timer, rclcpp::CallbackGroup::SharedPtr callback_group)=0
Add a timer to the node.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
rclcpp::TimerBase::SharedPtr create_timer(std::shared_ptr< node_interfaces::NodeBaseInterface > node_base, std::shared_ptr< node_interfaces::NodeTimersInterface > node_timers, rclcpp::Clock::SharedPtr clock, rclcpp::Duration period, CallbackT &&callback, rclcpp::CallbackGroup::SharedPtr group=nullptr, bool autostart=true)
rclcpp::WallTimer< CallbackT >::SharedPtr create_wall_timer(std::chrono::duration< DurationRepT, DurationT > period, CallbackT callback, rclcpp::CallbackGroup::SharedPtr group, node_interfaces::NodeBaseInterface *node_base, node_interfaces::NodeTimersInterface *node_timers, bool autostart=true)
Convenience method to create a wall timer with node resources.