Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ if(CURSES_FOUND)
target_link_libraries(t12_ncurses_manual_selector ${BEHAVIOR_TREE_LIBRARY} bt_sample_nodes )
endif()

add_executable(t13_load_multiple_BTs t13_load_multiple_BTs.cpp )
target_link_libraries(t13_load_multiple_BTs ${BEHAVIOR_TREE_LIBRARY} bt_sample_nodes )
84 changes: 84 additions & 0 deletions examples/t13_load_multiple_BTs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "dummy_nodes.h"
#include "behaviortree_cpp_v3/bt_factory.h"


/** This example show how it is possible to:
* - load BehaviorTrees from multiple files manually (without the <include> tag)
* - instantiate a specific tree, instead of the one specified by [main_tree_to_execute]
*/

// clang-format off

static const char* xml_text_main = R"(
<root main_tree_to_execute="MainTree">
<BehaviorTree ID="MainTree">
<Sequence>
<SaySomething message="starting MainTree" />
<SubTree ID="SubA"/>
<SubTree ID="SubB"/>
</Sequence>
</BehaviorTree>
</root> )";

static const char* xml_text_subA = R"(
<root>
<BehaviorTree ID="SubA">
<SaySomething message="Executing SubA" />
</BehaviorTree>
</root> )";

static const char* xml_text_subB = R"(
<root>
<BehaviorTree ID="SubB">
<SaySomething message="Executing SubB" />
</BehaviorTree>
</root> )";

// clang-format on

using namespace BT;

int main()
{
BT::BehaviorTreeFactory factory;
factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");

// Register the behavior tree definitions, but do not instantiate them yet.
// Order is not important.
factory.registerBehaviorTreeFromText(xml_text_subA);
factory.registerBehaviorTreeFromText(xml_text_subB);
factory.registerBehaviorTreeFromText(xml_text_main);

//Check that the BTs have been registered correctly
std::cout << "Registered BehaviorTrees:" << std::endl;
for(const std::string& bt_name: factory.registeredBehaviorTrees())
{
std::cout << " - " << bt_name << std::endl;
}

// You can create the MainTree and the subtrees will be added automatically.
std::cout << "----- MainTree tick ----" << std::endl;
auto main_tree = factory.createdTree("MainTree");
main_tree.tickRoot();

// ... or you can create only one of the subtree
std::cout << "----- SubA tick ----" << std::endl;
auto subA_tree = factory.createdTree("SubA");
subA_tree.tickRoot();

return 0;
}
/* Expected output:

Registered BehaviorTrees:
- MainTree
- SubA
- SubB
----- MainTree tick ----
Robot says: starting MainTree
Robot says: Executing SubA
Robot says: Executing SubB
----- SubA tick ----
Robot says: Executing SubA

*/
14 changes: 13 additions & 1 deletion include/behaviortree_cpp_v3/bt_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <algorithm>
#include <set>


#include "behaviortree_cpp_v3/behavior_tree.h"

namespace BT
Expand Down Expand Up @@ -197,6 +196,8 @@ class Tree

};

class Parser;

/**
* @brief The BehaviorTreeFactory is used to create instances of a
* TreeNode at run-time.
Expand Down Expand Up @@ -270,6 +271,12 @@ class BehaviorTreeFactory
*/
void registerFromROSPlugins();

void registerBehaviorTreeFromFile(const std::string& filename);

void registerBehaviorTreeFromText(const std::string& xml_text);

std::vector<std::string> registeredBehaviorTrees() const;

/**
* @brief instantiateTreeNode creates an instance of a previously registered TreeNode.
*
Expand Down Expand Up @@ -374,11 +381,16 @@ class BehaviorTreeFactory
Tree createTreeFromFile(const std::string& file_path,
Blackboard::Ptr blackboard = Blackboard::create());

Tree createdTree(const std::string& tree_name,
Blackboard::Ptr blackboard = Blackboard::create());

private:
std::unordered_map<std::string, NodeBuilder> builders_;
std::unordered_map<std::string, TreeNodeManifest> manifests_;
std::set<std::string> builtin_IDs_;
std::unordered_map<std::string, Any> behavior_tree_definitions_;

std::shared_ptr<BT::Parser> parser_;
// clang-format on
};

Expand Down
8 changes: 5 additions & 3 deletions include/behaviortree_cpp_v3/bt_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ class Parser
Parser(const Parser& other) = delete;
Parser& operator=(const Parser& other) = delete;

virtual void loadFromFile(const std::string& filename) = 0;
virtual void loadFromFile(const std::string& filename, bool add_includes = true) = 0;

virtual void loadFromText(const std::string& xml_text) = 0;
virtual void loadFromText(const std::string& xml_text, bool add_includes = true) = 0;

virtual Tree instantiateTree(const Blackboard::Ptr &root_blackboard) = 0;
virtual std::vector<std::string> registeredBehaviorTrees() const = 0;

virtual Tree instantiateTree(const Blackboard::Ptr &root_blackboard, std::string tree_name = {}) = 0;
};

}
Expand Down
11 changes: 7 additions & 4 deletions include/behaviortree_cpp_v3/xml_parsing.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ class XMLParser: public Parser
public:
XMLParser(const BehaviorTreeFactory& factory);

~XMLParser();
~XMLParser() override;

XMLParser(const XMLParser& other) = delete;
XMLParser& operator=(const XMLParser& other) = delete;

void loadFromFile(const std::string& filename) override;
void loadFromFile(const std::string& filename, bool add_includes = true) override;

void loadFromText(const std::string& xml_text) override;
void loadFromText(const std::string& xml_text, bool add_includes = true) override;

Tree instantiateTree(const Blackboard::Ptr &root_blackboard) override;
std::vector<std::string> registeredBehaviorTrees() const override;

Tree instantiateTree(const Blackboard::Ptr &root_blackboard,
std::string main_tree_to_execute = {}) override;

private:

Expand Down
26 changes: 26 additions & 0 deletions src/bt_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <fstream>
#include "behaviortree_cpp_v3/bt_factory.h"
#include "behaviortree_cpp_v3/utils/shared_library.h"
#include "behaviortree_cpp_v3/xml_parsing.h"
#include "private/tinyxml2.h"

#ifdef USING_ROS
#include "filesystem/path.h"
Expand All @@ -23,6 +25,7 @@ namespace BT
{
BehaviorTreeFactory::BehaviorTreeFactory()
{
parser_ = std::make_shared<XMLParser>(*this);
registerNodeType<FallbackNode>("Fallback");
registerNodeType<SequenceNode>("Sequence");
registerNodeType<SequenceStarNode>("SequenceStar");
Expand Down Expand Up @@ -212,6 +215,22 @@ void BehaviorTreeFactory::registerFromROSPlugins()
}
#endif


void BehaviorTreeFactory::registerBehaviorTreeFromFile(const std::string &filename)
{
parser_->loadFromFile(filename);
}

void BehaviorTreeFactory::registerBehaviorTreeFromText(const std::string &xml_text)
{
parser_->loadFromText(xml_text);
}

std::vector<std::string> BehaviorTreeFactory::registeredBehaviorTrees() const
{
return parser_->registeredBehaviorTrees();
}

std::unique_ptr<TreeNode> BehaviorTreeFactory::instantiateTreeNode(
const std::string& name,
const std::string& ID,
Expand Down Expand Up @@ -268,6 +287,13 @@ Tree BehaviorTreeFactory::createTreeFromFile(const std::string &file_path,
return tree;
}

Tree BehaviorTreeFactory::createdTree(const std::string &tree_name, Blackboard::Ptr blackboard)
{
auto tree = parser_->instantiateTree(blackboard, tree_name);
tree.manifests = this->manifests();
return tree;
}

Tree::~Tree()
{
haltTree();
Expand Down
Loading