Glossary

Xacro

Xacro – definition

Xacro is an XML macro language used to generate URDF robot description files. Its name derives from XML Macros. In ROS and ROS 2, Xacro is commonly used to create maintainable robot models for mobile robots, including UGV platforms with multiple sensors, wheel configurations, payload variants, and alternative compute units.

A URDF file describes a robot as a kinematic tree of link and joint elements. Xacro extends this XML structure with reusable macros, properties, conditional expressions, file inclusion, and parameter substitution. The Xacro processor expands the source file into standard URDF XML before the description is consumed by tools such as robot_state_publisher, RViz, Gazebo Classic, Gazebo Sim, MoveIt, or navigation-related simulation environments.

For a mobile robot, Xacro is useful when the base platform remains constant but the sensor payload changes. A Leo Rover can, for example, use one Xacro configuration for its differential-drive chassis and separate optional macros for a LiDAR, Intel RealSense depth camera, IMU, GNSS receiver, or Jetson-based compute module. A Raph Rover can use the same approach for heavier payload configurations and larger sensor mounting structures.

How Xacro differs from URDF

URDF is the final robot-description format interpreted by ROS tools. Xacro is not a runtime robot model format. It is a preprocessing language that produces URDF. The generated output must be valid XML and must comply with the URDF elements required by the target software.

The practical distinction is important in ROS 2 deployments. A node such as robot_state_publisher receives the expanded URDF text through the robot_description parameter. It does not normally process Xacro syntax itself.

Aspect URDF Xacro
Primary role Robot kinematic and visual description Generation of reusable URDF XML
Syntax Standard XML with URDF tags XML plus xacro: elements and expressions
Reuse mechanism Limited Macros, properties, includes, arguments
ROS 2 runtime input Typically passed as robot_description Expanded before or during launch

Core Xacro elements

Xacro reduces duplication in robot descriptions. This is particularly relevant for four-wheel UGVs, where repeated wheel geometry, collision models, wheel joints, and sensor frames would otherwise be written manually.

The following constructs are used most often in ROS 2 robot-description packages:

  • <xacro:property> defines a named value, such as wheel radius, chassis length, mass, or sensor offset.
  • <xacro:macro> defines reusable XML content with parameters.
  • <xacro:include> imports macros or common material definitions from another Xacro file.
  • <xacro:arg> defines an argument that can be set when processing the file.
  • <xacro:if> and <xacro:unless> conditionally include XML sections.
  • ${...} evaluates supported expressions and substitutes property values.

A simplified wheel macro can define geometry and a continuous joint once, then instantiate it for each wheel position. The joint axis for a conventional differential-drive wheel is usually aligned with the wheel axle. The exact axis and transform must match the coordinate convention of the physical platform and its encoder driver.

<xacro:macro name="wheel" params="name parent xyz">
  <link name="${name}_link">
    <visual>
      <geometry>
        <cylinder radius="${wheel_radius}" length="${wheel_width}"/>
      </geometry>
    </visual>
  </link>

  <joint name="${name}_joint" type="continuous">
    <parent link="${parent}"/>
    <child link="${name}_link"/>
    <origin xyz="${xyz}" rpy="1.5708 0 0"/>
    <axis xyz="0 0 1"/>
  </joint>
</xacro:macro>

Xacro in ROS 2 robot-description workflows

In ROS 2, Xacro is usually processed by a launch file. The resulting URDF is assigned to the robot_description parameter of robot_state_publisher. The node publishes transforms for fixed joints and computes transforms for movable joints from joint states received through the /joint_states topic.

For a UGV, the description should define a stable frame hierarchy. A common structure is base_link or base_footprint as the vehicle reference frame, followed by fixed frames for sensors. Navigation, mapping, and perception nodes depend on correct transforms between these frames.

from launch_ros.actions import Node
from launch.substitutions import Command, FindExecutable
from launch_ros.substitutions import FindPackageShare
from launch.substitutions import PathJoinSubstitution

robot_description = Command([
    FindExecutable(name="xacro"),
    " ",
    PathJoinSubstitution([
        FindPackageShare("my_rover_description"),
        "urdf",
        "rover.urdf.xacro"
    ]),
    " use_lidar:=true"
])

robot_state_publisher = Node(
    package="robot_state_publisher",
    executable="robot_state_publisher",
    parameters=[{"robot_description": robot_description}]
)

Sensor integration for Leo Rover and Raph Rover

On Leo Rover, Xacro can document the physical placement of added sensors without implying that autonomy is available by default. Leo Rover provides ROS 2 integration and uses a differential-drive, four-wheel base. A navigation stack still requires separate integration of odometry, sensor drivers, localization or SLAM, costmaps, and safety logic.

For sensor integration, each sensor macro should define a fixed joint from the chassis frame to the sensor frame. The transform must be measured from the real installation. Incorrect translation or rotation values degrade LiDAR scan matching, visual odometry, depth processing, and sensor fusion.

  • LiDAR models commonly require a frame such as laser or lidar_link.
  • IMU drivers commonly publish measurements in an imu_link frame.
  • Depth cameras may expose separate optical frames. ROS optical-frame conventions are defined by REP 103.
  • GNSS and RTK antennas require an accurately measured antenna reference point relative to base_link.

Raph Rover configurations may include larger batteries, enclosures, mast-mounted sensors, or heavier research payloads. Xacro allows these variants to share a common base description while keeping payload-specific mass, collision, visual, and transform data in separate files.

Validation and limitations

Xacro can report XML parsing and expansion errors, but it does not verify that the model matches the physical robot or that the generated URDF is semantically valid. It cannot confirm wheel radius, sensor extrinsics, collision clearance, inertial properties, or TF consistency. These values require measurement, CAD data, manufacturer specifications, and system-level testing.

A basic validation workflow should include the following steps:

  • Expand the file with xacro and inspect XML errors.
  • Check the URDF with check_urdf, where available in the installed ROS environment.
  • Visualize links, joints, and frames in RViz.
  • Verify the live TF tree with tf2_tools view_frames.
  • Compare sensor frame orientation and position against the installed hardware.
ros2 run xacro xacro rover.urdf.xacro > rover.urdf
check_urdf rover.urdf
ros2 run tf2_tools view_frames

Normative references and documentation

Xacro is maintained as part of the ROS ecosystem. ROS 1 and ROS 2 both use Xacro, but package versions, Python compatibility, launch mechanisms, and supported ROS distributions differ. ROS 2 projects should use the Xacro package and documentation available for their installed distribution, such as Humble, Jazzy, or later.

See also