gtest_coroutines.cpp
Go to the documentation of this file.
00001 #include "behaviortree_cpp/decorators/timeout_node.h"
00002 #include "behaviortree_cpp/behavior_tree.h"
00003 #include <chrono>
00004 #include <gtest/gtest.h>
00005 
00006 using namespace std::chrono;
00007 
00008 using Millisecond = std::chrono::milliseconds;
00009 using Timepoint = std::chrono::time_point<std::chrono::steady_clock>;
00010 
00011 class SimpleCoroAction : public BT::CoroActionNode
00012 {
00013   public:
00014     SimpleCoroAction(milliseconds timeout, bool will_fail,
00015                      const std::string &node_name,
00016                      const BT::NodeConfiguration &config)
00017       : BT::CoroActionNode(node_name, config)
00018       , will_fail_(will_fail)
00019       , timeout_(timeout)
00020       , start_time_(Timepoint::min())
00021     {
00022     }
00023 
00024     virtual void halt() override
00025     {
00026         std::cout << "Action was halted. doing cleanup here" << std::endl;
00027         start_time_ = Timepoint::min();
00028         halted_ = true;
00029         BT::CoroActionNode::halt();
00030     }
00031 
00032     bool wasHalted()
00033     {
00034         return halted_;
00035     }
00036 
00037     void setRequiredTime(Millisecond ms)
00038     {
00039         timeout_ = ms;
00040     }
00041 
00042   protected:
00043     virtual BT::NodeStatus tick() override
00044     {
00045         std::cout << "Starting action " << std::endl;
00046         halted_ = false;
00047 
00048         if (start_time_ == Timepoint::min())
00049         {
00050             start_time_ = std::chrono::steady_clock::now();
00051         }
00052 
00053         while (std::chrono::steady_clock::now() < (start_time_ + timeout_))
00054         {
00055             setStatusRunningAndYield();
00056         }
00057 
00058         halted_ = false;
00059 
00060         std::cout << "Done" << std::endl;
00061         start_time_ = Timepoint::min();
00062         return (will_fail_ ? BT::NodeStatus::FAILURE : BT::NodeStatus::SUCCESS);
00063     }
00064 
00065   public:
00066     bool will_fail_;
00067 
00068   private:
00069     std::chrono::milliseconds timeout_;
00070     Timepoint start_time_;
00071     bool halted_;
00072 };
00073 
00074 BT::NodeStatus executeWhileRunning(BT::TreeNode &node)
00075 {
00076     auto status = node.executeTick();
00077     while (status == BT::NodeStatus::RUNNING)
00078     {
00079         status = node.executeTick();
00080         std::this_thread::sleep_for(Millisecond(1));
00081     }
00082     return status;
00083 }
00084 
00085 
00086 TEST(CoroTest, do_action)
00087 {
00088     BT::NodeConfiguration node_config_;
00089     node_config_.blackboard = BT::Blackboard::create();
00090     BT::assignDefaultRemapping<SimpleCoroAction>(node_config_);
00091     SimpleCoroAction node( milliseconds(200), false, "Action", node_config_);
00092 
00093     EXPECT_EQ(BT::NodeStatus::SUCCESS, executeWhileRunning(node));
00094     EXPECT_FALSE( node.wasHalted() );
00095 
00096     EXPECT_EQ(BT::NodeStatus::SUCCESS, executeWhileRunning(node)) << "Second call to coro action";
00097     EXPECT_FALSE( node.wasHalted() );
00098 
00099     node.will_fail_ = true;
00100     EXPECT_EQ(BT::NodeStatus::FAILURE, executeWhileRunning(node))
00101         << "Should execute again and retun failure";
00102     EXPECT_FALSE( node.wasHalted() );
00103 
00104 
00105     EXPECT_EQ(BT::NodeStatus::FAILURE, executeWhileRunning(node))
00106         << "Shoudln't fail because we set status to idle";
00107     EXPECT_FALSE( node.wasHalted() );
00108 }
00109 
00110 
00111 TEST(CoroTest, do_action_timeout)
00112 {
00113     BT::NodeConfiguration node_config_;
00114     node_config_.blackboard = BT::Blackboard::create();
00115     BT::assignDefaultRemapping<SimpleCoroAction>(node_config_);
00116 
00117     SimpleCoroAction node( milliseconds(300), false, "Action", node_config_);
00118     BT::TimeoutNode timeout("TimeoutAction", 200);
00119 
00120     timeout.setChild(&node);
00121 
00122     EXPECT_EQ(BT::NodeStatus::FAILURE, executeWhileRunning(timeout) ) << "should timeout";
00123     EXPECT_TRUE( node.wasHalted() );
00124 
00125     node.setRequiredTime( Millisecond(100) );
00126 
00127     EXPECT_EQ(BT::NodeStatus::SUCCESS, executeWhileRunning(timeout) );
00128     EXPECT_FALSE( node.wasHalted() );
00129 }
00130 
00131 TEST(CoroTest, sequence_child)
00132 {
00133     BT::NodeConfiguration node_config_;
00134     node_config_.blackboard = BT::Blackboard::create();
00135     BT::assignDefaultRemapping<SimpleCoroAction>(node_config_);
00136 
00137     SimpleCoroAction actionA( milliseconds(200), false, "action_A", node_config_);
00138     SimpleCoroAction actionB( milliseconds(200), false, "action_B", node_config_);
00139     BT::TimeoutNode timeout("timeout", 300);
00140     BT::SequenceNode sequence("sequence");
00141 
00142     timeout.setChild(&sequence);
00143     sequence.addChild(&actionA);
00144     sequence.addChild(&actionB);
00145 
00146     EXPECT_EQ(BT::NodeStatus::FAILURE, executeWhileRunning(timeout) ) << "should timeout";
00147     EXPECT_FALSE( actionA.wasHalted() );
00148     EXPECT_TRUE( actionB.wasHalted() );
00149 
00150 }
00151 


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 20:17:15