行为树notes

注册节点

#include "behaviortree_cpp_v3/bt_factory.h"
using namespace BT;
BehaviorTreeFactory factory;

// 下面的funciton指的是:
// BT::NodeStatus FunctionName() {}

// 1.registerNodeType<ClassName>("nodeName"); 这里的类需要继承BT::SyncActionNode
factory.registerNodeType<SaySomething>("SaySomething");

// 2.registerSimpleCondition("nodeName", function)
factory.registerSimpleCondition("CheckBattery", std::bind(CheckBattery));

// 3.普通类
GripperInterface gripper;
factory.registerSimpleAction("OpenGripper", std::bind(&GripperInterface::open, &gripper));

// 4.registerSimpleAction("nodeName", function, portsList);
PortsList say_something_ports = { InputPort<std::string>("message") };
factory.registerSimpleAction("SaySomething2", SaySomethingSimple,
                                 say_something_ports );

// 5.registerBuilder
NodeBuilder builder_A = [](const std::string& name, const NodeConfiguration& config) {
    return std::make_unique<Action_A>(name, config, 42, 3.14, "hello world");
  };
factory.registerBuilder<Action_A>("Action_A", builder_A);

创建行为树

BehaviorTreeFactory factory;
// 1.from file,第二个参数可以传入黑板
auto tree = factory.createTreeFromFile("source/turtle2.xml");

// 2.from text,第二个参数可以传入黑板
std::string text;
auto tree = factory.createTreeFromText(text);

//3.第二个参数可以传入黑板
auto tree = factory.createTree("name", blackboard)

注册行为树

// 方法一 有效
static const char* xml_text_main = R"(
<root main_tree_to_execute="MainTree">
    <BehaviorTree ID="MainTree">
        <Sequence>
            <SaySomething message="starting MainTree" />
            <SubTree ID="SubA"/>
            <SubTree ID="SubB"/>
        </Sequence>
    </BehaviorTree>
</root>  )";
factory.registerBehaviorTreeFromText(xml_text_main);
// 方法二 写demo测试有问题
factory.registerBehaviorTreeFromFile("main_tree.xml");

节点的参数传递与对应的注册方法

// 方法一
class Action_A : public SyncActionNode
{
public:
  // additional arguments passed to the constructor
  Action_A(const std::string& name, const NodeConfiguration& config, int arg1,
           double arg2, std::string arg3) :
    SyncActionNode(name, config), _arg1(arg1), _arg2(arg2), _arg3(arg3)
  {}
    
  static PortsList providedPorts()
  {
    return {};
  }
    
   ...
}

// 方法二
class Action_B : public SyncActionNode
{
public:
  Action_B(const std::string& name, const NodeConfiguration& config) :
    SyncActionNode(name, config)
  {}

  // we want this method to be called ONCE and BEFORE the first tick()
  void init(int arg1, double arg2, std::string arg3)
  {
    _arg1 = (arg1);
    _arg2 = (arg2);
    _arg3 = (arg3);
  }
    
  static PortsList providedPorts()
  {
    return {};
  }
    
  ...
}

// 对应的注册方式也不一样
BehaviorTreeFactory factory;
NodeBuilder builder_A = [](const std::string& name, const NodeConfiguration& config) {
    return std::make_unique<Action_A>(name, config, 42, 3.14, "hello world");
  };
factory.registerBuilder<Action_A>("Action_A", builder_A);

factory.registerNodeType<Action_B>("Action_B");
auto tree = factory.createTreeFromText(xml_text);

for (auto& node : tree.nodes)
{
    if (auto action_B_node = dynamic_cast<Action_B*>(node.get()))
    {
        action_B_node->init(69, 9.99, "interesting_value");
    }
}
Type of ControlNodeChild returns RUNNING
FallbackTick again
ReactiveFallbackRestart
  • 重新开始”意味着整个回退将从列表的第一个子节点重新开始。
  • 再次触发”意味着下次触发回退时,同一子节点将再次被触发。已经返回失败的前一个兄弟节点不会再次被触发。
Type of ControlNodeChild returns FAILUREChild returns RUNNING
SequenceRestartTick again
ReactiveSequenceRestartRestart
SequenceStarTick againTick again

数据流、端口和黑板

  • 一个黑板是树的所有节点共享的键/值存储

  • 端口是节点之间交换信息的机制。

  • 端口用黑板的相同键进行连接

  • 节点的数量、名称和类型端口必须在编译时(C++)知道;端口之间的连接在部署时(XML)完成

Types of nodes

Type of TreeNodeChildren CountNotes
ControlNode1…N通常,根据其兄弟节点的状态和/或自身状态来确定一个子节点是否执行
DecoratorNode1可能会改变子节点的结果或多次tick它
ConditionNode0不应该改变系统,不应该返回RUNNING
ActionNode0它可以改变系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值