1. 碰撞检测基础

各位同学,欢迎来到《碰撞检测与避障策略实战》的第一章。

说实话,我入行做机器人那会儿,对碰撞检测的理解特别肤浅。觉得不就是「两个东西挨上了嘛」,写个距离判断不就完了?结果第一次在真实机械臂上跑我的代码,差点把价值十几万的协作臂给撞报废。嗯,从那以后,我才真正开始认真对待这个看似简单、实则门道极深的问题。

今天,我们就从最基础的概念讲起。把地基打牢,后面三十章你才能走得稳。

1.1 什么是碰撞检测?

碰撞检测,英文叫 Collision Detection,简称 CD。说白了,就是判断两个或多个几何体在空间里有没有发生重叠。

你可能会说:「这不就是算距离嘛?」

对,也不全对。算距离只是最朴素的方式。真正的碰撞检测,要考虑的远不止这些:

  • 几何层面:两个物体的形状是否相交?
  • 时间层面:在什么时刻开始接触?
  • 响应层面:碰撞之后,物体应该怎么运动?

我个人习惯把碰撞检测拆成两个阶段:

  1. 粗略检测(Broad Phase):快速排除掉那些明显不相交的物体对。比如用包围盒先筛一遍。
  2. 精细检测(Narrow Phase):对可能相交的物体对,做精确的几何求交计算。

这两个阶段缺一不可。我在项目中遇到过不少新手,一上来就做精细检测,结果场景里几千个物体,每帧都要算 O(n²) 次精确求交,性能直接崩掉。

核心定义:碰撞检测 = 空间几何体的相交测试 + 接触时间与位置的确定。

1.2 为什么碰撞检测如此重要?

你想想看,如果一个机器人没有碰撞检测,会发生什么?

  • 机械臂会直接撞向工件,损坏末端执行器。
  • AGV 小车会怼上货架,货物散落一地。
  • 手术机器人可能会伤及患者组织。

我曾经在一个仓储机器人项目里,就因为碰撞检测的阈值设得太宽松,导致两台机器人面对面「亲」上了。结果呢?一台的激光雷达支架直接断裂,维修花了三天。那之后,我们团队把碰撞检测模块的测试用例增加了三倍。

碰撞检测的重要性,可以归纳为三点:

维度 具体意义 我的经验
安全 保护设备、环境和人员 安全永远是第一优先级,性能可以妥协,安全不行
精度 确保运动规划的可行性 路径规划如果没有碰撞检测,就是纸上谈兵
效率 减少重试和异常处理 好的碰撞检测能大幅降低系统卡顿和死锁

注意:碰撞检测不是「有就行」,而是要在 实时性 和 准确性 之间找到平衡。过于保守的检测会导致机器人不敢运动,过于激进的检测则可能漏报。

1.3 应用领域:机器人、自动驾驶、游戏

碰撞检测的应用面非常广。我挑三个最典型的领域来讲,这三个领域我都亲手做过项目。

1.3.1 机器人领域

这是我最熟悉的领域。在机器人里,碰撞检测几乎无处不在:

  • 工业机械臂:自碰撞检测(手臂各关节之间)、与环境碰撞检测(工作台、夹具)。
  • 移动机器人(AGV/AMR):与障碍物、墙壁、其他机器人的碰撞。
  • 人形机器人:全身运动规划中的自碰撞和外部碰撞。

我记得有一次做双臂协作机器人,两个机械臂要在同一个工作空间里协同搬运一个箱子。自碰撞检测还好说,但双臂之间的互碰撞检测,如果处理不好,两个臂就会「打架」。我们最后用了 FCL(Flexible Collision Library) 库,配合自定义的连续碰撞检测算法,才把这个问题搞定。

1.3.2 自动驾驶领域

自动驾驶对碰撞检测的要求,比机器人还要苛刻。为什么?因为车速快、环境复杂、而且涉及人身安全。

在自动驾驶里,碰撞检测通常分为:

  1. 纵向碰撞检测:判断与前车/后车的距离是否安全。
  2. 横向碰撞检测:判断与侧方车辆、行人、非机动车的距离。
  3. 路口碰撞检测:判断交叉路口是否有冲突目标。

我参与过一个 L4 级无人驾驶项目,最头疼的不是高速场景,反而是城市低速路口的复杂交互。行人突然横穿、电动车鬼探头……这些场景下,碰撞检测必须做到 毫秒级响应,而且不能误报。误报会导致急刹车,后面的车追尾你。

小技巧:在自动驾驶中,我建议把碰撞检测和预测模块结合起来。单纯检测当前时刻的碰撞是不够的,要预测未来 2-3 秒内是否会发生碰撞。这就是 碰撞预测 的概念。

1.3.3 游戏领域

游戏里的碰撞检测,大家可能更熟悉。从《超级马里奥》踩蘑菇,到《绝地求生》里的子弹命中判定,背后都是碰撞检测在支撑。

游戏领域对碰撞检测的要求,和机器人、自动驾驶不太一样:

  • 实时性要求极高:必须 60fps 甚至 120fps 下稳定运行。
  • 可以「作弊」:为了性能,游戏里经常用简化模型(比如用胶囊体代替人体)。
  • 允许一定误差:玩家肉眼看不出来就行。

我曾经给一个独立游戏团队做过顾问,他们用 Unity 开发一款动作游戏。一开始他们用 Mesh Collider(网格碰撞器)做精确碰撞,结果手机端直接卡成 PPT。后来我建议他们换成 基本几何体组合(球体+长方体+胶囊体),性能提升了 10 倍,玩家根本感觉不到差异。

1.4 本章知识体系总览

下面这张图,是我自己梳理的本章知识结构。你可以把它当作一个「地图」,后面深入学习时随时回来对照。

碰撞检测基础 - 知识体系 碰撞检测基础 - 知识体系 碰撞检测 定义与核心概念 粗略检测 (Broad Phase) 精细检测 (Narrow Phase) 连续碰撞检测 (CCD) 重要性 安全 精度 效率 应用领域 机器人 自动驾驶 游戏 核心目标:在实时性与准确性之间找到最佳平衡 方法:Broad Phase 快速筛选 → Narrow Phase 精确求交 图1-1 碰撞检测基础知识体系

1.5 一个简单的碰撞检测示例

光说不练假把式。我们来看一个最简单的碰撞检测代码——判断两个圆是否相交。

// 二维空间中两个圆的碰撞检测
struct Circle {
    float x, y;   // 圆心坐标
    float r;      // 半径
};

bool checkCircleCollision(const Circle& a, const Circle& b) {
    // 计算圆心距离的平方
    float dx = a.x - b.x;
    float dy = a.y - b.y;
    float distSq = dx * dx + dy * dy;
    
    // 计算半径和的平方
    float radSum = a.r + b.r;
    float radSumSq = radSum * radSum;
    
    // 如果圆心距离小于半径和,则发生碰撞
    return distSq <= radSumSq;
}

这段代码很简单,但背后有一个重要的优化思想:尽量用平方运算代替开方。开方是计算密集型的操作,能省则省。我在项目中见过有人直接写 sqrt(distSq),然后跟半径和比较。对于几千个物体对来说,这个 sqrt 就是性能杀手。

经验之谈:在碰撞检测中,能用平方比较就绝不用开方。这个习惯,能让你在 Broad Phase 阶段省下 30% 以上的计算时间。

1.6 本章小结

好了,第一章的内容就到这里。我们讲了三个核心问题:

  • 碰撞检测是什么——几何体的相交测试,分 Broad Phase 和 Narrow Phase。
  • 为什么重要——安全、精度、效率,缺一不可。
  • 用在哪里——机器人、自动驾驶、游戏,每个领域的要求各有侧重。

我个人觉得,碰撞检测是机器人算法里最「实在」的一个模块。它不像路径规划那么抽象,也不像控制理论那么数学化。它就是实打实地判断「撞没撞」,然后告诉系统该怎么处理。但越是基础的东西,越容易出问题。