15 #ifndef NAV2_CORE__BEHAVIOR_TREE_NAVIGATOR_HPP_
16 #define NAV2_CORE__BEHAVIOR_TREE_NAVIGATOR_HPP_
24 #include "nav2_util/odometry_utils.hpp"
25 #include "nav2_ros_common/tf2_factories.hpp"
26 #include "rclcpp/clock.hpp"
27 #include "rclcpp/logger.hpp"
28 #include "rclcpp/logging.hpp"
29 #include "rclcpp/rate.hpp"
30 #include "nav2_ros_common/lifecycle_node.hpp"
31 #include "pluginlib/class_loader.hpp"
32 #include "nav2_behavior_tree/bt_action_server.hpp"
33 #include "nav2_ros_common/node_utils.hpp"
45 std::string robot_frame;
46 std::string global_frame;
47 double transform_tolerance;
48 nav2::TransformBuffer::SharedPtr tf;
69 nav2::LifecycleNode::WeakPtr parent_node,
70 const std::vector<std::string> & plugin_lib_names,
73 std::shared_ptr<nav2_util::OdomSmoother> odom_smoother) = 0;
93 virtual void preempt() = 0;
108 : current_navigator_(nullptr) {}
116 std::scoped_lock l(mutex_);
117 return current_navigator_ !=
nullptr;
126 std::scoped_lock l(mutex_);
127 if (current_navigator_ !=
nullptr) {
129 rclcpp::get_logger(
"NavigatorMutex"),
130 "Major error! Navigation requested while another navigation"
131 " task is in progress! This likely occurred from an incorrect"
132 "implementation of a navigator plugin.");
134 current_navigator_ = navigator;
143 std::scoped_lock l(mutex_);
144 if (current_navigator_ != navigator) {
146 rclcpp::get_logger(
"NavigatorMutex"),
147 "Major error! Navigation stopped while another navigation"
148 " task is in progress! This likely occurred from an incorrect"
149 "implementation of a navigator plugin.");
151 current_navigator_ =
nullptr;
155 void preemptCurrentNavigator()
157 std::scoped_lock l(mutex_);
158 current_navigator_->preempt();
168 std::scoped_lock l(mutex_);
169 return current_navigator_ == navigator;
183 template<
class ActionT>
187 using Ptr = std::shared_ptr<nav2_core::BehaviorTreeNavigator<ActionT>>;
195 plugin_muxer_ =
nullptr;
214 nav2::LifecycleNode::WeakPtr parent_node,
215 const std::vector<std::string> & plugin_lib_names,
218 std::shared_ptr<nav2_util::OdomSmoother> odom_smoother)
final
220 auto node = parent_node.lock();
221 logger_ = node->get_logger();
222 clock_ = node->get_clock();
223 feedback_utils_ = feedback_utils;
224 plugin_muxer_ = plugin_muxer;
227 std::string default_bt_xml_filename = getDefaultBTFilepath(parent_node);
229 auto search_directories = node->declare_or_get_parameter(
230 "bt_search_directories",
231 std::vector<std::string>{nav2::get_package_share_directory(
232 "nav2_bt_navigator") +
"/behavior_trees"}
235 allow_navigator_preemption_ = node->declare_or_get_parameter(
236 "allow_navigator_preemption",
false);
238 navigator_preemption_timeout_ = std::chrono::milliseconds(
239 node->declare_or_get_parameter(
"navigator_preemption_timeout", 500));
243 std::make_unique<nav2_behavior_tree::BtActionServer<ActionT, nav2::LifecycleNode>>(
247 default_bt_xml_filename,
253 std::placeholders::_1, std::placeholders::_2),
257 if (!bt_action_server_->on_configure()) {
261 BT::Blackboard::Ptr blackboard = bt_action_server_->getBlackboard();
262 blackboard->set(
"tf_buffer", feedback_utils.tf);
263 blackboard->set(
"initial_pose_received",
false);
264 blackboard->set(
"number_recoveries", 0);
265 blackboard->set(
"odom_smoother", odom_smoother);
267 return configure(parent_node, odom_smoother) && ok;
278 if (!bt_action_server_->on_activate()) {
292 if (!bt_action_server_->on_deactivate()) {
306 if (!bt_action_server_->on_cleanup()) {
310 bt_action_server_.reset();
315 virtual std::string getDefaultBTFilepath(nav2::LifecycleNode::WeakPtr node) = 0;
325 bt_action_server_->preemptCurrentNavigator();
336 if (!allow_navigator_preemption_) {
339 "Requested navigation from %s while another navigator is processing,"
340 " rejecting request.",
getName().c_str());
346 "Requested navigation from %s while another navigator is processing,"
347 " stopping current navigator.",
getName().c_str());
348 plugin_muxer_->preemptCurrentNavigator();
350 const auto start = std::chrono::steady_clock::now();
353 if (std::chrono::steady_clock::now() - start > navigator_preemption_timeout_) {
356 "Timed out waiting for current navigator to stop before accepting"
357 " goal from %s. Rejecting request.",
getName().c_str());
370 return goal_accepted;
377 typename ActionT::Result::SharedPtr result,
378 nav2_behavior_tree::BtStatus & final_bt_status)
389 virtual bool goalReceived(
typename ActionT::Goal::ConstSharedPtr goal) = 0;
400 virtual void onPreempt(
typename ActionT::Goal::ConstSharedPtr goal) = 0;
407 typename ActionT::Result::SharedPtr result,
408 nav2_behavior_tree::BtStatus & final_bt_status) = 0;
414 nav2::LifecycleNode::WeakPtr ,
415 std::shared_ptr<nav2_util::OdomSmoother>)
435 std::unique_ptr<nav2_behavior_tree::BtActionServer<ActionT, nav2::LifecycleNode>>
437 rclcpp::Logger logger_{rclcpp::get_logger(
"Navigator")};
438 rclcpp::Clock::SharedPtr clock_;
439 FeedbackUtils feedback_utils_;
440 NavigatorMuxer * plugin_muxer_;
443 bool allow_navigator_preemption_;
446 std::chrono::milliseconds navigator_preemption_timeout_;
Navigator interface that acts as a base class for all BT-based Navigator action's plugins All methods...
virtual void goalCompleted(typename ActionT::Result::SharedPtr result, nav2_behavior_tree::BtStatus &final_bt_status)=0
A callback that is called when a the action is completed; Can fill in action result message or indica...
virtual void onPreempt(typename ActionT::Goal::ConstSharedPtr goal)=0
A callback that is called when a preempt is requested.
void onCompletion(typename ActionT::Result::SharedPtr result, nav2_behavior_tree::BtStatus &final_bt_status)
An intermediate completion function to mux navigators.
BehaviorTreeNavigator()
A Navigator constructor.
virtual ~BehaviorTreeNavigator()=default
Virtual destructor.
virtual std::string getName()=0
Get the action name of this navigator to expose.
bool onGoalReceived(typename ActionT::Goal::ConstSharedPtr goal)
An intermediate goal reception function to mux navigators.
bool on_cleanup() final
Cleanup a navigator.
virtual bool deactivate()
Method to deactivate and any threads involved in execution.
virtual void onLoop()=0
A callback that defines execution that happens on one iteration through the BT Can be used to publish...
virtual bool activate()
Method to activate any threads involved in execution.
bool on_deactivate() final
Deactivation of the navigator's backend BT and actions.
virtual bool cleanup()
Method to cleanup resources.
virtual bool configure(nav2::LifecycleNode::WeakPtr, std::shared_ptr< nav2_util::OdomSmoother >)
virtual bool goalReceived(typename ActionT::Goal::ConstSharedPtr goal)=0
A callback to be called when a new goal is received by the BT action server Can be used to check if g...
bool on_activate() final
Activation of the navigator's backend BT and actions.
bool on_configure(nav2::LifecycleNode::WeakPtr parent_node, const std::vector< std::string > &plugin_lib_names, const FeedbackUtils &feedback_utils, nav2_core::NavigatorMuxer *plugin_muxer, std::shared_ptr< nav2_util::OdomSmoother > odom_smoother) final
Configuration to setup the navigator's backend BT and actions.
Navigator interface to allow navigators to be stored in a vector and accessed via pluginlib due to te...
virtual bool on_cleanup()=0
Cleanup a navigator.
virtual bool on_deactivate()=0
Deactivation of the navigator's backend BT and actions.
virtual bool on_activate()=0
Activation of the navigator's backend BT and actions.
virtual bool on_configure(nav2::LifecycleNode::WeakPtr parent_node, const std::vector< std::string > &plugin_lib_names, const FeedbackUtils &feedback_utils, nav2_core::NavigatorMuxer *plugin_muxer, std::shared_ptr< nav2_util::OdomSmoother > odom_smoother)=0
Configuration of the navigator's backend BT and actions.
A class to control the state of the BT navigator by allowing only a single plugin to be processed at ...
void stopNavigating(nav2_core::NavigatorBase *navigator)
Stop navigating with a given navigator.
void startNavigating(nav2_core::NavigatorBase *navigator)
Start navigating with a given navigator.
bool isNavigating()
Get the navigator muxer state.
NavigatorMuxer()
A Navigator Muxer constructor.
bool isCurrentNavigator(nav2_core::NavigatorBase *navigator)
Check if the given navigator is the currently active navigator.
Navigator feedback utilities required to get transforms and reference frames.