t08_async_actions_coroutines.cpp
Go to the documentation of this file.
00001 #include "behaviortree_cpp/blackboard/blackboard_local.h"
00002 #include "behaviortree_cpp/behavior_tree.h"
00003 
00004 using namespace BT;
00005 
00012 class MyAsyncAction: public CoroActionNode
00013 {
00014   public:
00015     MyAsyncAction(const std::string& name):
00016       CoroActionNode(name, NodeParameters())
00017     {}
00018 
00019     // This is the ideal skeleton/template of an async action:
00020     //  - A request to a remote service provider.
00021     //  - A loop where we check if the reply has been received.
00022     //    Call setStatusRunningAndYield() to "pause".
00023     //  - Code to execute after the reply.
00024     //  - a simple way to handle halt().
00025 
00026     NodeStatus tick() override
00027     {
00028         std::cout << name() <<": Started. Send Request to server." << std::endl;
00029 
00030         int cycle = 0;
00031         bool reply_received = false;
00032 
00033         while( !reply_received )
00034         {
00035             std::cout << name() <<": Waiting reply." << std::endl;
00036             reply_received = ++cycle >= 3;
00037 
00038             if( !reply_received )
00039             {
00040                 // set status to RUNNING and "pause/sleep"
00041                 // If halt() is called, we will not resume execution
00042                 setStatusRunningAndYield();
00043             }
00044         }
00045 
00046         // this part of the code is never reached if halt() is invoked.
00047         std::cout << name() <<": Done." << std::endl;
00048         return NodeStatus::SUCCESS;
00049     }
00050 
00051     void halt() override
00052     {
00053         std::cout << name() <<": Halted. Do your cleanup here." << std::endl;
00054 
00055         // Do not forget to call this at the end.
00056         CoroActionNode::halt();
00057     }
00058 };
00059 
00060 
00061 int main()
00062 {
00063     // Simple tree: a sequence of two asycnhronous actions
00064     BT::SequenceNode sequence_root("sequence");
00065     MyAsyncAction action_A("actionA");
00066     MyAsyncAction action_B("actionB");
00067 
00068     // Add children to the sequence.
00069     sequence_root.addChild(&action_A);
00070     sequence_root.addChild(&action_B);
00071 
00072     NodeStatus status = NodeStatus::IDLE;
00073 
00074     while( status != NodeStatus::SUCCESS && status != NodeStatus::FAILURE)
00075     {
00076         status = sequence_root.executeTick();
00077 
00078         // It is often a good idea to add a sleep here to avoid busy loops
00079         std::this_thread::sleep_for( std::chrono::milliseconds(1) );
00080     }
00081 
00082     return 0;
00083 }
00084 
00085 /* Expected output:
00086 
00087 actionA: Started. Request service using async call
00088 actionA: Waiting reply
00089 actionA: Waiting reply
00090 actionA: Waiting reply
00091 actionA: Done
00092 actionB: Started. Request service using async call
00093 actionB: Waiting reply
00094 actionB: Waiting reply
00095 actionB: Waiting reply
00096 actionB: Done
00097 */


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 03:50:10