gtest_subtree.cpp
Go to the documentation of this file.
1 #include <gtest/gtest.h>
3 #include "../sample_nodes/dummy_nodes.h"
4 
5 using namespace BT;
6 
7 TEST(SubTree, SiblingPorts_Issue_72)
8 {
9 
10 static const char* xml_text = R"(
11 
12 <root main_tree_to_execute = "MainTree" >
13 
14  <BehaviorTree ID="MainTree">
15  <Sequence>
16  <SetBlackboard value="hello" output_key="myParam" />
17  <SubTree ID="mySubtree" param="myParam" />
18  <SetBlackboard value="world" output_key="myParam" />
19  <SubTree ID="mySubtree" param="myParam" />
20  </Sequence>
21  </BehaviorTree>
22 
23  <BehaviorTree ID="mySubtree">
24  <SaySomething ID="AlwaysSuccess" message="{param}" />
25  </BehaviorTree>
26 </root> )";
27 
28  BehaviorTreeFactory factory;
29  factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
30 
31  Tree tree = factory.createTreeFromText(xml_text);
32 
33  for( auto& bb: tree.blackboard_stack)
34  {
35  bb->debugMessage();
36  std::cout << "-----" << std::endl;
37  }
38 
39  auto ret = tree.tickRoot();
40 
41  ASSERT_EQ(ret, NodeStatus::SUCCESS );
42  ASSERT_EQ(tree.blackboard_stack.size(), 3 );
43 }
44 
46 {
47 public:
48  CopyPorts(const std::string& name, const BT::NodeConfiguration& config)
49  : BT::SyncActionNode(name, config)
50  {
51  }
52 
53  BT::NodeStatus tick() override
54  {
55  auto msg = getInput<std::string>("in");
56  if (!msg)
57  {
58  throw BT::RuntimeError( "missing required input [message]: ", msg.error() );
59  }
60  setOutput("out", msg.value());
62  }
63 
65  {
66  return{ BT::InputPort<std::string>("in"),
67  BT::OutputPort<std::string>("out")};
68  }
69 };
70 
71 
72 TEST(SubTree, GoodRemapping)
73 {
74  static const char* xml_text = R"(
75 
76 <root main_tree_to_execute = "MainTree" >
77 
78  <BehaviorTree ID="MainTree">
79  <Sequence>
80  <SetBlackboard value="hello" output_key="thoughts" />
81  <SubTree ID="CopySubtree" in_arg="thoughts" out_arg="greetings"/>
82  <SaySomething message="{greetings}" />
83  </Sequence>
84  </BehaviorTree>
85 
86  <BehaviorTree ID="CopySubtree">
87  <CopyPorts in="{in_arg}" out="{out_arg}"/>
88  </BehaviorTree>
89 </root> )";
90 
91  BehaviorTreeFactory factory;
92  factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
93  factory.registerNodeType<CopyPorts>("CopyPorts");
94 
95  Tree tree = factory.createTreeFromText(xml_text);
96  auto ret = tree.tickRoot();
97  ASSERT_EQ(ret, NodeStatus::SUCCESS );
98 }
99 
100 TEST(SubTree, BadRemapping)
101 {
102  BehaviorTreeFactory factory;
103  factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
104  factory.registerNodeType<CopyPorts>("CopyPorts");
105 
106  static const char* xml_text_bad_in = R"(
107 <root main_tree_to_execute = "MainTree" >
108 
109  <BehaviorTree ID="MainTree">
110  <Sequence>
111  <SetBlackboard value="hello" output_key="thoughts" />
112  <SubTree ID="CopySubtree" out_arg="greetings"/>
113  <SaySomething message="{greetings}" />
114  </Sequence>
115  </BehaviorTree>
116 
117  <BehaviorTree ID="CopySubtree">
118  <CopyPorts in="{in_arg}" out="{out_arg}"/>
119  </BehaviorTree>
120 </root> )";
121 
122  Tree tree_bad_in = factory.createTreeFromText(xml_text_bad_in);
123  EXPECT_ANY_THROW( tree_bad_in.tickRoot() );
124 
125  static const char* xml_text_bad_out = R"(
126 <root main_tree_to_execute = "MainTree" >
127 
128  <BehaviorTree ID="MainTree">
129  <Sequence>
130  <SetBlackboard value="hello" output_key="thoughts" />
131  <SubTree ID="CopySubtree" in_arg="thoughts"/>
132  <SaySomething message="{greetings}" />
133  </Sequence>
134  </BehaviorTree>
135 
136  <BehaviorTree ID="CopySubtree">
137  <CopyPorts in="{in_arg}" out="{out_arg}"/>
138  </BehaviorTree>
139 </root> )";
140 
141  Tree tree_bad_out = factory.createTreeFromText(xml_text_bad_out);
142  EXPECT_ANY_THROW( tree_bad_out.tickRoot() );
143 }
144 
145 TEST(SubTree, SubtreePlusA)
146 {
147  static const char* xml_text = R"(
148 
149 <root main_tree_to_execute = "MainTree" >
150 
151  <BehaviorTree ID="MainTree">
152  <Sequence>
153  <SetBlackboard value="Hello" output_key="myParam" />
154  <SubTreePlus ID="mySubtree" param="{myParam}" />
155  <SubTreePlus ID="mySubtree" param="World" />
156  <SetBlackboard value="Auto remapped" output_key="param" />
157  <SubTreePlus ID="mySubtree" __autoremap="1" />
158  </Sequence>
159  </BehaviorTree>
160 
161  <BehaviorTree ID="mySubtree">
162  <SaySomething message="{param}" />
163  </BehaviorTree>
164 </root> )";
165 
166  BehaviorTreeFactory factory;
167  factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
168 
169  Tree tree = factory.createTreeFromText(xml_text);
170  auto ret = tree.tickRoot();
171  ASSERT_EQ(ret, NodeStatus::SUCCESS );
172 }
173 
174 TEST(SubTree, SubtreePlusB)
175 {
176  static const char* xml_text = R"(
177 
178 <root main_tree_to_execute = "MainTree" >
179 
180  <BehaviorTree ID="MainTree">
181  <Sequence>
182  <SetBlackboard value="Hello World" output_key="myParam" />
183  <SetBlackboard value="Auto remapped" output_key="param3" />
184  <SubTreePlus ID="mySubtree" __autoremap="1" param1="{myParam}" param2="Straight Talking" />
185  </Sequence>
186  </BehaviorTree>
187 
188  <BehaviorTree ID="mySubtree">
189  <Sequence>
190  <SaySomething message="{param1}" />
191  <SaySomething message="{param2}" />
192  <SaySomething message="{param3}" />
193  </Sequence>
194  </BehaviorTree>
195 </root> )";
196 
197  BehaviorTreeFactory factory;
198  factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
199 
200  Tree tree = factory.createTreeFromText(xml_text);
201  auto ret = tree.tickRoot();
202  ASSERT_EQ(ret, NodeStatus::SUCCESS );
203 }
204 
205 TEST(SubTree, SubtreePlusC)
206 {
207  static const char* xml_text = R"(
208 
209 <root main_tree_to_execute = "MainTree" >
210 
211  <BehaviorTree ID="MainTree">
212  <Sequence>
213  <SetBlackboard value="Hello" output_key="param1" />
214  <SetBlackboard value="World" output_key="param2" />
215  <SubTree ID="mySubtree" __shared_blackboard="true"/>
216  </Sequence>
217  </BehaviorTree>
218 
219  <BehaviorTree ID="mySubtree">
220  <Sequence>
221  <SaySomething message="{param1}" />
222  <SaySomething message="{param2}" />
223  </Sequence>
224  </BehaviorTree>
225 </root> )";
226 
227  BehaviorTreeFactory factory;
228  factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
229 
230  Tree tree = factory.createTreeFromText(xml_text);
231  auto ret = tree.tickRoot();
232  ASSERT_EQ(ret, NodeStatus::SUCCESS );
233 }
234 
235 
237 {
238  public:
239  ReadInConstructor(const std::string& name, const BT::NodeConfiguration& config)
240  : BT::SyncActionNode(name, config)
241  {
242  auto msg = getInput<std::string>("message");
243  if (!msg) {
244  throw BT::RuntimeError("missing required input [message]: ", msg.error());
245  }
246  }
247 
249  static BT::PortsList providedPorts() { return {BT::InputPort<std::string>("message")}; }
250 };
251 
252 TEST(SubTree, SubtreePlusD)
253 {
254  BT::NodeConfiguration config;
256  static const char* xml_text = R"(
257 
258 <root main_tree_to_execute = "MainTree" >
259 
260  <BehaviorTree ID="MainTree">
261  <Sequence>
262  <SubTreePlus ID="mySubtree" __autoremap="1"/>
263  </Sequence>
264  </BehaviorTree>
265  <BehaviorTree ID="mySubtree">
266  <ReadInConstructor message="{message}" />
267  </BehaviorTree>
268 </root> )";
269 
270  BT::BehaviorTreeFactory factory;
271  factory.registerNodeType<ReadInConstructor>("ReadInConstructor");
272  config.blackboard->set("message", "hello");
273  BT::Tree tree = factory.createTreeFromText(xml_text, config.blackboard);
274  auto ret = tree.tickRoot();
275  ASSERT_EQ(ret, BT::NodeStatus::SUCCESS);
276 }
277 
278 
279 
static Blackboard::Ptr create(Blackboard::Ptr parent={})
Definition: blackboard.h:38
void registerNodeType(const std::string &ID)
Definition: bt_factory.h:290
CopyPorts(const std::string &name, const BT::NodeConfiguration &config)
static BT::PortsList providedPorts()
TEST(SubTree, SiblingPorts_Issue_72)
BT::NodeStatus tick() override
Method to be implemented by the user.
Blackboard::Ptr blackboard
Definition: tree_node.h:47
static BT::PortsList providedPorts()
The SyncActionNode is an ActionNode that explicitly prevents the status RUNNING and doesn&#39;t require a...
Definition: action_node.h:53
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:207
NodeStatus tickRoot()
Definition: bt_factory.h:181
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
Definition: bt_factory.cpp:249
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
Definition: bt_factory.h:130
BT::NodeStatus tick() override
Method to be implemented by the user.
std::unordered_map< std::string, PortInfo > PortsList
Definition: basic_types.h:317
ReadInConstructor(const std::string &name, const BT::NodeConfiguration &config)
static const char * xml_text
NodeStatus
Definition: basic_types.h:35


behaviotree_cpp_v3
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Tue May 4 2021 02:56:24