15#include "auto_apms_behavior_tree_core/node.hpp"
16#include "auto_apms_interfaces/action/start_tree_executor.hpp"
18#define INPUT_KEY_EXECUTOR_NAME "executor"
19#define INPUT_KEY_TREE_BUILD_REQUEST "build_request"
20#define INPUT_KEY_TREE_BUILD_HANDLER "build_handler"
21#define INPUT_KEY_ENTRY_POINT "entry_point"
22#define INPUT_KEY_NODE_MANIFEST "node_manifest"
23#define INPUT_KEY_ATTACH "attach"
24#define INPUT_KEY_CLEAR_BB "clear_blackboard"
29class StartExecutor :
public core::RosActionNode<auto_apms_interfaces::action::StartTreeExecutor>
32 using RosActionNode::RosActionNode;
34 static BT::PortsList providedPorts()
39 INPUT_KEY_ATTACH,
true,
"Boolean flag wether to attach to the execution process or start in detached mode."),
41 INPUT_KEY_CLEAR_BB,
true,
42 "Boolean flag wether to clear the existing blackboard entries before the execution starts or not."),
43 BT::InputPort<std::string>(
44 INPUT_KEY_NODE_MANIFEST,
"",
45 "YAML/JSON formatted string encoding the name and the registration options for the tree nodes supposed to be "
46 "loaded before building the tree."),
47 BT::InputPort<std::string>(
48 INPUT_KEY_ENTRY_POINT,
"",
49 "Entry point for the behavior. If empty, let the build handler determine it automatically."),
50 BT::InputPort<std::string>(
51 INPUT_KEY_TREE_BUILD_HANDLER,
"",
52 "Fully qualified class name of the build handler that is supposed to take care of the request. If empty, use "
54 BT::InputPort<std::string>(
55 INPUT_KEY_TREE_BUILD_REQUEST,
"",
56 "String passed to the tree build handler defining which tree is to be built."),
57 BT::InputPort<std::string>(
58 INPUT_KEY_EXECUTOR_NAME,
59 "Name of the executor responsible for building and running the specified behavior tree."),
63 bool setGoal(Goal & goal)
override final
65 if (
const BT::Expected<std::string> expected = getInput<std::string>(INPUT_KEY_TREE_BUILD_REQUEST)) {
66 goal.build_request = expected.value();
68 RCLCPP_ERROR(logger_,
"%s", expected.error().c_str());
71 if (
const BT::Expected<std::string> expected = getInput<std::string>(INPUT_KEY_TREE_BUILD_HANDLER)) {
72 goal.build_handler = expected.value();
74 RCLCPP_ERROR(logger_,
"%s", expected.error().c_str());
77 if (
const BT::Expected<std::string> expected = getInput<std::string>(INPUT_KEY_ENTRY_POINT)) {
78 goal.entry_point = expected.value();
80 RCLCPP_ERROR(logger_,
"%s", expected.error().c_str());
83 if (
const BT::Expected<std::string> expected = getInput<std::string>(INPUT_KEY_NODE_MANIFEST)) {
84 goal.node_manifest = expected.value();
86 RCLCPP_ERROR(logger_,
"%s", expected.error().c_str());
89 if (
const BT::Expected<bool> expected = getInput<bool>(INPUT_KEY_ATTACH)) {
90 goal.attach = expected.value();
92 RCLCPP_ERROR(logger_,
"%s", expected.error().c_str());
95 if (
const BT::Expected<bool> expected = getInput<bool>(INPUT_KEY_CLEAR_BB)) {
96 goal.clear_blackboard = expected.value();
98 RCLCPP_ERROR(logger_,
"%s", expected.error().c_str());
104 BT::NodeStatus onResultReceived(
const WrappedResult & wr)
override final
107 case rclcpp_action::ResultCode::ABORTED: {
108 const std::string msg =
109 context_.getFullyQualifiedTreeNodeName(
this) +
" - Received result ABORTED: " + wr.result->message;
110 RCLCPP_ERROR_STREAM(logger_, msg);
111 throw exceptions::RosNodeError(msg);
114 case rclcpp_action::ResultCode::CANCELED:
116 logger_,
"%s - Received result CANCELED: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
117 wr.result->message.c_str());
119 return BT::NodeStatus::SUCCESS;
127 logger_,
"%s - Tree execution finished successfully with result %i: %s",
128 context_.getFullyQualifiedTreeNodeName(
this).c_str(), wr.result->tree_result, wr.result->message.c_str());
131 if (getInput<bool>(INPUT_KEY_ATTACH).value()) {
132 if (wr.result->tree_result == ActionType::Result::TREE_RESULT_SUCCESS)
return BT::NodeStatus::SUCCESS;
133 return BT::NodeStatus::FAILURE;
137 if (wr.result->tree_result == ActionType::Result::TREE_RESULT_NOT_SET)
return BT::NodeStatus::SUCCESS;
138 const std::string msg = context_.getFullyQualifiedTreeNodeName(
this) +
139 " - Expected tree_result to be TREE_RESULT_NOT_SET when started in detached mode.";
140 RCLCPP_ERROR_STREAM(logger_, msg);
141 throw exceptions::RosNodeError(msg);
Generic behavior tree node wrapper for a ROS 2 action client.
#define AUTO_APMS_BEHAVIOR_TREE_REGISTER_NODE(type)
Macro for registering a behavior tree node plugin.
Powerful tooling for incorporating behavior trees for task development.