1 #include <gtest/gtest.h>
6 #include "../sample_nodes/crossdoor_nodes.h"
7 #include "../sample_nodes/dummy_nodes.h"
15 <root main_tree_to_execute = "MainTree" >
17 <BehaviorTree ID="MainTree">
18 <Fallback name="root_selector">
20 <Sequence name="door_open_sequence">
21 <Action ID="IsDoorOpen" />
22 <Action ID="PassThroughDoor" />
25 <Sequence name="door_closed_sequence">
26 <Decorator ID="Inverter">
27 <Action ID="IsDoorOpen" />
29 <Action ID="OpenDoor" />
30 <Action ID="PassThroughDoor" />
31 <Action ID="CloseDoor" />
34 <Action ID="PassThroughWindow" />
39 <!-- TreeNodesModel is used only by the Graphic interface -->
41 <Action ID="IsDoorOpen" />
42 <Action ID="PassThroughDoor" />
43 <Action ID="CloseDoor" />
44 <Action ID="OpenDoor" />
45 <Action ID="PassThroughWindow" />
52 <root main_tree_to_execute = "MainTree" >
54 <BehaviorTree ID="CrossDoorSubtree">
55 <Sequence name="door_sequence">
56 <Decorator ID="Inverter">
57 <Action ID="IsDoorLocked" />
59 <Action ID="OpenDoor" />
60 <Action ID="PassThroughDoor" />
61 <Action ID="CloseDoor" />
65 <!-- This tree will include the other one -->
66 <BehaviorTree ID="MainTree">
67 <Fallback name="root_selector">
68 <SubTree ID="CrossDoorSubtree" />
69 <Action ID="PassThroughWindow" />
78 <BehaviorTree ID="MainTree">
79 <Fallback name="root_selector">
80 <SubTree ID="CrossDoorSubtree" />
81 <Action ID="PassThroughWindow" />
89 <BehaviorTree ID="CrossDoorSubtree">
90 <Sequence name="door_sequence">
91 <Decorator ID="Inverter">
92 <Action ID="IsDoorLocked" />
94 <Action ID="OpenDoor" />
95 <Action ID="PassThroughDoor" />
96 <Action ID="CloseDoor" />
112 ASSERT_EQ(trees.size(), 2);
113 ASSERT_EQ(trees[0],
"CrossDoorSubtree");
114 ASSERT_EQ(trees[1],
"MainTree");
121 ASSERT_EQ(trees.size(), 2);
122 ASSERT_EQ(trees[0],
"CrossDoorSubtree");
123 ASSERT_EQ(trees[1],
"MainTree");
130 ASSERT_EQ(trees.size(), 2);
131 ASSERT_EQ(trees[0],
"CrossDoorSubtree");
132 ASSERT_EQ(trees[1],
"MainTree");
148 ASSERT_TRUE(fallback !=
nullptr);
150 ASSERT_EQ(fallback->children().size(), 3);
151 ASSERT_EQ(fallback->child(0)->name(),
"door_open_sequence");
152 ASSERT_EQ(fallback->child(1)->name(),
"door_closed_sequence");
153 ASSERT_EQ(fallback->child(2)->name(),
"PassThroughWindow");
155 auto sequence_open =
dynamic_cast<const SequenceNode*
>(fallback->child(0));
156 ASSERT_TRUE(sequence_open !=
nullptr);
158 ASSERT_EQ(sequence_open->children().size(), 2);
159 ASSERT_EQ(sequence_open->child(0)->name(),
"IsDoorOpen");
160 ASSERT_EQ(sequence_open->child(1)->name(),
"PassThroughDoor");
162 auto sequence_closed =
dynamic_cast<const SequenceNode*
>(fallback->child(1));
163 ASSERT_TRUE(sequence_closed !=
nullptr);
165 ASSERT_EQ(sequence_closed->children().size(), 4);
166 ASSERT_EQ(sequence_closed->child(0)->name(),
"Inverter");
167 ASSERT_EQ(sequence_closed->child(1)->name(),
"OpenDoor");
168 ASSERT_EQ(sequence_closed->child(2)->name(),
"PassThroughDoor");
169 ASSERT_EQ(sequence_closed->child(3)->name(),
"CloseDoor");
171 auto decorator =
dynamic_cast<const InverterNode*
>(sequence_closed->child(0));
172 ASSERT_TRUE(decorator !=
nullptr);
174 ASSERT_EQ(decorator->child()->name(),
"IsDoorOpen");
189 ASSERT_TRUE(root_selector !=
nullptr);
190 ASSERT_EQ(root_selector->children().size(), 2);
191 ASSERT_EQ(root_selector->child(0)->name(),
"CrossDoorSubtree");
192 ASSERT_EQ(root_selector->child(1)->name(),
"PassThroughWindow");
194 auto subtree =
dynamic_cast<const SubtreeNode*
>(root_selector->child(0));
195 ASSERT_TRUE(subtree !=
nullptr);
197 auto sequence =
dynamic_cast<const SequenceNode*
>(subtree->child());
198 ASSERT_TRUE(sequence !=
nullptr);
200 ASSERT_EQ(sequence->children().size(), 4);
201 ASSERT_EQ(sequence->child(0)->name(),
"Inverter");
202 ASSERT_EQ(sequence->child(1)->name(),
"OpenDoor");
203 ASSERT_EQ(sequence->child(2)->name(),
"PassThroughDoor");
204 ASSERT_EQ(sequence->child(3)->name(),
"CloseDoor");
206 auto decorator =
dynamic_cast<const InverterNode*
>(sequence->child(0));
207 ASSERT_TRUE(decorator !=
nullptr);
209 ASSERT_EQ(decorator->child()->name(),
"IsDoorLocked");
214 const std::string xml_text_issue = R
"(
216 <BehaviorTree ID="ReceiveGuest">
228 EXPECT_TRUE( trees.empty() );
235 <root main_tree_to_execute = "MainTree" >
237 <BehaviorTree ID="TalkToMe">
239 <SaySomething message="{hello_msg}" />
240 <SaySomething message="{bye_msg}" />
241 <SetBlackboard output_key="output" value="done!" />
245 <BehaviorTree ID="MainTree">
247 <SetBlackboard output_key="talk_hello" value="hello" />
248 <SetBlackboard output_key="talk_bye" value="bye bye" />
249 <SubTree ID="TalkToMe" hello_msg="talk_hello"
252 <SaySomething message="{talk_out}" />
268 auto talk_bb = tree.blackboard_stack.at(1);
270 std::cout <<
"\n --------------------------------- \n" << std::endl;
271 main_bb->debugMessage();
272 std::cout <<
"\n ----- \n" << std::endl;
273 talk_bb->debugMessage();
274 std::cout <<
"\n --------------------------------- \n" << std::endl;
276 ASSERT_EQ(main_bb->portInfo(
"talk_hello")->type(), &
typeid(std::string));
277 ASSERT_EQ(main_bb->portInfo(
"talk_bye")->type(), &
typeid(std::string));
278 ASSERT_EQ(main_bb->portInfo(
"talk_out")->type(), &
typeid(std::string));
280 ASSERT_EQ(talk_bb->portInfo(
"bye_msg")->type(), &
typeid(std::string));
281 ASSERT_EQ(talk_bb->portInfo(
"hello_msg")->type(), &
typeid(std::string));
286 std::cout <<
"\n --------------------------------- \n" << std::endl;
287 main_bb->debugMessage();
288 std::cout <<
"\n ----- \n" << std::endl;
289 talk_bb->debugMessage();
290 std::cout <<
"\n --------------------------------- \n" << std::endl;
292 ASSERT_EQ(main_bb->portInfo(
"talk_hello")->type(), &
typeid(std::string));
293 ASSERT_EQ(main_bb->portInfo(
"talk_bye")->type(), &
typeid(std::string));
294 ASSERT_EQ(main_bb->portInfo(
"talk_out")->type(), &
typeid(std::string));
296 ASSERT_EQ(talk_bb->portInfo(
"bye_msg")->type(), &
typeid(std::string));
297 ASSERT_EQ(talk_bb->portInfo(
"hello_msg")->type(), &
typeid(std::string));
298 ASSERT_EQ(talk_bb->portInfo(
"output")->type(), &
typeid(std::string));
300 ASSERT_EQ(main_bb->get<std::string>(
"talk_hello"),
"hello");
301 ASSERT_EQ(main_bb->get<std::string>(
"talk_bye"),
"bye bye");
302 ASSERT_EQ(main_bb->get<std::string>(
"talk_out"),
"done!");
305 ASSERT_FALSE(talk_bb->getAny(
"talk_hello"));
306 ASSERT_FALSE(talk_bb->getAny(
"talk_bye"));
307 ASSERT_FALSE(talk_bb->getAny(
"talk_out"));
310 #if !defined(USING_ROS) && !defined(USING_ROS2)
317 "parent_no_include.xml");
327 auto path = (
environment->executable_path.parent_path() /
"trees/child/"
328 "child_include_sibling.xml");
339 "parent_include_child.xml");
346 CreateTreeFromFileWhichIncludesFileFromChildDirectoryWhichIncludesFileFromSameDirectory)
352 "parent_include_child_"
353 "include_sibling.xml");
360 CreateTreeFromFileWhichIncludesFileFromChildDirectoryWhichIncludesFileFromChildDirectory)
366 "parent_include_child_"
367 "include_child.xml");
374 CreateTreeFromFileWhichIncludesFileFromChildDirectoryWhichIncludesFileFromParentDirectory)
380 "parent_include_child_"
381 "include_parent.xml");
390 const std::string tree_xml = R
"(
392 <BehaviorTree ID="Main">
405 const std::string tree_xml = R
"(
407 <BehaviorTree ID="Main">
422 const std::string xml_text_ok = R
"(
424 <BehaviorTree ID="ValidTree">
425 <Sequence name="door_open_sequence">
426 <Action ID="AlwaysSuccess" />
431 const std::string xml_text_invalid = R
"(
433 <BehaviorTree ID="InvalidTreeWithNoChildren">
448 ASSERT_EQ(trees.size(), 1);
449 EXPECT_EQ(trees[0],
"ValidTree");
457 const std::string xml_text_invalid = R
"(
459 <BehaviorTree ID="InvalidTreeWithBadChild">
460 <Sequence name="seq">
461 <Action ID="AlwaysSuccess" >
475 EXPECT_TRUE(trees.empty());
482 const std::string xml_text_invalid = R
"(
483 <BehaviorTree ID="InvalidTreeNoRoot">
484 <Sequence name="seq">
485 <Action ID="AlwaysSuccess" />
498 EXPECT_TRUE(trees.empty());
503 const std::string tree_xml = R
"(
505 <BehaviorTree ID="Main">
517 ASSERT_FALSE(trees.empty());
522 EXPECT_TRUE(trees_after_clear.empty());
528 const std::string tree_xml = R
"(
530 <BehaviorTree ID="Main">
539 ASSERT_FALSE(trees.empty());
544 EXPECT_TRUE(trees_after_clear.empty());