31int main(
int argc,
char** argv)
35 std::cerr <<
"run_behavior_tree: Missing inputs! The program requires: \n\t1.) Name of the registered behavior "
36 "tree file (extension may be omitted).\n\t2.) Optional: Name of the tree to be executed "
37 "(Default is \"\": Using the main tree).\n\t3.) Optional: Name of the package to be searched "
38 "(Default is \"\": Searching in all packages).\n";
39 std::cerr <<
"Usage: run_behavior_tree <file_name> [<tree_name>] [<package_name>]\n";
42 const std::string tree_file_name{ argv[1] };
43 const std::string tree_name{ argc > 2 ? argv[2] :
"" };
44 const std::string package_name{ argc > 3 ? argv[3] :
"" };
48 rclcpp::init(argc, argv, rclcpp::InitOptions(), rclcpp::SignalHandlerOptions::SigTerm);
49 signal(SIGINT, [](
int sig) {
53 auto node_ptr = std::make_shared<rclcpp::Node>(
"run_behavior_tree");
56 std::unique_ptr<TreeResource> tree_resource_ptr;
61 catch (
const std::exception& e)
63 RCLCPP_ERROR(node_ptr->get_logger(),
64 "ERROR searching for corresponding behavior tree resource with arguments tree_file_name: '%s', "
65 "package_name: '%s': %s",
66 tree_file_name.c_str(), package_name.c_str(), e.what());
75 catch (
const std::exception& e)
77 RCLCPP_ERROR(node_ptr->get_logger(),
"ERROR loading behavior tree '%s' from resource %s: %s", tree_name.c_str(),
78 tree_resource_ptr->tree_file_path.c_str(), e.what());
86 RCLCPP_INFO(node_ptr->get_logger(),
"Executing tree with identity '%s::%s::%s'.",
87 tree_resource_ptr->tree_file_stem.c_str(), builder.
getMainTreeName().c_str(),
88 tree_resource_ptr->package_name.c_str());
90 const auto termination_timeout = std::chrono::duration<double>(1.5);
91 std::chrono::steady_clock::time_point termination_start;
92 bool termination_started =
false;
95 while (rclcpp::spin_until_future_complete(node_ptr, future, std::chrono::milliseconds(250)) !=
96 rclcpp::FutureReturnCode::SUCCESS)
98 if (termination_started)
100 if (std::chrono::steady_clock::now() - termination_start > termination_timeout)
102 RCLCPP_WARN(node_ptr->get_logger(),
"Termination took too long. Aborted.");
108 termination_start = std::chrono::steady_clock::now();
109 executor.setControlCommand(TreeExecutor::ControlCommand::TERMINATE);
110 termination_started =
true;
111 RCLCPP_INFO(node_ptr->get_logger(),
"Terminating tree execution...");
115 catch (
const std::exception& e)
117 RCLCPP_ERROR(node_ptr->get_logger(),
"ERROR during behavior tree execution: %s", e.what());
122 if (future.wait_for(std::chrono::seconds(0)) != std::future_status::ready)
124 throw std::logic_error(
"Future object is not ready.");
127 RCLCPP_INFO(node_ptr->get_logger(),
"Finished with status %s.",
toStr(future.get()).c_str());