ROS官方教程[翻譯]---xacro的介紹與使用

ROS官方教程[翻譯]—xacro的介紹與使用

本教程基於ROS官方xacro教程中jade版本ROS翻譯

功能包綜述

Xacro(XML Macros)Xacro是一種XML宏語言。 使用xacro,您可以通過使用宏命令構建更精悍短小但又具有更高可讀性的XML文件,這種宏命令可以擴展達到更大的XML表達範圍。
- 維護狀態:正在開發中
- 維護方:Morgan Quigley
- 作者:Stuart Glaser, William Woodall, Robert Haschke
- 許可證:BSD
- 漏洞和特徵彙報鏈接:https://github.com/ros/xacro/issues
- 源:git https://github.com/ros/xacro.git (branch: jade-devel)

目錄

  • 1.案例
  • 2.屬性和屬性塊
  • 3.數學表達式
  • 4.條件塊
  • 5.Rospack命令
  • 6.宏命令
    • 6.1默認參數
    • 6.2局部屬性
  • 7.包含其他xacro文件
  • 8.YAML語言支持
  • 9.用CMakeLists.txt進行構建
  • 10.元素和屬性
  • 11.處理訂單
  • 12.已棄用的語法

此包在處理大型XML文檔(如機器人說明)時最爲有用。 它在如urdf的包中大量使用。 通過看下面的例子,本教程教您如何使用xacro來簡化urdf文件。

1.案例

參考以下的Xacro XML片段:

<xacro:macro name="pr2_arm" params="suffix parent reflect">
  <pr2_upperarm suffix="${suffix}" reflect="${reflect}" parent="${parent}" />
  <pr2_forearm suffix="${suffix}" reflect="${reflect}" parent="elbow_flex_${suffix}" />
</xacro:macro>

<xacro:pr2_arm suffix="left" reflect="1" parent="torso" />
<xacro:pr2_arm suffix="right" reflect="-1" parent="torso" />

上面的片段擴展成爲下面的樣子:

<pr2_upperarm suffix="left" reflect="1" parent="torso" />
<pr2_forearm suffix="left" reflect="1" parent="elbow_flex_left" />
<pr2_upperarm suffix="right" reflect="-1" parent="torso" />
<pr2_forearm suffix="right" reflect="-1" parent="elbow_flex_right" />

如果我們還定義了pr2_upperarm和pr2_forearm的宏,那麼這個片段可以擴展以描述整個機器人臂。
本頁的其餘部分描述了xacro的功能。

2.屬性和屬性塊

屬性是可以插入到XML文檔中的任何位置的值。 屬性塊是XML的名稱片段,可以插入允許XML的任何位置。 兩者都使用屬性標籤來定義值。屬性標記不能在xacro:宏中聲明。以下示例將顯示如何聲明和使用屬性:

<xacro:property name="the_radius" value="2.1" />
<xacro:property name="the_length" value="4.5" />

<geometry type="cylinder" radius="${the_radius}" length="${the_length}" />

通過將名稱放在dollared-braces( {”,你應該將其轉義爲“$$ {”。
下面是使用屬性塊的示例:

<xacro:property name="front_left_origin">
  <origin xyz="0.3 0 0" rpy="0 0 0" />
</xacro:property>

<pr2_wheel name="front_left_wheel">
  <xacro:insert_block name="front_left_origin" />
</pr2_wheel>

3.數學表達式

在dollared-braces($ {})中,您還可以編寫簡單的數學表達式。 目前,該結構支持基本算術和變量替換。 下面是一個例子:

<xacro:property name="pi" value="3.1415926535897931" />
<circle circumference="${2.5 * pi}" />

Jade版本的ROS中更新的地方:

自ROS Jade以來,Xacro使用python來評估包含在dollared-braces($ {})中的表達式。 這允許用戶使用更復雜的算術表達式。 此外,一些基本常數,例如 pi,已經被預定義過了:

<xacro:property name="R" value="2" />
<xacro:property name="alpha" value="${30/180*pi}" />
<circle circumference="${2 * pi * R}" pos="${sin(alpha)} ${cos(alpha)}" />

4.條件塊

Hydro版本的ROS中更新的地方:

自從ROS Hydro以來,Xacro有類似於roslaunch的條件塊。 這對於可配置的機器人或加載不同的Gazebo插件等事情很有用。 它遵循以下語法:

<xacro:if value="<expression>">
  <... some xml code here ...>
</xacro:if>
<xacro:unless value="<expression>">
  <... some xml code here ...>
</xacro:unless>

表達式需要計算結果爲“0”,“1”,“true”或“false”,否則將拋出錯誤。

Jade版本的ROS中更新的地方:

ROS Jade中更強大的評估功能允許使用更復雜的表達式。 幾乎任何python表達式的計算結果都是可行的:

<xacro:property name="var" value="useit"/>
<xacro:if value="${var == 'useit'}"/>
<xacro:if value="${var.startswith('use') and var.endswith('it')}"/>

<xacro:property name="allowed" value="[1,2,3]"/>
<xacro:if value="${1 in allowed}"/>

5.Rospack命令

Xacro允許你使用某些rospack命令和dollared括號($())。

<foo value="$(find xacro)" />
<foo value="$(arg myvar)" />

Xacro目前支持roslaunch使用替換args支持的所有rospack命令。 參數需要在命令行中使用myvar:= true語法指定。

Indigo版本的ROS中更新的地方:

自從ROS Indigo,它也可以定義默認值如下:

<xacro:arg name="myvar" default="false"/>

使用上面的定義語句,你可以像下面這樣運行xacro:

<param name="robot_description" command="$(find xacro)/xacro.py $(arg model) myvar:=true" />

6.宏命令

xacro的主要特性是它對宏的支持。 使用宏標籤定義宏,並指定宏名稱和參數列表。 參數列表應以空格分隔。 它們變成宏觀本地屬性。

<xacro:macro name="pr2_caster" params="suffix *origin **content **anothercontent">
  <joint name="caster_${suffix}_joint">
    <axis xyz="0 0 1" />
  </joint>
  <link name="caster_${suffix}">
    <xacro:insert_block name="origin" />
    <xacro:insert_block name="content" />
    <xacro:insert_block name="anothercontent" />
  </link>
</xacro:macro>

<xacro:pr2_caster suffix="front_left">
  <pose xyz="0 1 0" rpy="0 0 0" />
  <container>
    <color name="yellow"/>
    <mass>0.1</mass>
  </container>
  <another>
    <inertial>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <mass value="1"/>
      <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
    </inertial>
  </another>
</xacro:pr2_caster>

該示例聲明瞭一個宏“pr2_caster”,它有兩個參數:suffix和origin。 請注意,“origin”已加星標。 這表明origin是一個塊參數,而不是一個簡單的文本參數。 向前看pr2_caster的使用。 後綴屬性在pr2_caster標記中定義爲屬性,但沒有定義origin屬性。 相反,origin指的是第一個元素(在這種情況下是“pose”塊)。 雙星號版本(“content”,“anothercontent”)允許插入在隨後可用的元素(在上面的示例中分別是“container”,“another”)中傳遞的任意數量的元素。 此示例擴展爲以下內容:

<joint name="caster_front_left_joint">
  <axis xyz="0 0 1" />
</joint>
<link name="caster_front_left">
  <pose xyz="0 1 0" rpy="0 0 0" />
  <color name="yellow" />
  <mass>0.1</mass>
  <inertial>
    <origin xyz="0 0 0.5" rpy="0 0 0"/>
    <mass value="1"/>
    <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
  </inertial>
</link>

將按指定的順序處理多個塊參數:

<xacro:macro name="reorder" params="*first *second">
  <xacro:insert_block name="second"/>
  <xacro:insert_block name="first"/>
</xacro:macro>
<reorder>
  <first/>
  <second/>
</reorder>

宏可能包含其他宏。 外部宏將首先展開,然後內部宏將展開。 例如:

<a>
  <xacro:macro name="foo" params="x">
    <in_foo the_x="${x}" />
  </xacro:macro>

  <xacro:macro name="bar" params="y">
    <in_bar>
      <xacro:foo x="${y}" />
    </in_bar>
  </xacro:macro>

  <xacro:bar y="12" />
</a>

變成:

<a>
  <in_bar>
    <in_foo the_x="12.0"/>
  </in_bar>
</a>

6.1默認參數

Indigo中更新

宏參數可以有默認值:

<xacro:macro name="foo" params="x:=${x} y:=${2*y} z:=0"/>

如果默認值包含評估表達式,則將在實例化時評估它們。

Jade中更新

通常,您需要將外部變量傳遞到本地宏參數(如上面的x)。 要簡化此任務,可以使用^語法:

<xacro:macro name="foo" params="p1 p2:=expr_a p3:=^ p4:=^|expr_b">

插入符號^表示使用外部scope屬性(具有相同名稱)。 管| 表示如果屬性未在外部範圍中定義,則使用給定的回退。

6.2局部屬性

Jade中更新

在宏中定義的屬性和宏在此宏的本地,即在外部不可見。 使用可選屬性scope =“parent | global”,屬性定義可以導出到宏的父作用域(或全局作用域)。

7.包含其他xacro文件

您可以使用xacro:include標記來包含其他xacro文件:

<xacro:include filename="$(find package)/other_file.xacro" />
<xacro:include filename="other_file.xacro" />
<xacro:include filename="$(cwd)/other_file.xacro" />

文件“other_file.xacro”將被xacro包含和擴展。 Jade中的新功能:相對文件名相對於當前處理的文件進行解釋。 注意:當在宏中包含文件時,不是宏定義,而是宏調用文件是處理包含! $(cwd)顯式允許訪問當前工作目錄中的文件。
爲了避免各種包含文件的屬性和宏之間的名稱衝突,可以爲包含的文件指定命名空間 - 提供屬性ns:

<xacro:include filename="other_file.xacro" ns="namespace"/>

訪問命名空間宏和屬性是通過預先命名空間來實現的,用點分隔:

${namespace.property}

8.YAML語言支

Jade中的新功能

屬性可以是用python語法過度聲明的字典或列表,如下所示:

<xacro:property name="props" value="${dict(a=1, b=2, c=3)}"/>
<xacro:property name="numbers" value="${[1,2,3,4]}"/>

或者從YAML文件中加載,如下:

<xacro:property name="props" value="${load_yaml('props.yaml')}"/

注意,評估括號$ {}區分評價和純文本定義。 校準數據是從YAML加載的理想候選。

9.用CMakeLists.txt進行構建

以下代碼段顯示如何在程序包的申明期間使用xacro:

# Generate .world files from .world.xacro files
find_package(xacro REQUIRED)
# You can also add xacro to the list of catkin packages:
#   find_package(catkin REQUIRED COMPONENTS ... xacro)

# Xacro files
file(GLOB xacro_files ${CMAKE_CURRENT_SOURCE_DIR}/worlds/*.world.xacro)

foreach(it ${xacro_files})
  # remove .xacro extension
  string(REGEX MATCH "(.*)[.]xacro$" unused ${it})
  set(output_filename ${CMAKE_MATCH_1})

  # create a rule to generate ${output_filename} from {it}
  xacro_add_xacro_file(${it} ${output_filename})

  list(APPEND world_files ${output_filename})
endforeach(it)

# add an abstract target to actually trigger the builds
add_custom_target(media_files ALL DEPENDS ${world_files})

Jade中的新功能:

雖然這個cmake代碼提供了對目標名稱和構建順序的完全控制,但還有一個easyilities宏:

file(GLOB xacro_files worlds/*.world.xacro)
xacro_add_files(${xacro_files} TARGET media_files)

10.元素與屬性

Jade中的新功能:

要使用動態定義的名稱添加元素或屬性,可以使用特殊的xacro標記

<xacro:element xacro:name="${element_name}" [other attributes]>
 [content]
</xacro:element>
<xacro:attribute name="${attribute_name}" value="${attribute_value}"/>

11.處理訂單

Classicly Xacro首先加載所有包含項,然後處理所有屬性和宏定義,最後實例化宏並評估表達式。 因此,後期定義的屬性或宏定義將覆蓋先前的定義。 此外,條件標籤和對宏或屬性定義以及包含其他文件沒有影響。

Jade中的新功能:

自ROS Jade以來,Xacro提供了命令行選項–inorder,允許以讀取順序處理整個文檔。 因此,將使用目前爲止看到的屬性或宏的最新定義。 這是一個更直觀的評估過程,提供了一些不錯的新功能:

  • 如果標籤分別放置在宏內或條件標籤中,則可以推遲或完全禁止包含文件。
  • 包含文件名可以通過屬性或宏參數指定。
  • 通過更改全局範圍的屬性,如果在宏中使用這些屬性,則宏的實例化可以產生不同的結果。
  • 屬性定義可以是有條件的。
  • 宏可以在本地範圍內定義屬性,而不會影響外部。

因爲 - 順序處理更強大,在未來Jade以後的版本,新的處理風格將成爲默認風格,所以你應該檢查你的xacro文件的兼容性。 通常,兩種加工方式應該給出相同的結果。 你可以很容易地像下面這樣檢查:

rosrun xacro xacro file.xacro > /tmp/old.xml
rosrun xacro xacro --inorder file.xacro > /tmp/new.xml
diff /tmp/old.xml /tmp/new.xml

如果結果顯示出任何差異,你應檢查並調整您的xacro文件。 常見的原因是校準數據後期進行了加載(作爲屬性)。 在這種情況下,只需將加載行爲向前移動,即在使用之前進行校準數據的加載。 爲了方便搜索錯誤放置的屬性定義,可以使用選項–check-order運行xacro。 如果有任何有問題的屬性,它們將在stderr上列出:

Document is incompatible to --inorder processing.
The following properties were redefined after usage:
foo redefined in issues.xacro

使用命令行選項-vv或-vvv,可以增加詳細程度級別以記錄屬性的所有定義。

12.已棄用的語法

Jade中的新功能:

雖然在以前的版本中,沒有命名空間前綴的xacro標籤能夠被接受並使用,但是這種草率的語法是我們應當強烈反對的,因爲它阻止在最終的XML中使用這些標籤。 從Jade開始,這種語法已被棄用,你應該相應地更新你的文件。 以下腳本將爲您更新文件:

find . -iname "*.xacro" | xargs sed -i 's#<\([/]\?\)\(if\|unless\|include\|arg\|property\|macro\|insert_block\)#<\1xacro:\2#g'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章