- Code API
- diamondback
- electric
- unstable - Tutorials
- Troubleshooting
- FAQ
- Reviews (doc reviewed)
Used by (43)
Stack Summary
Xacro is an XML macro language. With xacro, you can construct shorter and more readable XML files by using macros that expand to larger XML expressions.
- Author: Maintained by Stu Glaser
- License: BSD
- Repository: wg-kforge
- Source: hg https://kforge.ros.org/common/xacro
Contents
New in Electric: filters is now a separate stack. In previous releases, it was part of common.
This package is most useful when working with large XML documents such as robot descriptions. It is heavily used in packages such as the urdf. See for example, this tutorial for how xacro is used to simplify urdf files.
Example
Consider the following Xacro XML snippet:
<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" />
This snippet expands to:
<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" />
If we also define macros for pr2_upperarm and pr2_forearm, then this snippet could expand to describe an entire robotic arm.
The remainder of this document describes the features of xacro.
Property and Property Blocks
Properties are named values that can be inserted anywhere into the XML document. Property blocks are named snippets of XML that can be inserted anywhere that XML is allowed. Both use the property tag to define values. Property tags cannot be declared inside of a xacro:macro. The following example shows how to declare and use a property:
<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}" />
The two properties are inserted into the geometry expression by placing the names inside dollared-braces (${}). If you want a literal "${", you should escape it as "$${".
Here's an example of using a property block:
<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>
Math expressions
Within dollared-braces (${}), you can also write simple math expressions. Currently, basic arithmetic and variable substitution is supported. Here's an example:
<xacro:property name="pi" value="3.1415926535897931" /> <circle circumference="${2.5 * pi}" />
Rospack commands
Xacro allows you to use certain rospack commands with dollared-parentheses ($()).
<foo value="$(find xacro)" />
Xacro currently supports all the rospack commands that roslaunch supports using substitution args
Macros
The main feature of xacro is its support for macros. Define macros with the macro tag, and specify the macro name and the list of properties. The list of properties should be whitespace separated.
<xacro:macro name="pr2_caster" params="suffix *origin"> <joint name="caster_${suffix}_joint"> <axis xyz="0 0 1" /> </joint> <link name="caster_${suffix}"> <xacro:insert_block name="origin" /> </link> </xacro:macro> <xacro:pr2_caster suffix="front_left"> <pose xyz="0 1 0" rpy="0 0 0" /> </xacro:pr2_caster>
The example declares a macro "pr2_caster", which takes two properties: suffix and origin. Note that "origin" is starred. This indicates that origin is a block property instead of a normal property. Look ahead to the use of pr2_caster. The suffix property is defined in the pr2_caster tag, but no origin property is defined. Instead, origin refers to everything contained inside the use of pr2_caster (the "pose" block, in this case). This example expands to the following:
<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" /> </link>
Macros may contain other macros. The outer macro will be expanded first, and then the inner macro will be expanded. For example:
<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>
becomes:
<a> <in_bar> <in_foo the_x="12.0"/> </in_bar> </a>
Building from CMakeLists.txt
The following snippet shows how to use xacro during a package's make call:
# Generate .world files from .world.xacro files rosbuild_find_ros_package(xacro) include(${xacro_PACKAGE_PATH}/cmake/xacro.cmake) set(world_files "") # Xacro files file(GLOB model_xacro_files ${CMAKE_CURRENT_SOURCE_DIR}/worlds/*/*.xacro) # Dependency files file(GLOB world_xacro_files ${CMAKE_CURRENT_SOURCE_DIR}/worlds/*.world.xacro) foreach(it ${world_xacro_files}) get_filename_component(basepath ${it} PATH) get_filename_component(basename ${it} NAME_WE) message(" processing world file :",${basepath}," : ",${basename}) set(expanded_file "${basepath}/${basename}.world") message(" produce expanded file :",${expanded_file}) xacro_add_xacro_file(${it} ${expanded_file}) set(world_files ${world_files} ${expanded_file}) endforeach(it) add_custom_target(media_files ALL DEPENDS ${world_files})