移动机器人运动规划

常用地图结构#

occupancy grid map - 栅格地图

  • Most Dense;
  • Structural;
  • Direct Index Query;

octo-map - 栅格地图的优化,在障碍物存在的地方稠密,无障碍物的地方稀疏

  • Sparse;
  • Structural;
  • Indirect Index Query;

voxel hashing - 将坐标哈希化,通过哈希表查询地图信息

  • Most Sparse;
  • Structural;
  • Indirect Index Query;

point cloud map

  • Un-ordered;
  • No Index Query;

基于图搜索的算法#

基础概念

  • 机器人配置(Robot configuration):机器人上所有点的位置的描述;
  • 机器人自由度(Robot degree of freedom, DOF):能够表示机器人配置空间最少需要的值的数量;
  • 机器人配置空间(Robot configuration space):包含机器人所有可能的配置的 n 维向量空间,又称为 C-space;
  • 机器人任何一个可能的位置都是在配置空间中的一个点;

2.1 Graph Search Basis#

算法核心思想

  • Maintain a container to store all the nodes to be visited;
  • The container is initialized with the start state Xs ;
  • Loop:
    • Remove a node from the container according to some pre-defined score function;
      • Visit a node;
    • Expansion: Obtain all neighbors of the node;
      • Discover all its neighbors;
    • Push them (neighbors) into the container;
  • End loop;

Question 1:When to end the loop?
Answer:容器为空,或者目标节点已经被访问到;

Question 2:What if the graph is cyclic?
Answer:维护一个新的容器,存储被访问过的节点,避免节点被再次添加到容器中重复访问;

图的遍历

  • 广度优先搜索(Breadth First Search, BFS)
    • 先进先出,使用 queue;
    • Strategy: 优先移除和扩张容器中最浅的节点;
  • 深度优先搜索(Depth First Search, DFS)
    • 先进后出,使用 stack;
    • Strategy: 优先移除和扩张容器中最深的节点;

Dijkstra 算法#

  • Strategy: expand/visit the node with cheapest accumulated cost g(n) ;
    • g(n):The current best estimates of the accumulated cost from the start state to node n ;
    • Update the accumulated costs g(m) for all unexpanded neighbors m of node n ;
    • A node that has been expanded/visited is guaranteed to have the smallest cost from the start state.

算法流程:

  1. 初始时,S 集只包含起点 s,U 集包含除 s 外的其他节点,U 集中的节点 v 与起点 s 相邻,则该节点存储值为距起点 s 的距离,若与起点 s 不相邻,则距离为无限大;
  2. 从 U 集中选出距离起点最短的节点 k,并将节点 k 加入到 S 集中,同时从 U 集中移除节点 k;
  3. 更新 U 集中各个节点到起点 s 的距离。之所以更新 U 集中节点的距离,是因为由于上一步确定了节点 k 是求出最短路径的节点,从而可以利用节点 k 来更新其他节点的距离;例如,(s, v)的距离可能大于(s, k) + (k, v)的距离。
  4. 重复步骤 2 和步骤 3,直到遍历完所有节点。

2.3 A star 算法#

算法简介:

  1. A*算法是一种静态路网中求解最短路径最有效的直接搜索方法。广泛应用于室内机器人的路径搜索、游戏动画路径搜索等;
  2. A*算法结合了贪心算法(深度优先)和 Dijkstra 算法(广度优先),是一种启发式的搜索算法;
  3. 路径优劣评价公式为:f(n)=g(n)+h(n)g(n)是在状态空间中从初始状态到状态 n 的实际代价,h(n)是从状态 n目标状态的最佳路径的估计代价
  4. A*算法使用了两个状态表,分别称为OpenListCloseListOpenList存储待考察的节点,CloseList存储已考察过的节点。

地图预处理:

  1. 将地图栅格化,把每一个正方形格子的中央称为节点;
  2. 确定栅格属性,即每一个格子有两种状态:可走和不可走;
  3. 定义两个列表集合:OpenList 和 CloseList,OpenList 可以存储节点的 g 值;
  4. 确定起始节点和目标节点。

A* 算法流程:

  1. 初始时,定义起始节点为父节点,移入 CloseList 中;
  2. 逐个检查与父节点 i 相邻的周围的节点 j,忽略不可走节点和已经存在于 CloseList 中的节点:
    • 若节点 j 不在 OpenList 中,则将节点 j 的父节点记为节点 i,计算节点 i 到节点 j 的距离 d,计算 g(j)=g(i)+d,并把它们加入到 OpenList 中成为待考察的对象;
    • 若节点 j 已经在 OpenList 中,则检查这条路径是否更优,即经由节点 i 到达节点 j 是否有更小的 g 值:计算节点 i 到节点 j 的距离 d,若 g(i)+d 小于 OpenList 中节点 j 存储的 g(j),则这条路径更优,更新 OpenList 中节点 j 存储的 gg(j)=g(i)+d,并将节点 j 的父节点记为节点 i,若这条路径不是更优,则不进行任何操作;
  3. 计算 OpenList 中所有节点的 f 值:f(n)=g(n)+h(n),从 OpenList 中取出 f 值最小的节点,放到 CloseList 中,并把它作为新的父节点 i
    • 这里启发式函数 h(n)一般用曼哈顿距离或者欧氏距离来替代。
  4. 重复步骤 2 和步骤 3,不断重复,直到搜索到目标节点,完成路径搜索。搜索出路径的结果可以直接遍历父节点得到。

Question 1:欧式距离(L2)作为启发式函数一定是最优的吗?
Amswer:是的

Question 2:曼哈顿(L1)作为启发式函数一定是最优的吗?
Amswer:不一定

Question 3:L 作为启发式函数一定是最优的吗?
Amswer:是

Question 4:常值 0 作为启发式函数一定是最优的吗?
Amswer:退化成 Dijkstra 算法,保证最优

思考:

  • 如果启发式函数 h(n)<h(n) ,即启发式函数估计的距离小于真实距离,则保证路径的最优性。如果设计出的 h(n)h(n),可以视为更加贪心,牺牲路径的最优性来换取计算时间,这就是 weight A*。

weighted A*:

将 A* 中的 f(n)=g(n)+h(n) 替换为 f(n)=g(n)+ϵh(n),ϵ>0 ,以牺牲路径最优性来换取计算时间上的效率。

若有 f(n)=ag(n)+bh(n),则:

  • a=0b=1 时为最贪心的路径;
  • a=1b=ϵ>1 时为偏向贪心的路径;
  • a=1b=1 时为最优路径;
  • a=1b=0 时退化为 Dijkstra 算法;

Tie Breaker:

在寻找路径时,有时会出现多个节点的 f(n) 相同的情况,这可能会在搜索的过程中导致 expand 很多节点,导致搜索效率低下。

解决:

  • 方案一:当几个节点拥有相同的 f(n) 值时,对 h(n) 进行比较;
  • 方案二:我们倾向于对角线抵达终点,在计算 h(n) 时进行如下修正:

    (1)dx1=abs(node.xgoal.x)(2)dy1=abs(node.ygoal.y)(3)dx2=abs(start.xgoal.x)(4)dy2=abs(start.ygoal.y)(5)cross=abs(dx1×dy2dx2×dy1)(6)h=h+cross×0.001

Jump Point Search 算法#

与 A* 的区别:

  • A* 在扩张时考虑自然的邻居节点,而 JPS 考虑的是跳跃的邻居点;
  • JPS 可以在空旷的区域进行大范围的跳跃;

搜索流程:

Question:JPS 一定比 A* 好吗?
Answer:不是,如果在障碍物多的场景,JPS 具有较好的效果,但是如果在障碍物较少的场景,JPS 需要扩展大量的节点;

总结:

  • 在大多数情况下,尤其是复杂环境,JPS 的效果比 A*好,因为 JPS 减少了加入到 Open List 中节点的数量,减少了内存消耗,和 Open List 中排序的次数等,但是 JPS 增加了对地图中节点状态(有无障碍物)查询的次数;
  • JPS 只适用于 uniform grid map;
posted @   HeyRay_Yang  阅读(184)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示
主题色彩