How to create a BehaviorTree

网友投稿 270 2022-11-27

How to create a BehaviorTree

行为树类似于状态机,只是一种机制,在正确的条件下,正确的时间来唤醒回调函数。

进一步,我们使用callback和tick来相互替换;

这些回调函数里面具体执行什么取决于你;

怎样创建你自己的ActionNodes

默认的方法是采用继承的方式来实现一个TreeNode:

//Example of custom SyncActionNode(synchronous action) without ports.class ApproachObject : public BT::SyncActionNode{ public: ApproachObject(const std::string& name) : BT::SyncActionNode(name, {}) {} //You must override the virtual function tick() BT::NodeStatus tick() override { std::out << "ApproachObject: " << this->name() <

任何一个TreeNode的实例需要有一个名字,但不要求是唯一的;

方法tick()是实际行为发生的地方。它必须总是返回一个节点状态,如RUNNING,SUCCESS或者FAILURE。

另外,也可以用依赖注入的方式创建一个TreeNode,给定一个函数指针(如functor)

对functor唯一的要求是具有如下之一的表示:

BT::NodeStatus myFunction() BT::NodeStatus myFunction(BT::TreeNode& self)

例如:

using namespace BT;// Simple function that return a NodeStatusBT::NodeStatus CheckBattery(){ std::cout << "[ Battery: OK ]" << std::endl; return BT::NodeStatus::SUCCESS;}// We want to wrap into an ActionNode the methods open() and close()class GripperInterface{public: GripperInterface(): _open(true) {} NodeStatus open() { _open = true; std::cout << "GripperInterface::open" << std::endl; return NodeStatus::SUCCESS; } NodeStatus close() { std::cout << "GripperInterface::close" << std::endl; _open = false; return NodeStatus::SUCCESS; }private: bool _open; // shared information};

我们可以构建一个SimpleActionNode从下面的functors中的任何一个:

CheckBattery()GripperInterface::open()GripperInterface::close()

用一个XML来动态创建一棵树

XML文件命名为my_tree.xml:

You can find more details about the XML schema ​​here​​.

首先比如注册我们自定义的TreeNodes到BehaviorTreeFactory中,然后从文件或者text中加载XML;

在XML中使用的标志符必须与注册TreeNodes中使用的一致;

属性name表示实例的名字,它是可选的;

#include "behaviortree_cpp_v3/bt_factory.h"// file that contains the custom nodes definitions#include "dummy_nodes.h"int main(){ // We use the BehaviorTreeFactory to register our custom nodes BehaviorTreeFactory factory; // Note: the name used to register should be the same used in the XML. using namespace DummyNodes; // The recommended way to create a Node is through inheritance. factory.registerNodeType("ApproachObject"); // Registering a SimpleActionNode using a function pointer. // you may also use C++11 lambdas instead of std::bind factory.registerSimpleCondition("CheckBattery", std::bind(CheckBattery)); //You can also create SimpleActionNodes using methods of a class GripperInterface gripper; factory.registerSimpleAction("OpenGripper", std::bind(&GripperInterface::open, &gripper)); factory.registerSimpleAction("CloseGripper", std::bind(&GripperInterface::close, &gripper)); // Trees are created at deployment-time (i.e. at run-time, but only // once at the beginning). // IMPORTANT: when the object "tree" goes out of scope, all the // TreeNodes are destroyed auto tree = factory.createTreeFromFile("./my_tree.xml"); // To "execute" a Tree you need to "tick" it. // The tick is propagated to the children based on the logic of the tree. // In this case, the entire sequence is executed, because all the children // of the Sequence return SUCCESS. tree.tickRoot(); return 0;}/* Expected output:* [ Battery: OK ] GripperInterface::open ApproachObject: approach_object GripperInterface::close*/

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Fallback
下一篇:LG发布首款4K分辨率显示器Ultra Gear 27GP950
相关文章

 发表评论

暂时没有评论,来抢沙发吧~