gtest_factory.cpp
Go to the documentation of this file.
00001 #include <gtest/gtest.h>
00002 #include "action_test_node.h"
00003 #include "condition_test_node.h"
00004 #include "behaviortree_cpp/xml_parsing.h"
00005 #include "../sample_nodes/crossdoor_nodes.h"
00006 #include "../sample_nodes/dummy_nodes.h"
00007 
00008 using namespace BT;
00009 
00010 // clang-format off
00011 
00012 static const char* xml_text = R"(
00013 
00014 <root main_tree_to_execute = "MainTree" >
00015 
00016     <BehaviorTree ID="MainTree">
00017         <Fallback name="root_selector">
00018 
00019             <Sequence name="door_open_sequence">
00020                 <Action ID="IsDoorOpen" />
00021                 <Action ID="PassThroughDoor" />
00022             </Sequence>
00023 
00024             <Sequence name="door_closed_sequence">
00025                 <Decorator ID="Inverter">
00026                      <Action ID="IsDoorOpen" />
00027                 </Decorator>
00028                 <Action ID="OpenDoor" />
00029                 <Action ID="PassThroughDoor" />
00030                 <Action ID="CloseDoor" />
00031             </Sequence>
00032 
00033             <Action ID="PassThroughWindow" />
00034 
00035         </Fallback>
00036     </BehaviorTree>
00037 
00038     <!-- TreeNodesModel is used only by the Graphic interface -->
00039     <TreeNodesModel>
00040         <Action ID="IsDoorOpen" />
00041         <Action ID="PassThroughDoor" />
00042         <Action ID="CloseDoor" />
00043         <Action ID="OpenDoor" />
00044         <Action ID="PassThroughWindow" />
00045     </TreeNodesModel>
00046 </root>
00047         )";
00048 
00049 static const char* xml_text_subtree = R"(
00050 
00051 <root main_tree_to_execute = "MainTree" >
00052 
00053   <BehaviorTree ID="CrossDoorSubtree">
00054     <Sequence name="door_sequence">
00055       <Decorator ID="Inverter">
00056         <Action ID="IsDoorLocked" />
00057       </Decorator>
00058       <Action ID="OpenDoor" />
00059       <Action ID="PassThroughDoor" />
00060       <Action ID="CloseDoor" />
00061     </Sequence>
00062   </BehaviorTree>
00063 
00064   <!-- This tree will include the other one -->
00065   <BehaviorTree ID="MainTree">
00066     <Fallback name="root_selector">
00067       <SubTree ID="CrossDoorSubtree" />
00068       <Action ID="PassThroughWindow" />
00069     </Fallback>
00070   </BehaviorTree>
00071 
00072 </root>  )";
00073 
00074 // clang-format on
00075 
00076 TEST(BehaviorTreeFactory, VerifyLargeTree)
00077 {
00078     BehaviorTreeFactory factory;
00079     CrossDoor::RegisterNodes(factory);
00080 
00081     Tree tree = factory.createTreeFromText(xml_text);
00082 
00083     printTreeRecursively(tree.root_node);
00084 
00085     ASSERT_EQ(tree.root_node->name(), "root_selector");
00086 
00087     auto fallback = dynamic_cast<const FallbackNode*>(tree.root_node);
00088     ASSERT_TRUE(fallback != nullptr);
00089 
00090     ASSERT_EQ(fallback->children().size(), 3);
00091     ASSERT_EQ(fallback->child(0)->name(), "door_open_sequence");
00092     ASSERT_EQ(fallback->child(1)->name(), "door_closed_sequence");
00093     ASSERT_EQ(fallback->child(2)->name(), "PassThroughWindow");
00094 
00095     auto sequence_open = dynamic_cast<const SequenceNode*>(fallback->child(0));
00096     ASSERT_TRUE(sequence_open != nullptr);
00097 
00098     ASSERT_EQ(sequence_open->children().size(), 2);
00099     ASSERT_EQ(sequence_open->child(0)->name(), "IsDoorOpen");
00100     ASSERT_EQ(sequence_open->child(1)->name(), "PassThroughDoor");
00101 
00102     auto sequence_closed = dynamic_cast<const SequenceNode*>(fallback->child(1));
00103     ASSERT_TRUE(sequence_closed != nullptr);
00104 
00105     ASSERT_EQ(sequence_closed->children().size(), 4);
00106     ASSERT_EQ(sequence_closed->child(0)->name(), "Inverter");
00107     ASSERT_EQ(sequence_closed->child(1)->name(), "OpenDoor");
00108     ASSERT_EQ(sequence_closed->child(2)->name(), "PassThroughDoor");
00109     ASSERT_EQ(sequence_closed->child(3)->name(), "CloseDoor");
00110 
00111     auto decorator = dynamic_cast<const InverterNode*>(sequence_closed->child(0));
00112     ASSERT_TRUE(decorator != nullptr);
00113 
00114     ASSERT_EQ(decorator->child()->name(), "IsDoorOpen");
00115 }
00116 
00117 TEST(BehaviorTreeFactory, Subtree)
00118 {
00119     BehaviorTreeFactory factory;
00120     CrossDoor::RegisterNodes(factory);
00121 
00122     Tree tree = factory.createTreeFromText(xml_text_subtree);
00123 
00124     printTreeRecursively(tree.root_node);
00125 
00126     ASSERT_EQ(tree.root_node->name(), "root_selector");
00127 
00128     auto root_selector = dynamic_cast<const FallbackNode*>(tree.root_node);
00129     ASSERT_TRUE(root_selector != nullptr);
00130     ASSERT_EQ(root_selector->children().size(), 2);
00131     ASSERT_EQ(root_selector->child(0)->name(), "CrossDoorSubtree");
00132     ASSERT_EQ(root_selector->child(1)->name(), "PassThroughWindow");
00133 
00134     auto subtree = dynamic_cast<const DecoratorSubtreeNode*>(root_selector->child(0));
00135     ASSERT_TRUE(subtree != nullptr);
00136 
00137     auto sequence = dynamic_cast<const SequenceNode*>(subtree->child());
00138     ASSERT_TRUE(sequence != nullptr);
00139 
00140     ASSERT_EQ(sequence->children().size(), 4);
00141     ASSERT_EQ(sequence->child(0)->name(), "Inverter");
00142     ASSERT_EQ(sequence->child(1)->name(), "OpenDoor");
00143     ASSERT_EQ(sequence->child(2)->name(), "PassThroughDoor");
00144     ASSERT_EQ(sequence->child(3)->name(), "CloseDoor");
00145 
00146     auto decorator = dynamic_cast<const InverterNode*>(sequence->child(0));
00147     ASSERT_TRUE(decorator != nullptr);
00148 
00149     ASSERT_EQ(decorator->child()->name(), "IsDoorLocked");
00150 }
00151 
00152 TEST(BehaviorTreeFactory, Issue7)
00153 {
00154 const std::string xml_text_issue = R"(
00155 <root>
00156     <BehaviorTree ID="ReceiveGuest">
00157     </BehaviorTree>
00158 </root> )";
00159 
00160     BehaviorTreeFactory factory;
00161     XMLParser parser(factory);
00162 
00163     EXPECT_THROW( parser.loadFromText(xml_text_issue), RuntimeError );
00164 }
00165 
00166 
00167 // clang-format off
00168 
00169 static const char* xml_ports_subtree = R"(
00170 
00171 <root main_tree_to_execute = "MainTree" >
00172 
00173   <BehaviorTree ID="TalkToMe">
00174     <Sequence>
00175       <SaySomething message="{hello_msg}" />
00176       <SaySomething message="{bye_msg}" />
00177       <SetBlackboard output_key="output" value="done!" />
00178     </Sequence>
00179   </BehaviorTree>
00180 
00181   <BehaviorTree ID="MainTree">
00182     <Sequence>
00183       <SetBlackboard output_key="talk_hello" value="hello" />
00184       <SetBlackboard output_key="talk_bye"   value="bye bye" />
00185       <SubTree ID="TalkToMe" hello_msg="talk_hello"
00186                              bye_msg="talk_bye"
00187                              output="talk_out" />
00188       <SaySomething message="{talk_out}" />
00189     </Sequence>
00190   </BehaviorTree>
00191 
00192 </root> )";
00193 
00194 // clang-format on
00195 
00196 TEST(BehaviorTreeFactory, SubTreeWithRemapping)
00197 {
00198     BehaviorTreeFactory factory;
00199     factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
00200 
00201     Tree tree = factory.createTreeFromText(xml_ports_subtree);
00202 
00203     auto main_bb = tree.blackboard_stack.at(0);
00204     auto talk_bb = tree.blackboard_stack.at(1);
00205 
00206     std::cout << "\n --------------------------------- \n" << std::endl;
00207     main_bb->debugMessage();
00208     std::cout << "\n ----- \n" << std::endl;
00209     talk_bb->debugMessage();
00210     std::cout << "\n --------------------------------- \n" << std::endl;
00211 
00212     ASSERT_EQ( main_bb->portInfo("talk_hello")->type(), &typeid(std::string) );
00213     ASSERT_EQ( main_bb->portInfo("talk_bye")->type(),   &typeid(std::string) );
00214     ASSERT_EQ( main_bb->portInfo("talk_out")->type(),   &typeid(std::string) );
00215 
00216     ASSERT_EQ( talk_bb->portInfo("bye_msg")->type(),   &typeid(std::string) );
00217     ASSERT_EQ( talk_bb->portInfo("hello_msg")->type(), &typeid(std::string) );
00218 
00219     // Should not throw
00220     tree.root_node->executeTick();
00221 
00222     std::cout << "\n --------------------------------- \n" << std::endl;
00223     main_bb->debugMessage();
00224     std::cout << "\n ----- \n" << std::endl;
00225     talk_bb->debugMessage();
00226     std::cout << "\n --------------------------------- \n" << std::endl;
00227 
00228     ASSERT_EQ( main_bb->portInfo("talk_hello")->type(), &typeid(std::string) );
00229     ASSERT_EQ( main_bb->portInfo("talk_bye")->type(),   &typeid(std::string) );
00230     ASSERT_EQ( main_bb->portInfo("talk_out")->type(),   &typeid(std::string) );
00231 
00232     ASSERT_EQ( talk_bb->portInfo("bye_msg")->type(),   &typeid(std::string) );
00233     ASSERT_EQ( talk_bb->portInfo("hello_msg")->type(), &typeid(std::string) );
00234     ASSERT_EQ( talk_bb->portInfo("output")->type(),    &typeid(std::string) );
00235 
00236 
00237     ASSERT_EQ( main_bb->get<std::string>("talk_hello"), "hello");
00238     ASSERT_EQ( main_bb->get<std::string>("talk_bye"), "bye bye");
00239     ASSERT_EQ( main_bb->get<std::string>("talk_out"), "done!");
00240 
00241     // these ports should not be present in the subtree TalkToMe
00242     ASSERT_FALSE( talk_bb->getAny("talk_hello") );
00243     ASSERT_FALSE( talk_bb->getAny("talk_bye") );
00244     ASSERT_FALSE( talk_bb->getAny("talk_out") );
00245 }
00246 


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 20:17:15