t06_wrap_legacy.cpp
Go to the documentation of this file.
00001 #include "behaviortree_cpp/xml_parsing.h"
00002 #include "behaviortree_cpp/loggers/bt_cout_logger.h"
00003 #include "behaviortree_cpp/blackboard/blackboard_local.h"
00004 
00005 
00011 // clang-format off
00012 const std::string xml_text = R"(
00013 
00014  <root main_tree_to_execute = "MainTree" >
00015      <BehaviorTree ID="MainTree">
00016         <SequenceStar name="root">
00017             <MoveTo  goal="-1;3;0.5" />
00018             <MoveTo  goal="${myGoal}" />
00019         </SequenceStar>
00020      </BehaviorTree>
00021  </root>
00022  )";
00023 
00024 // clang-format on
00025 
00026 // This is my custom type.
00027 // By default, we don't know how to read this from a NodeParameter.
00028 struct Point3D { double x,y,z; };
00029 
00030 // We want to create an ActionNode that calls the method MyLegacyMoveTo::go
00031 class MyLegacyMoveTo
00032 {
00033 public:
00034     bool go(Point3D goal)
00035     {
00036         printf("Going to: %f %f %f\n", goal.x, goal.y, goal.z);
00037         return true; // true means success in my legacy code
00038     }
00039 };
00040 
00041 // Similarly to the previous tutorials, we need to implement this parsing method,
00042 // providing a specialization of BT::convertFromString
00043 namespace BT
00044 {
00045 template <> Point3D convertFromString(const StringView& key)
00046 {
00047     // three real numbers separated by semicolons
00048     auto parts = BT::splitString(key, ';');
00049     if (parts.size() != 3)
00050     {
00051         throw std::runtime_error("invalid input)");
00052     }
00053     else
00054     {
00055         Point3D output;
00056         output.x  = convertFromString<double>(parts[0]);
00057         output.y  = convertFromString<double>(parts[1]);
00058         output.z  = convertFromString<double>(parts[2]);
00059         return output;
00060     }
00061 }
00062 }
00063 
00064 
00065 int main()
00066 {
00067     using namespace BT;
00068 
00069     MyLegacyMoveTo move_to;
00070 
00071     // Here we use a lambda that captures the reference of move_to
00072     auto MoveToWrapperWithLambda = [&move_to](TreeNode& parent_node) -> NodeStatus
00073     {
00074         Point3D goal;
00075         // thanks to paren_node, you can access easily the NodeParameters and the blackboard
00076         parent_node.getParam("goal", goal);
00077 
00078         // you can write and read the blackboard if you like
00079         //parent_node.blackboard() ....
00080 
00081         bool res = move_to.go( goal );
00082         // convert bool to NodeStatus
00083         return res ? NodeStatus::SUCCESS : NodeStatus::FAILURE;
00084     };
00085 
00086     BehaviorTreeFactory factory;
00087     // Register the lambda with BehaviorTreeFactory::registerSimpleAction
00088     factory.registerSimpleAction("MoveTo", MoveToWrapperWithLambda);
00089 
00090     auto blackboard = Blackboard::create<BlackboardLocal>();
00091     auto tree = buildTreeFromText(factory, xml_text, blackboard);
00092 
00093     // We set the entry "myGoal" in the blackboard.
00094     Point3D my_goal = {3,4,5};
00095     blackboard->set("myGoal", my_goal);
00096 
00097     NodeStatus status = NodeStatus::RUNNING;
00098     while (status == NodeStatus::RUNNING)
00099     {
00100         status = tree.root_node->executeTick();
00101     }
00102     return 0;
00103 }
00104 
00105 /* Expected output:
00106 
00107 Going to: -1.000000 3.000000 0.500000
00108 Going to: 3.000000 4.000000 5.000000
00109 
00110 The first MoveTo read the parameter from the string "-1;3;0.5"
00111 whilst the second from the blackboard, that contains a copy of the Point3D my_goal.
00112 
00113 */


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