15#include "auto_apms_behavior_tree_core/tree/tree_resource.hpp"
21#include "ament_index_cpp/get_resource.hpp"
22#include "auto_apms_behavior_tree_core/definitions.hpp"
23#include "auto_apms_behavior_tree_core/exceptions.hpp"
24#include "auto_apms_behavior_tree_core/tree/tree_document.hpp"
25#include "auto_apms_util/resource.hpp"
26#include "auto_apms_util/string.hpp"
34 if (tokens.size() == 1) {
35 tokens.insert(tokens.begin(),
"");
38 if (tokens.size() != 3) {
39 throw auto_apms_util::exceptions::ResourceIdentityFormatError(
40 "Identity string '" + identity +
"' has wrong format. Number of string tokens separated by '::' must be 3.");
46 throw auto_apms_util::exceptions::ResourceIdentityFormatError(
47 "Behavior tree resource identity string '" + identity +
48 "' has wrong format. It's not allowed to omit both <tree_file_stem> and <tree_name>.");
56bool TreeResourceIdentity::operator<(
const TreeResourceIdentity & other)
const {
return str() < other.str(); }
64 if (identity.
empty()) {
65 throw auto_apms_util::exceptions::ResourceIdentityFormatError(
"Cannot create TreeResource with empty identity.");
68 std::set<std::string> search_packages;
70 search_packages.insert(identity.package_name);
73 auto_apms_util::getPackagesWithResourceType(_AUTO_APMS_BEHAVIOR_TREE_CORE__RESOURCE_TYPE_NAME__TREE);
76 size_t matching_count = 0;
77 std::string matching_package_name;
78 std::string matching_tree_file_path;
79 std::vector<std::string> matching_node_manifest_file_paths;
80 for (
const auto & p : search_packages) {
82 std::string base_path;
83 if (ament_index_cpp::get_resource(
84 _AUTO_APMS_BEHAVIOR_TREE_CORE__RESOURCE_TYPE_NAME__TREE, p, content, &base_path)) {
87 if (parts.size() != 4) {
88 throw auto_apms_util::exceptions::ResourceError(
89 "Invalid behavior tree resource file (Package: '" + p +
"'). Invalid line: " + line +
".");
91 const std::string & found_tree_file_stem = parts[0];
96 if (found_tree_file_stem != identity.
file_stem) {
104 found_tree_file_stem != identity.
file_stem ||
110 matching_package_name = p;
111 matching_tree_file_path = base_path +
"/" + parts[2];
113 matching_node_manifest_file_paths.push_back(
114 std::filesystem::path(path).is_absolute() ? path : (base_path +
"/" + path));
120 if (matching_count == 0) {
121 throw auto_apms_util::exceptions::ResourceError(
122 "No behavior tree file with identity '" + identity.
str() +
"' was registered.");
124 if (matching_count > 1) {
125 throw auto_apms_util::exceptions::ResourceError(
126 "Resource identity '" + identity.
str() +
"' is ambiguous. You must be more precise.");
130 package_name_ = matching_package_name;
131 tree_file_path_ = matching_tree_file_path;
132 node_manifest_file_paths_ = matching_node_manifest_file_paths;
138 }
catch (
const std::exception & e) {
139 throw auto_apms_util::exceptions::ResourceError(
140 "Failed to create TreeResource with identity '" + identity.
str() +
"' because tree file " + tree_file_path_ +
141 " cannot be parsed: " + e.what());
146 if (!auto_apms_util::contains(doc.getAllTreeNames(), identity.tree_name)) {
147 throw auto_apms_util::exceptions::ResourceError(
148 "Cannot create TreeResource with identity '" + identity.str() +
"' because '" + identity.tree_name +
149 "' does not exist in tree file " + tree_file_path_ +
".");
154 if (doc.hasRootTreeName()) {
155 doc_root_tree_name_ = doc.getRootTreeName();
170 return TreeResource(package_name +
"::" + file_name +
"::");
177 if (!identity_.tree_name.empty())
return identity_.tree_name;
180 if (!doc_root_tree_name_.empty())
return doc_root_tree_name_;
183 throw auto_apms_util::exceptions::ResourceError(
184 "Cannot get root tree name of tree resource '" + identity_.str() +
"'. Since there is no XML attribute named '" +
185 TreeDocument::ROOT_TREE_ATTRIBUTE_NAME +
186 "' and the resource identity doesn't specify <tree_name>, the root tree is unkown.");
Data structure for information about which behavior tree node plugin to load and how to configure the...
static NodeManifest fromFiles(const std::vector< std::string > &paths)
Create a node plugin manifest from multiple files. They are loaded in the given order.
TreeDocument & mergeFile(const std::string &path, bool adopt_root_tree=false)
Create a tree document from a file and merge it with this one.
std::string getRootTreeName() const
Get the name of the root tree of this behavior tree resource.
static TreeResource selectByFileStem(const std::string &file_stem, const std::string &package_name="")
Find an installed behavior tree resource using a specific behavior tree XML file stem.
TreeResource(const Identity &identity)
Assemble a behavior tree resource using a TreeResourceIdentity.
std::string getPackageName() const
Get the name of the package this resource was registered by.
std::string getFileStem() const
Get the file stem of the XML file containing the tree document associated with this resource.
Identity createIdentity(const std::string &tree_name="") const
Create a valid tree resource identity string representing this resource.
static TreeResource selectByTreeName(const std::string &tree_name, const std::string &package_name="")
Find an installed behavior tree resource using a specific behavior tree name.
NodeManifest getNodeManifest() const
Get the node manifest associated with this resource.
bool hasRootTreeName() const
Determine if this behavior tree resource specifies a root tree.
bool contains(const ContainerT< ValueT, AllocatorT > &c, const ValueT &val)
Check whether a particular container structure contains a value.
std::vector< std::string > splitString(const std::string &str, const std::string &delimiter, bool remove_empty=true)
Split a string into multiple tokens using a specific delimiter string (Delimiter may consist of multi...
Core API for AutoAPMS's behavior tree implementation.
Struct that encapsulates the identity string for a declared behavior tree.
std::string tree_name
Name of a specific tree inside the resource's tree document.
bool empty() const
Determine whether this tree resource identity object is considered empty.
std::string file_stem
Name of the file (without extension) that contains the resource's tree document.
TreeResourceIdentity()=default
Constructor of an empty tree resource identity object.
TreeResourceIdentity(const std::string &identity)
Constructor of a behavior tree resource identity object.
std::string package_name
Name of the package that registers the resource.
std::string str() const
Create the corresponding identity string.