24#include "auto_apms_behavior_tree_core/node/node_manifest.hpp"
25#include "auto_apms_behavior_tree_core/node/node_registration_loader.hpp"
26#include "auto_apms_behavior_tree_core/node/node_registration_options.hpp"
27#include "auto_apms_behavior_tree_core/tree/script.hpp"
28#include "behaviortree_cpp/bt_factory.h"
29#include "behaviortree_cpp/tree_node.h"
30#include "rclcpp/rclcpp.hpp"
135 using XMLElement = tinyxml2::XMLElement;
137 inline static const std::string LOGGER_NAME =
"tree_document";
140 static inline const char BTCPP_FORMAT_ATTRIBUTE_NAME[] =
"BTCPP_format";
141 static inline const char BTCPP_FORMAT_DEFAULT_VERSION[] =
"4";
142 static inline const char ROOT_ELEMENT_NAME[] =
"root";
143 static inline const char ROOT_TREE_ATTRIBUTE_NAME[] =
"main_tree_to_execute";
144 static inline const char TREE_ELEMENT_NAME[] =
"BehaviorTree";
145 static inline const char SUBTREE_ELEMENT_NAME[] =
"SubTree";
146 static inline const char TREE_NAME_ATTRIBUTE_NAME[] =
"ID";
147 static inline const char TREE_NODE_MODEL_ELEMENT_NAME[] =
"TreeNodesModel";
148 static inline const char NODE_INSTANCE_NAME_ATTRIBUTE_NAME[] =
"name";
292 typename std::enable_if_t<std::is_base_of_v<NodeModelType, T> && !std::is_same_v<model::SubTree, T>, T>
insertNode(
310 template <
class SubTreeT>
312 const std::string & tree_name,
const NodeElement * before_this =
nullptr);
332 template <
class SubTreeT>
444 const std::string & tree_str,
const std::string & tree_name,
const NodeElement * before_this =
nullptr);
487 const std::string & path,
const std::string & tree_name,
const NodeElement * before_this =
nullptr);
591 NodeElement getFirstNode(
const std::string & registration_name =
"",
const std::string & instance_name =
"")
const;
612 typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, T>
getFirstNode(
613 const std::string & instance_name =
"")
const;
654 const std::string & instance_name =
"");
732 virtual std::string
getName()
const;
789 static void deepApplyImpl(
801 std::vector<std::string> port_names_;
815 friend class TreeDocument;
823 explicit TreeElement(TreeDocument * doc_ptr, XMLElement * ele_ptr);
854 std::string
getName()
const override;
882 BT::Result
verify()
const;
905 const std::string & instance_name =
"");
915 const std::vector<std::string> & getPortNames() =
delete;
933 const std::string & format_version = BTCPP_FORMAT_DEFAULT_VERSION,
934 NodeRegistrationLoader::SharedPtr tree_node_loader = NodeRegistrationLoader::make_shared());
1194 bool hasTreeName(
const std::string & tree_name)
const;
1330 BT::Result
verify()
const;
1351 template <
typename ReturnT,
typename DocumentT>
1352 static ReturnT getXMLElementForTreeWithNameImpl(DocumentT & doc,
const std::string & tree_name);
1354 const XMLElement * getXMLElementForTreeWithName(
const std::string & tree_name)
const;
1356 XMLElement * getXMLElementForTreeWithName(
const std::string & tree_name);
1358 const std::map<std::string, std::string> all_node_classes_package_map_;
1359 const std::set<std::string> native_node_names_;
1360 std::string format_version_;
1361 NodeRegistrationLoader::SharedPtr tree_node_loader_ptr_;
1365 BT::BehaviorTreeFactory factory_;
1366 rclcpp::Logger logger_;
1367 rclcpp::Node::WeakPtr ros_node_wptr_;
1368 rclcpp::CallbackGroup::WeakPtr tree_node_waitables_callback_group_wptr_;
1369 rclcpp::executors::SingleThreadedExecutor::WeakPtr tree_node_waitables_executor_wptr_;
1370 bool only_non_ros_nodes_ =
false;
1378template <
typename T,
typename =
void>
1379struct has_static_method_registrationOptions : std::false_type
1383template <
typename T>
1384struct has_static_method_registrationOptions<
1385 T, typename std::enable_if_t<std::is_same_v<decltype(T::registrationOptions()), NodeRegistrationOptions>>>
1392inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T> && !std::is_same_v<model::SubTree, T>, T>
1397 if constexpr (has_static_method_registrationOptions<T>::value) {
1407inline typename std::enable_if_t<std::is_same_v<model::SubTree, T>,
model::SubTree>
1410 return insertSubTreeNode(tree_name, before_this);
1414inline typename std::enable_if_t<std::is_same_v<model::SubTree, T>,
model::SubTree>
1417 return insertSubTreeNode(tree, before_this);
1422 const std::string & instance_name)
const
1424 const NodeElement ele = getFirstNode(T::name(), instance_name);
1425 return T(ele.doc_ptr_, ele.ele_ptr_);
1429inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, TreeDocument::NodeElement &>
1432 return removeFirstChild(T::name(), instance_name);
1436inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, TreeDocument::TreeElement &>
Data structure for information about which behavior tree node plugin to load and how to configure the...
Class that encapsulates behavior tree script expressions.
Handle for a single node of a TreeDocument.
const TreeDocument & getParentDocument() const
Get a const view of this node's parent tree document.
NodeElement insertTreeFromResource(const TreeResource &resource, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from one of the installed package's behavior tree resources and add its first chil...
const std::vector< std::string > & getPortNames() const
Get the names of the data ports implemented by the node represented by this element.
virtual std::string getRegistrationName() const
Get the name of this node given during registration representing its dynamic type.
std::function< bool(const NodeElement &)> ConstDeepApplyCallback
Callback invoked for every node found under another node. It cannot modify the current node.
NodeElement & resetPorts()
Delete all currently specified port values and reset with the defaults.
NodeElement(const NodeElement &ele)=default
Copy constructor for a node element.
std::function< bool(NodeElement &)> DeepApplyCallback
Callback invoked for every node found under another node. It may modify the current node.
NodeElement & removeFirstChild(const std::string ®istration_name="", const std::string &instance_name="")
Recursively visit this node's children in execution order and remove the first node with a particular...
NodeElement & setPorts(const PortValues &port_values)
Populate the the node's data ports.
std::enable_if_t< std::is_base_of_v< NodeModelType, T >, T > getFirstNode(const std::string &instance_name="") const
Recursively visit this node's children in execution order and get the first node with a particular in...
std::enable_if_t< std::is_same_v< model::SubTree, SubTreeT >, model::SubTree > insertNode(const TreeElement &tree, const NodeElement *before_this=nullptr)
Add a subtree node for a specific tree element to the children of this node.
virtual NodeElement & setName(const std::string &instance_name)
Assign a name for this specific node instance.
NodeElement getFirstNode(const std::string ®istration_name="", const std::string &instance_name="") const
Recursively visit this node's children in execution order and get the first node with a particular re...
NodeElement(TreeDocument *doc_ptr, XMLElement *ele_ptr)
Protected constructor intended for internal use only.
std::map< std::string, std::string > PortValues
Mapping of port names and its respective value encoded as string.
const std::vector< NodeElement > deepApplyConst(ConstDeepApplyCallback apply_callback) const
Recursively apply a callback to this node's children.
TreeDocument * doc_ptr_
Pointer to the tree document that created the tree this node belongs to.
virtual std::string getName() const
Get the name of this node given to this specific instance by the developer.
PortValues getPorts() const
Assemble the values given to each data port implemented by this node.
NodeElement & setConditionalScript(BT::PreCond type, const Script &script)
Specify a script that is evaluated before this node is ticked.
NodeElement insertTreeFromString(const std::string &tree_str, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from a document created from a string and add its first child node to the children...
tinyxml2::XMLElement * ele_ptr_
Pointer to the corresponding XMLElement of the base document.
NodeElement insertTree(const TreeElement &tree, const NodeElement *before_this=nullptr)
Concatenate a tree and add its first child node to the children of this node.
std::string getFullyQualifiedName() const
Create a string that uniquely identifies this node considering its registration and its instance name...
NodeElement insertTreeFromDocument(const TreeDocument &doc, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from a document and add its first child node to the children of this node.
model::SubTree insertSubTreeNode(const std::string &tree_name, const NodeElement *before_this=nullptr)
Add a subtree node for a specific tree element to the children of this node.
bool hasChildren() const
Determine whether any children have been given to this node.
std::enable_if_t< std::is_same_v< model::SubTree, SubTreeT >, model::SubTree > insertNode(const std::string &tree_name, const NodeElement *before_this=nullptr)
Add a subtree node for a specific tree element to the children of this node.
bool operator==(const NodeElement &other) const
Determine if two node elements refer to the same node.
NodeElement insertNode(const std::string &name, const NodeElement *before_this=nullptr)
Add a new node to the children of this node.
NodeElement insertTreeFromFile(const std::string &path, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from a document created from a file and add its first child node to the children o...
std::enable_if_t< std::is_base_of_v< NodeModelType, T >, NodeElement & > removeFirstChild(const std::string &instance_name="")
Recursively visit this node's children in execution order and remove the first node with a particular...
NodeElement & removeChildren()
Recursively remove all children of this node element.
NodeElement & operator=(const NodeElement &other)
Replace this node with another.
std::vector< NodeElement > deepApply(DeepApplyCallback apply_callback)
Recursively apply a callback to this node's children.
Handle for a single behavior tree of a TreeDocument.
TreeElement & removeChildren()
TreeElement(TreeDocument *doc_ptr, XMLElement *ele_ptr)
Protected constructor intended to be used only by certain factory methods of TreeDocument.
std::string getName() const override
Get the name of the behavior tree.
BT::Result verify() const
Verify that this behavior tree is structured correctly and can be created successfully.
NodeManifest getRequiredNodeManifest() const
Assemble the node manifest that is required for successfully creating an instance of this tree.
TreeElement & makeRoot()
Set this behavior tree as the root tree of the parent document.
TreeElement & removeFirstChild(const std::string ®istration_name="", const std::string &instance_name="")
TreeElement & operator=(const TreeElement &other)
Replace the behavior tree represented by this element with another.
std::enable_if_t< std::is_base_of_v< NodeModelType, T >, TreeElement & > removeFirstChild(const std::string &instance_name="")
TreeElement & setName(const std::string &tree_name) override
Set the name of the behavior tree.
std::string writeToString() const
Write this behavior tree to an XML encoded in a string.
TreeElement(const TreeElement &ele)=default
Copy constructor for a tree element.
TreeElement getRootTree()
Get the corresponding behavior tree element for the root tree of this document.
TreeDocument & mergeResource(const TreeResource &resource, bool adopt_root_tree=false)
Merge the behavior trees from one of the installed package's behavior tree resources.
std::string getRootTreeName() const
Get the name of this document's root tree.
TreeDocument & mergeTreeDocument(const XMLDocument &other, bool adopt_root_tree=false)
Merge another tree document with this one.
TreeDocument & mergeString(const std::string &tree_str, bool adopt_root_tree=false)
Create a tree document from a string and merge it with this one.
TreeElement newTreeFromDocument(const TreeDocument &other, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one found inside another tree doc...
void writeToFile(const std::string &path) const
Write the XML of this tree document to a file.
TreeElement newTreeFromFile(const std::string &path, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one found inside the XML file.
BT::Result verify() const
Verify that all behavior trees of this document are structured correctly and can be created successfu...
NodeManifest getRequiredNodeManifest() const
Assemble the node manifest that is required for successfully creating an instance of any of the docum...
std::map< std::string, NodeModel > NodeModelMap
Mapping of node registration names and their implementation details.
std::set< std::string > getRegisteredNodeNames(bool include_native=true) const
Get the names of all nodes that are known to this document.
TreeElement newTreeFromString(const std::string &tree_str, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one found inside the XML string.
TreeElement newTreeFromResource(const TreeResource &resource, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one the trees found inside a part...
TreeDocument & reset()
Clear this document and reset it to its initial state.
TreeElement getTree(const std::string &tree_name)
Get the corresponding behavior tree element for a tree inside this document.
TreeDocument & addNodeModel(bool include_native=false)
Add an behavior tree node model element to the document.
virtual TreeDocument & registerNodes(const NodeManifest &tree_node_manifest, bool override=false)
Load behavior tree node plugins and register them with the internal behavior tree factory.
TreeDocument & setRootTreeName(const std::string &tree_name)
Define the root tree of this document.
bool hasTreeName(const std::string &tree_name) const
Determine if this document specifies a behavior tree with a particular name.
static NodeModelMap getNodeModel(tinyxml2::XMLDocument &doc)
Convert a behavior tree node model document to the corresponding data structure.
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::vector< std::string > getAllTreeNames() const
Get the names of all behavior trees inside this document.
TreeDocument & mergeTree(const TreeElement &tree, bool make_root_tree=false)
Merge an existing behavior tree with this tree document.
std::string writeToString() const
Write the XML of this tree document to a string.
bool hasRootTreeName() const
Determine if this document specifies which of its trees is the root tree.
TreeDocument & removeTree(const std::string &tree_name)
Remove a particular behavior tree from this document.
TreeDocument(const std::string &format_version=BTCPP_FORMAT_DEFAULT_VERSION, NodeRegistrationLoader::SharedPtr tree_node_loader=NodeRegistrationLoader::make_shared())
Create a an empty tree document.
TreeElement newTree(const std::string &tree_name)
Create a new behavior tree inside this document.
Class containing behavior tree resource data.
Subtree behavior tree node model.
Core API for AutoAPMS's behavior tree implementation.
Models for all available behavior tree nodes.
Parameters for loading and registering a behavior tree node class from a shared library using e....
Data structure encapsulating the information of all ports implemented by a behavior tree node.
BT::NodeType type
Abstract type of the node.
std::vector< NodePortInfo > port_infos
Vector of implementation details for each data port.
Implementation details of a single data port.
std::string port_default
Default value of the port encoded as string.
std::string port_description
Description of the port.
BT::PortDirection port_direction
Direction of the port.
std::string port_type
String representation of the C++ type given to the port.
std::string port_name
Name of the port.