16 #include "nav2_behavior_tree/behavior_tree_engine.hpp"
23 #include "rclcpp/logger.hpp"
24 #include "rclcpp/logging.hpp"
25 #include "rclcpp/utilities.hpp"
26 #include "behaviortree_cpp/json_export.h"
27 #include "behaviortree_cpp/utils/shared_library.h"
28 #include "nav2_behavior_tree/json_utils.hpp"
29 #include "nav2_behavior_tree/utils/loop_rate.hpp"
30 #include "nav2_ros_common/rate.hpp"
32 namespace nav2_behavior_tree
36 const std::vector<std::string> & plugin_libraries,
37 const nav2::LifecycleNode::SharedPtr node)
39 BT::SharedLibrary loader;
40 for (
const auto & p : plugin_libraries) {
41 factory_.registerFromPlugin(loader.getOSName(p));
50 std::function<
void()> onLoop,
51 std::function<
bool()> cancelRequested,
52 std::chrono::milliseconds loopTimeout)
54 auto node = node_.lock();
57 rclcpp::get_logger(
"BehaviorTreeEngine"),
58 "BehaviorTreeEngine node expired. Exiting with failure.");
59 return BtStatus::FAILED;
62 auto rate_clock = nav2::selectSteadyOrSimClock(node);
64 BT::NodeStatus result = BT::NodeStatus::RUNNING;
68 while (rclcpp::ok() && result == BT::NodeStatus::RUNNING) {
69 if (cancelRequested()) {
71 return BtStatus::CANCELED;
74 result = tree->tickOnce();
76 if (result == BT::NodeStatus::RUNNING || result == BT::NodeStatus::IDLE) {
80 if (!loopRate.sleep()) {
81 RCLCPP_DEBUG_THROTTLE(
82 rclcpp::get_logger(
"BehaviorTreeEngine"),
84 "Behavior Tree tick rate %0.2f was exceeded!",
85 1.0 / (loopRate.period().count() * 1.0e-9));
88 }
catch (
const BT::NodeExecutionError & ex) {
90 rclcpp::get_logger(
"BehaviorTreeEngine"),
91 "BT Exception at Node: [%s] (Path: %s). Original error: %s. Exiting with failure.",
92 ex.failedNode().registration_name.c_str(),
93 ex.failedNode().node_path.c_str(),
94 ex.originalMessage().c_str());
95 return BtStatus::FAILED;
96 }
catch (
const std::exception & ex) {
98 rclcpp::get_logger(
"BehaviorTreeEngine"),
99 "Behavior tree threw exception: %s. Exiting with failure.", ex.what());
100 return BtStatus::FAILED;
103 return (result == BT::NodeStatus::SUCCESS) ? BtStatus::SUCCEEDED : BtStatus::FAILED;
108 const std::string & xml_string,
109 BT::Blackboard::Ptr blackboard)
111 return factory_.createTreeFromText(xml_string, blackboard);
116 const std::string & file_path,
117 BT::Blackboard::Ptr blackboard)
119 return factory_.createTreeFromFile(file_path, blackboard);
125 if (filename.empty()) {
126 RCLCPP_ERROR(rclcpp::get_logger(
"BehaviorTreeEngine"),
"Empty BT file path.");
130 tinyxml2::XMLDocument doc;
131 if (doc.LoadFile(filename.c_str()) != tinyxml2::XML_SUCCESS) {
132 RCLCPP_ERROR(rclcpp::get_logger(
"BehaviorTreeEngine"),
"Could not parse: %s", filename.c_str());
136 tinyxml2::XMLElement * root = doc.RootElement();
138 RCLCPP_ERROR(rclcpp::get_logger(
"BehaviorTreeEngine"),
"No root element in: %s",
144 for (
auto * bt = root->FirstChildElement(
"BehaviorTree"); bt;
145 bt = bt->NextSiblingElement(
"BehaviorTree"))
147 const char *
id = bt->Attribute(
"ID");
149 info.behavior_tree_ids.emplace_back(
id);
154 const char * main_attr = root->Attribute(
"main_tree_to_execute");
156 info.main_id = main_attr;
160 if (info.main_id.empty()) {
164 if (info.behavior_tree_ids.size() == 1) {
165 info.main_id = info.behavior_tree_ids[0];
166 }
else if (info.behavior_tree_ids.size() > 1) {
167 throw std::runtime_error(
168 "Multiple BehaviorTree elements found in " + filename +
169 " but no main_tree_to_execute attribute specified. Unable to determine main tree.");
178 const std::string & tree_id,
179 BT::Blackboard::Ptr blackboard)
181 return factory_.createTree(tree_id, blackboard);
186 const std::string & file_path)
188 factory_.registerBehaviorTreeFromFile(file_path);
194 uint16_t server_port)
197 groot_monitor_ = std::make_unique<BT::Groot2Publisher>(*tree, server_port);
200 BT::RegisterJsonDefinition<builtin_interfaces::msg::Time>();
201 BT::RegisterJsonDefinition<std_msgs::msg::Header>();
207 if (groot_monitor_) {
208 groot_monitor_.reset();
BT::Tree createTree(const std::string &tree_id, BT::Blackboard::Ptr blackboard)
Function to create a BT from a BehaviorTree ID.
BehaviorTreeEngine(const std::vector< std::string > &plugin_libraries, nav2::LifecycleNode::SharedPtr node)
A constructor for nav2_behavior_tree::BehaviorTreeEngine.
void addGrootMonitoring(BT::Tree *tree, uint16_t server_port)
Add Groot2 monitor to publish BT status changes.
void resetGrootMonitor()
Reset groot monitor.
BT::Tree createTreeFromFile(const std::string &file_path, BT::Blackboard::Ptr blackboard)
Function to create a BT from an XML file.
void registerTreeFromFile(const std::string &file_path)
Function to register a BT from an XML file.
BT::Tree createTreeFromText(const std::string &xml_string, BT::Blackboard::Ptr blackboard)
Function to create a BT from a XML string.
void haltAllActions(BT::Tree &tree)
Function to explicitly reset all BT nodes to initial state.
BtStatus run(BT::Tree *tree, std::function< void()> onLoop, std::function< bool()> cancelRequested, std::chrono::milliseconds loopTimeout=std::chrono::milliseconds(10))
Function to execute a BT at a specific rate.
BTInfo parseTreeInfo(const std::string &filename)
Function to parse Behavior Tree information from an XML file.
A struct to hold Behavior Tree ID information.