15 #ifndef NAV2_ROS_COMMON__LIFECYCLE_NODE_HPP_
16 #define NAV2_ROS_COMMON__LIFECYCLE_NODE_HPP_
25 #include "lifecycle_msgs/msg/state.hpp"
26 #include "nav2_ros_common/node_utils.hpp"
27 #include "rcl_interfaces/msg/parameter_descriptor.hpp"
28 #include "nav2_ros_common/node_thread.hpp"
29 #include "rclcpp_lifecycle/lifecycle_node.hpp"
30 #include "rclcpp/rclcpp.hpp"
31 #include "bondcpp/bond.hpp"
32 #include "bond/msg/constants.hpp"
33 #include "nav2_ros_common/interface_factories.hpp"
34 #include "nav2_ros_common/rate.hpp"
39 using CallbackReturn = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn;
40 using namespace std::chrono_literals;
49 using SharedPtr = std::shared_ptr<nav2::LifecycleNode>;
50 using WeakPtr = std::weak_ptr<nav2::LifecycleNode>;
51 using SharedConstPointer = std::shared_ptr<const nav2::LifecycleNode>;
60 const std::string & node_name,
61 const std::string & ns,
62 const rclcpp::NodeOptions & options = rclcpp::NodeOptions())
63 : rclcpp_lifecycle::
LifecycleNode(node_name, ns, options, getEnableLifecycleServices(options))
66 this->declare_parameter(bond::msg::Constants::DISABLE_HEARTBEAT_TIMEOUT_PARAM,
true);
69 bond::msg::Constants::DISABLE_HEARTBEAT_TIMEOUT_PARAM,
true));
71 bond_heartbeat_period = this->declare_or_get_parameter<double>(
"bond_heartbeat_period", 0.25);
72 bool autostart_node = this->declare_or_get_parameter(
"autostart_node",
false);
77 printLifecycleNodeNotification();
79 register_rcl_preshutdown_callback();
88 const std::string & node_name,
89 const rclcpp::NodeOptions & options = rclcpp::NodeOptions())
95 RCLCPP_INFO(get_logger(),
"Destroying");
99 if (rcl_preshutdown_cb_handle_) {
100 rclcpp::Context::SharedPtr context = get_node_base_interface()->get_context();
101 context->remove_pre_shutdown_callback(*(rcl_preshutdown_cb_handle_.get()));
102 rcl_preshutdown_cb_handle_.reset();
114 template<
typename ParameterT>
116 const std::string & parameter_name,
117 const ParameterDescriptor & parameter_descriptor = ParameterDescriptor())
119 return nav2::declare_or_get_parameter<ParameterT>(
120 this, parameter_name, parameter_descriptor);
132 template<
typename ParamType>
134 const std::string & parameter_name,
135 const ParamType & default_value,
136 const ParameterDescriptor & parameter_descriptor = ParameterDescriptor())
138 return nav2::declare_or_get_parameter(
139 this, parameter_name,
140 default_value, parameter_descriptor);
154 typename nav2::Subscription<MessageT>::SharedPtr
156 const std::string & topic_name,
157 CallbackT && callback,
159 const rclcpp::CallbackGroup::SharedPtr & callback_group =
nullptr)
161 return nav2::interfaces::create_subscription<MessageT>(
162 shared_from_this(), topic_name,
163 std::forward<CallbackT>(callback), qos, callback_group);
173 template<
typename MessageT>
174 typename nav2::Publisher<MessageT>::SharedPtr
176 const std::string & topic_name,
178 const rclcpp::CallbackGroup::SharedPtr & callback_group =
nullptr)
180 auto pub = nav2::interfaces::create_publisher<MessageT>(
181 shared_from_this(), topic_name, qos, callback_group);
182 this->add_managed_entity(pub);
185 if (get_current_state().
id() ==
186 lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE)
200 template<
typename ServiceT>
201 typename nav2::ServiceClient<ServiceT>::SharedPtr
203 const std::string & service_name,
204 bool use_internal_executor =
false)
206 return nav2::interfaces::create_client<ServiceT>(
207 shared_from_this(), service_name, use_internal_executor);
217 template<
typename ServiceT>
218 typename nav2::ServiceServer<ServiceT>::SharedPtr
220 const std::string & service_name,
221 typename nav2::ServiceServer<ServiceT>::CallbackType cb,
222 rclcpp::CallbackGroup::SharedPtr callback_group =
nullptr)
224 return nav2::interfaces::create_service<ServiceT>(
225 shared_from_this(), service_name, cb, callback_group);
235 template<
typename DurationRepT,
typename DurationT,
typename CallbackT>
236 typename rclcpp::GenericTimer<CallbackT>::SharedPtr
238 std::chrono::duration<DurationRepT, DurationT> period,
240 rclcpp::CallbackGroup::SharedPtr group =
nullptr)
242 return rclcpp::create_timer(
243 nav2::selectSteadyOrSimClock(
this),
247 this->get_node_base_interface().get(),
248 this->get_node_timers_interface().get());
261 template<
typename ActionT>
262 typename nav2::SimpleActionServer<ActionT>::SharedPtr
264 const std::string & action_name,
265 typename nav2::SimpleActionServer<ActionT>::ExecuteCallback execute_callback,
266 typename nav2::SimpleActionServer<ActionT>::GoalReceivedCallback goal_received_callback =
268 typename nav2::SimpleActionServer<ActionT>::CompletionCallback compl_cb =
nullptr,
269 std::chrono::milliseconds server_timeout = std::chrono::milliseconds(500),
270 bool spin_thread =
false,
271 const bool realtime =
false)
273 return nav2::interfaces::create_action_server<ActionT>(
274 shared_from_this(), action_name, execute_callback,
275 goal_received_callback, compl_cb, server_timeout, spin_thread, realtime);
284 template<
typename ActionT>
285 typename nav2::ActionClient<ActionT>::SharedPtr
287 const std::string & action_name,
288 rclcpp::CallbackGroup::SharedPtr callback_group =
nullptr)
290 return nav2::interfaces::create_action_client<ActionT>(
291 shared_from_this(), action_name, callback_group);
299 return std::static_pointer_cast<nav2::LifecycleNode>(
300 rclcpp_lifecycle::LifecycleNode::shared_from_this());
308 return std::static_pointer_cast<nav2::LifecycleNode>(
309 rclcpp_lifecycle::LifecycleNode::shared_from_this());
318 nav2::CallbackReturn
on_error(
const rclcpp_lifecycle::State & )
322 "Lifecycle node %s does not have error state implemented", get_name());
323 return nav2::CallbackReturn::SUCCESS;
331 using lifecycle_msgs::msg::State;
332 autostart_timer_ = this->create_timer(
335 autostart_timer_->cancel();
336 RCLCPP_INFO(get_logger(),
"Auto-starting node: %s", this->get_name());
337 if (configure().
id() != State::PRIMARY_STATE_INACTIVE) {
339 get_logger(),
"Auto-starting node %s failed to configure!", this->get_name());
342 if (activate().
id() != State::PRIMARY_STATE_ACTIVE) {
344 get_logger(),
"Auto-starting node %s failed to activate!", this->get_name());
357 get_logger(),
"Running Nav2 LifecycleNode rcl preshutdown (%s)",
370 if (bond_heartbeat_period > 0.0) {
371 RCLCPP_INFO(get_logger(),
"Creating bond (%s) to lifecycle manager.", this->get_name());
373 bond_ = std::make_shared<bond::Bond>(
378 bond_->setHeartbeatPeriod(bond_heartbeat_period);
379 bond_->setHeartbeatTimeout(4.0);
389 if (bond_heartbeat_period > 0.0) {
390 RCLCPP_INFO(get_logger(),
"Destroying bond (%s) to lifecycle manager.", this->get_name());
406 "\n\t%s lifecycle node launched. \n"
407 "\tWaiting on external lifecycle transitions to activate\n"
408 "\tSee https://design.ros2.org/articles/node_lifecycle.html for more information.",
419 rclcpp::Context::SharedPtr context = get_node_base_interface()->get_context();
421 rcl_preshutdown_cb_handle_ = std::make_unique<rclcpp::PreShutdownCallbackHandle>(
422 context->add_pre_shutdown_callback(
437 if (get_current_state().
id() ==
438 lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE)
443 if (get_current_state().
id() ==
444 lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE)
451 std::unique_ptr<rclcpp::PreShutdownCallbackHandle> rcl_preshutdown_cb_handle_{
nullptr};
452 std::shared_ptr<bond::Bond> bond_{
nullptr};
453 double bond_heartbeat_period{0.1};
454 rclcpp::TimerBase::SharedPtr autostart_timer_;
462 static bool getEnableLifecycleServices(
const rclcpp::NodeOptions & options)
465 for (
const auto & param : options.parameter_overrides()) {
466 if (param.get_name() ==
"enable_lifecycle_services") {
467 return param.as_bool();
A lifecycle node wrapper to enable common Nav2 needs such as manipulating parameters.
nav2::CallbackReturn on_error(const rclcpp_lifecycle::State &)
Abstracted on_error state transition callback, since unimplemented as of 2020 in the managed ROS2 nod...
void autostart()
Automatically configure and active the node.
void destroyBond()
Destroy bond connection to lifecycle manager.
nav2::LifecycleNode::SharedPtr shared_from_this()
Get a shared pointer of this.
void printLifecycleNodeNotification()
Print notifications for lifecycle node.
nav2::Publisher< MessageT >::SharedPtr create_publisher(const std::string &topic_name, const rclcpp::QoS &qos=nav2::qos::StandardTopicQoS(), const rclcpp::CallbackGroup::SharedPtr &callback_group=nullptr)
Create a publisher to a topic using Nav2 QoS profiles and PublisherOptions.
rclcpp::GenericTimer< CallbackT >::SharedPtr create_timer(std::chrono::duration< DurationRepT, DurationT > period, CallbackT callback, rclcpp::CallbackGroup::SharedPtr group=nullptr)
Create a sim-time-aware timer for Nav2 lifecycle nodes.
ParameterT declare_or_get_parameter(const std::string ¶meter_name, const ParameterDescriptor ¶meter_descriptor=ParameterDescriptor())
Declares or gets a parameter with specified type (not value). If the parameter is already declared,...
nav2::SimpleActionServer< ActionT >::SharedPtr create_action_server(const std::string &action_name, typename nav2::SimpleActionServer< ActionT >::ExecuteCallback execute_callback, typename nav2::SimpleActionServer< ActionT >::GoalReceivedCallback goal_received_callback=nullptr, typename nav2::SimpleActionServer< ActionT >::CompletionCallback compl_cb=nullptr, std::chrono::milliseconds server_timeout=std::chrono::milliseconds(500), bool spin_thread=false, const bool realtime=false)
Create a SimpleActionServer to host with an action.
nav2::ServiceClient< ServiceT >::SharedPtr create_client(const std::string &service_name, bool use_internal_executor=false)
Create a ServiceClient to interface with a service.
void createBond()
Create bond connection to lifecycle manager.
LifecycleNode(const std::string &node_name, const std::string &ns, const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
A lifecycle node constructor.
virtual void on_rcl_preshutdown()
Perform preshutdown activities before our Context is shutdown. Note that this is related to our Conte...
nav2::Subscription< MessageT >::SharedPtr create_subscription(const std::string &topic_name, CallbackT &&callback, const rclcpp::QoS &qos=nav2::qos::StandardTopicQoS(), const rclcpp::CallbackGroup::SharedPtr &callback_group=nullptr)
Create a subscription to a topic using Nav2 QoS profiles and SubscriptionOptions.
nav2::ServiceServer< ServiceT >::SharedPtr create_service(const std::string &service_name, typename nav2::ServiceServer< ServiceT >::CallbackType cb, rclcpp::CallbackGroup::SharedPtr callback_group=nullptr)
Create a ServiceServer to host with a service.
nav2::LifecycleNode::WeakPtr weak_from_this()
Get a shared pointer of this.
void register_rcl_preshutdown_callback()
ParamType declare_or_get_parameter(const std::string ¶meter_name, const ParamType &default_value, const ParameterDescriptor ¶meter_descriptor=ParameterDescriptor())
Declares or gets a parameter. If the parameter is already declared, returns its value; otherwise decl...
nav2::ActionClient< ActionT >::SharedPtr create_action_client(const std::string &action_name, rclcpp::CallbackGroup::SharedPtr callback_group=nullptr)
Create a ActionClient to call an action using.
LifecycleNode(const std::string &node_name, const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
A lifecycle node constructor with no namespace.
A QoS profile for standard reliable topics with a history of 10 messages.