gtest_coroutines.cpp
Go to the documentation of this file.
3 #include <chrono>
4 #include <gtest/gtest.h>
5 
6 using namespace std::chrono;
7 
8 using Millisecond = std::chrono::milliseconds;
9 using Timepoint = std::chrono::time_point<std::chrono::steady_clock>;
10 
12 {
13  public:
14  SimpleCoroAction(milliseconds timeout, bool will_fail,
15  const std::string &node_name,
16  const BT::NodeConfiguration &config)
17  : BT::CoroActionNode(node_name, config)
18  , will_fail_(will_fail)
19  , timeout_(timeout)
20  , start_time_(Timepoint::min())
21  {
22  }
23 
24  virtual void halt() override
25  {
26  std::cout << "Action was halted. doing cleanup here" << std::endl;
27  start_time_ = Timepoint::min();
28  halted_ = true;
30  }
31 
32  bool wasHalted()
33  {
34  return halted_;
35  }
36 
38  {
39  timeout_ = ms;
40  }
41 
42  protected:
43  virtual BT::NodeStatus tick() override
44  {
45  std::cout << "Starting action " << std::endl;
46  halted_ = false;
47 
48  if (start_time_ == Timepoint::min())
49  {
50  start_time_ = std::chrono::steady_clock::now();
51  }
52 
53  while (std::chrono::steady_clock::now() < (start_time_ + timeout_))
54  {
55  setStatusRunningAndYield();
56  }
57 
58  halted_ = false;
59 
60  std::cout << "Done" << std::endl;
61  start_time_ = Timepoint::min();
62  return (will_fail_ ? BT::NodeStatus::FAILURE : BT::NodeStatus::SUCCESS);
63  }
64 
65  public:
66  bool will_fail_;
67 
68  private:
69  std::chrono::milliseconds timeout_;
71  bool halted_;
72 };
73 
75 {
76  auto status = node.executeTick();
77  while (status == BT::NodeStatus::RUNNING)
78  {
79  status = node.executeTick();
80  std::this_thread::sleep_for(Millisecond(1));
81  }
82  return status;
83 }
84 
85 
86 TEST(CoroTest, do_action)
87 {
88  BT::NodeConfiguration node_config_;
89  node_config_.blackboard = BT::Blackboard::create();
90  BT::assignDefaultRemapping<SimpleCoroAction>(node_config_);
91  SimpleCoroAction node( milliseconds(200), false, "Action", node_config_);
92 
94  EXPECT_FALSE( node.wasHalted() );
95 
96  EXPECT_EQ(BT::NodeStatus::SUCCESS, executeWhileRunning(node)) << "Second call to coro action";
97  EXPECT_FALSE( node.wasHalted() );
98 
99  node.will_fail_ = true;
101  << "Should execute again and retun failure";
102  EXPECT_FALSE( node.wasHalted() );
103 
104 
106  << "Shoudln't fail because we set status to idle";
107  EXPECT_FALSE( node.wasHalted() );
108 }
109 
110 
111 TEST(CoroTest, do_action_timeout)
112 {
113  BT::NodeConfiguration node_config_;
114  node_config_.blackboard = BT::Blackboard::create();
115  BT::assignDefaultRemapping<SimpleCoroAction>(node_config_);
116 
117  SimpleCoroAction node( milliseconds(300), false, "Action", node_config_);
118  BT::TimeoutNode timeout("TimeoutAction", 200);
119 
120  timeout.setChild(&node);
121 
122  EXPECT_EQ(BT::NodeStatus::FAILURE, executeWhileRunning(timeout) ) << "should timeout";
123  EXPECT_TRUE( node.wasHalted() );
124 
125  node.setRequiredTime( Millisecond(100) );
126 
127  EXPECT_EQ(BT::NodeStatus::SUCCESS, executeWhileRunning(timeout) );
128  EXPECT_FALSE( node.wasHalted() );
129 }
130 
131 TEST(CoroTest, sequence_child)
132 {
133  BT::NodeConfiguration node_config_;
134  node_config_.blackboard = BT::Blackboard::create();
135  BT::assignDefaultRemapping<SimpleCoroAction>(node_config_);
136 
137  SimpleCoroAction actionA( milliseconds(200), false, "action_A", node_config_);
138  SimpleCoroAction actionB( milliseconds(200), false, "action_B", node_config_);
139  BT::TimeoutNode timeout("timeout", 300);
140  BT::SequenceNode sequence("sequence");
141 
142  timeout.setChild(&sequence);
143  sequence.addChild(&actionA);
144  sequence.addChild(&actionB);
145 
146  EXPECT_EQ(BT::NodeStatus::FAILURE, executeWhileRunning(timeout) ) << "should timeout";
147  EXPECT_FALSE( actionA.wasHalted() );
148  EXPECT_TRUE( actionB.wasHalted() );
149 
150 }
151 
virtual void halt() override
TEST(CoroTest, do_action)
std::chrono::time_point< std::chrono::steady_clock > Timepoint
static Blackboard::Ptr create(Blackboard::Ptr parent={})
Definition: blackboard.h:38
BT::NodeStatus executeWhileRunning(BT::TreeNode &node)
The TimeoutNode will halt() a running child if the latter has been RUNNING for more than a give time...
Definition: timeout_node.h:23
std::chrono::milliseconds Millisecond
Blackboard::Ptr blackboard
Definition: tree_node.h:47
virtual BT::NodeStatus tick() override
Method to be implemented by the user.
void halt() override
The CoroActionNode class is an ideal candidate for asynchronous actions which need to communicate wit...
Definition: action_node.h:147
void setChild(TreeNode *child)
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:53
SimpleCoroAction(milliseconds timeout, bool will_fail, const std::string &node_name, const BT::NodeConfiguration &config)
void addChild(TreeNode *child)
The method used to add nodes to the children vector.
NodeStatus
Definition: basic_types.h:35
virtual BT::NodeStatus executeTick()
The method that should be used to invoke tick() and setStatus();.
Definition: tree_node.cpp:33
void setRequiredTime(Millisecond ms)
The SequenceNode is used to tick children in an ordered sequence. If any child returns RUNNING...
Definition: sequence_node.h:34
std::chrono::milliseconds timeout_


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 18:04:05