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自带)。
步骤:
- 将上述代码保存为
arm.xacro。 - 终端执行xacro展开,生成标准URDF:
ros2 run xacro xacro arm.xacro > arm.urdf
- 检查生成的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块,本宏已默认添加,实际使用时可根据质量调整数值。