gtest_sequence.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2015-2017 Michele Colledanchise - All Rights Reserved
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
4 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
5 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
10 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include <gtest/gtest.h>
14 #include "action_test_node.h"
15 #include "condition_test_node.h"
17 
18 using BT::NodeStatus;
19 
20 struct SimpleSequenceTest : testing::Test
21 {
25 
26  SimpleSequenceTest() : root("root_sequence"), action("action"), condition("condition")
27  {
28  root.addChild(&condition);
29  root.addChild(&action);
30  }
32  {
33  haltAllActions(&root);
34  }
35 };
36 
37 struct ComplexSequenceTest : testing::Test
38 {
43 
45 
47  : root("root_sequence")
48  , action_1("action_1")
49  , condition_1("condition_1")
50  , condition_2("condition_2")
51  , seq_conditions("sequence_conditions")
52  {
53  root.addChild(&seq_conditions);
54  {
55  seq_conditions.addChild(&condition_1);
56  seq_conditions.addChild(&condition_2);
57  }
58  root.addChild(&action_1);
59  }
61  {
62  haltAllActions(&root);
63  }
64 };
65 
66 struct SequenceTripleActionTest : testing::Test
67 {
73 
75  : root("root_sequence")
76  , condition("condition")
77  , action_1("action_1")
78  , action_2("action_2")
79  , action_3("action_3")
80  {
81  root.addChild(&condition);
82  root.addChild(&action_1);
83  root.addChild(&action_2);
84  root.addChild(&action_3);
85  }
87  {
88  haltAllActions(&root);
89  }
90 };
91 
92 struct ComplexSequence2ActionsTest : testing::Test
93 {
99 
102 
104  : root("root_sequence")
105  , action_1("action_1")
106  , action_2("action_2")
107  , seq_1("sequence_1")
108  , seq_2("sequence_2")
109  , condition_1("condition_1")
110  , condition_2("condition_2")
111  {
112  root.addChild(&seq_1);
113  {
114  seq_1.addChild(&condition_1);
115  seq_1.addChild(&action_1);
116  }
117  root.addChild(&seq_2);
118  {
119  seq_2.addChild(&condition_2);
120  seq_2.addChild(&action_2);
121  }
122  }
124  {
125  haltAllActions(&root);
126  }
127 };
128 
129 struct SimpleSequenceWithMemoryTest : testing::Test
130 {
134 
135  SimpleSequenceWithMemoryTest() : root("root_sequence"), action("action"), condition("condition")
136  {
137  root.addChild(&condition);
138  root.addChild(&action);
139  }
141  {
142  haltAllActions(&root);
143  }
144 };
145 
146 struct ComplexSequenceWithMemoryTest : testing::Test
147 {
149 
152 
155 
158 
160  : root("root_sequence")
161  , action_1("action_1")
162  , action_2("action_2")
163  , condition_1("condition_1")
164  , condition_2("condition_2")
165  , seq_conditions("sequence_conditions")
166  , seq_actions("sequence_actions")
167  {
168  root.addChild(&seq_conditions);
169  {
170  seq_conditions.addChild(&condition_1);
171  seq_conditions.addChild(&condition_2);
172  }
173  root.addChild(&seq_actions);
174  {
175  seq_actions.addChild(&action_1);
176  seq_actions.addChild(&action_2);
177  }
178  }
180  {
181  haltAllActions(&root);
182  }
183 };
184 
185 struct SimpleParallelTest : testing::Test
186 {
188  BT::AsyncActionTest action_1;
189  BT::ConditionTestNode condition_1;
190 
191  BT::AsyncActionTest action_2;
192  BT::ConditionTestNode condition_2;
193 
195  : root("root_parallel", 4)
196  , action_1("action_1")
197  , condition_1("condition_1")
198  , action_2("action_2")
199  , condition_2("condition_2")
200  {
201  root.addChild(&condition_1);
202  root.addChild(&action_1);
203  root.addChild(&condition_2);
204  root.addChild(&action_2);
205  }
207  {
208  haltAllActions(&root);
209  }
210 };
211 
212 /****************TESTS START HERE***************************/
213 
214 TEST_F(SimpleSequenceTest, ConditionTrue)
215 {
216  std::cout << "Ticking the root node !" << std::endl << std::endl;
217  // Ticking the root node
218  BT::NodeStatus state = root.executeTick();
219 
220  ASSERT_EQ(NodeStatus::RUNNING, action.status());
221  ASSERT_EQ(NodeStatus::RUNNING, state);
222 }
223 
224 TEST_F(SimpleSequenceTest, ConditionTurnToFalse)
225 {
226  BT::NodeStatus state = root.executeTick();
227  condition.setBoolean(false);
228 
229  state = root.executeTick();
230  ASSERT_EQ(NodeStatus::FAILURE, state);
231  ASSERT_EQ(NodeStatus::IDLE, condition.status());
232  ASSERT_EQ(NodeStatus::IDLE, action.status());
233 }
234 
235 TEST_F(ComplexSequenceTest, ComplexSequenceConditionsTrue)
236 {
237  BT::NodeStatus state = root.executeTick();
238 
239  ASSERT_EQ(NodeStatus::RUNNING, state);
240  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
241  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
242  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
243  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
244 }
245 
247 {
248  using namespace BT;
249  using namespace std::chrono;
250  const auto timeout = system_clock::now() + milliseconds(650);
251 
252  action_1.setTime(3);
253  action_3.setTime(3);
254  // the sequence is supposed to finish in (300 ms * 2) = 600 ms
255 
256  // first tick
257  NodeStatus state = root.executeTick();
258 
259  ASSERT_EQ(NodeStatus::RUNNING, state);
260  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
261  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
262  ASSERT_EQ(NodeStatus::IDLE, action_3.status());
263 
264  // continue until succesfull
265  while (state != NodeStatus::SUCCESS && system_clock::now() < timeout)
266  {
267  std::this_thread::sleep_for(milliseconds(20));
268  state = root.executeTick();
269  }
270 
271  ASSERT_EQ(NodeStatus::SUCCESS, state);
272 
273  // Condition is called many times
274  ASSERT_NE(condition.tickCount(), 30);
275  // all the actions are called only once
276  ASSERT_EQ(action_1.tickCount(), 1);
277  ASSERT_EQ(action_2.tickCount(), 1);
278  ASSERT_EQ(action_3.tickCount(), 1);
279 
280  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
281  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
282  ASSERT_EQ(NodeStatus::IDLE, action_3.status());
283  ASSERT_TRUE(system_clock::now() < timeout); // no timeout should occur
284 }
285 
287 {
288  BT::NodeStatus state = root.executeTick();
289 
290  state = root.executeTick();
291 
292  ASSERT_EQ(NodeStatus::RUNNING, state);
293  ASSERT_EQ(NodeStatus::RUNNING, seq_1.status());
294  ASSERT_EQ(NodeStatus::SUCCESS, condition_1.status());
295  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
296  ASSERT_EQ(NodeStatus::IDLE, seq_2.status());
297  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
298  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
299 
300  std::this_thread::sleep_for(std::chrono::milliseconds(500));
301  state = root.executeTick();
302 
303  ASSERT_EQ(NodeStatus::RUNNING, state);
304  ASSERT_EQ(NodeStatus::SUCCESS, seq_1.status());
305  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
306  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
307  ASSERT_EQ(NodeStatus::RUNNING, seq_2.status());
308  ASSERT_EQ(NodeStatus::SUCCESS, condition_2.status());
309  ASSERT_EQ(NodeStatus::RUNNING, action_2.status());
310 
311  state = root.executeTick();
312 }
313 
314 TEST_F(ComplexSequenceTest, ComplexSequenceConditions1ToFalse)
315 {
316  BT::NodeStatus state = root.executeTick();
317 
318  condition_1.setBoolean(false);
319 
320  state = root.executeTick();
321 
322  ASSERT_EQ(NodeStatus::FAILURE, state);
323  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
324  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
325  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
326  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
327 }
328 
329 TEST_F(ComplexSequenceTest, ComplexSequenceConditions2ToFalse)
330 {
331  BT::NodeStatus state = root.executeTick();
332 
333  condition_2.setBoolean(false);
334 
335  state = root.executeTick();
336 
337  ASSERT_EQ(NodeStatus::FAILURE, state);
338  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
339  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
340  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
341  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
342 }
343 
345 {
346  BT::NodeStatus state = root.executeTick();
347  std::this_thread::sleep_for(std::chrono::milliseconds(100));
348 
349  ASSERT_EQ(NodeStatus::RUNNING, state);
350  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
351  ASSERT_EQ(NodeStatus::RUNNING, action.status());
352 }
353 
354 TEST_F(SimpleSequenceWithMemoryTest, ConditionTurnToFalse)
355 {
356  BT::NodeStatus state = root.executeTick();
357 
358  ASSERT_EQ(NodeStatus::RUNNING, state);
359  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
360  ASSERT_EQ(NodeStatus::RUNNING, action.status());
361 
362  condition.setBoolean(false);
363  state = root.executeTick();
364 
365  ASSERT_EQ(NodeStatus::RUNNING, state);
366  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
367  ASSERT_EQ(NodeStatus::RUNNING, action.status());
368 }
369 
371 {
372  BT::NodeStatus state = root.executeTick();
373 
374  ASSERT_EQ(NodeStatus::RUNNING, state);
375  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
376  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
377  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
378  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
379  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
380  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
381 }
382 
384 {
385  BT::NodeStatus state = root.executeTick();
386 
387  condition_1.setBoolean(false);
388  state = root.executeTick();
389  // change in condition_1 does not affect the state of the tree,
390  // since the seq_conditions was executed already
391  ASSERT_EQ(NodeStatus::RUNNING, state);
392  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
393  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
394  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
395  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
396  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
397  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
398 }
399 
401 {
402  BT::NodeStatus state = root.executeTick();
403 
404  condition_2.setBoolean(false);
405  state = root.executeTick();
406  // change in condition_2 does not affect the state of the tree,
407  // since the seq_conditions was executed already
408  ASSERT_EQ(NodeStatus::RUNNING, state);
409  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
410  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
411  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
412  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
413  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
414  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
415 }
416 
418 {
419  root.executeTick();
420 
421  condition_2.setBoolean(false);
422  root.executeTick();
423 
424  // change in condition_2 does not affect the state of the tree,
425  // since the seq_conditions was executed already
426  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
427  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
428  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
429  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
430  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
431  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
432 
433  std::this_thread::sleep_for(std::chrono::milliseconds(400));
434  root.executeTick();
435 
436  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
437  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
438  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
439  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
440  ASSERT_EQ(NodeStatus::SUCCESS, action_1.status());
441  ASSERT_EQ(NodeStatus::RUNNING, action_2.status());
442 
443  std::this_thread::sleep_for(std::chrono::milliseconds(400));
444  root.executeTick();
445 
446  ASSERT_EQ(NodeStatus::SUCCESS, root.status());
447  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
448  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
449  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
450  ASSERT_EQ(NodeStatus::IDLE, seq_actions.status());
451  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
452  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
453 }
BT::ConditionTestNode condition_1
BT::AsyncActionTest action_2
The SequenceStarNode is used to execute a sequence of children. If any child returns RUNNING...
BT::ConditionTestNode condition_1
BT::ConditionTestNode condition_2
BT::SequenceNode root
BT::SequenceStarNode seq_conditions
BT::ConditionTestNode condition_1
TEST_F(SimpleSequenceTest, ConditionTrue)
BT::AsyncActionTest action_1
void setBoolean(bool boolean_value)
BT::ConditionTestNode condition_2
BT::AsyncActionTest action
BT::AsyncActionTest action_1
void haltAllActions(TreeNode *root_node)
BT::ConditionTestNode condition
BT::SequenceStarNode seq_actions
BT::SyncActionTest action_2
BT::ConditionTestNode condition_2
BT::AsyncActionTest action_3
void addChild(TreeNode *child)
BT::SequenceNode seq_conditions
BT::ConditionTestNode condition
BT::ConditionTestNode condition
NodeStatus status() const
Definition: tree_node.cpp:75
BT::AsyncActionTest action_1
NodeStatus
Definition: basic_types.h:28
BT::SequenceNode root
virtual BT::NodeStatus executeTick()
The method that will be executed to invoke tick(); and setStatus();.
Definition: tree_node.cpp:35
The SequenceNode is used to execute a sequence of children. If any child returns RUNNING, previous children will be ticked again.
Definition: sequence_node.h:34


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 04:01:53