1. 程式人生 > 實用技巧 >6.行為樹(Behavior Tree)XML格式

6.行為樹(Behavior Tree)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"/>

原文