BehaviorTree.CPP.行为树XML格式(六)

The XML format

XML模式的基础

在第一个教程中,介绍了这个简单的树。

 <root main_tree_to_execute = "MainTree" >
     <BehaviorTree ID="MainTree">
        <Sequence name="root_sequence">
            <SaySomething   name="action_hello" message="Hello"/>
            <OpenGripper    name="open_gripper"/>
            <ApproachObject name="approach_object"/>
            <CloseGripper   name="close_gripper"/>
        </Sequence>
     </BehaviorTree>
 </root>

您可能会注意到:

  • 树的第一个标签是<root>。它应包含1个或多个标签<BehaviorTree>
  • 标签<BehaviorTree>应具有属性[ID]
  • 标签<root>应包含属性[main_tree_to_execute]
  • [main_tree_to_execute]如果文件包含多个<BehaviorTree>,则该属性为必填,否则为可选。
  • 每个TreeNode由单个标签表示。特别是:
    • 标签的名称是用于在工厂中注册TreeNodeID
    • 该属性[name]引用实例的名称,并且是可选的
    • 使用属性配置端口。在前面的示例中,该操作SaySomething需要输入端口message
  • 在子节点的数量方面:
    • ControlNodes容纳1到N个子节点。
    • DecoratorNodes和子树仅包含1个子项。
    • ActionNodesConditionNodes有没有子项。

端口重新映射和指向Blackboards条目的指针

如第二篇教程中所述,可以使用Blackboard中条目的名称(即BB的键/值对的键)来重新映射输入/输出端口。

BB密钥使用以下语法表示:{key_name}

在以下示例中:

  • 序列的第一个子节点打印"Hello"
  • 第二个子节点读取和写入包含在黑板条目“ my_message”中的值;
 <root main_tree_to_execute = "MainTree" >
     <BehaviorTree ID="MainTree">
        <Sequence name="root_sequence">
            <SaySomething message="Hello"/>
            <SaySomething message="{my_message}"/>
        </Sequence>
     </BehaviorTree>
 </root>

紧凑与显式表示

以下两种语法均有效:

 <SaySomething               name="action_hello" message="Hello World"/>
 <Action ID="SaySomething"   name="action_hello" message="Hello World"/>

我们将前一种语法称为“紧凑”,而后一种称为“显式”。用显式语法表示的第一个示例将变为:

 <root main_tree_to_execute = "MainTree" >
     <BehaviorTree ID="MainTree">
        <Sequence name="root_sequence">
           <Action ID="SaySomething"   name="action_hello" message="Hello"/>
           <Action ID="OpenGripper"    name="open_gripper"/>
           <Action ID="ApproachObject" name="approach_object"/>
           <Action ID="CloseGripper"   name="close_gripper"/>
        </Sequence>
     </BehaviorTree>
 </root>

即使紧凑语法更方便和易于编写,但它提供的有关TreeNode模型的信息也太少了。像Groot这样的工具需要显式语法或其他信息。可以使用标签添加此信息<TreeNodeModel>

为了使我们的树的精简版与Groot兼容,必须对XML进行如下修改:

 <root main_tree_to_execute = "MainTree" >
     <BehaviorTree ID="MainTree">
        <Sequence name="root_sequence">
           <SaySomething   name="action_hello" message="Hello"/>
           <OpenGripper    name="open_gripper"/>
           <ApproachObject name="approach_object"/>
           <CloseGripper   name="close_gripper"/>
        </Sequence>
    </BehaviorTree>

    <!-- the BT executor don't require this, but Groot does -->     
    <TreeNodeModel>
        <Action ID="SaySomething">
            <input_port name="message" type="std::string" />
        </Action>
        <Action ID="OpenGripper"/>
        <Action ID="ApproachObject"/>
        <Action ID="CloseGripper"/>      
    </TreeNodeModel>
 </root>

您可以在此处下载XML模式

子树

正如我们在本教程中所看到的,可以在另一棵树中包括一个子树,以避免在多个位置“复制和粘贴”同一棵树并降低复杂性。

假设我们想将很少的动作封装到behaviorTree"GraspObject"中(为方便起见,省略了属性[name])。

 <root main_tree_to_execute = "MainTree" >
 
     <BehaviorTree ID="MainTree">
        <Sequence>
           <Action  ID="SaySomething"  message="Hello World"/>
           <Subtree ID="GraspObject"/>    <!-- "GraspObject" -->
        </Sequence>
     </BehaviorTree>
     
     <BehaviorTree ID="GraspObject">
        <Sequence>
           <Action ID="OpenGripper"/>
           <Action ID="ApproachObject"/>
           <Action ID="CloseGripper"/>
        </Sequence>
     </BehaviorTree>  
 </root>

我们可能会注意到,整个树"GraspObject"在"SaySomething"之后执行。

包括外部文件

从2.4版本开始。

您可以采用类似于#include的方式包含外部文件在C++中。我们可以使用标签轻松地做到这一点:

  <include path="relative_or_absolute_path_to_file"> 

使用前面的示例,我们可以将两个行为树分成两个文件:

 <!-- file maintree.xml -->

 <root main_tree_to_execute = "MainTree" >

     <include path="grasp.xml"/>

     <BehaviorTree ID="MainTree">
        <Sequence>
           <Action  ID="SaySomething"  message="Hello World"/>
           <Subtree ID="GraspObject"/>
        </Sequence>
     </BehaviorTree>
  </root>
 <!-- file grasp.xml -->

 <root main_tree_to_execute = "GraspObject" >
     <BehaviorTree ID="GraspObject">
        <Sequence>
           <Action ID="OpenGripper"/>
           <Action ID="ApproachObject"/>
           <Action ID="CloseGripper"/>
        </Sequence>
     </BehaviorTree>  
 </root>

^ x ^
ROS用户注意事项

如果要在ROS包中查找文件,可以使用以下语法:

<include ros_pkg="name_package" path="path_relative_to_pkg/grasp.xml"/>

原文

posted @ 2020-12-19 10:49  hokori  阅读(1771)  评论(2编辑  收藏  举报