从零掌握 URDF 建模:基础结构、xacro 宏、Transmission、Fusion360 导出及常见问题。
一、URDF 基础结构
一个 link 包含三个核心标签:
1 | <link name="car_link"> |
| 标签 | 作用 | 缺失后果 |
|---|---|---|
visual |
图形界面显示 | 看不到模型 |
collision |
传感器/碰撞检测 | 激光雷达穿透、不碰撞 |
inertial |
物理引擎驱动 | Gazebo 中无法驱动 |
geometry 支持的类型
1 | <box size="x y z"/> <!-- 立方体 --> |
自定义 STL 文件时,尽量用碰撞箱包裹——STL 碰撞面复杂得多,严重影响仿真性能。
二、Joint:连接 link
1 | <joint name="joint_name" type="revolute"> |
Joint 类型:
| type | 说明 | 自由度 |
|---|---|---|
fixed |
固定连接 | 0 |
revolute |
旋转关节(有角度限制) | 1 |
continuous |
连续旋转(无限制) | 1 |
prismatic |
滑动关节 | 1 |
floating |
6 自由度浮动 | 6 |
三、xacro 宏:消除重复
当有多个相同部件(如四个轮子),使用 xacro 宏:
1 | <xacro:macro name="wheel" params="name prefix"> |
四、Transmission:连接驱动与仿真
Transmission 是 URDF 和 ros_control 之间的桥梁——当物理引擎中驱动设备动作时,ROS 知道哪个 TF 需要变化。
1 | <transmission name="wheel_trans"> |
控制器与硬件接口对应:
| 接口 | 控制器 |
|---|---|
EffortJointInterface |
joint_effort_controller |
VelocityJointInterface |
joint_velocity_controller |
PositionJointInterface |
joint_position_controller |
| Joint State | joint_state_controller |
还需在 URDF 中添加 ros_control 插件:
1 | <gazebo> |
五、手动建模要点
当脚本无法处理复杂模型时,需要手动编写 URDF:
属性设置顺序
1 | link(inertial) → joint → link(visual/collision) → 子 link... |
关键注意事项
- base_link 位置:排除轮子后车体的质心位置
- 惯性矩换算:Fusion360 给出的值需 ×10⁻⁹(如 689.2 → 6.892E-07)
- 质心 vs 原点:选择相对于质心的惯性,而非相对于原点的
- 碰撞简化:用碰撞箱代替 STL,STL 碰撞面复杂会导致仿真卡顿
- STL 缩放:若机械给的是米制 STL,需
scale="0.001 0.001 0.001";毫米制则不需要 - 单个 STL 小于 2MB:过大文件严重影响运行
六、Fusion360 脚本导出
使用 fusion2urdf 脚本自动导出。
建模规范
- 一个零部件只能包含一个实体,不能有内部零部件
- 零部件命名只能字母或数字(Gazebo 要求)
- 不允许快速联接,只允许刚体/旋转/滑动联接
- 联接时按子-父顺序,不能弄反
- 不要鼠标拖动位置——用参数精确设置
- 必须有一个零部件命名为
base_link
常见问题
RViz 报错 “root link has inertia”:
1 | The root link base_link has an inertia specified in the URDF, |
解法:添加一个空属性的虚拟 link:
1 | <link name="dummy"></link> |
模型灰白无色:
检查是否安装 joint_state_publisher:
1 | sudo apt-get install ros-noetic-joint-state-publisher |
Controller Spawner 找不到 controller_manager:
把 launch 文件中的 spawner 换成 controller_manager:
1 | <!-- 改前 --> |