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);
174 template<
typename MessageT>
175 typename nav2::Publisher<MessageT>::SharedPtr
177 const std::string & topic_name,
179 const rclcpp::CallbackGroup::SharedPtr & callback_group =
nullptr,
180 rclcpp::PublisherMatchedCallbackType matched_callback =
nullptr)
182 auto pub = nav2::interfaces::create_publisher<MessageT>(
183 shared_from_this(), topic_name, qos, callback_group, matched_callback);
184 this->add_managed_entity(pub);
187 if (get_current_state().
id() ==
188 lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE)
202 template<
typename ServiceT>
203 typename nav2::ServiceClient<ServiceT>::SharedPtr
205 const std::string & service_name,
206 bool use_internal_executor =
false)
208 return nav2::interfaces::create_client<ServiceT>(
209 shared_from_this(), service_name, use_internal_executor);
219 template<
typename ServiceT>
220 typename nav2::ServiceServer<ServiceT>::SharedPtr
222 const std::string & service_name,
223 typename nav2::ServiceServer<ServiceT>::CallbackType cb,
224 rclcpp::CallbackGroup::SharedPtr callback_group =
nullptr)
226 return nav2::interfaces::create_service<ServiceT>(
227 shared_from_this(), service_name, cb, callback_group);
237 template<
typename DurationRepT,
typename DurationT,
typename CallbackT>
238 typename rclcpp::GenericTimer<CallbackT>::SharedPtr
240 std::chrono::duration<DurationRepT, DurationT> period,
242 rclcpp::CallbackGroup::SharedPtr group =
nullptr)
244 return rclcpp::create_timer(
245 nav2::selectSteadyOrSimClock(
this),
249 this->get_node_base_interface().get(),
250 this->get_node_timers_interface().get());
263 template<
typename ActionT>
264 typename nav2::SimpleActionServer<ActionT>::SharedPtr
266 const std::string & action_name,
267 typename nav2::SimpleActionServer<ActionT>::ExecuteCallback execute_callback,
268 typename nav2::SimpleActionServer<ActionT>::GoalReceivedCallback goal_received_callback =
270 typename nav2::SimpleActionServer<ActionT>::CompletionCallback compl_cb =
nullptr,
271 std::chrono::milliseconds server_timeout = std::chrono::milliseconds(500),
272 bool spin_thread =
false,
273 const bool realtime =
false)
275 return nav2::interfaces::create_action_server<ActionT>(
276 shared_from_this(), action_name, execute_callback,
277 goal_received_callback, compl_cb, server_timeout, spin_thread, realtime);
286 template<
typename ActionT>
287 typename nav2::ActionClient<ActionT>::SharedPtr
289 const std::string & action_name,
290 rclcpp::CallbackGroup::SharedPtr callback_group =
nullptr)
292 return nav2::interfaces::create_action_client<ActionT>(
293 shared_from_this(), action_name, callback_group);
301 return std::static_pointer_cast<nav2::LifecycleNode>(
302 rclcpp_lifecycle::LifecycleNode::shared_from_this());
310 return std::static_pointer_cast<nav2::LifecycleNode>(
311 rclcpp_lifecycle::LifecycleNode::shared_from_this());
320 nav2::CallbackReturn
on_error(
const rclcpp_lifecycle::State & )
324 "Lifecycle node %s does not have error state implemented", get_name());
325 return nav2::CallbackReturn::SUCCESS;
333 using lifecycle_msgs::msg::State;
334 autostart_timer_ = this->create_timer(
337 autostart_timer_->cancel();
338 RCLCPP_INFO(get_logger(),
"Auto-starting node: %s", this->get_name());
339 if (configure().
id() != State::PRIMARY_STATE_INACTIVE) {
341 get_logger(),
"Auto-starting node %s failed to configure!", this->get_name());
344 if (activate().
id() != State::PRIMARY_STATE_ACTIVE) {
346 get_logger(),
"Auto-starting node %s failed to activate!", this->get_name());
359 get_logger(),
"Running Nav2 LifecycleNode rcl preshutdown (%s)",
372 if (bond_heartbeat_period > 0.0) {
373 RCLCPP_INFO(get_logger(),
"Creating bond (%s) to lifecycle manager.", this->get_name());
375 bond_ = std::make_shared<bond::Bond>(
380 bond_->setHeartbeatPeriod(bond_heartbeat_period);
381 bond_->setHeartbeatTimeout(4.0);
391 if (bond_heartbeat_period > 0.0) {
392 RCLCPP_INFO(get_logger(),
"Destroying bond (%s) to lifecycle manager.", this->get_name());
408 "\n\t%s lifecycle node launched. \n"
409 "\tWaiting on external lifecycle transitions to activate\n"
410 "\tSee https://design.ros2.org/articles/node_lifecycle.html for more information.",
421 rclcpp::Context::SharedPtr context = get_node_base_interface()->get_context();
423 rcl_preshutdown_cb_handle_ = std::make_unique<rclcpp::PreShutdownCallbackHandle>(
424 context->add_pre_shutdown_callback(
439 if (get_current_state().
id() ==
440 lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE)
445 if (get_current_state().
id() ==
446 lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE)
453 std::unique_ptr<rclcpp::PreShutdownCallbackHandle> rcl_preshutdown_cb_handle_{
nullptr};
454 std::shared_ptr<bond::Bond> bond_{
nullptr};
455 double bond_heartbeat_period{0.1};
456 rclcpp::TimerBase::SharedPtr autostart_timer_;
464 static bool getEnableLifecycleServices(
const rclcpp::NodeOptions & options)
467 for (
const auto & param : options.parameter_overrides()) {
468 if (param.get_name() ==
"enable_lifecycle_services") {
469 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, rclcpp::PublisherMatchedCallbackType matched_callback=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.