t08_additional_node_args.cpp
Go to the documentation of this file.
00001 #include "behaviortree_cpp/bt_factory.h"
00002 
00003 using namespace BT;
00004 
00005 /*
00006  * Sometimes, it is convenient to pass additional (static) arguments to a Node.
00007  * If these parameters are known at compilation time or at deployment-time
00008  * and they don't change at run-time, input ports are probably overkill and cumbersome.
00009  *
00010  * This tutorial demonstrates two possible ways to initialize a custom node with
00011  * additional arguments.
00012  */
00013 
00014 // Action_A has a different constructor than the default one.
00015 class Action_A: public SyncActionNode
00016 {
00017 
00018 public:
00019     // additional arguments passed to the constructor
00020     Action_A(const std::string& name, const NodeConfiguration& config,
00021              int arg1, double arg2, std::string arg3 ):
00022         SyncActionNode(name, config),
00023         _arg1(arg1),
00024         _arg2(arg2),
00025         _arg3(arg3) {}
00026 
00027     NodeStatus tick() override
00028     {
00029         std::cout << "Action_A: " << _arg1 << " / " << _arg2 << " / " << _arg3 << std::endl;
00030         return NodeStatus::SUCCESS;
00031     }
00032     static PortsList providedPorts() { return {}; }
00033 
00034 private:
00035     int _arg1;
00036     double _arg2;
00037     std::string _arg3;
00038 };
00039 
00040 // Action_B implements an init(...) method that must be called once at the beginning.
00041 class Action_B: public SyncActionNode
00042 {
00043 
00044 public:
00045     Action_B(const std::string& name, const NodeConfiguration& config):
00046         SyncActionNode(name, config) {}
00047 
00048     // we want this method to be called ONCE and BEFORE the first tick()
00049     void init( int arg1, double arg2, std::string arg3 )
00050     {
00051         _arg1 = (arg1);
00052         _arg2 = (arg2);
00053         _arg3 = (arg3);
00054     }
00055 
00056     NodeStatus tick() override
00057     {
00058         std::cout << "Action_B: " << _arg1 << " / " << _arg2 << " / " << _arg3 << std::endl;
00059         return NodeStatus::SUCCESS;
00060     }
00061     static PortsList providedPorts() { return {}; }
00062 
00063 private:
00064     int _arg1;
00065     double _arg2;
00066     std::string _arg3;
00067 };
00068 
00069 // Simple tree, used to execute once each action.
00070 static const char* xml_text = R"(
00071 
00072  <root >
00073      <BehaviorTree>
00074         <Sequence>
00075             <Action_A/>
00076             <Action_B/>
00077         </Sequence>
00078      </BehaviorTree>
00079  </root>
00080  )";
00081 
00082 int main()
00083 {
00084     BehaviorTreeFactory factory;
00085 
00086     // A node builder is nothing more than a function pointer to create a
00087     // std::unique_ptr<TreeNode>.
00088     // Using lambdas or std::bind, we can easily "inject" additional arguments.
00089     NodeBuilder builder_A = [](const std::string& name, const NodeConfiguration& config)
00090     {
00091         return std::make_unique<Action_A>( name, config, 42, 3.14, "hello world" );
00092     };
00093 
00094     // BehaviorTreeFactory::registerBuilder is the more general way to register a custom node.
00095     // Not the most user friendly, but definitely the most flexible one.
00096     factory.registerBuilder<Action_A>( "Action_A", builder_A);
00097 
00098     // The regitration of  Action_B is done as usual, but we still need to call Action_B::init()
00099     factory.registerNodeType<Action_B>( "Action_B" );
00100 
00101     auto tree = factory.createTreeFromText(xml_text);
00102 
00103     // Iterate through all the nodes and call init if it is an Action_B
00104     for( auto& node: tree.nodes )
00105     {
00106         if( auto action_B_node = dynamic_cast<Action_B*>( node.get() ))
00107         {
00108             action_B_node->init( 69, 9.99, "interesting_value" );
00109         }
00110     }
00111 
00112     tree.root_node->executeTick();
00113 
00114     /* Expected output:
00115 
00116         Action_A: 42 / 3.14 / hello world
00117         Action_B: 69 / 9.99 / interesting_value
00118     */
00119     return 0;
00120 }


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