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");
134 auto subtree =
dynamic_cast<const SubtreeNode*
>(root_selector->child(0));
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) );
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
std::vector< Blackboard::Ptr > blackboard_stack
static const char * xml_text_subtree
TreeNode * rootNode() const
void RegisterNodes(BT::BehaviorTreeFactory &factory)
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
void printTreeRecursively(const TreeNode *root_node, std::ostream &stream=std::cout)
The SubtreeNode is a way to wrap an entire Subtree, creating a separated BlackBoard. If you want to have data flow through ports, you need to explicitly remap the ports.
The InverterNode returns SUCCESS if child fails of FAILURE is child succeeds. RUNNING status is propa...
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
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
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...