3. Xacro宏定义与参数化

任务目标

本案例将使用Xacro宏定义重构URDF机械臂模型,实现参数化设计。完成本案例后,你可以通过修改少量参数(如连杆长度、关节限位)快速调整机械臂模型,无需逐行修改URDF中的重复XML代码。

环境依赖

  • ROS2(Humble或更新版本)
  • MoveIt2(用于后续运动规划,本案例仅需URDF/Xacro解析功能)
  • 安装xacro包:sudo apt install ros-$ROS_DISTRO-xacro

实现方案

创建一个两连杆机械臂的Xacro文件,使用宏定义连杆和关节结构,通过参数控制连杆长度、半径、颜色和关节限位。相比传统URDF,修改模型尺寸只需调整文件顶部的参数值。

关键完整代码

创建文件 robot_arm.xacro:

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="param_arm">

  <!-- 全局参数 -->
  <xacro:property name="link1_len" value="0.3"/>
  <xacro:property name="link2_len" value="0.25"/>
  <xacro:property name="link_radius" value="0.03"/>
  <xacro:property name="joint1_limit" value="1.57"/>
  <xacro:property name="joint2_limit" value="1.2"/>

  <!-- 连杆宏定义 -->
  <xacro:macro name="link_cylinder" params="name length radius color">
    <link name="${name}">
      <visual>
        <geometry>
          <cylinder length="${length}" radius="${radius}"/>
        </geometry>
        <material name="${color}">
          <color rgba="${color}"/>
        </material>
      </visual>
      <collision>
        <geometry>
          <cylinder length="${length}" radius="${radius}"/>
        </geometry>
      </collision>
      <inertial>
        <mass value="0.5"/>
        <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
      </inertial>
    </link>
  </xacro:macro>

  <!-- 关节宏定义 -->
  <xacro:macro name="revolute_joint" params="name parent child axis_xyz limit">
    <joint name="${name}" type="revolute">
      <parent link="${parent}"/>
      <child link="${child}"/>
      <origin xyz="0 0 ${link1_len}" rpy="0 0 0"/>
      <axis xyz="${axis_xyz}"/>
      <limit lower="-${limit}" upper="${limit}" effort="10" velocity="1.0"/>
    </joint>
  </xacro:macro>

  <!-- 使用宏构建机械臂 -->
  <link name="base_link"/>

  <xacro:link_cylinder name="link1" length="${link1_len}" radius="${link_radius}" color="0.8 0.2 0.2 1.0"/>
  <xacro:link_cylinder name="link2" length="${link2_len}" radius="${link_radius}" color="0.2 0.4 0.8 1.0"/>

  <joint name="joint1" type="revolute">
    <parent link="base_link"/>
    <child link="link1"/>
    <origin xyz="0 0 0.05" rpy="0 0 0"/>
    <axis xyz="0 0 1"/>
    <limit lower="-${joint1_limit}" upper="${joint1_limit}" effort="10" velocity="1.0"/>
  </joint>

  <xacro:revolute_joint name="joint2" parent="link1" child="link2" axis_xyz="0 1 0" limit="${joint2_limit}"/>

</robot>

运行与验证

  1. 解析Xacro为URDF:
    source /opt/ros/$ROS_DISTRO/setup.bash
    xacro robot_arm.xacro > robot_arm.urdf
  2. 检查模型结构:
    ros2 run urdf_tutorial display_urdf robot_arm.urdf
    或使用check_urdf robot_arm.urdf验证URDF语法。
  3. 参数化验证:修改文件顶部的link1_len为0.5,重新执行xacro命令,检查生成的URDF中link1的cylinder长度是否变为0.5。

通过条件:xacro命令无报错输出;生成的URDF包含2个连杆和2个关节;修改参数后重新生成,对应尺寸随之变化。

关键说明

  • 宏link_cylinder封装了连杆的visual/collision/inertial定义,revolute_joint封装了关节的通用属性,避免重复代码。
  • 关节宏中origin的z值固定使用${link1_len},这适用于本案例的串联结构;若需更通用,可将origin也作为宏参数传入。
  • 颜色参数直接传入RGBA字符串,便于通过参数调整外观。