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 #include "test_helper.hpp"
18 
19 using BT::NodeStatus;
20 using std::chrono::milliseconds;
21 
22 struct SimpleSequenceTest : testing::Test
23 {
27 
29  : root("root_sequence"), condition("condition"), action("action", milliseconds(100))
30  {
33  }
35  {}
36 };
37 
38 struct ComplexSequenceTest : testing::Test
39 {
44 
46 
48  : root("root")
49  , action_1("action_1", milliseconds(100))
50  , condition_1("condition_1")
51  , condition_2("condition_2")
52  , seq_conditions("sequence_conditions")
53  {
55  {
58  }
60  }
62  {}
63 };
64 
65 struct SequenceTripleActionTest : testing::Test
66 {
72 
74  : root("root_sequence")
75  , condition("condition")
76  , action_1("action_1", milliseconds(100))
77  , action_2("action_2")
78  , action_3("action_3", milliseconds(100))
79  {
84  }
86  {}
87 };
88 
89 struct ComplexSequence2ActionsTest : testing::Test
90 {
96 
99 
101  : root("root_sequence")
102  , action_1("action_1", milliseconds(100))
103  , action_2("action_2", milliseconds(100))
104  , seq_1("sequence_1")
105  , seq_2("sequence_2")
106  , condition_1("condition_1")
107  , condition_2("condition_2")
108  {
109  root.addChild(&seq_1);
110  {
113  }
114  root.addChild(&seq_2);
115  {
118  }
119  }
121  {}
122 };
123 
124 struct SimpleSequenceWithMemoryTest : testing::Test
125 {
129 
131  : root("root_sequence"), action("action", milliseconds(100)), condition("condition")
132  {
134  root.addChild(&action);
135  }
137  {}
138 };
139 
140 struct ComplexSequenceWithMemoryTest : testing::Test
141 {
143 
146 
149 
152 
154  : root("root_sequence")
155  , action_1("action_1", milliseconds(100))
156  , action_2("action_2", milliseconds(100))
157  , condition_1("condition_1")
158  , condition_2("condition_2")
159  , seq_conditions("sequence_conditions")
160  , seq_actions("sequence_actions")
161  {
163  {
166  }
168  {
171  }
172  }
174  {}
175 };
176 
177 struct SimpleParallelTest : testing::Test
178 {
182 
185 
187  : root("root_parallel")
188  , action_1("action_1", milliseconds(100))
189  , condition_1("condition_1")
190  , action_2("action_2", milliseconds(100))
191  , condition_2("condition_2")
192  {
198  }
200  {}
201 };
202 
203 /****************TESTS START HERE***************************/
204 
205 TEST_F(SimpleSequenceTest, ConditionTrue)
206 {
207  std::cout << "Ticking the root node !" << std::endl << std::endl;
208  // Ticking the root node
209  BT::NodeStatus state = root.executeTick();
210 
211  ASSERT_EQ(NodeStatus::RUNNING, action.status());
212  ASSERT_EQ(NodeStatus::RUNNING, state);
213 }
214 
215 TEST_F(SimpleSequenceTest, ConditionTurnToFalse)
216 {
217  condition.setExpectedResult(NodeStatus::FAILURE);
218  BT::NodeStatus state = root.executeTick();
219 
220  state = root.executeTick();
221  ASSERT_EQ(NodeStatus::FAILURE, state);
222  ASSERT_EQ(NodeStatus::IDLE, condition.status());
223  ASSERT_EQ(NodeStatus::IDLE, action.status());
224 }
225 
226 TEST_F(ComplexSequenceTest, ComplexSequenceConditionsTrue)
227 {
228  BT::NodeStatus state = root.executeTick();
229 
230  ASSERT_EQ(NodeStatus::RUNNING, state);
231  // reactive node already reset seq_conditions
232  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
233  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
234  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
235  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
236 }
237 
239 {
240  using namespace BT;
241  using namespace std::chrono;
242 
243 #ifdef WIN32
244  const int margin_msec = 60;
245 #else
246  const int margin_msec = 20;
247 #endif
248 
249  const auto timeout = system_clock::now() + milliseconds(600 + margin_msec);
250 
251  action_1.setTime(milliseconds(300));
252  action_3.setTime(milliseconds(300));
253  // the sequence is supposed to finish in (300 ms * 2) = 600 ms
254 
255  // first tick
256  NodeStatus state = root.executeTick();
257 
258  ASSERT_EQ(NodeStatus::RUNNING, state);
259  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
260  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
261  ASSERT_EQ(NodeStatus::IDLE, action_3.status());
262 
263  // continue until successful
264  while(state != NodeStatus::SUCCESS && system_clock::now() < timeout)
265  {
266  std::this_thread::sleep_for(milliseconds(1));
267  state = root.executeTick();
268  }
269 
270  ASSERT_EQ(NodeStatus::SUCCESS, state);
271 
272  // Condition is called only once
273  ASSERT_EQ(condition.tickCount(), 1);
274  // all the actions are called only once
275  ASSERT_EQ(action_1.tickCount(), 1);
276  ASSERT_EQ(action_2.tickCount(), 1);
277  ASSERT_EQ(action_3.tickCount(), 1);
278 
279  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
280  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
281  ASSERT_EQ(NodeStatus::IDLE, action_3.status());
282  ASSERT_TRUE(system_clock::now() < timeout); // no timeout should occur
283 }
284 
286 {
287  BT::NodeStatus state = root.executeTick();
288 
289  state = root.executeTick();
290 
291  ASSERT_EQ(NodeStatus::RUNNING, state);
292  ASSERT_EQ(NodeStatus::RUNNING, seq_1.status());
293  ASSERT_EQ(NodeStatus::SUCCESS, condition_1.status());
294  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
295  ASSERT_EQ(NodeStatus::IDLE, seq_2.status());
296  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
297  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
298 
299  std::this_thread::sleep_for(milliseconds(300));
300  state = root.executeTick();
301 
302  ASSERT_EQ(NodeStatus::RUNNING, state);
303  ASSERT_EQ(NodeStatus::SUCCESS, seq_1.status());
304  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
305  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
306  ASSERT_EQ(NodeStatus::RUNNING, seq_2.status());
307  ASSERT_EQ(NodeStatus::SUCCESS, condition_2.status());
308  ASSERT_EQ(NodeStatus::RUNNING, action_2.status());
309 
310  state = root.executeTick();
311 }
312 
313 TEST_F(ComplexSequenceTest, ComplexSequenceConditions1ToFalse)
314 {
315  BT::NodeStatus state = root.executeTick();
316 
317  condition_1.setExpectedResult(NodeStatus::FAILURE);
318 
319  state = root.executeTick();
320 
321  ASSERT_EQ(NodeStatus::FAILURE, state);
322  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
323  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
324  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
325  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
326 }
327 
328 TEST_F(ComplexSequenceTest, ComplexSequenceConditions2ToFalse)
329 {
330  BT::NodeStatus state = root.executeTick();
331 
332  condition_2.setExpectedResult(NodeStatus::FAILURE);
333 
334  state = root.executeTick();
335 
336  ASSERT_EQ(NodeStatus::FAILURE, state);
337  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
338  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
339  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
340  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
341 }
342 
344 {
345  BT::NodeStatus state = root.executeTick();
346  std::this_thread::sleep_for(milliseconds(50));
347 
348  ASSERT_EQ(NodeStatus::RUNNING, state);
349  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
350  ASSERT_EQ(NodeStatus::RUNNING, action.status());
351 }
352 
353 TEST_F(SimpleSequenceWithMemoryTest, ConditionTurnToFalse)
354 {
355  BT::NodeStatus state = root.executeTick();
356 
357  ASSERT_EQ(NodeStatus::RUNNING, state);
358  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
359  ASSERT_EQ(NodeStatus::RUNNING, action.status());
360 
361  condition.setExpectedResult(NodeStatus::FAILURE);
362  state = root.executeTick();
363 
364  ASSERT_EQ(NodeStatus::RUNNING, state);
365  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
366  ASSERT_EQ(NodeStatus::RUNNING, action.status());
367 }
368 
370 {
371  BT::NodeStatus state = root.executeTick();
372 
373  ASSERT_EQ(NodeStatus::RUNNING, state);
374  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
375  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
376  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
377  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
378  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
379  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
380 }
381 
383 {
384  BT::NodeStatus state = root.executeTick();
385 
386  condition_1.setExpectedResult(NodeStatus::FAILURE);
387  state = root.executeTick();
388  // change in condition_1 does not affect the state of the tree,
389  // since the seq_conditions was executed already
390  ASSERT_EQ(NodeStatus::RUNNING, state);
391  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
392  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
393  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
394  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
395  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
396  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
397 }
398 
399 TEST(SequenceWithMemoryTest, Issue_636)
400 {
401  static const char* xml_text = R"(
402 
403 <root BTCPP_format="4" main_tree_to_execute="MainTree" >
404 
405  <BehaviorTree ID="MainTree">
406  <SequenceWithMemory>
407  <Script code = " var := 0 " />
408  <TestA/>
409  <ScriptCondition code = "var+=1; var >= 5" />
410  <TestB/>
411  <TestC/>
412  </SequenceWithMemory>
413  </BehaviorTree>
414 </root> )";
415 
416  BT::BehaviorTreeFactory factory;
417 
418  std::array<int, 3> counters;
419  RegisterTestTick(factory, "Test", counters);
420 
421  auto tree = factory.createTreeFromText(xml_text);
422 
423  auto res = tree.tickOnce();
424  int tick_count = 1;
425 
426  while(res != BT::NodeStatus::SUCCESS)
427  {
428  res = tree.tickOnce();
429  tick_count++;
430  }
431 
432  ASSERT_EQ(1, counters[0]);
433  ASSERT_EQ(1, counters[1]);
434  ASSERT_EQ(1, counters[2]);
435 
436  ASSERT_EQ(5, tick_count);
437 }
BT
Definition: ex01_wrap_legacy.cpp:29
SimpleSequenceTest::SimpleSequenceTest
SimpleSequenceTest()
Definition: gtest_sequence.cpp:28
ComplexSequenceTest::seq_conditions
BT::SequenceNode seq_conditions
Definition: gtest_sequence.cpp:45
ComplexSequence2ActionsTest::seq_2
BT::SequenceNode seq_2
Definition: gtest_sequence.cpp:95
ComplexSequenceWithMemoryTest::condition_2
BT::ConditionTestNode condition_2
Definition: gtest_sequence.cpp:148
SimpleParallelTest::SimpleParallelTest
SimpleParallelTest()
Definition: gtest_sequence.cpp:186
SimpleSequenceWithMemoryTest::~SimpleSequenceWithMemoryTest
~SimpleSequenceWithMemoryTest() override
Definition: gtest_sequence.cpp:136
ComplexSequence2ActionsTest
Definition: gtest_sequence.cpp:89
SimpleParallelTest::condition_1
BT::ConditionTestNode condition_1
Definition: gtest_parallel.cpp:28
SimpleParallelTest::action_2
BT::AsyncActionTest action_2
Definition: gtest_parallel.cpp:30
TEST_F
TEST_F(SimpleSequenceTest, ConditionTrue)
Definition: gtest_sequence.cpp:205
ComplexSequenceTest::~ComplexSequenceTest
~ComplexSequenceTest() override
Definition: gtest_sequence.cpp:61
SequenceTripleActionTest::action_3
BT::AsyncActionTest action_3
Definition: gtest_sequence.cpp:71
RegisterTestTick
void RegisterTestTick(BT::BehaviorTreeFactory &factory, const std::string &name_prefix, std::array< int, N > &tick_counters)
Definition: test_helper.hpp:15
BT::ParallelNode
The ParallelNode execute all its children concurrently, but not in separate threads!
Definition: parallel_node.h:40
ComplexSequenceWithMemoryTest::condition_1
BT::ConditionTestNode condition_1
Definition: gtest_sequence.cpp:147
ComplexSequence2ActionsTest::action_1
BT::AsyncActionTest action_1
Definition: gtest_sequence.cpp:92
SimpleSequenceWithMemoryTest::SimpleSequenceWithMemoryTest
SimpleSequenceWithMemoryTest()
Definition: gtest_sequence.cpp:130
BT::Tree::tickOnce
NodeStatus tickOnce()
by default, tickOnce() sends a single tick, BUT as long as there is at least one node of the tree inv...
Definition: bt_factory.cpp:604
bt_factory.h
SimpleSequenceWithMemoryTest
Definition: gtest_sequence.cpp:124
BT::AsyncActionTest
Definition: action_test_node.h:32
SimpleSequenceTest::action
BT::AsyncActionTest action
Definition: gtest_sequence.cpp:26
ComplexSequenceWithMemoryTest::~ComplexSequenceWithMemoryTest
~ComplexSequenceWithMemoryTest() override
Definition: gtest_sequence.cpp:173
ComplexSequenceWithMemoryTest::ComplexSequenceWithMemoryTest
ComplexSequenceWithMemoryTest()
Definition: gtest_sequence.cpp:153
SimpleSequenceTest::condition
BT::ConditionTestNode condition
Definition: gtest_sequence.cpp:25
ComplexSequence2ActionsTest::condition_1
BT::ConditionTestNode condition_1
Definition: gtest_sequence.cpp:97
ComplexSequenceTest
Definition: gtest_sequence.cpp:38
BT::SyncActionTest
Definition: action_test_node.h:8
ComplexSequence2ActionsTest::root
BT::SequenceNode root
Definition: gtest_sequence.cpp:91
test_helper.hpp
ComplexSequenceWithMemoryTest
Definition: gtest_sequence.cpp:140
SimpleSequenceWithMemoryTest::root
BT::SequenceWithMemory root
Definition: gtest_sequence.cpp:126
ComplexSequenceWithMemoryTest::seq_conditions
BT::SequenceWithMemory seq_conditions
Definition: gtest_sequence.cpp:150
ComplexSequenceTest::root
BT::ReactiveSequence root
Definition: gtest_sequence.cpp:40
condition_test_node.h
ComplexSequence2ActionsTest::action_2
BT::AsyncActionTest action_2
Definition: gtest_sequence.cpp:93
BT::NodeStatus::FAILURE
@ FAILURE
SimpleSequenceTest
Definition: gtest_sequence.cpp:22
ComplexSequenceWithMemoryTest::action_1
BT::AsyncActionTest action_1
Definition: gtest_sequence.cpp:144
TEST
TEST(SequenceWithMemoryTest, Issue_636)
Definition: gtest_sequence.cpp:399
BT::BehaviorTreeFactory::createTreeFromText
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
createTreeFromText will parse the XML directly from string. The XML needs to contain either a single ...
Definition: bt_factory.cpp:395
SimpleSequenceWithMemoryTest::action
BT::AsyncActionTest action
Definition: gtest_sequence.cpp:127
SimpleParallelTest
Definition: gtest_parallel.cpp:24
ComplexSequenceWithMemoryTest::root
BT::SequenceWithMemory root
Definition: gtest_sequence.cpp:142
SimpleParallelTest::condition_2
BT::ConditionTestNode condition_2
Definition: gtest_parallel.cpp:31
SequenceTripleActionTest::action_2
BT::SyncActionTest action_2
Definition: gtest_sequence.cpp:70
SequenceTripleActionTest::action_1
BT::AsyncActionTest action_1
Definition: gtest_sequence.cpp:69
SimpleSequenceTest::~SimpleSequenceTest
~SimpleSequenceTest() override
Definition: gtest_sequence.cpp:34
SimpleSequenceTest::root
BT::SequenceNode root
Definition: gtest_sequence.cpp:24
BT::BehaviorTreeFactory
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:205
ComplexSequence2ActionsTest::~ComplexSequence2ActionsTest
~ComplexSequence2ActionsTest() override
Definition: gtest_sequence.cpp:120
BT::NodeStatus::SUCCESS
@ SUCCESS
ComplexSequenceTest::condition_2
BT::ConditionTestNode condition_2
Definition: gtest_sequence.cpp:43
BT::NodeStatus::RUNNING
@ RUNNING
ComplexSequence2ActionsTest::seq_1
BT::SequenceNode seq_1
Definition: gtest_sequence.cpp:94
SequenceTripleActionTest::SequenceTripleActionTest
SequenceTripleActionTest()
Definition: gtest_sequence.cpp:73
BT::SequenceWithMemory
The SequenceWithMemory is used to tick children in an ordered sequence. If any child returns RUNNING,...
Definition: sequence_with_memory_node.h:34
SimpleSequenceWithMemoryTest::condition
BT::ConditionTestNode condition
Definition: gtest_sequence.cpp:128
ComplexSequence2ActionsTest::condition_2
BT::ConditionTestNode condition_2
Definition: gtest_sequence.cpp:98
ComplexSequenceTest::ComplexSequenceTest
ComplexSequenceTest()
Definition: gtest_sequence.cpp:47
BT::ReactiveSequence
The ReactiveSequence is similar to a ParallelNode. All the children are ticked from first to last:
Definition: reactive_sequence.h:33
SequenceTripleActionTest::root
BT::SequenceNode root
Definition: gtest_sequence.cpp:67
action_test_node.h
BT::NodeStatus::IDLE
@ IDLE
SequenceTripleActionTest
Definition: gtest_sequence.cpp:65
BT::SequenceNode
The SequenceNode is used to tick children in an ordered sequence. If any child returns RUNNING,...
Definition: sequence_node.h:34
SimpleParallelTest::root
BT::ParallelNode root
Definition: gtest_parallel.cpp:26
BT::ConditionTestNode
Definition: condition_test_node.h:8
BT::ParallelNode::setSuccessThreshold
void setSuccessThreshold(int threshold)
Definition: parallel_node.cpp:171
SequenceTripleActionTest::~SequenceTripleActionTest
~SequenceTripleActionTest() override
Definition: gtest_sequence.cpp:85
SequenceTripleActionTest::condition
BT::ConditionTestNode condition
Definition: gtest_sequence.cpp:68
BT::ControlNode::addChild
void addChild(TreeNode *child)
The method used to add nodes to the children vector.
Definition: control_node.cpp:22
ComplexSequence2ActionsTest::ComplexSequence2ActionsTest
ComplexSequence2ActionsTest()
Definition: gtest_sequence.cpp:100
xml_text
static const char * xml_text
Definition: ex01_wrap_legacy.cpp:52
ComplexSequenceWithMemoryTest::seq_actions
BT::SequenceWithMemory seq_actions
Definition: gtest_sequence.cpp:151
ComplexSequenceTest::action_1
BT::AsyncActionTest action_1
Definition: gtest_sequence.cpp:41
BT::NodeStatus
NodeStatus
Definition: basic_types.h:33
SimpleParallelTest::~SimpleParallelTest
~SimpleParallelTest() override
Definition: gtest_sequence.cpp:199
ComplexSequenceWithMemoryTest::action_2
BT::AsyncActionTest action_2
Definition: gtest_sequence.cpp:145
ComplexSequenceTest::condition_1
BT::ConditionTestNode condition_1
Definition: gtest_sequence.cpp:42
SimpleParallelTest::action_1
BT::AsyncActionTest action_1
Definition: gtest_parallel.cpp:27


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:07