随着人工智能的兴起,移动机器人逐渐走入了更多人的视线,ML和DL为移动机器人的导航及定位算法提供了很多的重要参考。对于移动机器人的研发最为基本的问题就是如何对机器人的运动进行控制,在目前众多的机器人路径规划算法中,针对静态、动态环境存在着很多不同的解决方案,本文将对现存的主流算法进行大致的讲解和优劣分析。同时,对于在静态环境中广泛使用的A*算法,进行详细的解读。
下面是现在流行的主要路径规划算法:
A*、LPA* 以及D* lite都可以用于静态环境下移动机器人的路径规划,此时三者计算效率都相差不大,都利用了启发式搜索来提高效率,LPA* 和D* Lite的增量式搜索在这时没有任何帮助,但对于动态环境的路径规划,A* 算法却有心无力,但是对于动态环境下进行二次搜索,LPA* 和D* Lite效率明显高于A*。
LPA* 以及D* lite原理大体类似,都是基于这样一个思想:发生变化后的环境与最初的地图信息相差不大,可以利用增量式搜索利用先前存储信息来提高二次、三次及以后的搜索效率。
A*算法的代价函数为f = g + h,其各个网格点的优先权也是用f来衡量。
而LPA* 和D* Lite都引入rhs变量并作为代价函数,key作为优先权的比较基准,而且key有两 个元素[k1;k2],打破A* 算法出现 “平级” 的局面;由于D* Lite算法Start点一直在移动,故引入km来提高计算效率。
LPA* 和D* Lite引入局部一致性的概念来描述网格点的状态以代替A*的Closedlist、Openlist,即所有Openlist的点都局部不一致,所有局部不一致的点都在Openlist列表上,减轻了储存负担,提高算法效率。
路径规划算法还有很多,其他的就不在此赘述了,大家可以自主搜索一些资料。
1.原理解析
A*算法是启发式搜索,是一种尽可能基于现有信息的搜索策略,也就是说搜索过程中尽量利用目前已知的诸如迭代步数,以及从初始状态和当前状态到目标状态估计所需的费用等信息。
A*算法可以选择下一个被检查的节点时引入了已知的全局信息,对当前结点距离终点的距离作出估计,作为评价该节点处于最优路线上的可能性的量度,这样可以首先搜索可能性大的节点,从而提高了搜索过程的效率。
A* 算法的基本思想如下:引入当前节点j的估计函数f*,当前节点j的估计函数定义为:
f*(j)= g(j)+h*(j)
其中g(j)是从起点到当前节点j的实际费用的量度,h*(j)是从节点j到终点的最小费用的估计,可以依据实际情况,选择h*(j)的具体形式,h*(j)要满足一个要求:不能高于节点j到终点的实际最小费用。从起始节点点向目的节点搜索时,每次都搜索f*(j)最小的节点,直到发现目的节点。
2.曼哈顿距离
A*算法的核心是设计估价函数,设计估价函数h(j)有很多方法,下面介绍其中的一种——曼哈顿距离。
利用欧几里德距离计算估价函数的计算量很大,因此考虑将两点之间的曼哈顿距离作为估价函数。其中A点的经纬度为(Ax,Ay),B点的经纬度是(Bx,By),则A、B之间的Manhattan距离可以表示为:
M(A,B)=P*(|Ax-Bx|+|Ay-By|)
P = 2* π *R / 360
由于P是常数,可以简化为
f(j)=g(j)+(|Ax-Bx|+|Ay-By|)
此估价函数计算量小,虽然不是严格的方向优先,但基本能保证最短路径的搜索方向向目标点的方向进行。
3.算法步骤
A*算法在搜索中设置两个表:Open表和Close表。Open表保存了所有已生成而未被考察的节点,Close表中记录已被考察过的节点。算法中有一步是根据估计函数重排Open表中的节点,这样,循环的每一步只考虑Open表中状态最好(代价最小)的节点,如果被发现在Open表中存在同一个节点,就应比较两个节点代价的大小,如扩展得到的新节点代价大于已有的节点代价,可以放弃扩展得到的新节点,否则就以新节点代替原来的节点。如果在Close表中存在同一个节点号,则新新生成的路径的代价肯定大于原来路径的代价,可以淘汰新生成的节点。
具体算法步骤如下:
步1:生成空的Open表、Close表,将起点S放入Open表
步2:如果Open表为空,则失败退出。
步3:从Open表中,找出头节点U,作为当前节点,将它从OPEN表中移除。
步4:判断U是否为终点,如果是,则通过节点U的父指针,一直遍历到起点,找到到最优路径,算法结束。否则,转步5.
步5:扩展当前节点U,找到其扩展的后继节点集合V,遍历集合V中的节点,如果节点即不在Open表也不在Close表,计算该节点的估计值,将节点加入到OPEN表,设置父节点为U.如果节点在Open表、Close表,比较当前节点的代价g(v)和Open表、Close表中代价,如果当前节点的代价g(v)小,更新表中的代价和父节点指针。
步6:按估价值递增的顺序,对Open表中所有节点进行排序。
步7:转步2.
4.伪代码实现
根据以上思路,A*算法的伪代码如下:
A*()
{
Open = [起始节点];
Closed = [];
while (Open表非空)
{
从Open中取得一个节点X,并从OPEN表中删除。
if (X是目标节点)
{
求得路径PATH;
返回路径PATH;
}
for (每一个X的子节点Y)
{
if (Y不在OPEN表和CLOSE表中)
{
求Y的估价值;
并将Y插入OPEN表中;
}
//还没有排序
else if (Y在OPEN表中)
{
if (Y的估价值小于OPEN表的估价值)
更新OPEN表中的估价值;
}
else //Y在CLOSE表中
{
if (Y的估价值小于CLOSE表的估价值)
{
更新CLOSE表中的估价值;
从CLOSE表中移出节点,并放入OPEN表中;
}
}
将X节点插入CLOSE表中;
按照估价值将OPEN表中的节点排序;
}//end for
} //end while
} //end function
5. A*算法总结
A* 算法是一种静态路网中求解最短路径最有效的直接搜索方法。估价值与实际值越接近,估价函数取得就越好。注意是最有效的直接搜索算法。之后涌现了很多预处理算法(ALT,CH,HL等等),在线查询效率是A*算法的数千甚至上万倍。公式表示为: f(n)=g(n)+h(n),其中 f(n) 是从初始点经由节点n到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n) 是从n到目标节点最佳路径的估计代价。保证找到最短路径(最优解的)条件,关键在于估价函数f(n)的选取:估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。并且如果h(n)=d(n),即距离估计h(n)等于最短距离,那么搜索将严格沿着最短路径进行,此时的搜索效率是最高的。如果估价值>实际值,搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。