- 背景
上次完成了初步的寻路设计方案之后,可以顺利的进行静态寻路了,但是对动态避障寻路支持并不好。经过跟项目设计者仔细研究,发现RVO等算法并不能满足现有需求,原因如下:
- 我们的动态障碍物是突然出现的,不是从某个其他方向走过来的
- 每个对象,都需要每隔一小段时间,就要检查一下自己前进的方向是否有阻挡
- 我们不能由前端运算,因为有时差问题,只能由后端运算。
据此,我们需要另辟蹊径,找到一个适合自己的算法。
- 算法描述
由于我们的障碍物是可能突然出现在前方的,我们并不能像ROV那样预先计算,选择一个另外路径,所以我们躲避障碍物的方式为:不会提前改变路径,而是到障碍物面前后才改变。
下图是ROV避障算法,蓝点方阵知道障碍物(红球)的存在,会与红球相撞的蓝点会提前改变路径
ROV避障算法
下图是我们的动态避障算法,本来obj要从C点移动到K点,但是由于有障碍物的出现,于是到快与障碍物相撞的D点时转向,走D-E-F-H-K各点,到达目标点与障碍物包围圆切线位置时走直线奔向目标点
此算法依赖于如下几点前提条件:
- 障碍物都可以被圆包围,不会无限大,按照圆(折线)躲避不会违和。
- 紧贴着障碍物的周围是可以走的,也就是障碍物不能连起来形成更大的障碍。
- 具体算法
本来要从N走到P点,结果走到O点时发现障碍物A。
- 将A的包围圆分成12份,每份30度。
- 由于已知A点位置,圆半径(基本都是固定半径),AB与AC夹角度数(30度),所以可知B,C,D,E,,,M等12个点的位置
- 由于绕开障碍物只需要绕最多90度,所以最多只需要走3个点。
- 当对象走到O点,发现障碍物时,首先计算A点在直线NP的位置,如果A点在直线下方,则从上面绕;相反如果A点在直线上方,则从下面绕
- 计算AO夹角如果小于AD角则走折线OD,其他以此类推
- 计算C点在直线DP的上方,则需要走折线DC
- 计算B点在直线CP的上方,则需要走折现CB
- 此时已经走了3个点了,可以直接走BP奔向目的地。如果不满3个点,则计算下一个点M在直线BP下方,则不需要走M了。
- 复杂度分析
- 当A已知时,由于包围圆的半径是固定值,所以B,,M点通过加减法就可以得到
- 接下来在计算一次AO夹角(两次浮点数乘法)
- 接下来最多计算3此点与直线的关系(每次是两次浮点数乘法)
由此可见运算量是很低的,此算法支持服务器大规模运算。