gtest_reactive.cpp
Go to the documentation of this file.
1 #include <gtest/gtest.h>
3 #include "test_helper.hpp"
5 
6 using BT::NodeStatus;
7 using std::chrono::milliseconds;
8 
9 TEST(Reactive, RunningChildren)
10 {
11  static const char* reactive_xml_text = R"(
12 <root BTCPP_format="4" >
13  <BehaviorTree ID="MainTree">
14  <ReactiveSequence>
15  <Sequence name="first">
16  <TestA/>
17  <TestB/>
18  <TestC/>
19  </Sequence>
20  <AsyncSequence name="second">
21  <TestD/>
22  <TestE/>
23  <TestF/>
24  </AsyncSequence>
25  </ReactiveSequence>
26  </BehaviorTree>
27 </root>
28 )";
29 
31  std::array<int, 6> counters;
32  RegisterTestTick(factory, "Test", counters);
33 
34  auto tree = factory.createTreeFromText(reactive_xml_text);
35 
36  NodeStatus status = NodeStatus::IDLE;
37 
38  int count = 0;
39  while(!BT::isStatusCompleted(status) && count < 100)
40  {
41  count++;
42  status = tree.tickExactlyOnce();
43  }
44 
45  ASSERT_NE(100, count);
46 
47  ASSERT_EQ(status, NodeStatus::SUCCESS);
48 
49  ASSERT_EQ(counters[0], 3);
50  ASSERT_EQ(counters[1], 3);
51  ASSERT_EQ(counters[2], 3);
52 
53  ASSERT_EQ(counters[3], 1);
54  ASSERT_EQ(counters[4], 1);
55  ASSERT_EQ(counters[5], 1);
56 }
57 
58 TEST(Reactive, Issue587)
59 {
60  // TestA should be executed only once, because of the variable "test"
61 
62  static const char* reactive_xml_text = R"(
63 <root BTCPP_format="4" >
64  <BehaviorTree ID="Example A">
65  <Sequence>
66  <Script code="test := false"/>
67  <ReactiveSequence>
68  <RetryUntilSuccessful name="Retry 1" num_attempts="-1" _skipIf="test ">
69  <TestA name="Success 1" _onSuccess="test = true"/>
70  </RetryUntilSuccessful>
71  <RetryUntilSuccessful name="Retry 2" num_attempts="5">
72  <AlwaysFailure name="Failure 2"/>
73  </RetryUntilSuccessful>
74  </ReactiveSequence>
75  </Sequence>
76  </BehaviorTree>
77 </root>
78 )";
79 
81  std::array<int, 2> counters;
82  RegisterTestTick(factory, "Test", counters);
83 
84  auto tree = factory.createTreeFromText(reactive_xml_text);
85  tree.tickWhileRunning();
86 
87  ASSERT_EQ(counters[0], 1);
88 }
89 
90 TEST(Reactive, PreTickHooks)
91 {
92  using namespace BT;
93 
94  static const char* reactive_xml_text = R"(
95 <root BTCPP_format="4" >
96  <BehaviorTree ID="Main">
97  <ReactiveSequence>
98  <AlwaysFailure name="failureA"/>
99  <AlwaysFailure name="failureB"/>
100  <Sleep msec="100"/>
101  </ReactiveSequence>
102  </BehaviorTree>
103 </root>
104 )";
105 
106  BehaviorTreeFactory factory;
107 
108  auto tree = factory.createTreeFromText(reactive_xml_text);
109 
111  std::cout << node.name() << " callback" << std::endl;
112  return NodeStatus::SUCCESS;
113  };
114 
115  tree.applyVisitor([&](TreeNode* node) -> void {
116  if(auto dd = dynamic_cast<BT::AlwaysFailureNode*>(node))
117  {
118  dd->setPreTickFunction(callback);
119  }
120  });
121 
122  auto ret = tree.tickWhileRunning();
123  ASSERT_EQ(ret, NodeStatus::SUCCESS);
124 }
125 
126 TEST(Reactive, TestLogging)
127 {
128  using namespace BT;
129 
130  static const char* reactive_xml_text = R"(
131 <root BTCPP_format="4" >
132  <BehaviorTree ID="Main">
133  <ReactiveSequence>
134  <TestA name="testA"/>
135  <AlwaysSuccess name="success"/>
136  <Sleep msec="100"/>
137  </ReactiveSequence>
138  </BehaviorTree>
139 </root>
140 )";
141 
142  BehaviorTreeFactory factory;
143 
144  std::array<int, 1> counters;
145  RegisterTestTick(factory, "Test", counters);
146 
147  auto tree = factory.createTreeFromText(reactive_xml_text);
148  TreeObserver observer(tree);
149 
150  auto ret = tree.tickWhileRunning();
151  ASSERT_EQ(ret, NodeStatus::SUCCESS);
152 
153  int num_ticks = counters[0];
154  ASSERT_GE(num_ticks, 5);
155 
156  ASSERT_EQ(observer.getStatistics("testA").success_count, num_ticks);
157  ASSERT_EQ(observer.getStatistics("success").success_count, num_ticks);
158 }
BT
Definition: ex01_wrap_legacy.cpp:29
BT::TreeObserver::getStatistics
const NodeStatistics & getStatistics(const std::string &path) const
Definition: bt_observer.cpp:80
RegisterTestTick
void RegisterTestTick(BT::BehaviorTreeFactory &factory, const std::string &name_prefix, std::array< int, N > &tick_counters)
Definition: test_helper.hpp:15
BT::TreeNode
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:118
bt_observer.h
bt_factory.h
BT::TreeNode::PreTickCallback
std::function< NodeStatus(TreeNode &)> PreTickCallback
Definition: tree_node.h:165
TEST
TEST(Reactive, RunningChildren)
Definition: gtest_reactive.cpp:9
test_helper.hpp
lexy::callback
constexpr auto callback(Fns &&... fns)
Creates a callback.
Definition: adapter.hpp:21
BT::Tree::tickWhileRunning
NodeStatus tickWhileRunning(std::chrono::milliseconds sleep_time=std::chrono::milliseconds(10))
Definition: bt_factory.cpp:609
lexy::count
constexpr auto count
Sink that counts all arguments.
Definition: fold.hpp:88
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::TreeObserver
The TreeObserver is used to collect statistics about which nodes are executed and their returned stat...
Definition: bt_observer.h:17
BT::NodeStatus::SUCCESS
@ SUCCESS
BT::TreeObserver::NodeStatistics::success_count
unsigned success_count
Definition: bt_observer.h:38
BT::isStatusCompleted
bool isStatusCompleted(const NodeStatus &status)
Definition: basic_types.h:47
BT::AlwaysFailureNode
Definition: always_failure_node.h:22
BT::NodeStatus
NodeStatus
Definition: basic_types.h:33


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