t09_async_actions_coroutines.cpp
Go to the documentation of this file.
00001 #include "behaviortree_cpp/bt_factory.h"
00002 
00003 using namespace BT;
00004 
00012 class MyAsyncAction: public CoroActionNode
00013 {
00014   public:
00015     MyAsyncAction(const std::string& name):
00016         CoroActionNode(name, {})
00017     {}
00018 
00019   private:
00020     // This is the ideal skeleton/template of an async action:
00021     //  - A request to a remote service provider.
00022     //  - A loop where we check if the reply has been received.
00023     //  - You may call setStatusRunningAndYield() to "pause".
00024     //  - Code to execute after the reply.
00025     //  - A simple way to handle halt().
00026 
00027     NodeStatus tick() override
00028 
00029     {
00030         std::cout << name() <<": Started. Send Request to server." << std::endl;
00031 
00032         auto Now = [](){ return std::chrono::high_resolution_clock::now(); };
00033 
00034         TimePoint initial_time = Now();
00035         TimePoint time_before_reply = initial_time + std::chrono::milliseconds(100);
00036 
00037         int count = 0;
00038         bool reply_received = false;
00039 
00040         while( !reply_received )
00041         {
00042             if( count++ == 0)
00043             {
00044                 // call this only once
00045                 std::cout << name() <<": Waiting Reply..." << std::endl;
00046             }
00047             // pretend that we received a reply
00048             if( Now() >= time_before_reply )
00049             {
00050                 reply_received = true;
00051             }
00052 
00053             if( !reply_received )
00054             {
00055                 // set status to RUNNING and "pause/sleep"
00056                 // If halt() is called, we will not resume execution (stack destroyed)
00057                 setStatusRunningAndYield();
00058             }
00059         }
00060 
00061         // This part of the code is never reached if halt() is invoked,
00062         // only if reply_received == true;
00063         std::cout << name() <<": Done. 'Waiting Reply' loop repeated "
00064                   << count << " times" << std::endl;
00065         cleanup(false);
00066         return NodeStatus::SUCCESS;
00067     }
00068 
00069     // you might want to cleanup differently if it was halted or successful
00070     void cleanup(bool halted)
00071     {
00072         if( halted )
00073         {
00074             std::cout << name() <<": cleaning up after an halt()\n" << std::endl;
00075         }
00076         else{
00077             std::cout << name() <<": cleaning up after SUCCESS\n" << std::endl;
00078         }
00079     }
00080     void halt() override
00081     {
00082         std::cout << name() <<": Halted." << std::endl;
00083         cleanup(true);
00084         // Do not forget to call this at the end.
00085         CoroActionNode::halt();
00086     }
00087 };
00088 
00089 
00090 // clang-format off
00091 static const char* xml_text = R"(
00092 
00093  <root >
00094      <BehaviorTree>
00095         <Timeout msec="150">
00096             <SequenceStar name="sequence">
00097                 <MyAsyncAction name="action_A"/>
00098                 <MyAsyncAction name="action_B"/>
00099             </SequenceStar>
00100         </Timeout>
00101      </BehaviorTree>
00102  </root>
00103  )";
00104 
00105 // clang-format on
00106 
00107 int main()
00108 {
00109     // Simple tree: a sequence of two asycnhronous actions,
00110     // but the second will be halted because of the timeout.
00111 
00112     BehaviorTreeFactory factory;
00113     factory.registerNodeType<MyAsyncAction>("MyAsyncAction");
00114 
00115     auto tree = factory.createTreeFromText(xml_text);
00116 
00117     //---------------------------------------
00118     // keep executin tick until it returns etiher SUCCESS or FAILURE
00119     while( tree.root_node->executeTick() == NodeStatus::RUNNING)
00120     {
00121         std::this_thread::sleep_for( std::chrono::milliseconds(10) );
00122     }
00123     return 0;
00124 }
00125 
00126 /* Expected output:
00127 
00128 action_A: Started. Send Request to server.
00129 action_A: Waiting Reply...
00130 action_A: Done. 'Waiting Reply' loop repeated 11 times
00131 action_A: cleaning up after SUCCESS
00132 
00133 action_B: Started. Send Request to server.
00134 action_B: Waiting Reply...
00135 action_B: Halted.
00136 action_B: cleaning up after an halt()
00137 
00138 */


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