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'