在使用 Gazebo 做机器人仿真时,很多人都遇到过这样一种情况:模型刚加载进来时看起来还算正常,但只要仿真一开始,整个机构就像“爆炸”了一样,零件四散飞开、抖动、穿插,完全没法正常使用。
这个现象通常被大家叫做“炸模”。
本文结合一个实际案例,系统整理一下 Gazebo 炸模的常见原因、排查思路和修复方法,适合刚开始做 URDF / Xacro / SDF 建模的同学参考。
一、什么是 Gazebo 炸模
所谓“炸模”,本质上不是显示错误,而是物理仿真不稳定。
更准确地说,是模型在进入 Gazebo 的物理引擎后,由于碰撞体重叠、关节位姿错误、惯性参数异常、模型穿地或自碰撞等问题,被求解器施加了很大的分离力,最终表现为:
- 零件突然弹飞;
- 机构瞬间散架;
- 模型剧烈抖动;
- 一些部件飞到很远的位置;
- 仿真无法继续稳定运行。
二、实际现象示例
先看一下本文中的两个现场图。
1. 仿真开始后机构局部挤压、形态异常

从这张图可以看到,模型虽然没有完全飞散,但结构已经明显不合理。多个部件围绕中心挤在一起,姿态异常,说明物理关系已经出现问题。
2. 仿真继续运行后零件彻底飞散

第二张图更典型:大量零件已经散落到场景各处。这说明 Gazebo 在仿真求解过程中,将模型判定为一组彼此冲突的刚体,并持续施加了分离和纠正作用力,最终导致整机“爆炸”。
三、Gazebo 炸模最常见的原因
1. collision 几何体重叠
这是最常见的原因,也是排查时首先要怀疑的问题。
在 Gazebo 里,真正参与碰撞和物理求解的是 collision,不是你肉眼看到的 visual。很多时候:
- visual 看起来位置是对的;
- 但 collision 的尺寸、原点、姿态、缩放和 visual 不一致;
- 多个 link 的碰撞体彼此穿插;
- 或者碰撞体一开始就和地面重叠。
这种情况下,Gazebo 会试图把重叠的物体强行分开,于是模型就被“弹炸”了。
2. joint 的原点配置错误
如果 joint 的 <origin xyz="" rpy=""> 配错,child link 相对于 parent link 的相对位姿就会出问题。
常见后果包括:
- 零件初始位置不对;
- 关节连接关系逻辑正确,但空间位置错误;
- link 一加载就发生穿插;
- 求解器不断修正姿态,造成剧烈抖动甚至炸模。
3. 该固定的 link 没有用 fixed joint 固定
很多模型在 CAD 中看起来是一个整体,但在 URDF 中其实是多个 link。如果这些部件本来应该刚性连接,却没有通过 fixed joint 正确绑定,那么 Gazebo 会把它们当作多个独立刚体处理。
结果就是:
- 一开始还能“堆”在一起;
- 一旦受重力、碰撞或约束作用,零件就会各自运动;
- 最后表现成散架。
4. 惯性参数不合理
Gazebo 对惯性参数非常敏感。如果你的 mass、质心或惯性矩阵写得不合理,物理计算很容易失稳。
典型问题包括:
- mass 太小;
- ixx/iyy/izz 等于 0;
- 惯性矩阵和真实几何差异过大;
- inertial origin 偏移严重。
这类问题通常会引起:
- 模型剧烈抖动;
- 转动异常;
- 落地后翻滚;
- 约束求解发散。
5. 单位或缩放错误
如果模型来源于 CAD,尤其要注意单位问题。CAD 常见单位是 mm,而 Gazebo / URDF 通常按 m 处理。
如果尺度错了,通常会连带引发:
- 碰撞体尺寸异常;
- 惯性计算不合理;
- 模型看起来正常,但物理行为完全不对。
6. 自碰撞开启导致相邻部件互相顶开
对于机械臂、夹爪、连杆机构这类本身结构紧凑的模型,如果开启了自碰撞,Gazebo 可能会把原本紧邻的 link 当作“正在相撞”的部件处理,进而把它们顶开。
四、如何快速判断问题出在哪
遇到炸模,最忌讳一上来就大改模型。更高效的方式是做隔离排查。
第一步:先确认是不是物理问题
把模型放到 RViz 中看一遍。
如果:
- RViz 中显示正常;
- Gazebo 中一运行就炸;
那基本可以判断:问题主要在 collision、joint 或 inertial,而不是 visual。
因为 RViz 只负责显示,不做物理求解。
第二步:临时去掉 collision
把各个 link 里的 <collision> 暂时注释掉,只保留 <visual>。
如果这样之后:
- 模型不再炸;
- 结构能稳定显示;
那就基本可以确定是 collision 配置有问题。
第三步:把所有活动关节临时改成 fixed
如果你怀疑关节定义有问题,可以先把所有 revolute、continuous、prismatic 关节临时改成 fixed。
如果改完之后模型稳定了,说明问题主要在:
- joint origin
- joint axis
- 父子 link 关系
- 可动范围约束
第四步:检查是否穿地或互相穿插
让模型只保留最基础的几部分,观察:
- 是否一开始就与地面重叠;
- 是否某些 link 初始就插进别的 link;
- base_link 是否悬空或放置错误。
第五步:检查惯性参数
如果结构和碰撞看起来都没问题,但模型依旧抖动、乱飞,就要重点查惯性参数。
可以先用保守值做测试,例如:
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="1.0"/>
<inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
</inertial>
如果这样模型明显稳定很多,说明原先的惯性定义不靠谱。
五、建议按这个顺序排查
这是比较实用的一套顺序,适合大多数 URDF / Xacro 模型:
这个顺序的核心思路是:先保证模型“站得住”,再保证模型“动得对”。
六、排查时重点看哪些字段
如果你是直接看 URDF / Xacro,最值得重点检查的是下面这些位置。
1. joint 定义
<joint name="joint_xxx" type="revolute">
<parent link="parent_link"/>
<child link="child_link"/>
<origin xyz="0 0 0" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
</joint>
重点看:
- parent 和 child 是否接反;
- origin 是否真的是子 link 相对父 link 的安装位姿;
- axis 是否符合真实转动方向。
2. collision 定义
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<mesh filename="package://xxx/meshes/part.stl" scale="1 1 1"/>
</geometry>
</collision>
重点看:
- collision origin 是否和 visual origin 一致;
- mesh scale 是否正确;
- 使用的碰撞模型是否过于复杂;
- 是否存在碰撞体大于视觉模型的情况。
3. inertial 定义
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="1.0"/>
<inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
</inertial>
重点看:
- 质量是否过小;
- 惯性矩阵是否非零;
- 质心位置是否合理;
- inertial origin 是否偏离实际几何中心太多。
七、工程上常用的修复建议
1. collision 不要直接照搬精细视觉模型
工程里通常会把:
- visual 用精细 mesh;
- collision 用简化后的 mesh 或基础几何体。
这样不仅更稳定,也更省仿真计算资源。
2. 固定结构尽量合并或用 fixed joint 明确绑定
如果某些零件在仿真中根本不需要相对运动,尽量不要拆成很多独立 link。 如果必须拆开,也要用 fixed joint 明确连接关系。
3. 先用保守惯性跑通,再逐步精细化
不要一开始就追求完全真实的动力学参数。先让模型稳定运行,再逐步替换为更准确的质量、惯性和质心。
4. 复杂机构建议逐级验证
例如夹爪、机械臂、多连杆机构,可以采用下面的方式:
- 先只验证底座;
- 再加一级连杆;
- 再加下一节;
- 每增加一层就进 Gazebo 跑一次。
这样一旦炸模,可以快速定位是哪个 link 或 joint 引入的问题。
八、一个经验判断
如果你看到的是下面这种现象:
- 模型外观看着差不多;
- 一按运行就飞散;
- 零件像被“顶开”一样弹出去;
那么第一怀疑对象通常不是 visual,而是:
- collision
- joint origin
- inertial
这三类问题基本覆盖了大多数 Gazebo 炸模案例。
九、总结
Gazebo 炸模,本质上是物理模型定义错误或不稳定,而不是简单的“显示不对”。
排查时建议抓住三个核心:
- 看 collision 是否重叠;
- 看 joint 是否定义正确;
- 看 inertial 是否合理;
最有效的排查方法不是盲改,而是按模块逐步隔离:
只要按这个顺序查,大部分 Gazebo 炸模问题都能比较快定位出来。
如果你也遇到过类似问题,建议先不要急着重画模型,优先回头检查 URDF / Xacro 里的 collision、joint origin 和 inertial,通常问题就出在这里。



![[springboot笔记四]解释相关创建文件-前端-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260815132850-6a8069929f02d-220x96.png)