步骤 3:URDF 与 xacro 建模
前置条件:完成步骤 2。 本步目标:理解并验证
mybot.urdf.xacro,得到一个结构合法的移动机器人模型。 预计时间:60-90 分钟。
1. 模型组成
mybot 由以下部件构成:
| Link | 类型 | 作用 |
|---|---|---|
base_link |
根链接 | 车体本体 |
left_wheel_link |
刚体 | 左驱动轮 |
right_wheel_link |
刚体 | 右驱动轮 |
caster_link |
刚体 | 后部支撑轮 |
laser_frame |
传感器 frame | 2D 激光雷达 |
camera_link |
传感器 frame | 前视 RGB 相机 |
关节:
| Joint | 类型 | 说明 |
|---|---|---|
left_wheel_joint |
continuous | 左轮连续旋转 |
right_wheel_joint |
continuous | 右轮连续旋转 |
caster_joint |
continuous | 支撑轮旋转 |
laser_joint |
fixed | 激光固定安装 |
camera_joint |
fixed | 相机固定安装 |
URDF 中三种几何标签的含义必须分清:
<visual>...</visual> <!-- 只负责显示 -->
<collision>...</collision> <!-- 参与物理碰撞 -->
<inertial>...</inertial> <!-- 决定质量和转动惯量 -->
只写 visual 的模型在 rviz 中可能可见,但进入 Gazebo 后会掉落、穿地或无法稳定接触地面。
2. 坐标约定
本实验固定使用 ROS 常见坐标方向:
x:机器人前方
y:机器人左侧
z:机器人上方
因此:
- 车体相机安装在正前方,
camera_joint的 x 为正; - 左右轮通过 y 方向镜像;
odom -> base_link表示机器人在里程计坐标系中的位姿;base_link -> laser_frame与base_link -> camera_link描述传感器安装位置。
3. 参数化
xacro 文件首先定义可复用参数:
<xacro:property name="base_length" value="0.42"/>
<xacro:property name="base_width" value="0.28"/>
<xacro:property name="base_height" value="0.12"/>
<xacro:property name="wheel_radius" value="0.05"/>
<xacro:property name="wheel_width" value="0.03"/>
<xacro:property name="wheel_separation" value="0.28"/>
<xacro:property name="wheel_offset_z" value="-0.07"/>
<xacro:property name="caster_radius" value="0.035"/>
<xacro:property name="caster_offset_z" value="-0.085"/>
修改这些参数后,必须同步考虑:
- 车轮是否仍然接触地面;
- 车体是否与地面碰撞;
- 差速插件中的轮径和轮距是否一致;
- Gazebo 生成模型的
z初值是否需要变化。
4. 车体与车轮
车体使用 box 几何体:
<link name="base_link">
<visual>
<geometry>
<box size="${base_length} ${base_width} ${base_height}"/>
</geometry>
</visual>
<collision>
<geometry>
<box size="${base_length} ${base_width} ${base_height}"/>
</geometry>
</collision>
<inertial>
<mass value="5.0"/>
<inertia ixx="0.090" ixy="0" ixz="0"
iyy="0.120" iyz="0" izz="0.155"/>
</inertial>
</link>
车轮使用 xacro 宏,左右轮共用同一套设置:
<xacro:macro name="wheel" params="prefix reflect">
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.57079632679 0 0"/>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_width}"/>
</geometry>
</visual>
</link>
<joint name="${prefix}_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<origin xyz="0 ${reflect * wheel_separation / 2.0} ${wheel_offset_z}"/>
<axis xyz="0 1 0"/>
</joint>
</xacro:macro>
最容易出错的地方:
- 圆柱默认轴是 z,忘记旋转 90 度会让车轮像圆盘一样直立;
- 左右轮镜像方向错误,会让机器人不能直行;
- 关节轴写错,差速插件给速度后车轮不会正确滚动。
5. 支撑轮与传感器
支撑轮让两轮机器人保持三点接触:
<joint name="caster_joint" type="continuous">
<parent link="base_link"/>
<child link="caster_link"/>
<origin xyz="-0.15 0 ${caster_offset_z}"/>
<axis xyz="0 1 0"/>
</joint>
激光和相机:
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="laser_frame"/>
<origin xyz="0 0 0.09"/>
</joint>
<joint name="camera_joint" type="fixed">
<parent link="base_link"/>
<child link="camera_link"/>
<origin xyz="0.20 0 0.06"/>
</joint>
传感器安装位置错误不会立刻让 Gazebo 崩溃,但会让地图、视觉和导航结果全部偏移。
6. 检查模型
展开 xacro:
xacro ~/catkin_ws/src/mybot_gazebo/urdf/mybot.urdf.xacro > /tmp/mybot.urdf
检查结构和链接关系:
check_urdf /tmp/mybot.urdf
urdf_to_graphiz /tmp/mybot.urdf
check_urdf 通过只代表结构合法,不代表物理参数正确。物理稳定性要在 Gazebo 中验证。
在 rviz 中查看 TF 和模型:
如果没有安装额外的 URDF 查看工具,本步骤只要求 check_urdf 通过;完整模型、TF 和传感器的首次显示安排在步骤 7中进行。若环境已安装 urdf_tutorial,也可以运行:
roslaunch urdf_tutorial display.launch model:=/tmp/mybot.urdf
7. 常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
| xacro 展开失败 | XML 语法或 ${} 表达式错误 |
检查标签是否闭合 |
check_urdf 报错 |
link/joint 父子关系不合法 | 检查 joint 的 parent 和 child |
| 模型在 Gazebo 中下陷 | 初始高度或支撑轮高度不对 | 调整 -z 和关节 origin |
| 模型抖动 | 质量或惯性矩阵不合理 | 让质量和几何尺寸匹配 |
| 车轮方向错误 | 关节轴或镜像方向错误 | 检查 axis 和 reflect |
| 相机看不到目标 | 相机朝向错误 | 检查 camera_joint 的 origin 和 rpy |
8. 本步验收
- [ ] 能解释 URDF 中 link 和 joint 的层级关系;
- [ ] 能说明 visual、collision 和 inertial 的区别;
- [ ]
xacro展开成功; - [ ]
check_urdf通过; - [ ] 能说出车轮、激光、相机的安装位置和坐标方向。
- 上一步:工作空间与功能包
- 返回教程总览
- 下一步:步骤 4:差速驱动与里程计