3. MoveIt 核心概念:规划组、规划场景、运动规划器与碰撞检测
各位同学,欢迎来到第三章。上一章我们聊了 MoveIt 的启动流程和整体架构,算是把地图摊开了。今天咱们要深入腹地,聊聊 MoveIt 最核心的四个概念:规划组、规划场景、运动规划器和碰撞检测。
这四个东西,说白了就是 MoveIt 的“四肢”和“大脑”。你配置机器人,本质上就是在跟它们打交道。我刚开始接触 MoveIt 时,总觉得这些概念很虚,直到自己动手搭了一个六轴机械臂的规划组,才真正明白它们各自扮演什么角色。
3.1 规划组 (Planning Group)
规划组是什么? 它是一组关节和连杆的集合。你可以把它理解成机器人的一个“肢体”。比如,一个机械臂的整个手臂可以是一个规划组,夹爪可以单独是另一个规划组。
我个人习惯把规划组看作“运动的最小单元”。你告诉 MoveIt:“我要让‘左臂’动一下”,MoveIt 就会去查“左臂”这个规划组里包含哪些关节,然后只控制这些关节。
核心要点: 规划组定义了运动控制的边界。一个机器人可以有多个规划组,它们可以独立运动,也可以协同运动。
在配置文件中,我们通常这样定义一个规划组:
<group name="arm_group">
<joint name="shoulder_pan_joint"/>
<joint name="shoulder_lift_joint"/>
<joint name="elbow_joint"/>
<joint name="wrist_1_joint"/>
<joint name="wrist_2_joint"/>
<joint name="wrist_3_joint"/>
</group>
你看,这里只列了关节。MoveIt 会自动根据 URDF 里的运动学链,把关节之间的连杆也纳入规划组。嗯,这里要注意:规划组里的关节顺序,必须和 URDF 里的运动学链顺序一致。我曾经因为顺序写反,导致运动学解算一直报错,排查了半天才发现是这里的问题。
3.2 规划场景 (Planning Scene)
规划场景,你可以把它想象成机器人运动时的“舞台”。这个舞台上不仅有机器人自己,还有周围的环境——桌子、墙壁、障碍物,甚至是一个正在移动的人。
为什么需要规划场景?因为机器人不能闭着眼睛乱动。它需要知道周围有什么,才能规划出一条安全的路径。规划场景就是 MoveIt 用来存储这些信息的“黑匣子”。
规划场景里主要包含三样东西:
- 机器人状态:当前所有关节的位置、速度、加速度。
- 附加物体:机器人抓在手里的东西,或者环境中固定的障碍物。
- 碰撞对象:其他需要避开的物体。
你想想看,如果规划场景里没有更新障碍物的位置,机器人就会一头撞上去。我见过一个案例,有人把桌子移走了,但规划场景没更新,结果机械臂还在原地做避障规划,路径奇奇怪怪的。
避坑指南: 我曾经在动态环境中做抓取,忘记更新规划场景中的障碍物位置,导致机械臂差点撞到人。从那以后,我每次做运动规划前,都会强制刷新一次规划场景。
3.3 运动规划器 (Planner)
运动规划器,就是 MoveIt 的“大脑”。它负责回答一个问题:“从 A 点到 B 点,怎么走?”
MoveIt 默认集成了 OMPL(Open Motion Planning Library),里面包含几十种规划算法。比如 RRT、PRM、KPIECE 等等。每种算法都有自己的脾气。
我个人习惯把规划器分成两类:
- 采样式规划器(如 RRT):随机采样,速度快,但路径可能不够平滑。
- 优化式规划器(如 CHOMP、STOMP):在已有路径上优化,路径平滑,但计算量大。
实际项目中,我通常先用 RRT 快速找一条可行路径,再用 CHOMP 做平滑优化。这样既快又好。
配置规划器时,你可以在 ompl_planning.yaml 里指定:
arm_group:
planner_configs:
- RRTConnect
- RRTstar
- CHOMP
default_planner_config: RRTConnect
这里我设了三个规划器,默认用 RRTConnect。为什么选它?因为 RRTConnect 是双向搜索,在大多数场景下效率很高。当然,如果你的机器人工作空间很狭窄,可以试试 RRTstar,它更擅长找最优路径。
注意: 规划器不是万能的。如果规划场景里障碍物太多,或者目标位姿不可达,再好的规划器也白搭。这时候要检查的是运动学是否解算成功,而不是换规划器。
3.4 碰撞检测 (Collision Checking)
碰撞检测,是 MoveIt 的“安全员”。它时刻在问:“机器人现在的位置,有没有碰到什么东西?”
MoveIt 的碰撞检测基于 FCL(Flexible Collision Library)。它把机器人和环境中的物体都抽象成几何形状(球体、立方体、网格),然后计算这些形状之间有没有重叠。
碰撞检测有两种模式:
- 自碰撞检测:检查机器人的连杆之间有没有互相碰撞。
- 环境碰撞检测:检查机器人和环境物体有没有碰撞。
你可能会问:“自碰撞检测有必要吗?” 当然有。我记得有一次调试一个七轴协作机器人,它的关节活动范围很大,如果不做自碰撞检测,手腕可能会打到自己的基座。嗯,那画面想想都疼。
在 MoveIt 中,碰撞检测的配置通常在 collision_checking.yaml 里:
collision:
enabled: true
self_collision: true
collision_margin: 0.01 # 单位:米
这里的 collision_margin 是碰撞裕量。我建议设成 0.01 米(1厘米),这样既不会太保守导致路径难找,也不会太激进导致碰撞风险。
个人经验: 如果你发现规划出来的路径总是贴着障碍物走,可以适当增大碰撞裕量。反之,如果路径经常找不到,可以减小裕量。这就像开车时留的安全距离,太远了堵车,太近了危险。
3.5 知识体系总览
为了让你更直观地理解这四个概念的关系,我画了一张图:
从这张图你可以看到,四个概念不是孤立的。规划组告诉 MoveIt “谁要动”,规划场景告诉它 “在哪动”,规划器告诉它 “怎么动”,碰撞检测则时刻盯着 “能不能动”。
好了,这一章的内容就到这里。这四个概念是 MoveIt 的基石,理解透了,后面的调参和实战才能游刃有余。下一章我们会聊聊如何配置一个完整的机器人,到时候你会看到这些概念是如何落地的。