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 using std::chrono::milliseconds;
20 
21 struct SimpleSequenceTest : testing::Test
22 {
26 
28  root("root_sequence"), action("action", milliseconds(100)), condition("condition")
29  {
30  root.addChild(&condition);
31  root.addChild(&action);
32  }
34  {}
35 };
36 
37 struct ComplexSequenceTest : testing::Test
38 {
43 
45 
47  root("root"),
48  action_1("action_1", milliseconds(100)),
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 };
63 
64 struct SequenceTripleActionTest : testing::Test
65 {
71 
73  root("root_sequence"),
74  condition("condition"),
75  action_1("action_1", milliseconds(100)),
76  action_2("action_2"),
77  action_3("action_3", milliseconds(100))
78  {
79  root.addChild(&condition);
80  root.addChild(&action_1);
81  root.addChild(&action_2);
82  root.addChild(&action_3);
83  }
85  {}
86 };
87 
88 struct ComplexSequence2ActionsTest : testing::Test
89 {
95 
98 
100  root("root_sequence"),
101  action_1("action_1", milliseconds(100)),
102  action_2("action_2", milliseconds(100)),
103  seq_1("sequence_1"),
104  seq_2("sequence_2"),
105  condition_1("condition_1"),
106  condition_2("condition_2")
107  {
108  root.addChild(&seq_1);
109  {
110  seq_1.addChild(&condition_1);
111  seq_1.addChild(&action_1);
112  }
113  root.addChild(&seq_2);
114  {
115  seq_2.addChild(&condition_2);
116  seq_2.addChild(&action_2);
117  }
118  }
120  {}
121 };
122 
123 struct SimpleSequenceWithMemoryTest : testing::Test
124 {
128 
130  root("root_sequence"), action("action", milliseconds(100)), condition("condition")
131  {
132  root.addChild(&condition);
133  root.addChild(&action);
134  }
136  {}
137 };
138 
139 struct ComplexSequenceWithMemoryTest : testing::Test
140 {
142 
145 
148 
151 
153  root("root_sequence"),
154  action_1("action_1", milliseconds(100)),
155  action_2("action_2", milliseconds(100)),
156  condition_1("condition_1"),
157  condition_2("condition_2"),
158  seq_conditions("sequence_conditions"),
159  seq_actions("sequence_actions")
160  {
161  root.addChild(&seq_conditions);
162  {
163  seq_conditions.addChild(&condition_1);
164  seq_conditions.addChild(&condition_2);
165  }
166  root.addChild(&seq_actions);
167  {
168  seq_actions.addChild(&action_1);
169  seq_actions.addChild(&action_2);
170  }
171  }
173  {}
174 };
175 
176 struct SimpleParallelTest : testing::Test
177 {
179  BT::AsyncActionTest action_1;
180  BT::ConditionTestNode condition_1;
181 
182  BT::AsyncActionTest action_2;
183  BT::ConditionTestNode condition_2;
184 
186  root("root_parallel", 4),
187  action_1("action_1", milliseconds(100)),
188  condition_1("condition_1"),
189  action_2("action_2", milliseconds(100)),
190  condition_2("condition_2")
191  {
192  root.addChild(&condition_1);
193  root.addChild(&action_1);
194  root.addChild(&condition_2);
195  root.addChild(&action_2);
196  }
198  {}
199 };
200 
201 /****************TESTS START HERE***************************/
202 
203 TEST_F(SimpleSequenceTest, ConditionTrue)
204 {
205  std::cout << "Ticking the root node !" << std::endl << std::endl;
206  // Ticking the root node
207  BT::NodeStatus state = root.executeTick();
208 
209  ASSERT_EQ(NodeStatus::RUNNING, action.status());
210  ASSERT_EQ(NodeStatus::RUNNING, state);
211 }
212 
213 TEST_F(SimpleSequenceTest, ConditionTurnToFalse)
214 {
215  condition.setExpectedResult(NodeStatus::FAILURE);
216  BT::NodeStatus state = root.executeTick();
217 
218  state = root.executeTick();
219  ASSERT_EQ(NodeStatus::FAILURE, state);
220  ASSERT_EQ(NodeStatus::IDLE, condition.status());
221  ASSERT_EQ(NodeStatus::IDLE, action.status());
222 }
223 
224 TEST_F(ComplexSequenceTest, ComplexSequenceConditionsTrue)
225 {
226  BT::NodeStatus state = root.executeTick();
227 
228  ASSERT_EQ(NodeStatus::RUNNING, state);
229  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
230  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
231  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
232  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
233 }
234 
236 {
237  using namespace BT;
238  using namespace std::chrono;
239  const auto timeout = system_clock::now() + milliseconds(650);
240 
241  action_1.setTime(milliseconds(300));
242  action_3.setTime(milliseconds(300));
243  // the sequence is supposed to finish in (300 ms * 2) = 600 ms
244 
245  // first tick
246  NodeStatus state = root.executeTick();
247 
248  ASSERT_EQ(NodeStatus::RUNNING, state);
249  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
250  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
251  ASSERT_EQ(NodeStatus::IDLE, action_3.status());
252 
253  // continue until succesful
254  while (state != NodeStatus::SUCCESS && system_clock::now() < timeout)
255  {
256  std::this_thread::sleep_for(milliseconds(10));
257  state = root.executeTick();
258  }
259 
260  ASSERT_EQ(NodeStatus::SUCCESS, state);
261 
262  // Condition is called only once
263  ASSERT_EQ(condition.tickCount(), 1);
264  // all the actions are called only once
265  ASSERT_EQ(action_1.tickCount(), 1);
266  ASSERT_EQ(action_2.tickCount(), 1);
267  ASSERT_EQ(action_3.tickCount(), 1);
268 
269  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
270  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
271  ASSERT_EQ(NodeStatus::IDLE, action_3.status());
272  ASSERT_TRUE(system_clock::now() < timeout); // no timeout should occur
273 }
274 
276 {
277  BT::NodeStatus state = root.executeTick();
278 
279  state = root.executeTick();
280 
281  ASSERT_EQ(NodeStatus::RUNNING, state);
282  ASSERT_EQ(NodeStatus::RUNNING, seq_1.status());
283  ASSERT_EQ(NodeStatus::SUCCESS, condition_1.status());
284  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
285  ASSERT_EQ(NodeStatus::IDLE, seq_2.status());
286  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
287  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
288 
289  std::this_thread::sleep_for(milliseconds(300));
290  state = root.executeTick();
291 
292  ASSERT_EQ(NodeStatus::RUNNING, state);
293  ASSERT_EQ(NodeStatus::SUCCESS, seq_1.status());
294  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
295  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
296  ASSERT_EQ(NodeStatus::RUNNING, seq_2.status());
297  ASSERT_EQ(NodeStatus::SUCCESS, condition_2.status());
298  ASSERT_EQ(NodeStatus::RUNNING, action_2.status());
299 
300  state = root.executeTick();
301 }
302 
303 TEST_F(ComplexSequenceTest, ComplexSequenceConditions1ToFalse)
304 {
305  BT::NodeStatus state = root.executeTick();
306 
307  condition_1.setExpectedResult(NodeStatus::FAILURE);
308 
309  state = root.executeTick();
310 
311  ASSERT_EQ(NodeStatus::FAILURE, state);
312  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
313  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
314  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
315  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
316 }
317 
318 TEST_F(ComplexSequenceTest, ComplexSequenceConditions2ToFalse)
319 {
320  BT::NodeStatus state = root.executeTick();
321 
322  condition_2.setExpectedResult(NodeStatus::FAILURE);
323 
324  state = root.executeTick();
325 
326  ASSERT_EQ(NodeStatus::FAILURE, state);
327  ASSERT_EQ(NodeStatus::IDLE, seq_conditions.status());
328  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
329  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
330  ASSERT_EQ(NodeStatus::IDLE, action_1.status());
331 }
332 
334 {
335  BT::NodeStatus state = root.executeTick();
336  std::this_thread::sleep_for(milliseconds(50));
337 
338  ASSERT_EQ(NodeStatus::RUNNING, state);
339  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
340  ASSERT_EQ(NodeStatus::RUNNING, action.status());
341 }
342 
343 TEST_F(SimpleSequenceWithMemoryTest, ConditionTurnToFalse)
344 {
345  BT::NodeStatus state = root.executeTick();
346 
347  ASSERT_EQ(NodeStatus::RUNNING, state);
348  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
349  ASSERT_EQ(NodeStatus::RUNNING, action.status());
350 
351  condition.setExpectedResult(NodeStatus::FAILURE);
352  state = root.executeTick();
353 
354  ASSERT_EQ(NodeStatus::RUNNING, state);
355  ASSERT_EQ(NodeStatus::SUCCESS, condition.status());
356  ASSERT_EQ(NodeStatus::RUNNING, action.status());
357 }
358 
360 {
361  BT::NodeStatus state = root.executeTick();
362 
363  ASSERT_EQ(NodeStatus::RUNNING, state);
364  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
365  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
366  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
367  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
368  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
369  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
370 }
371 
373 {
374  BT::NodeStatus state = root.executeTick();
375 
376  condition_1.setExpectedResult(NodeStatus::FAILURE);
377  state = root.executeTick();
378  // change in condition_1 does not affect the state of the tree,
379  // since the seq_conditions was executed already
380  ASSERT_EQ(NodeStatus::RUNNING, state);
381  ASSERT_EQ(NodeStatus::SUCCESS, seq_conditions.status());
382  ASSERT_EQ(NodeStatus::IDLE, condition_1.status());
383  ASSERT_EQ(NodeStatus::IDLE, condition_2.status());
384  ASSERT_EQ(NodeStatus::RUNNING, seq_actions.status());
385  ASSERT_EQ(NodeStatus::RUNNING, action_1.status());
386  ASSERT_EQ(NodeStatus::IDLE, action_2.status());
387 }
388 
BT::ConditionTestNode condition_1
BT::AsyncActionTest action_2
The SequenceStarNode is used to tick children in an ordered sequence. 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
NodeStatus status() const
Definition: tree_node.cpp:84
BT::ConditionTestNode condition_2
BT::AsyncActionTest action
void setExpectedResult(NodeStatus res)
BT::AsyncActionTest action_1
BT::ReactiveSequence root
BT::ConditionTestNode condition
BT::SequenceStarNode seq_actions
BT::SyncActionTest action_2
BT::ConditionTestNode condition_2
BT::AsyncActionTest action_3
void addChild(TreeNode *child)
The method used to add nodes to the children vector.
BT::SequenceNode seq_conditions
BT::ConditionTestNode condition
BT::ConditionTestNode condition
BT::AsyncActionTest action_1
The ParallelNode execute all its children concurrently, but not in separate threads! ...
Definition: parallel_node.h:40
NodeStatus
Definition: basic_types.h:35
The ReactiveSequence is similar to a ParallelNode. All the children are ticked from first to last: ...
virtual BT::NodeStatus executeTick()
The method that should be used to invoke tick() and setStatus();.
Definition: tree_node.cpp:32
The SequenceNode is used to tick children in an ordered sequence. If any child returns RUNNING...
Definition: sequence_node.h:33


behaviortree_cpp_v3
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Mon Jul 3 2023 02:50:14