自动驾驶运动规划学习_碰撞检测算法_GJK

自动驾驶运动规划学习:碰撞检测算法:GJK

Gilbert–Johnson–Keerthi(GJK)算法,是一种用于检测两个凸集是否重叠的高效算法,并且可以得到两个凸集的最小距离.

image

image.png

1.4.1 GJK算法原理

image.png

1.4.1.1 闵可夫斯基差(Minkowski Difference)

image.png

image

image.png

image

image.png

1.4.1.3 凸性

在二维空间中,如果一个凸集包含原点,那意味着我们一定能在边界上找到三个点,组成一个包含原点的三角形.

也就是说:如果A ⊖ B是凸的,那么我们只需要在边界上寻找点,这节省了大量的工作.

image

image.png

任何两个凸集的闵可夫斯基差也是凸的

所以,我们只需要保证A和B是凸集.也就是说,GJK也是一个只能处理凸集之间的碰撞检测算法.

如果需要处理非凸集,比如下图的A和B,是两个非凸集.我们把非凸集分解成凸的子集,然后依次对这些子集执行GJK算法.分解非凸集的方法这里不再赘述.

image

1.4.1.3 单纯形

image.png

对于规划算法中常见的2维问题,2d单纯形就是一个三角形.

image

那么问题也就变成了:

  • image.png

1.4.1.3 支持函数(Support Function)

image.png

1.4.1.4 点积和叉积

image.png

image

另外我们还需要知道叉积的几何意义:

  • image.png

1.4.2 GJK算法步骤

我们先给出GJK的算法步骤,在例子中会解释相关逻辑

1.4.2.1 步骤

image.png

循环:

(4)判断单纯形是否包含原点:

(4a)如果包含,则返回碰撞

(4b)如果不包含,单纯形只保留离原点最近的一条边上的两个点

(5)两个点组成的边,将方向�→更新为 边朝向原点方向的垂线.回到步骤(4)继续循环

注意:如果需要得到两个几何之间的最小距离, (2b)可以不直接返回是否碰撞,继续迭代

1.4.2.2 例子

为了能够更明白的解释算法步骤,这里我们举一个例子:

image

image.png

image

image.png

image

image.png

这里给出两个例子,左边点积是正的,代表仍然可能发生碰撞;右边点积结果是付的,代表一定不会碰撞.

**但是为什么可以做这样的判断呢?**我们这里回到没有闵可夫斯基差的视角,直观的解释一下:

image

image.png

image

image.png

(5)取这两个点组成的边的垂线方向,调用Support()函数,得到新的最远的点

(4)回到步骤(4)

单纯形不包含原点,留下离原点最近的边,也就是右边的这条边

image

(5)取这两个点组成的边的垂线方向,调用Support()函数,得到新的最远的点,也就是最右边的点

image

(4)再次回到步骤(4)

终于,单纯形包含了原点,返回碰撞!

posted @ 2024-09-18 21:28  AutoDriver  阅读(49)  评论(0编辑  收藏  举报