BT13:行为树内外的数据传输2

大家好,欢迎大家关注我的知乎专栏慢慢悠悠小马车


本文是继 BT11:行为树内外的数据传输 - 知乎 之后更深入的从源码角度分析BehaviorTree.CPP的Blackboard的数据传输机制,是这一系列文章的精华。

树内即ports之间

类Blackboard(以下简称BB或bb)有3个重要的数据成员:BT中数据的保存依赖于storage_(Entry集合),树间的映射依赖于parent_和internal_to_external_。

// 保存了blackboard的所有entry的信息,包含entry所对应的port的实时值
std::unordered_map<std::string, Entry> storage_;
// 指向父blackboard(父树的blackboard)的指针
// 若不是nullptr,说明该tree被其他树引用了,是subtree
std::weak_ptr<Blackboard> parent_bb_;
// 保存了blackboard中向外(向父blackboard)重映射的port名称
std::unordered_map<std::string, std::string> internal_to_external_;
struct Entry {
  Any value;                 // port的值
  const PortInfo port_info;  // port的其他信息

  Entry(const PortInfo& info) : port_info(info) {}
  Entry(Any&& other_any, const PortInfo& info)
      : value(std::move(other_any)), port_info(info) {}
};

我们可以理解为:node的数据读写通过port,但数据是放在对应着该port的Entry中,树中所有nodes的数据整体放在blackboard的storage_中。这是通过xml中如下语句实现的,EntryName就是storage_中元素的第1项string,“{EntryName}”是1个blackboard pointer。

<NodeName  PortName="{EntryName}" />

上面的语句不涉及树之间的关系,所以对internal_to_external_没影响。

<root main_tree_to_execute = "MainTree" >
  <BehaviorTree ID="MainTree">
    <Sequence>
      <SaySomething message="666" />
      <ThinkWhatToSay text="{the_answer}"/>
      <SaySomething message="{the_answer}" />
    </Sequence>
  </BehaviorTree>
</root>

以BehaviorTree.CPP/examples/t02_basic_ports.cpp中的树为例,如上。当树构建第1个SaySomething节点时,在XMLParser::Pimpl::createNodeFromXML()中,会将pair{message,666}存入该node.config_.input_ports中。其中,config_是NodeConfiguration类型,input_ports是PortsRemapping类型,即unordered_map<string, string>类型。因为“666”是普通的字面字符串,不是blackboard pointer(不带花括号),就与blackboard无关,数据是静态的,node构建后就不会改变,所以这个数据是存在node自身的数据结构中,当获取名为message的port的值时,也不会去bb中查找。

struct NodeConfiguration {
  Blackboard::Ptr blackboard;
  PortsRemapping input_ports;    // 输入port的映射关系
  PortsRemapping output_ports;   // 输出port的映射关系
};

当树构建ThinkWhatToSay节点时,会将pair{text,{the_answer}}存入该node.config_.input_ports中。发现"{the_answer}"是bb pointer,就会把pair{the_answer, Entry}存入所在树的bb的storage_。此时Entry还未赋值,因为树构建时节点并未运行tick(),也就没有对port数据的任何操作,仅仅定义了关系。这样,通过text port读写值,就变成了对bb的名为the_answer的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值