gtest_skipping.cpp
Go to the documentation of this file.
1 #include <gtest/gtest.h>
2 #include <string>
5 #include "test_helper.hpp"
6 #include "action_test_node.h"
7 
8 using namespace BT;
9 
10 TEST(SkippingLogic, Sequence)
11 {
12  BehaviorTreeFactory factory;
13  std::array<int, 2> counters;
14  RegisterTestTick(factory, "Test", counters);
15 
16  const std::string xml_text = R"(
17 
18  <root BTCPP_format="4" >
19  <BehaviorTree ID="MainTree">
20  <Sequence>
21  <Script code = "A:=1"/>
22  <TestA _successIf="A==2" _failureIf="A!=1" _skipIf="A==1"/>
23  <TestB/>
24  </Sequence>
25  </BehaviorTree>
26  </root>)";
27 
28  auto tree = factory.createTreeFromText(xml_text);
29  const auto status = tree.tickWhileRunning();
30  ASSERT_EQ(status, NodeStatus::SUCCESS);
31  ASSERT_EQ(counters[0], 0);
32  ASSERT_EQ(counters[1], 1);
33 }
34 
35 TEST(SkippingLogic, SkipAll)
36 {
37  BehaviorTreeFactory factory;
38  std::array<int, 3> counters;
39  RegisterTestTick(factory, "Test", counters);
40 
41  const std::string xml_text = R"(
42 
43  <root BTCPP_format="4" >
44  <BehaviorTree ID="MainTree">
45  <Sequence>
46  <TestA _skipIf="A==1"/>
47  <TestB _skipIf="A<2"/>
48  <TestC _skipIf="A>0"/>
49  </Sequence>
50  </BehaviorTree>
51  </root>)";
52 
53  auto tree = factory.createTreeFromText(xml_text);
54  tree.rootBlackboard()->set("A", 1);
55 
56  const auto status = tree.tickWhileRunning();
57  ASSERT_EQ(counters[0], 0);
58  ASSERT_EQ(counters[1], 0);
59  ASSERT_EQ(counters[2], 0);
60  ASSERT_EQ(status, NodeStatus::SKIPPED);
61 }
62 
63 TEST(SkippingLogic, SkipSubtree)
64 {
65  BehaviorTreeFactory factory;
66  std::array<int, 3> counters;
67  RegisterTestTick(factory, "Test", counters);
68 
69  const std::string xml_text = R"(
70 
71  <root BTCPP_format="4" >
72  <BehaviorTree ID="main">
73  <Sequence>
74  <TestA/>
75  <Script code=" data:=true "/>
76  <SubTree ID="sub" _skipIf="data"/>
77  </Sequence>
78  </BehaviorTree>
79 
80  <BehaviorTree ID="sub">
81  <TestB/>
82  </BehaviorTree>
83  </root>)";
84 
86  auto tree = factory.createTree("main");
87 
88  tree.rootBlackboard()->set("A", 1);
89 
90  const auto status = tree.tickWhileRunning();
91  ASSERT_EQ(counters[0], 1);
92  ASSERT_EQ(counters[1], 0);
93  ASSERT_EQ(status, NodeStatus::SUCCESS);
94 }
95 
96 TEST(SkippingLogic, ReactiveSingleChild)
97 {
98  static const char* xml_text = R"(
99  <root BTCPP_format="4">
100  <BehaviorTree ID="Untitled">
101  <ReactiveSequence>
102  <AlwaysSuccess _skipIf="flag"/>
103  </ReactiveSequence>
104  </BehaviorTree>
105  </root>
106  )";
107 
108  BT::BehaviorTreeFactory factory;
109  auto root_blackboard = BT::Blackboard::create();
110  root_blackboard->set<bool>("flag", true);
111 
112  auto tree = factory.createTreeFromText(xml_text, root_blackboard);
113 
114  tree.tickWhileRunning();
115 }
116 
117 TEST(SkippingLogic, SkippingReactiveSequence)
118 {
119  BehaviorTreeFactory factory;
120  std::array<int, 2> counters;
121  RegisterTestTick(factory, "Test", counters);
122 
123  const std::string xml_text_noskip = R"(
124  <root BTCPP_format="4" >
125  <BehaviorTree>
126  <ReactiveSequence>
127  <Script code=" value:=50 "/>
128  <TestA _skipIf="value < 25"/>
129  <AsyncActionTest/>
130  </ReactiveSequence>
131  </BehaviorTree>
132  </root>)";
133 
134  const std::string xml_text_skip = R"(
135  <root BTCPP_format="4" >
136  <BehaviorTree>
137  <ReactiveSequence>
138  <Script code=" value:=10 "/>
139  <TestB _skipIf="value < 25"/>
140  <AsyncActionTest/>
141  </ReactiveSequence>
142  </BehaviorTree>
143  </root>)";
144 
145  factory.registerNodeType<AsyncActionTest>("AsyncActionTest");
146 
147  int expected_test_A_ticks = 0;
148 
149  for(auto const* xml_text : { &xml_text_noskip, &xml_text_skip })
150  {
151  auto tree = factory.createTreeFromText(*xml_text);
152 
153  for(int repeat = 0; repeat < 3; repeat++)
154  {
155  NodeStatus status = NodeStatus::IDLE;
156  while(!isStatusCompleted(status))
157  {
158  status = tree.tickOnce();
159 
160  if(xml_text == &xml_text_noskip)
161  {
162  expected_test_A_ticks++;
163  }
164 
165  tree.sleep(std::chrono::milliseconds{ 15 });
166  }
167  ASSERT_EQ(status, NodeStatus::SUCCESS);
168  }
169  }
170  // counters[0] contains the number ot times TestA was ticked
171  ASSERT_EQ(counters[0], expected_test_A_ticks);
172 
173  // counters[1] contains the number ot times TestB was ticked
174  ASSERT_EQ(counters[1], 0);
175 }
176 
177 TEST(SkippingLogic, WhileSkip)
178 {
179  BehaviorTreeFactory factory;
180  std::array<int, 2> counters;
181  RegisterTestTick(factory, "Test", counters);
182 
183  const std::string xml_text_noskip = R"(
184  <root BTCPP_format="4" >
185  <BehaviorTree>
186  <Sequence>
187  <Script code=" doit:=true "/>
188  <Sequence>
189  <TestA _while="doit"/>
190  </Sequence>
191  </Sequence>
192  </BehaviorTree>
193  </root>)";
194 
195  const std::string xml_text_skip = R"(
196  <root BTCPP_format="4" >
197  <BehaviorTree>
198  <Sequence>
199  <Script code=" doit:=false "/>
200  <Sequence>
201  <TestB _while="doit"/>
202  </Sequence>
203  </Sequence>
204  </BehaviorTree>
205  </root>)";
206 
207  for(auto const* xml_text : { &xml_text_noskip, &xml_text_skip })
208  {
209  auto tree = factory.createTreeFromText(*xml_text);
210  NodeStatus status = tree.tickWhileRunning();
211  ASSERT_EQ(status, NodeStatus::SUCCESS);
212  }
213  // counters[0] contains the number ot times TestA was ticked
214  ASSERT_EQ(counters[0], 1);
215 
216  // counters[1] contains the number ot times TestB was ticked
217  ASSERT_EQ(counters[1], 0);
218 }
BT
Definition: ex01_wrap_legacy.cpp:29
BT::BehaviorTreeFactory::createTree
Tree createTree(const std::string &tree_name, Blackboard::Ptr blackboard=Blackboard::create())
Definition: bt_factory.cpp:432
basic_types.h
RegisterTestTick
void RegisterTestTick(BT::BehaviorTreeFactory &factory, const std::string &name_prefix, std::array< int, N > &tick_counters)
Definition: test_helper.hpp:15
bt_factory.h
BT::AsyncActionTest
Definition: action_test_node.h:32
test_helper.hpp
BT::Tree::tickWhileRunning
NodeStatus tickWhileRunning(std::chrono::milliseconds sleep_time=std::chrono::milliseconds(10))
Definition: bt_factory.cpp:609
BT::NodeStatus::SKIPPED
@ SKIPPED
BT::BehaviorTreeFactory::registerNodeType
void registerNodeType(const std::string &ID, const PortsList &ports, ExtraArgs... args)
Definition: bt_factory.h:322
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
BT::BehaviorTreeFactory
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:205
BT::Blackboard::create
static Blackboard::Ptr create(Blackboard::Ptr parent={})
Definition: blackboard.h:63
BT::NodeStatus::SUCCESS
@ SUCCESS
BT::isStatusCompleted
bool isStatusCompleted(const NodeStatus &status)
Definition: basic_types.h:47
lexyd::repeat
constexpr auto repeat(Count)
Parses a rule n times, where n is the value produced by Count.
Definition: repeat.hpp:176
BT::BehaviorTreeFactory::registerBehaviorTreeFromText
void registerBehaviorTreeFromText(const std::string &xml_text)
Definition: bt_factory.cpp:277
action_test_node.h
BT::NodeStatus::IDLE
@ IDLE
BT::Tree::rootBlackboard
Blackboard::Ptr rootBlackboard()
Definition: bt_factory.cpp:614
TEST
TEST(SkippingLogic, Sequence)
Definition: gtest_skipping.cpp:10
xml_text
static const char * xml_text
Definition: ex01_wrap_legacy.cpp:52
BT::NodeStatus
NodeStatus
Definition: basic_types.h:33


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