1 #include <gtest/gtest.h>
7 #include "../sample_nodes/crossdoor_nodes.h"
8 #include "../sample_nodes/dummy_nodes.h"
16 <root BTCPP_format="4" >
18 <BehaviorTree ID="MainTree">
19 <Fallback name="root_selector">
21 <Sequence name="door_open_sequence">
22 <Action ID="IsDoorOpen" />
23 <Action ID="PassThroughDoor" />
26 <Sequence name="door_closed_sequence">
27 <Decorator ID="Inverter">
28 <Action ID="IsDoorOpen" />
30 <Action ID="OpenDoor" />
31 <Action ID="PassThroughDoor" />
32 <Action ID="CloseDoor" />
35 <Action ID="PassThroughWindow" />
40 <!-- TreeNodesModel is used only by the Graphic interface -->
42 <Action ID="IsDoorOpen" />
43 <Action ID="PassThroughDoor" />
44 <Action ID="CloseDoor" />
45 <Action ID="OpenDoor" />
46 <Action ID="PassThroughWindow" />
53 <root BTCPP_format="4" main_tree_to_execute="MainTree" >
55 <BehaviorTree ID="MainTree">
61 <SubTree ID="DoorClosedSubtree"/>
67 <BehaviorTree ID="DoorClosedSubtree">
70 <RetryUntilSuccessful num_attempts="5">
72 </RetryUntilSuccessful>
81 <root BTCPP_format="4">
82 <BehaviorTree ID="MainTree">
83 <Fallback name="root_selector">
84 <SubTree ID="DoorClosedSubtree" />
85 <Action ID="PassThroughWindow" />
92 <root BTCPP_format="4">
93 <BehaviorTree ID="DoorClosedSubtree">
94 <Sequence name="door_sequence">
95 <Decorator ID="Inverter">
96 <Action ID="IsDoorLocked" />
98 <Action ID="OpenDoor" />
99 <Action ID="PassThroughDoor" />
100 <Action ID="CloseDoor" />
117 ASSERT_EQ(trees[0],
"DoorClosedSubtree");
118 ASSERT_EQ(trees[1],
"MainTree");
125 ASSERT_EQ(trees[0],
"DoorClosedSubtree");
126 ASSERT_EQ(trees[1],
"MainTree");
133 ASSERT_EQ(trees[0],
"DoorClosedSubtree");
134 ASSERT_EQ(trees[1],
"MainTree");
150 auto const& main_tree = tree.
subtrees[0];
151 auto const& subtree = tree.
subtrees[1];
153 ASSERT_EQ(main_tree->nodes.size(), 6);
154 ASSERT_EQ(main_tree->nodes[0]->name(),
"Sequence");
155 ASSERT_EQ(main_tree->nodes[1]->name(),
"Fallback");
156 ASSERT_EQ(main_tree->nodes[2]->name(),
"Inverter");
157 ASSERT_EQ(main_tree->nodes[3]->name(),
"IsDoorClosed");
159 ASSERT_EQ(main_tree->nodes[5]->name(),
"PassThroughDoor");
161 ASSERT_EQ(subtree->nodes.size(), 5);
162 ASSERT_EQ(subtree->nodes[0]->name(),
"Fallback");
163 ASSERT_EQ(subtree->nodes[1]->name(),
"OpenDoor");
164 ASSERT_EQ(subtree->nodes[2]->name(),
"RetryUntilSuccessful");
165 ASSERT_EQ(subtree->nodes[3]->name(),
"PickLock");
166 ASSERT_EQ(subtree->nodes[4]->name(),
"SmashDoor");
171 const std::string xml_text_issue = R
"(
172 <root BTCPP_format="4">
173 <BehaviorTree ID="ReceiveGuest">
187 <root BTCPP_format="4" main_tree_to_execute="MainTree">
189 <BehaviorTree ID="TalkToMe">
191 <SaySomething message="{hello_msg}" />
192 <SaySomething message="{bye_msg}" />
193 <Script code=" output:='done!' " />
197 <BehaviorTree ID="MainTree">
199 <Script code = " talk_hello:='hello' " />
200 <Script code = " talk_bye:='bye bye' " />
201 <SubTree ID="TalkToMe" hello_msg="{talk_hello}"
203 output="{talk_out}" />
204 <SaySomething message="{talk_out}" />
219 auto main_bb = tree.
subtrees.at(0)->blackboard;
220 auto talk_bb = tree.subtrees.at(1)->blackboard;
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;
229 tree.tickWhileRunning();
231 ASSERT_EQ(main_bb->entryInfo(
"talk_hello")->type(),
typeid(std::string));
232 ASSERT_EQ(main_bb->entryInfo(
"talk_bye")->type(),
typeid(std::string));
233 ASSERT_EQ(main_bb->entryInfo(
"talk_out")->type(),
typeid(std::string));
235 ASSERT_EQ(talk_bb->entryInfo(
"bye_msg")->type(),
typeid(std::string));
236 ASSERT_EQ(talk_bb->entryInfo(
"hello_msg")->type(),
typeid(std::string));
238 std::cout <<
"\n --------------------------------- \n" << std::endl;
239 main_bb->debugMessage();
240 std::cout <<
"\n ----- \n" << std::endl;
241 talk_bb->debugMessage();
242 std::cout <<
"\n --------------------------------- \n" << std::endl;
244 ASSERT_EQ(main_bb->entryInfo(
"talk_hello")->type(),
typeid(std::string));
245 ASSERT_EQ(main_bb->entryInfo(
"talk_bye")->type(),
typeid(std::string));
246 ASSERT_EQ(main_bb->entryInfo(
"talk_out")->type(),
typeid(std::string));
248 ASSERT_EQ(talk_bb->entryInfo(
"bye_msg")->type(),
typeid(std::string));
249 ASSERT_EQ(talk_bb->entryInfo(
"hello_msg")->type(),
typeid(std::string));
250 ASSERT_EQ(talk_bb->entryInfo(
"output")->type(),
typeid(std::string));
252 ASSERT_EQ(main_bb->get<std::string>(
"talk_hello"),
"hello");
253 ASSERT_EQ(main_bb->get<std::string>(
"talk_bye"),
"bye bye");
254 ASSERT_EQ(main_bb->get<std::string>(
"talk_out"),
"done!");
257 ASSERT_FALSE(talk_bb->getAnyLocked(
"talk_hello"));
258 ASSERT_FALSE(talk_bb->getAnyLocked(
"talk_bye"));
259 ASSERT_FALSE(talk_bb->getAnyLocked(
"talk_out"));
262 std::string
FilePath(
const std::filesystem::path& relative_path)
265 static const std::filesystem::path search_paths[] = {
267 std::filesystem::current_path() /
"tests"};
270 for(
auto const& path : search_paths)
272 if(std::filesystem::exists(path / relative_path))
274 return (path / relative_path).string();
285 std::string path =
FilePath(
"trees/parent_no_include.xml");
295 std::string path =
FilePath(
"trees/child/child_include_sibling.xml");
305 std::string path =
FilePath(
"trees/parent_include_child.xml");
312 CreateTreeFromFileWhichIncludesFileFromChildDirectoryWhichIncludesFileFromSameDirectory)
317 std::string path =
FilePath(
"trees/parent_include_child_include_sibling.xml");
324 CreateTreeFromFileWhichIncludesFileFromChildDirectoryWhichIncludesFileFromChildDirectory)
329 std::string path =
FilePath(
"trees/parent_include_child_include_child.xml");
336 CreateTreeFromFileWhichIncludesFileFromChildDirectoryWhichIncludesFileFromParentDirectory)
341 std::string path =
FilePath(
"trees/parent_include_child_include_parent.xml");
348 const char* xmlA = R
"(
349 <root BTCPP_format="4" >
350 <BehaviorTree ID="MainTree">
358 EXPECT_ANY_THROW(auto tree = factory.
createTree(
"Wrong Name"));
361 TEST(BehaviorTreeReload, ReloadSameTree)
363 const char* xmlA = R
"(
364 <root BTCPP_format="4" >
365 <BehaviorTree ID="MainTree">
370 const char* xmlB = R
"(
371 <root BTCPP_format="4" >
372 <BehaviorTree ID="MainTree">
395 std::make_pair<std::string, std::string>(
"foo",
"hello"),
396 std::make_pair<std::string, std::string>(
"bar",
"42"),
425 const char* expectedXML = R
"(
426 <Action ID="ActionWithMetadata">
428 <Metadata foo="hello"/>
439 std::cout << xml << std::endl;
441 EXPECT_NE(xml.find(expectedXML), std::string::npos);
448 const auto& initial_manifest = factory.
manifests().at(
"SaySomething");
449 EXPECT_TRUE(initial_manifest.metadata.empty());
451 const auto& modified_manifest = factory.
manifests().at(
"SaySomething");