3. 模型导入检查:URDF/SDF模型文件常见错误与修正
模型文件是仿真的起点。你想想看,如果机器人模型本身就有问题,那后面的仿真结果能靠谱吗?我个人习惯,拿到一个新模型,第一件事不是跑仿真,而是先做一次彻底的模型体检。
URDF和SDF是四足机器人仿真中最常用的两种模型格式。别看它们只是描述机器人长什么样、关节怎么连,里面的坑还真不少。我在项目中遇到过好几次,仿真里机器人走着走着突然“飞”起来,或者腿直接穿模到地里——查到最后,都是模型文件里一个小参数写错了。
3.1 URDF/SDF文件结构速览
先简单过一下这两种格式的核心结构。URDF用XML描述,SDF也是XML,但更灵活。四足机器人模型里,最关键的几个元素是:
| 元素 | URDF | SDF | 常见问题 |
|---|---|---|---|
| 连杆 | <link> |
<link> |
惯性参数缺失或错误 |
| 关节 | <joint> |
<joint> |
坐标轴方向反了、限位不对 |
| 碰撞 | <collision> |
<collision> |
碰撞形状与视觉模型不匹配 |
| 惯性 | <inertial> |
<inertial> |
质心位置离谱、惯性张量全零 |
3.2 常见错误一:惯性参数“假数据”
这是最隐蔽、也最致命的问题。很多初学者从CAD导模型时,惯性参数要么没填,要么随便填了个1。结果仿真里机器人像纸片一样轻,或者根本站不稳。
为什么会这样?因为物理引擎靠惯性参数计算每个连杆的质量分布。如果质心位置不对,四足机器人的重心就会偏移,行走时必然东倒西歪。
正确的做法:
- 质量必须大于0,单位是kg
- 惯性张量矩阵必须正定,不能有零或负值
- 质心位置
<origin>要相对于连杆坐标系,别搞反了
3.3 常见错误二:关节坐标轴“拧巴”
四足机器人的关节大多是旋转关节。URDF里用<axis>定义旋转轴。这个轴的方向一旦写错,仿真里腿的运动轨迹就全乱了。
我记得有一次,一个学员的机器人仿真里,大腿关节明明设的是绕X轴旋转,结果动起来却是绕Z轴转。查了半天,发现他写的是xyz="1 0 0",但实际模型里关节的局部坐标系和全局坐标系没对齐。
避坑指南:
- 关节的
<parent>和<child>连杆关系别搞反 - 旋转轴用单位向量表示,比如
xyz="0 0 1"表示绕Z轴 - 限位
<limit>里的lower和upper单位是弧度,不是角度
<dynamics>里阻尼设成了0。物理引擎算出来的关节力无限大,直接炸了。阻尼至少给个0.1,别偷懒。
3.4 常见错误三:碰撞模型“穿模”
仿真里的碰撞检测,用的是<collision>定义的形状,不是视觉模型。如果碰撞模型比视觉模型小,机器人看起来没碰到东西,但仿真里已经撞上了。反过来,碰撞模型太大,机器人还没碰到障碍物就被弹开了。
四足机器人行走时,脚底和地面的接触最敏感。我曾经见过一个案例,脚底的碰撞模型是个球体,半径设得比实际脚掌大了一倍。结果仿真里机器人走路像踩在棉花上,永远踩不实。
检查清单:
- 每个连杆必须有
<collision>,不能省略 - 碰撞形状尽量用简单几何体(box、cylinder、sphere),别用mesh,否则仿真卡死
- 脚底碰撞模型用
box或cylinder,比球体更稳定 - 碰撞模型的
<origin>要和视觉模型对齐
3.5 常见错误四:SDF特有的“世界坐标系”问题
SDF比URDF灵活,但也更容易出错。特别是<world>和<model>的嵌套关系。四足机器人仿真时,如果模型没有正确放在地面上,一启动就悬空或者陷进地里。
我个人习惯,在SDF里显式定义<gravity>和<physics>参数。默认值有时候不靠谱,尤其是当你用不同版本的Gazebo时。
<pose>,Z值要等于地面高度加上机器人底盘离地高度。别想当然地设成0,除非你的地面也在Z=0。
3.6 模型验证工具
别用手工一行行检查XML,太累了。用工具:
| 工具 | 用途 | 命令示例 |
|---|---|---|
check_urdf |
检查URDF语法和结构 | check_urdf my_robot.urdf |
urdf_to_graphiz |
生成连杆关节关系图 | urdf_to_graphiz my_robot.urdf |
gz sdf |
检查SDF文件 | gz sdf -k my_robot.sdf |
| RViz + RobotModel | 可视化查看模型 | 加载URDF后检查关节运动 |
嗯,这里要注意:check_urdf只能检查语法错误,检查不了物理合理性。比如惯性张量全零,它不会报错,但仿真里一定会出问题。
3.7 模型排查流程图
下面这张图是我自己总结的排查流程,每次拿到新模型都走一遍:
3.8 实战案例:一个真实的排查过程
有一次,我调试一台四足机器人,仿真里它总是往左边偏。检查了控制算法、地面参数,都没问题。最后回到模型文件,发现右前腿的髋关节<origin>的Y坐标写错了,比左腿多了2毫米。
2毫米,在现实里几乎看不出来。但在仿真里,物理引擎会精确计算每条腿的受力。左右不对称,机器人自然就往一边偏。
修正方法:
<!-- 错误写法 -->
<joint name="right_hip" type="revolute">
<origin xyz="0.15 0.08 0.0" rpy="0 0 0"/>
<parent link="base"/>
<child link="right_thigh"/>
<axis xyz="0 0 1"/>
</joint>
<!-- 正确写法 -->
<joint name="right_hip" type="revolute">
<origin xyz="0.15 -0.08 0.0" rpy="0 0 0"/>
<parent link="base"/>
<child link="right_thigh"/>
<axis xyz="0 0 1"/>
</joint>
你看,就差了那个负号。所以我说,模型文件里的每一个数字,都值得你认真对待。
diff命令对比新旧版本。这样能清楚看到改了哪里,避免手误。
3.9 总结一下
模型导入检查,说白了就是三件事:语法对、结构对、参数对。别嫌麻烦,这一步做扎实了,后面的仿真工作能省下80%的排查时间。
嗯,如果你现在手头有四足机器人的模型文件,不妨按上面的流程走一遍。我敢打赌,你至少能发现一两个小问题——别问我怎么知道的。