1 #include <gtest/gtest.h> 5 #include "../sample_nodes/crossdoor_nodes.h" 6 #include "../sample_nodes/dummy_nodes.h" 14 <root main_tree_to_execute = "MainTree" > 16 <BehaviorTree ID="MainTree"> 17 <Fallback name="root_selector"> 19 <Sequence name="door_open_sequence"> 20 <Action ID="IsDoorOpen" /> 21 <Action ID="PassThroughDoor" /> 24 <Sequence name="door_closed_sequence"> 25 <Decorator ID="Inverter"> 26 <Action ID="IsDoorOpen" /> 28 <Action ID="OpenDoor" /> 29 <Action ID="PassThroughDoor" /> 30 <Action ID="CloseDoor" /> 33 <Action ID="PassThroughWindow" /> 38 <!-- TreeNodesModel is used only by the Graphic interface --> 40 <Action ID="IsDoorOpen" /> 41 <Action ID="PassThroughDoor" /> 42 <Action ID="CloseDoor" /> 43 <Action ID="OpenDoor" /> 44 <Action ID="PassThroughWindow" /> 51 <root main_tree_to_execute = "MainTree" > 53 <BehaviorTree ID="CrossDoorSubtree"> 54 <Sequence name="door_sequence"> 55 <Decorator ID="Inverter"> 56 <Action ID="IsDoorLocked" /> 58 <Action ID="OpenDoor" /> 59 <Action ID="PassThroughDoor" /> 60 <Action ID="CloseDoor" /> 64 <!-- This tree will include the other one --> 65 <BehaviorTree ID="MainTree"> 66 <Fallback name="root_selector"> 67 <SubTree ID="CrossDoorSubtree" /> 68 <Action ID="PassThroughWindow" /> 88 ASSERT_TRUE(fallback !=
nullptr);
90 ASSERT_EQ(fallback->children().size(), 3);
91 ASSERT_EQ(fallback->child(0)->name(),
"door_open_sequence");
92 ASSERT_EQ(fallback->child(1)->name(),
"door_closed_sequence");
93 ASSERT_EQ(fallback->child(2)->name(),
"PassThroughWindow");
95 auto sequence_open =
dynamic_cast<const SequenceNode*
>(fallback->child(0));
96 ASSERT_TRUE(sequence_open !=
nullptr);
98 ASSERT_EQ(sequence_open->children().size(), 2);
99 ASSERT_EQ(sequence_open->child(0)->name(),
"IsDoorOpen");
100 ASSERT_EQ(sequence_open->child(1)->name(),
"PassThroughDoor");
102 auto sequence_closed =
dynamic_cast<const SequenceNode*
>(fallback->child(1));
103 ASSERT_TRUE(sequence_closed !=
nullptr);
105 ASSERT_EQ(sequence_closed->children().size(), 4);
106 ASSERT_EQ(sequence_closed->child(0)->name(),
"Inverter");
107 ASSERT_EQ(sequence_closed->child(1)->name(),
"OpenDoor");
108 ASSERT_EQ(sequence_closed->child(2)->name(),
"PassThroughDoor");
109 ASSERT_EQ(sequence_closed->child(3)->name(),
"CloseDoor");
111 auto decorator =
dynamic_cast<const InverterNode*
>(sequence_closed->child(0));
112 ASSERT_TRUE(decorator !=
nullptr);
114 ASSERT_EQ(decorator->child()->name(),
"IsDoorOpen");
129 ASSERT_TRUE(root_selector !=
nullptr);
130 ASSERT_EQ(root_selector->children().size(), 2);
131 ASSERT_EQ(root_selector->child(0)->name(),
"CrossDoorSubtree");
132 ASSERT_EQ(root_selector->child(1)->name(),
"PassThroughWindow");
135 ASSERT_TRUE(subtree !=
nullptr);
137 auto sequence =
dynamic_cast<const SequenceNode*
>(subtree->child());
138 ASSERT_TRUE(sequence !=
nullptr);
140 ASSERT_EQ(sequence->children().size(), 4);
141 ASSERT_EQ(sequence->child(0)->name(),
"Inverter");
142 ASSERT_EQ(sequence->child(1)->name(),
"OpenDoor");
143 ASSERT_EQ(sequence->child(2)->name(),
"PassThroughDoor");
144 ASSERT_EQ(sequence->child(3)->name(),
"CloseDoor");
146 auto decorator =
dynamic_cast<const InverterNode*
>(sequence->child(0));
147 ASSERT_TRUE(decorator !=
nullptr);
149 ASSERT_EQ(decorator->child()->name(),
"IsDoorLocked");
154 const std::string xml_text_issue = R
"( 156 <BehaviorTree ID="ReceiveGuest"> 171 <root main_tree_to_execute = "MainTree" > 173 <BehaviorTree ID="TalkToMe"> 175 <SaySomething message="{hello_msg}" /> 176 <SaySomething message="{bye_msg}" /> 177 <SetBlackboard output_key="output" value="done!" /> 181 <BehaviorTree ID="MainTree"> 183 <SetBlackboard output_key="talk_hello" value="hello" /> 184 <SetBlackboard output_key="talk_bye" value="bye bye" /> 185 <SubTree ID="TalkToMe" hello_msg="talk_hello" 188 <SaySomething message="{talk_out}" /> 204 auto talk_bb = tree.blackboard_stack.at(1);
206 std::cout <<
"\n --------------------------------- \n" << std::endl;
207 main_bb->debugMessage();
208 std::cout <<
"\n ----- \n" << std::endl;
209 talk_bb->debugMessage();
210 std::cout <<
"\n --------------------------------- \n" << std::endl;
212 ASSERT_EQ( main_bb->portInfo(
"talk_hello")->type(), &
typeid(std::string) );
213 ASSERT_EQ( main_bb->portInfo(
"talk_bye")->type(), &
typeid(std::string) );
214 ASSERT_EQ( main_bb->portInfo(
"talk_out")->type(), &
typeid(std::string) );
216 ASSERT_EQ( talk_bb->portInfo(
"bye_msg")->type(), &
typeid(std::string) );
217 ASSERT_EQ( talk_bb->portInfo(
"hello_msg")->type(), &
typeid(std::string) );
220 tree.root_node->executeTick();
222 std::cout <<
"\n --------------------------------- \n" << std::endl;
223 main_bb->debugMessage();
224 std::cout <<
"\n ----- \n" << std::endl;
225 talk_bb->debugMessage();
226 std::cout <<
"\n --------------------------------- \n" << std::endl;
228 ASSERT_EQ( main_bb->portInfo(
"talk_hello")->type(), &
typeid(std::string) );
229 ASSERT_EQ( main_bb->portInfo(
"talk_bye")->type(), &
typeid(std::string) );
230 ASSERT_EQ( main_bb->portInfo(
"talk_out")->type(), &
typeid(std::string) );
232 ASSERT_EQ( talk_bb->portInfo(
"bye_msg")->type(), &
typeid(std::string) );
233 ASSERT_EQ( talk_bb->portInfo(
"hello_msg")->type(), &
typeid(std::string) );
234 ASSERT_EQ( talk_bb->portInfo(
"output")->type(), &
typeid(std::string) );
237 ASSERT_EQ( main_bb->get<std::string>(
"talk_hello"),
"hello");
238 ASSERT_EQ( main_bb->get<std::string>(
"talk_bye"),
"bye bye");
239 ASSERT_EQ( main_bb->get<std::string>(
"talk_out"),
"done!");
242 ASSERT_FALSE( talk_bb->getAny(
"talk_hello") );
243 ASSERT_FALSE( talk_bb->getAny(
"talk_bye") );
244 ASSERT_FALSE( talk_bb->getAny(
"talk_out") );
const std::string & name() const
Name of the instance, not the type.
void registerNodeType(const std::string &ID)
TEST(BehaviorTreeFactory, VerifyLargeTree)
static const char * xml_ports_subtree
void printTreeRecursively(const TreeNode *root_node)
static const char * xml_text_subtree
void RegisterNodes(BT::BehaviorTreeFactory &factory)
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
std::vector< Blackboard::Ptr > blackboard_stack
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
The InverterNode returns SUCCESS if child fails of FAILURE is child succeeds. RUNNING status is propa...
The XMLParser is a class used to read the model of a BehaviorTree from file or text and instantiate t...
void loadFromText(const std::string &xml_text) override
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
The FallbackNode is used to try different strategies, until one succeeds. If any child returns RUNNIN...
static const char * xml_text
The SequenceNode is used to tick children in an ordered sequence. If any child returns RUNNING...