15#include "auto_apms_behavior_tree/executor/executor_node.hpp"
19#include "auto_apms_behavior_tree/exceptions.hpp"
20#include "auto_apms_behavior_tree_core/definitions.hpp"
21#include "auto_apms_util/container.hpp"
22#include "auto_apms_util/string.hpp"
23#include "rclcpp/utilities.hpp"
31 start_action_name.empty() ? name + _AUTO_APMS_BEHAVIOR_TREE__EXECUTOR_START_ACTION_NAME_SUFFIX : start_action_name,
35 std::vector<std::string> args_with_ros_arguments =
node_ptr_->get_node_options().arguments();
36 int argc = args_with_ros_arguments.size();
37 char ** argv =
new char *[argc + 1];
38 for (
int i = 0; i < argc; ++i) {
39 argv[i] =
const_cast<char *
>(args_with_ros_arguments[i].c_str());
45 if (
const std::vector<std::string> args = rclcpp::remove_ros_arguments(argc, argv); args.size() > 1) {
47 std::vector<std::string> relevant_args{args.begin() + 1, args.end()};
49 logger_,
"Additional cli arguments in rclcpp::NodeOptions: [ %s ]",
50 auto_apms_util::join(relevant_args,
", ").c_str());
52 const ExecutorParameters initial_params = executor_param_listener_.get_params();
61:
TreeExecutorNode(_AUTO_APMS_BEHAVIOR_TREE__EXECUTOR_DEFAULT_NAME, Options(ros_options))
66 const rclcpp_action::GoalUUID & uuid, std::shared_ptr<const TriggerGoal> )
70 logger_,
"Goal %s was REJECTED: Tree '%s' is currently executing.", rclcpp_action::to_string(uuid).c_str(),
79 if (!goal_ptr->build_handler.empty()) {
80 if (executor_param_listener_.get_params().allow_other_build_handlers) {
82 }
else if (goal_ptr->build_handler != current_build_handler_name_) {
83 throw exceptions::TreeExecutorError(
84 "Current tree build handler '" + current_build_handler_name_ +
85 "' must not change since the 'Allow other build handlers' option is disabled.");
89 core::NodeManifest node_manifest = core::NodeManifest::decode(goal_ptr->node_manifest);
96 if (goal_handle_ptr->get_goal()->clear_blackboard) {
103 const std::string started_tree_name =
getTreeName();
107 if (goal_handle_ptr->get_goal()->attach) {
108 trigger_action_context_.setUp(goal_handle_ptr);
109 RCLCPP_INFO(
logger_,
"Successfully started execution of tree '%s' (Mode: Attached).", started_tree_name.c_str());
111 auto result_ptr = std::make_shared<TriggerResult>();
112 result_ptr->message =
"Successfully started execution of tree '" + started_tree_name +
"' (Mode: Detached).";
113 result_ptr->tree_result = TriggerResult::TREE_RESULT_NOT_SET;
114 result_ptr->terminated_tree_identity = started_tree_name;
115 goal_handle_ptr->succeed(result_ptr);
116 RCLCPP_INFO_STREAM(
logger_, result_ptr->message);
120bool TreeExecutorNode::afterTick()
123 if (!GenericTreeExecutorNode::afterTick())
return false;
126 if (trigger_action_context_.
isValid()) {
130 feedback_ptr->running_tree_identity =
getTreeName();
132 if (!running_action_history.empty()) {
134 feedback_ptr->running_action_name = auto_apms_util::join(running_action_history,
" + ");
135 feedback_ptr->running_action_timestamp =
136 std::chrono::duration<double>{std::chrono::high_resolution_clock::now().time_since_epoch()}.count();
139 state_observer.
flush();
141 trigger_action_context_.publishFeedback();
149 auto result_ptr = context.getResultPtr();
150 result_ptr->terminated_tree_identity =
getTreeName();
153 result_ptr->tree_result = TriggerResult::TREE_RESULT_SUCCESS;
154 result_ptr->message =
"Tree execution finished with status SUCCESS";
158 result_ptr->tree_result = TriggerResult::TREE_RESULT_FAILURE;
159 result_ptr->message =
"Tree execution finished with status FAILURE";
163 result_ptr->tree_result = TriggerResult::TREE_RESULT_NOT_SET;
164 if (context.getGoalHandlePtr()->is_canceling()) {
165 result_ptr->message =
"Tree execution canceled successfully";
168 result_ptr->message =
"Tree execution terminated prematurely";
173 result_ptr->tree_result = TriggerResult::TREE_RESULT_NOT_SET;
174 result_ptr->message =
"An unexpected error occurred during tree execution";
178 result_ptr->tree_result = TriggerResult::TREE_RESULT_NOT_SET;
179 result_ptr->message =
"Execution result unknown";
ActionBasedTreeExecutorNode(const std::string &name, const std::string &action_name, Options options)
virtual bool clearGlobalBlackboard() override
Reset the global blackboard and clear all entries.
std::shared_future< ExecutionResult > startExecution(const std::string &build_request, const std::string &entry_point="", const core::NodeManifest &node_manifest={})
Start the behavior tree specified by a particular build request.
void loadBuildHandler(const std::string &name)
Load a particular behavior tree build handler plugin.
TreeConstructor makeTreeConstructor(const std::string &build_request, const std::string &entry_point="", const core::NodeManifest &node_manifest={})
Create a callback that builds a behavior tree according to a specific request.
ExecutionState getExecutionState()
Get a status code indicating the current state of execution.
bool isBusy()
Determine whether this executor is currently executing a behavior tree.
rclcpp::Node::SharedPtr node_ptr_
Shared pointer to the parent ROS 2 node.
TreeStateObserver & getStateObserver()
Get a reference to the current behavior tree state observer.
std::string getTreeName()
Get the name of the tree that is currently executing.
ExecutionResult
Enum representing possible behavior tree execution results.
@ TREE_SUCCEEDED
Tree completed with BT::NodeStatus::SUCCESS.
@ TERMINATED_PREMATURELY
Execution terminated before the tree was able to propagate the tick to all its nodes.
@ TREE_FAILED
Tree completed with BT::NodeStatus::FAILURE.
@ ERROR
An unexpected error occurred.
const rclcpp::Logger logger_
Logger associated with the parent ROS 2 node.
TreeConstructor getTreeConstructorFromGoal(std::shared_ptr< const TriggerGoal > goal_ptr) override
Create a TreeConstructor from a StartTreeExecutor action goal.
void onExecutionStarted(std::shared_ptr< TriggerGoalHandle > goal_handle_ptr) override
Hook called after execution has been started successfully.
TreeExecutorNode(const std::string &name, const std::string &start_action_name, Options options)
Constructor allowing to specify a custom node name and executor options.
void onAcceptedGoal(std::shared_ptr< TriggerGoalHandle > goal_handle_ptr) override
Hook called after a start action goal has been accepted and before execution begins.
void onGoalExecutionTermination(const ExecutionResult &result, TriggerActionContext &context) override
Handle the execution result for the StartTreeExecutor action client.
bool shouldAcceptGoal(const rclcpp_action::GoalUUID &uuid, std::shared_ptr< const TriggerGoal > goal_ptr) override
Determine whether an incoming start action goal should be accepted.
State observer for a particular behavior tree object that writes introspection and debugging informat...
virtual void flush() override
Reset the internal state variables.
const std::vector< std::string > & getRunningActionHistory() const
Get all names of action nodes that returned BT::NodeStatus::RUNNING since the last time TreeStateObse...
Data structure for information about which behavior tree node plugin to load and how to configure the...
std::shared_ptr< Feedback > getFeedbackPtr()
Access the internal action feedback buffer.
bool isValid()
Check if this ActionContext is valid (e.g. is managing a valid action goal handle).
Powerful tooling for incorporating behavior trees for task development.