4. 使用xacro优化URDF

任务目标

将上一案例中直接编写的URDF文件重构为xacro格式,利用宏定义消除重复的关节与连杆定义,使机械臂模型更易于维护和参数化修改。

核心改动说明

本案例以6自由度机械臂为例,将URDF中重复的关节-连杆结构抽象为宏link_joint_macro,通过参数传入连杆名称、长度、质量等属性。宏内部自动生成连杆与关节的完整XML结构,调用时只需一行即可添加一个关节。同时将颜色、材料等常量提取为xacro属性,便于统一修改。

关键完整代码

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

  <!-- 全局属性:材料颜色 -->
  <xacro:property name="link_color" value="0.8 0.2 0.2 1.0"/>
  <xacro:property name="joint_color" value="0.2 0.2 0.8 1.0"/>

  <!-- 宏:生成一个连杆+关节(末端关节可选) -->
  <xacro:macro name="link_joint_macro" params="prefix parent child length mass is_last">
    <link name="${child}">
      <visual>
        <geometry>
          <box size="0.05 0.05 ${length}"/>
        </geometry>
        <material name="link_mat">
          <color rgba="${link_color}"/>
        </material>
      </visual>
      <collision>
        <geometry>
          <box size="0.05 0.05 ${length}"/>
        </geometry>
      </collision>
      <inertial>
        <mass value="0.5"/>
        <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001"/>
      </inertial>
    </link>

    <joint name="${prefix}_joint_${child}" type="revolute">
      <parent link="${parent}"/>
      <child link="${child}"/>
      <origin xyz="0 0 ${length/2}" rpy="0 0 0"/>
      <axis xyz="0 0 1"/>
      <limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
    </joint>

    <!-- 末端工具坐标 -->
    <xacro:if value="${is_last}">
      <link name="tool0"/>
      <joint name="tool_joint" type="fixed">
        <parent link="${child}"/>
        <child link="tool0"/>
        <origin xyz="0 0 ${length/2}" rpy="0 0 0"/>
      </joint>
    </xacro:if>
  </xacro:macro>

  <!-- 基座 -->
  <link name="base_link">
    <visual>
      <geometry><box size="0.1 0.1 0.05"/></geometry>
      <material name="base_mat">
        <color rgba="0.1 0.8 0.1 1.0"/>
      </material>
    </visual>
  </link>

  <!-- 通过宏生成6个关节 -->
  <xacro:link_joint_macro prefix="arm" parent="base_link" child="link1" length="0.3" mass="0.5" is_last="false"/>
  <xacro:link_joint_macro prefix="arm" parent="link1" child="link2" length="0.25" mass="0.4" is_last="false"/>
  <xacro:link_joint_macro prefix="arm" parent="link2" child="link3" length="0.25" mass="0.4" is_last="false"/>
  <xacro:link_joint_macro prefix="arm" parent="link3" child="link4" length="0.2" mass="0.3" is_last="false"/>
  <xacro:link_joint_macro prefix="arm" parent="link4" child="link5" length="0.2" mass="0.3" is_last="false"/>
  <xacro:link_joint_macro prefix="arm" parent="link5" child="link6" length="0.15" mass="0.2" is_last="true"/>

</robot>

运行与验证

环境依赖:ROS2(Humble或更新版本)、xacro包(ROS2自带)。

步骤:

  1. 将上述代码保存为 arm.xacro。
  2. 终端执行xacro展开,生成标准URDF:
ros2 run xacro xacro arm.xacro > arm.urdf
  1. 检查生成的URDF是否包含6个转动关节和1个固定工具关节:
grep -c "<joint" arm.urdf   # 预期输出:7
grep -c "<link" arm.urdf    # 预期输出:8(含base_link和tool0)

通过条件:上述grep计数与预期一致,且arm.urdf中无xacro:残留标签,说明宏展开成功。若在RViz中加载该URDF,应能看到6节串联连杆模型,且各关节可正常旋转。

常见问题

  • 宏参数未生效:检查xacro属性引用是否使用${}语法,且宏调用时参数顺序与定义一致。
  • 关节原点偏移错误:宏中origin xyz="0 0 ${length/2}"将子连杆原点置于父连杆末端,若需调整关节间距,修改此表达式即可。
  • 惯性参数不可用:若后续用于MoveIt2运动规划,需确保每个link均包含inertial块,本宏已默认添加,实际使用时可根据质量调整数值。