15#include "pyrobosim_msgs/action/execute_task_action.hpp"
19#include "auto_apms_behavior_tree_core/node.hpp"
20#include "auto_apms_simulation/util.hpp"
22#define INPUT_KEY_ROBOT_NAME "robot"
23#define INPUT_KEY_TARGET_LOCATION "target"
24#define INPUT_KEY_OBJECT "object"
26namespace auto_apms_simulation
29class ExecuteTaskAction :
public auto_apms_behavior_tree::core::RosActionNode<pyrobosim_msgs::action::ExecuteTaskAction>
32 using RosActionNode::RosActionNode;
34 virtual bool setGoal(Goal & goal) = 0;
36 BT::NodeStatus onResultReceived(
const WrappedResult & result)
override final
38 const BT::NodeStatus base_status = RosActionNode::onResultReceived(result);
39 if (base_status != BT::NodeStatus::SUCCESS)
return base_status;
41 result.result->execution_result.status == ExecutionResultMsg::SUCCESS ||
42 result.result->execution_result.status == ExecutionResultMsg::CANCELED) {
44 logger_,
"%s - SUCCESS: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
45 toStr(result.result->execution_result).c_str());
46 return BT::NodeStatus::SUCCESS;
49 logger_,
"%s - FAILURE: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
50 toStr(result.result->execution_result).c_str());
51 return BT::NodeStatus::FAILURE;
55class NavigateToLocation :
public ExecuteTaskAction
58 using ExecuteTaskAction::ExecuteTaskAction;
60 static BT::PortsList providedPorts()
63 BT::InputPort<std::string>(
64 INPUT_KEY_TARGET_LOCATION,
65 "Name of the target to navigate to (Terms for the knowledge query are separated by whitespace)."),
66 BT::InputPort<std::string>(INPUT_KEY_ROBOT_NAME,
"Name of the robot.")};
69 bool setGoal(Goal & goal)
71 const BT::Expected<std::string> expected_robot = getInput<std::string>(INPUT_KEY_ROBOT_NAME);
72 if (!expected_robot || expected_robot.value().empty()) {
74 logger_,
"%s - You must provide a non-empty robot name.", context_.getFullyQualifiedTreeNodeName(
this).c_str());
75 RCLCPP_DEBUG_EXPRESSION(
76 logger_, !expected_robot,
"%s - Error message: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
77 expected_robot.error().c_str());
80 const BT::Expected<std::string> expected_location = getInput<std::string>(INPUT_KEY_TARGET_LOCATION);
81 if (!expected_location || expected_location.value().empty()) {
83 logger_,
"%s - You must provide a non-empty target location name.",
84 context_.getFullyQualifiedTreeNodeName(
this).c_str());
85 RCLCPP_DEBUG_EXPRESSION(
86 logger_, !expected_location,
"%s - Error message: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
87 expected_location.error().c_str());
90 goal.action.type =
"navigate";
91 goal.action.robot = expected_robot.value();
92 goal.action.target_location = expected_location.value();
97class PickObject :
public ExecuteTaskAction
100 using ExecuteTaskAction::ExecuteTaskAction;
102 static BT::PortsList providedPorts()
105 BT::InputPort<std::string>(INPUT_KEY_OBJECT,
" ",
"Name of the object to pick. Empty for the nearest object."),
106 BT::InputPort<std::string>(INPUT_KEY_ROBOT_NAME,
"Name of the robot.")};
109 bool setGoal(Goal & goal)
111 const BT::Expected<std::string> expected_robot = getInput<std::string>(INPUT_KEY_ROBOT_NAME);
112 if (!expected_robot || expected_robot.value().empty()) {
114 logger_,
"%s - You must provide a non-empty robot name.", context_.getFullyQualifiedTreeNodeName(
this).c_str());
115 RCLCPP_DEBUG_EXPRESSION(
116 logger_, !expected_robot,
"%s - Error message: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
117 expected_robot.error().c_str());
120 goal.action.type =
"pick";
121 goal.action.robot = expected_robot.value();
122 goal.action.object = getInput<std::string>(INPUT_KEY_OBJECT).value();
123 if (goal.action.object.empty()) goal.action.object =
" ";
128class PlaceObject :
public ExecuteTaskAction
131 using ExecuteTaskAction::ExecuteTaskAction;
133 static BT::PortsList providedPorts()
135 return {BT::InputPort<std::string>(INPUT_KEY_ROBOT_NAME,
"Name of the robot.")};
138 bool setGoal(Goal & goal)
140 const BT::Expected<std::string> expected_robot = getInput<std::string>(INPUT_KEY_ROBOT_NAME);
141 if (!expected_robot || expected_robot.value().empty()) {
143 logger_,
"%s - You must provide a non-empty robot name.", context_.getFullyQualifiedTreeNodeName(
this).c_str());
144 RCLCPP_DEBUG_EXPRESSION(
145 logger_, !expected_robot,
"%s - Error message: %s", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
146 expected_robot.error().c_str());
149 goal.action.type =
"place";
150 goal.action.robot = expected_robot.value();
#define AUTO_APMS_BEHAVIOR_TREE_DECLARE_NODE(type)
Macro for registering a behavior tree node plugin.
const char * toStr(const ActionNodeErrorCode &err)
Convert the action error code to string.