4. SRDF 与配置包:SRDF 文件的作用、MoveIt Setup Assistant 工具、生成配置包
好,我们进入第四章。前面我们把 URDF 模型搞定了,但 MoveIt 光有机器人模型还不够,它还需要知道:哪些关节是主动的?哪些是冗余的?夹爪怎么开合?自碰撞怎么忽略?这些信息,就写在 SRDF 文件里。
说白了,SRDF 就是 MoveIt 的「行为说明书」。URDF 告诉系统「我长什么样」,SRDF 告诉系统「我怎么动」。我个人习惯把 SRDF 看作机器人的「运动配置清单」——没有它,MoveIt 就是个瞎子。
4.1 SRDF 文件到底在干什么?
SRDF 全称是 Semantic Robot Description Format,语义机器人描述格式。名字挺唬人,其实内容很直白。我拆开给你看:
- 定义规划组(Group):比如「左臂」、「右臂」、「夹爪」、「躯干」。每个组包含哪些连杆和关节。
- 定义默认姿态(Default Pose):比如「home 位姿」、「抓取准备位姿」。方便后续直接调用。
- 定义自碰撞矩阵(Self-Collision Matrix):哪些连杆对永远不会碰撞?比如相邻的两个连杆,或者距离永远够不着的。告诉 MoveIt 别浪费算力去检查它们。
- 定义虚拟关节(Virtual Joint):机器人基座固定在世界上,还是可以移动?用虚拟关节描述基座与世界的连接关系。
- 定义被动关节(Passive Joint):有些关节是弹簧阻尼的,或者被外力拖着走,规划器不能主动控制它们。标出来,MoveIt 就不碰它们。
核心一句话:SRDF 把 URDF 的「物理模型」翻译成 MoveIt 能理解的「运动模型」。
我在项目里遇到过有人把 SRDF 当成可选项,结果 MoveIt 启动后规划总报错,查了半天才发现是自碰撞矩阵没生成,规划器在疯狂计算两个永远不会碰到的连杆。嗯,从那以后我再也不敢跳过 SRDF 了。
4.2 MoveIt Setup Assistant:图形化配置利器
手动写 SRDF ?别傻了,那玩意儿 XML 嵌套深得很,写错一个标签就得排查半天。MoveIt 官方提供了一个图形化工具——MoveIt Setup Assistant(简称 MSA)。
启动方式很简单:
roslaunch moveit_setup_assistant setup_assistant.launch
或者如果你用的是 ROS Noetic 或更新版本:
rosrun moveit_setup_assistant moveit_setup_assistant
界面一出来,你会看到两个选项:Create New MoveIt Configuration Package 和 Edit Existing MoveIt Configuration Package。第一次用,选第一个。
然后它会让你加载 URDF 文件。注意,这里加载的是 完整的、包含所有 mesh 的 URDF。加载成功后,左侧会出现一个导航栏,包含十几个配置步骤。别慌,核心步骤其实就这几个:
| 步骤 | 做什么 | 我的建议 |
|---|---|---|
| Self-Collisions | 自动生成自碰撞矩阵 | 采样密度选「Default」就行,别贪多 |
| Planning Groups | 定义规划组 | 命名要规范,比如 arm_left_group |
| Robot Poses | 添加默认姿态 | 至少加一个 home 姿态 |
| Virtual Joints | 定义基座类型 | 固定基座选 fixed,移动基座选 planar |
| Passive Joints | 标记被动关节 | 没有就不填 |
| Configuration Files | 生成配置包 | 检查路径,别覆盖已有包 |
小技巧:在 Self-Collisions 步骤里,MSA 会基于随机采样生成碰撞矩阵。如果你机器人连杆很多,采样数设太高会导致生成时间暴涨。我一般用默认的 10000 次采样,效果足够。
4.3 生成配置包:你得到了什么?
点完「Generate Package」,MSA 会在你指定的目录下生成一个完整的 MoveIt 配置包。这个包的结构长这样:
your_robot_moveit_config/
├── config/
│ ├── srdf/
│ │ └── your_robot.srdf # 核心 SRDF 文件
│ ├── kinematics.yaml # 运动学求解器配置
│ ├── joint_limits.yaml # 关节限位(可覆盖 URDF)
│ ├── ompl_planning.yaml # OMPL 规划器参数
│ ├── fake_controllers.yaml # 仿真控制器
│ └── moveit_controllers.yaml # 真实控制器配置
├── launch/
│ ├── demo.launch # 一键启动演示
│ ├── move_group.launch # 启动 move_group 节点
│ ├── planning_context.launch # 加载模型和 SRDF
│ └── setup_assistant.launch # 重新打开 MSA
└── package.xml # 包描述文件
这里面,config/srdf/ 下的 .srdf 文件是灵魂。其他 yaml 文件都是可调的参数。你想想看,如果没有 MSA,你要手写这些 yaml 和 launch 文件,光一个 ompl_planning.yaml 就能让你折腾半天。
我曾经接手过一个项目,前同事手写的配置包,kinematics.yaml 里求解器名字拼错了,导致运动学一直解不出来。我花了两个小时排查,最后发现就是少了个下划线。所以,能用工具生成的,别手写。
4.4 SRDF 文件内部结构速览
我们打开生成的 SRDF 文件看一眼,其实结构很清晰:
<robot name="your_robot">
<!-- 规划组定义 -->
<group name="arm_group">
<joint name="joint1"/>
<joint name="joint2"/>
<joint name="joint3"/>
<joint name="joint4"/>
<joint name="joint5"/>
<joint name="joint6"/>
</group>
<group name="gripper_group">
<link name="gripper_left_finger"/>
<link name="gripper_right_finger"/>
<joint name="gripper_joint"/>
</group>
<!-- 默认姿态 -->
<group_state name="home" group="arm_group">
<joint name="joint1" value="0"/>
<joint name="joint2" value="-1.57"/>
<joint name="joint3" value="0"/>
<joint name="joint4" value="0"/>
<joint name="joint5" value="0"/>
<joint name="joint6" value="0"/>
</group_state>
<!-- 自碰撞禁用对 -->
<disable_collisions link1="base_link" link2="arm_link3" reason="Adjacent"/>
<disable_collisions link1="arm_link3" link2="arm_link4" reason="Adjacent"/>
<disable_collisions link1="base_link" link2="gripper_link" reason="Never"/>
<!-- 虚拟关节 -->
<virtual_joint name="world_joint" type="fixed" parent_frame="world" child_link="base_link"/>
</robot>
看到没?每个标签都对应 MSA 里的一个配置步骤。你完全可以在 MSA 里配好,然后手动微调 SRDF 文件。我个人习惯是:MSA 生成骨架,手写调细节。比如某些特殊姿态,直接在 SRDF 里加 group_state 比在 MSA 里点来点去快得多。
注意:SRDF 文件里的关节值单位是弧度,不是度。我见过有人把 90 度写成 90,结果机器人直接飞到奇异点。MoveIt 不会帮你做单位转换,写错了就是错了。
4.5 知识体系总览
为了让你更直观地理解 SRDF 和配置包在整个 MoveIt 体系中的位置,我画了一张图:
这张图把整个流程串起来了:URDF 是输入,MSA 是加工厂,SRDF 是核心产物,配置包是最终交付物。你只要走通一次这个流程,后面再改模型,直接在 MSA 里点「Edit Existing Package」更新就行,不用从头再来。
4.6 避坑指南与最佳实践
最后,分享几个我踩过的坑,你遇到了能少走弯路:
- URDF 路径不要用中文:MSA 对中文路径支持很差,加载 mesh 时会报错。我习惯把所有模型文件放在英文路径下。
- 生成配置包前检查 URDF 完整性:如果 URDF 里引用了不存在的 mesh 文件,MSA 会卡在加载阶段。先用
check_urdf工具验证一下。 - 自碰撞矩阵不是越多越好:禁用太多碰撞对,虽然规划快了,但可能漏掉真实碰撞。我一般保持 MSA 的默认采样结果,只手动加几个明显不会碰的对。
- 配置包生成后先跑 demo.launch:别急着接真实机器人。先用
roslaunch your_robot_moveit_config demo.launch在 RViz 里看看规划正不正常。这一步能过滤掉 80% 的配置错误。
我的习惯:每次修改 SRDF 后,我都会在 RViz 里手动拖拽机器人到几个极端位姿,看看自碰撞矩阵有没有漏掉该禁用的对。虽然麻烦,但比在真实机器人上撞坏东西强多了。
好了,第四章就到这里。SRDF 和配置包是 MoveIt 的基石,你花时间把它搞透,后面学运动学、规划算法、控制器配置都会轻松很多。记住:配置包生成只是开始,调优才是常态。