gtest_factory.cpp
Go to the documentation of this file.
1 #include <gtest/gtest.h>
2 #include "action_test_node.h"
3 #include "condition_test_node.h"
5 #include "../sample_nodes/crossdoor_nodes.h"
6 
7 // clang-format off
8 
9 const std::string xml_text = R"(
10 
11 <root main_tree_to_execute = "MainTree" >
12 
13  <BehaviorTree ID="MainTree">
14  <Fallback name="root_selector">
15 
16  <Sequence name="door_open_sequence">
17  <Action ID="IsDoorOpen" />
18  <Action ID="PassThroughDoor" />
19  </Sequence>
20 
21  <Sequence name="door_closed_sequence">
22  <Decorator ID="Inverter">
23  <Action ID="IsDoorOpen" />
24  </Decorator>
25  <Action ID="OpenDoor" />
26  <Action ID="PassThroughDoor" />
27  <Action ID="CloseDoor" />
28  </Sequence>
29 
30  <Action ID="PassThroughWindow" />
31 
32  </Fallback>
33  </BehaviorTree>
34 
35  <!-- TreeNodesModel is used only by the Graphic interface -->
36  <TreeNodesModel>
37  <Action ID="IsDoorOpen" />
38  <Action ID="PassThroughDoor" />
39  <Action ID="CloseDoor" />
40  <Action ID="OpenDoor" />
41  <Action ID="PassThroughWindow" />
42  <Decorator ID="Invert" />
43  <Decorator ID="RetryUntilSuccesful">
44  <Parameter label="num_attempts" type="Int" />
45  </Decorator>
46  <Decorator ID="Repeat">
47  <Parameter label="num_cycles" type="Int" />
48  </Decorator>
49  </TreeNodesModel>
50 </root>
51  )";
52 
53 const std::string xml_text_subtree = R"(
54 
55 <root main_tree_to_execute = "MainTree" >
56 
57  <BehaviorTree ID="CrossDoorSubtree">
58  <Sequence name="door_sequence">
59  <Decorator ID="Inverter">
60  <Action ID="IsDoorLocked" />
61  </Decorator>
62  <Action ID="OpenDoor" />
63  <Action ID="PassThroughDoor" />
64  <Action ID="CloseDoor" />
65  </Sequence>
66  </BehaviorTree>
67 
68  <!-- This tree will include the other one -->
69  <BehaviorTree ID="MainTree">
70  <Fallback name="root_selector">
71  <SubTree ID="CrossDoorSubtree" />
72  <Action ID="PassThroughWindow" />
73  </Fallback>
74  </BehaviorTree>
75 
76 </root>
77  )";
78 // clang-format on
79 
80 TEST(BehaviorTreeFactory, VerifyLargeTree)
81 {
83  CrossDoor::RegisterNodes(factory);
84 
85  BT::XMLParser parser(factory);
86  parser.loadFromText(xml_text);
87 
88  std::vector<BT::TreeNode::Ptr> nodes;
89 
90  BT::TreeNode::Ptr root_node = parser.instantiateTree(nodes, Blackboard::Ptr());
91 
92  BT::printTreeRecursively(root_node.get());
93 
94  ASSERT_EQ(root_node->name(), "root_selector");
95 
96  auto fallback = dynamic_cast<const BT::FallbackNode*>(root_node.get());
97  ASSERT_TRUE(fallback != nullptr);
98 
99  ASSERT_EQ(fallback->children().size(), 3);
100  ASSERT_EQ(fallback->child(0)->name(), "door_open_sequence");
101  ASSERT_EQ(fallback->child(1)->name(), "door_closed_sequence");
102  ASSERT_EQ(fallback->child(2)->name(), "PassThroughWindow");
103 
104  auto sequence_open = dynamic_cast<const BT::SequenceNode*>(fallback->child(0));
105  ASSERT_TRUE(sequence_open != nullptr);
106 
107  ASSERT_EQ(sequence_open->children().size(), 2);
108  ASSERT_EQ(sequence_open->child(0)->name(), "IsDoorOpen");
109  ASSERT_EQ(sequence_open->child(1)->name(), "PassThroughDoor");
110 
111  auto sequence_closed = dynamic_cast<const BT::SequenceNode*>(fallback->child(1));
112  ASSERT_TRUE(sequence_closed != nullptr);
113 
114  ASSERT_EQ(sequence_closed->children().size(), 4);
115  ASSERT_EQ(sequence_closed->child(0)->name(), "Inverter");
116  ASSERT_EQ(sequence_closed->child(1)->name(), "OpenDoor");
117  ASSERT_EQ(sequence_closed->child(2)->name(), "PassThroughDoor");
118  ASSERT_EQ(sequence_closed->child(3)->name(), "CloseDoor");
119 
120  auto decorator = dynamic_cast<const BT::InverterNode*>(sequence_closed->child(0));
121  ASSERT_TRUE(decorator != nullptr);
122 
123  ASSERT_EQ(decorator->child()->name(), "IsDoorOpen");
124 }
125 
127 {
128  BT::BehaviorTreeFactory factory;
129  CrossDoor::RegisterNodes(factory);
130 
131  BT::XMLParser parser(factory);
133 
134  std::vector<BT::TreeNode::Ptr> nodes;
135 
136  BT::TreeNode::Ptr root_node = parser.instantiateTree(nodes, Blackboard::Ptr());
137  BT::printTreeRecursively(root_node.get());
138 
139  ASSERT_EQ(root_node->name(), "root_selector");
140 
141  auto root_selector = dynamic_cast<const BT::FallbackNode*>(root_node.get());
142  ASSERT_TRUE(root_selector != nullptr);
143  ASSERT_EQ(root_selector->children().size(), 2);
144  ASSERT_EQ(root_selector->child(0)->name(), "CrossDoorSubtree");
145  ASSERT_EQ(root_selector->child(1)->name(), "PassThroughWindow");
146 
147  auto subtree = dynamic_cast<const BT::DecoratorSubtreeNode*>(root_selector->child(0));
148  ASSERT_TRUE(subtree != nullptr);
149 
150  auto sequence = dynamic_cast<const BT::SequenceNode*>(subtree->child());
151  ASSERT_TRUE(sequence != nullptr);
152 
153  ASSERT_EQ(sequence->children().size(), 4);
154  ASSERT_EQ(sequence->child(0)->name(), "Inverter");
155  ASSERT_EQ(sequence->child(1)->name(), "OpenDoor");
156  ASSERT_EQ(sequence->child(2)->name(), "PassThroughDoor");
157  ASSERT_EQ(sequence->child(3)->name(), "CloseDoor");
158 
159  auto decorator = dynamic_cast<const BT::InverterNode*>(sequence->child(0));
160  ASSERT_TRUE(decorator != nullptr);
161 
162  ASSERT_EQ(decorator->child()->name(), "IsDoorLocked");
163 }
164 
166 {
167 const std::string xml_text_issue = R"(
168 <root>
169  <BehaviorTree ID="ReceiveGuest">
170  </BehaviorTree>
171 </root> )";
172 
173  BT::BehaviorTreeFactory factory;
174  BT::XMLParser parser(factory);
175 
176  EXPECT_THROW( parser.loadFromText(xml_text_issue), std::runtime_error );
177 }
const std::string xml_text_subtree
const std::string xml_text
TEST(BehaviorTreeFactory, VerifyLargeTree)
void printTreeRecursively(const TreeNode *root_node)
std::shared_ptr< Blackboard > Ptr
Definition: blackboard.h:40
void RegisterNodes(BT::BehaviorTreeFactory &factory)
TreeNode::Ptr instantiateTree(std::vector< TreeNode::Ptr > &nodes, const Blackboard::Ptr &blackboard)
void loadFromText(const std::string &xml_text)
Definition: xml_parsing.cpp:97
std::shared_ptr< TreeNode > Ptr
Definition: tree_node.h:63
The FallbackNode is used to try different strategies, until one succeed. If any child returns RUNNING...
Definition: fallback_node.h:35
The SequenceNode is used to execute a sequence of children. If any child returns RUNNING, previous children will be ticked again.
Definition: sequence_node.h:34


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sun Feb 3 2019 03:14:32