AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
build_handler.cpp
1// Copyright 2024 Robin Müller
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "auto_apms_behavior_tree/build_handler/build_handler.hpp"
16
17#include "auto_apms_behavior_tree/exceptions.hpp"
18
20{
21
22TreeBasedEntryPoint::TreeBasedEntryPoint(const std::string & encoded_str)
23{
24 if (encoded_str.empty()) {
25 throw exceptions::TreeBuildHandlerError("Entry point string must not be empty.");
26 }
27
28 // Find the opening parenthesis
29 const auto open_paren = encoded_str.find('(');
30 if (open_paren == std::string::npos) {
31 // No parentheses: the entire string is the tree name
32 root_tree_name = encoded_str;
33 return;
34 }
35
36 // Validate closing parenthesis
37 if (encoded_str.back() != ')') {
38 throw exceptions::TreeBuildHandlerError(
39 "Invalid entry point format: missing closing parenthesis in '" + encoded_str + "'.");
40 }
41
42 root_tree_name = encoded_str.substr(0, open_paren);
43 if (root_tree_name.empty()) {
44 throw exceptions::TreeBuildHandlerError(
45 "Invalid entry point format: tree name must not be empty in '" + encoded_str + "'.");
46 }
47
48 // Extract the content between the parentheses
49 const std::string params_str = encoded_str.substr(open_paren + 1, encoded_str.size() - open_paren - 2);
50 if (params_str.empty()) {
51 return;
52 }
53
54 // Parse comma-separated key=value pairs
55 std::string::size_type pos = 0;
56 while (pos < params_str.size()) {
57 const auto comma = params_str.find(',', pos);
58 const std::string token = params_str.substr(pos, comma - pos);
59
60 const auto eq = token.find('=');
61 if (eq == std::string::npos) {
62 throw exceptions::TreeBuildHandlerError(
63 "Invalid entry point format: expected 'key=value' but got '" + token + "' in '" + encoded_str + "'.");
64 }
65
66 const std::string key = token.substr(0, eq);
67 const std::string value = token.substr(eq + 1);
68 if (key.empty()) {
69 throw exceptions::TreeBuildHandlerError(
70 "Invalid entry point format: blackboard key must not be empty in '" + encoded_str + "'.");
71 }
72 inital_blackboard[key] = value;
73
74 if (comma == std::string::npos) {
75 break;
76 }
77 pos = comma + 1;
78 }
79}
80
82 const std::string & name, rclcpp::Node::SharedPtr ros_node_ptr, NodeLoader::SharedPtr tree_node_loader_ptr)
83: logger_(ros_node_ptr->get_logger().get_child(name)),
84 ros_node_wptr_(ros_node_ptr),
85 tree_node_loader_ptr(tree_node_loader_ptr)
86{
87}
88
89TreeBuildHandler::TreeBuildHandler(rclcpp::Node::SharedPtr ros_node_ptr, NodeLoader::SharedPtr tree_node_loader_ptr)
90: TreeBuildHandler("tree_build_handler", ros_node_ptr, tree_node_loader_ptr)
91{
92}
93
95 const std::string & /*build_request*/, const std::string & /*entry_point*/, const NodeManifest & /*node_manifest*/)
96{
97 return true;
98}
99
100rclcpp::Node::SharedPtr TreeBuildHandler::getRosNodePtr() const
101{
102 if (ros_node_wptr_.expired()) {
103 throw std::runtime_error("TreeBuildHandler: Weak pointer to rclcpp::Node expired.");
104 }
105 return ros_node_wptr_.lock();
106}
107
108TreeBuildHandler::NodeLoader::SharedPtr TreeBuildHandler::getNodeLoaderPtr() const { return tree_node_loader_ptr; }
109
110} // namespace auto_apms_behavior_tree
NodeLoader::SharedPtr getNodeLoaderPtr() const
Get a shared pointer to the class loader instance used for loading the required behavior tree nodes.
virtual bool setBuildRequest(const std::string &build_request, const std::string &entry_point, const NodeManifest &node_manifest)
Specify the behavior tree build request encoded in a string.
TreeBuildHandler(const std::string &name, rclcpp::Node::SharedPtr ros_node_ptr, NodeLoader::SharedPtr tree_node_loader_ptr)
Constructor allowing to give the build handler a specific name.
const rclcpp::Logger logger_
ROS 2 logger initialized with the name of the build handler.
rclcpp::Node::SharedPtr getRosNodePtr() const
Get a shared pointer to the parent rclcpp::Node of this build handler.
Powerful tooling for incorporating behavior trees for task development.
Definition behavior.hpp:32
TreeBasedEntryPoint()=default
Default constructor.