1. 程式人生 > >ROS官方教程[翻譯]---xacro的介紹與使用

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'

相關推薦

no