|
| 1 | +// Copyright 2024 Marq Rasmussen |
| 2 | +// |
| 3 | +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
| 4 | +// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the |
| 5 | +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to |
| 6 | +// permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright |
| 7 | +// notice and this permission notice shall be included in all copies or substantial portions of the Software. |
| 8 | +// |
| 9 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
| 10 | +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| 11 | +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| 12 | +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 13 | + |
| 14 | +#include <memory> |
| 15 | +#include <optional> |
| 16 | + |
| 17 | +#include "btcpp_ros2_interfaces/action/execute_tree.hpp" |
| 18 | + |
| 19 | +#include "behaviortree_cpp/bt_factory.h" |
| 20 | + |
| 21 | +#include "rclcpp/rclcpp.hpp" |
| 22 | +#include "rclcpp_action/rclcpp_action.hpp" |
| 23 | + |
| 24 | +namespace action_server_bt |
| 25 | +{ |
| 26 | + |
| 27 | +/** |
| 28 | + * @brief ActionServerBT class hosts a ROS Action Server that is able |
| 29 | + * to load Behavior plugins, BehaviorTree.xml files and execute them. |
| 30 | + */ |
| 31 | +class ActionServerBT |
| 32 | +{ |
| 33 | +public: |
| 34 | + using ExecuteTree = btcpp_ros2_interfaces::action::ExecuteTree; |
| 35 | + using GoalHandleExecuteTree = rclcpp_action::ServerGoalHandle<ExecuteTree>; |
| 36 | + |
| 37 | + /** |
| 38 | + * @brief Constructor for ActionServerBT. |
| 39 | + * @details This initializes a ParameterListener to read configurable options from the user and |
| 40 | + * starts an Action Server that takes requests to execute BehaviorTrees. |
| 41 | + * |
| 42 | + * @param options rclcpp::NodeOptions to pass to node_ when initializing it. |
| 43 | + * after the tree is created, while its running and after it finishes. |
| 44 | + */ |
| 45 | + explicit ActionServerBT(const rclcpp::NodeOptions& options); |
| 46 | + |
| 47 | + virtual ~ActionServerBT(); |
| 48 | + |
| 49 | + /** |
| 50 | + * @brief Gets the NodeBaseInterface of node_. |
| 51 | + * @details This function exists to allow running ActionServerBT as a component in a composable node container. |
| 52 | + * |
| 53 | + * @return A shared_ptr to the NodeBaseInterface of node_. |
| 54 | + */ |
| 55 | + rclcpp::node_interfaces::NodeBaseInterface::SharedPtr nodeBaseInterface(); |
| 56 | + |
| 57 | + // name of the tree being executed |
| 58 | + const std::string& currentTreeName() const; |
| 59 | + |
| 60 | + // tree being executed, nullptr if it doesn't exist yet. |
| 61 | + BT::Tree* currentTree(); |
| 62 | + |
| 63 | + // pointer to the global blackboard |
| 64 | + BT::Blackboard::Ptr globalBlackboard(); |
| 65 | + |
| 66 | +protected: |
| 67 | + // To be overridden by the user. |
| 68 | + // Callback invoked when the tree is created and before it is executed, |
| 69 | + // Can be used to update the blackboard or to attach loggers. |
| 70 | + virtual void onTreeCreated(BT::Tree& tree) |
| 71 | + {} |
| 72 | + |
| 73 | + // To be overridden by the user. |
| 74 | + // In addition to the built in mechanism to register nodes from plugins, |
| 75 | + // you can use this method to register custom nodes into the factory. |
| 76 | + virtual void registerNodesIntoFactory(BT::BehaviorTreeFactory& factory) |
| 77 | + {} |
| 78 | + |
| 79 | + // To be overridden by the user. |
| 80 | + // Callback invoked after the tickOnce. |
| 81 | + // If it returns something different than std::nullopt, the tree execution will |
| 82 | + // be halted and the returned value will be the optional NodeStatus. |
| 83 | + virtual std::optional<BT::NodeStatus> onLoopAfterTick(BT::NodeStatus status) |
| 84 | + { |
| 85 | + return std::nullopt; |
| 86 | + } |
| 87 | + |
| 88 | + // To be overridden by the user. |
| 89 | + // Callback invoked when the tree execution is completed |
| 90 | + virtual void onTreeExecutionCompleted(BT::NodeStatus status, bool was_cancelled) |
| 91 | + {} |
| 92 | + |
| 93 | + virtual std::optional<std::string> onLoopFeedback() |
| 94 | + { |
| 95 | + return std::nullopt; |
| 96 | + } |
| 97 | + |
| 98 | +private: |
| 99 | + struct Pimpl; |
| 100 | + std::unique_ptr<Pimpl> p_; |
| 101 | + |
| 102 | + /** |
| 103 | + * @brief handle the goal requested: accept or reject. This implementation always accepts. |
| 104 | + * @param uuid Goal ID |
| 105 | + * @param goal A shared pointer to the specific goal |
| 106 | + * @return GoalResponse response of the goal processed |
| 107 | + */ |
| 108 | + rclcpp_action::GoalResponse handle_goal(const rclcpp_action::GoalUUID& uuid, |
| 109 | + std::shared_ptr<const ExecuteTree::Goal> goal); |
| 110 | + |
| 111 | + /** |
| 112 | + * @brief Accepts cancellation requests of action server. |
| 113 | + * @param goal A server goal handle to cancel |
| 114 | + * @return CancelResponse response of the goal cancelled |
| 115 | + */ |
| 116 | + rclcpp_action::CancelResponse |
| 117 | + handle_cancel(const std::shared_ptr<GoalHandleExecuteTree> goal_handle); |
| 118 | + |
| 119 | + /** |
| 120 | + * @brief Handles accepted goals and starts a thread to process them |
| 121 | + * @param goal_handle Server goal handle to process feedback and set the response when finished |
| 122 | + */ |
| 123 | + void handle_accepted(const std::shared_ptr<GoalHandleExecuteTree> goal_handle); |
| 124 | + |
| 125 | + /** |
| 126 | + * @brief Background processes to execute the BehaviorTree and handle stop requests |
| 127 | + * @param goal_handle Server goal handle to process feedback and set the response when finished |
| 128 | + */ |
| 129 | + void execute(const std::shared_ptr<GoalHandleExecuteTree> goal_handle); |
| 130 | +}; |
| 131 | + |
| 132 | +} // namespace action_server_bt |
0 commit comments