苏宁 11.11:仓库内多 AGV 协作的全局路径规划算法研究

2023-11-09

本文为『InfoQ x 苏宁 2018双十一』技术特别策划系列文章之一。

1. 背景

随着物联网和人工智能的发展,越来越多的任务渐渐的被机器人取代,机器人逐渐在发展中慢慢进入物流领域,“智能叉车”,AGV(Automated Guided Vehicle,自主导航车)的出现不仅大大降低了人工成本,还在提升效率,面对海量订单拣选时候有不错的表现。在实际应用中,一个仓库内多个AGV协作完成订单是不可或缺的部分,而且多个AGV共同运输的过程中同时进行路径规划需要一定的算法做支撑,本文在一个仓库内多个AGV协作进行路径规划的方向上进行算法的研究,对其原理和实现进行分析和介绍。

2. 分析

首先,我们的背景设置在物流仓库,针对仓库中常见的入库、拣货、出库等具体的任务细节进行分析,来了解我们AGV所面临的场景。

传统的方式一般采用静止的货架,入库时将商品运输到指定货架前,人工上架入库,拣货时人工去到指定的货架拣选订单对应的商品打包出库,引入AGV之后,模式将发生改变,我们会在仓库规划指定的入库区、拣选区,AGV会将包含订单的货架动态地运输到拣选区,排队等待人工或者机械臂拣选到指定的订单拣选筐内打包出库,完成拣选后将货架运输至指定位置。

所以,引入AGV之后,我们面临的问题是为了最大限度的提高效率,多个AGV如何避免拥堵和碰撞,如何对每个AGV规划出更好的行走路线,怎样才能让每个AGV花最小的代价,完成更多的任务,将是此文讨论的重点。

3. 问题拆解

要使得多个机器人在道路规划上最优,无非是在单个小车规划路径时考虑其他小车的行驶路线,进而选取最优的一个行驶方案。另外,不同于室外场景,我们在仓库中规划小车路径,整个道路都是可以设计的,所以我们的问题可拆解为:

(1)\t仓库中道路的设计;
(2)\t获取到其他小车的路径行驶状态;
(3)\t定义可能的道路拥堵;
(4)\t规划最短路径;
(5)\t交通管制。

3.1 仓库中的道路设计

一些常见的道路设计如图1和图2,根据实际的应用场景来布局,考虑的因素包括仓库的结构,商品的种类等,根据实际测试或模拟来选取最优的设计。

\"image\"
图1. V字型道路设计

\"image\"
图2. 井字型道路设计

3.2 获取到其他小车的路径行驶状态

要做到全局路径规划,必须得到每一个时刻小车的位置和运行状态,所以必须和小车建立起稳定的通信系统,一般采用无线局域网的方式,用TCP建立连接,选取合适的WIFI通道来保证小车和全局路径规划系统的通信的稳健。

3.3 定义可能的道路拥堵

在仓库的道路规划完成之后,首先要考虑的因素是可能的道路拥堵情况,一般小车在仓库中都是直线行走,需要转弯时要停在原地,原地旋转90°或180°之后继续直线行走,所以每个转弯都有机会造成当前道路拥堵。另外,同一条道路车流量较大时,也会造成道路拥堵,加上路口会车的情况,主要造成道路拥堵的有转弯、会车和车流量较大3种常见的可能情况。

3.4 规划最短路径

最短路径规划是全局路径规划的核心,要从地图上的一个位置到达另一个位置,在中间有障碍物以及考虑到可能的道路拥堵情况,必须使用一个路径搜索算法来寻找从初始点到目标点的一条最短路径,常见的搜索路径的算法有广度优先算法、深度优先算法、Dijkstra算法、A*算法等,广度优先算法和深度优先算法适用于树形结构求解最短路径或最小权重的场景,环状结构求解最短路径一般采用Dijkstra算法,A*算法是静态路网中求解最短路径最有效的直接搜索方法。

每一种算法都有其应用场景,对于我们全局路径规划的场景,我们的地图更容易转换成栅格地图,而A*算法在栅格地图上搜索最短路径有明显的优势,而且方便于修改加上我们道路拥堵场景的考量,所以我们以A*算法为首选最短路径算法,进而分析实现全局路径规划。

3.5 交通管制

交通管制主要应用于会车和并流场景,一方面为了避免车辆碰撞,另一方面路口会车比较常见,处理不好会导致车辆死锁,车辆相互等待,进而导致任务无法完成,也是全局路径规划的核心算法,常见的会车场景如图3。

\"image\"
图3. 路口会车

4. 核心算法实现

路径规划算法的核心主要在于最短路径的规划和交通管制,这里将对一种最短路径规划算法和交通管制算法进行算法剖析,进而设计出一套完整的全局路径规划算法。

4.1 A*算法规划最短路径

A*算法类似于图论中寻找最优树,通常是通盘考虑选择某一路径的路径耗费,在所有可通过的路径中总有一条路径相对于其他任何可通行的路径来说是耗费最少的。在图论中寻找最佳路径时每一条的路径耗费是已知且固定的,但在用A*算法求解最佳路径时,沿着不同的路径前进,尽管是同一节点但其耗费可能是不同的,这便是启发式寻路的精髓。

运用此方式时,首先将实际问题抽象出来,用矩阵的形式表示问题中的各元素,包括起点位置,目标点位置,以及出现的障碍物。我们会逐渐地发现在寻路方面都是将实际问题抽象地用矩阵表示,之后通过对矩阵的操作模拟实现寻路过程。

其基本思想是以起点为中心,其周围紧邻的8个点都通过指针指向它,在其周围点内选择最佳路径点并以它为中心点将其还未建立指针联系的周围点(可行的,这在后文中解释)通过指针指向它,并选择最佳路径点再以此点为中心寻路直到寻找到点的周围点中有目标点,这样寻找的路径就通过指针一一连接起来了,最后通过输出这些点就是寻找的路径了。

下文主要通过以下几个方面来逐步分析A*算法的寻路过程:

(1)\t将实际问题抽象化为矩阵表示

抽象出的矩阵如图4,其中绿色区域表示起始点,红色区域表示目标点,中间蓝色区域表示障碍物(如不可通过的高山或是河流),黑色区域表示可产生路径的区域。

(2)\t以起点为中心寻找到下一节点

如图5所示,以起点为中心与之紧密相邻的8个点是其所寻路径上可到的下一点,且都以指针的形式将中间当前点作为与其紧邻的周围点的父节点。对于这8个点,应该选择哪一点作为寻路的下一个起点呢,A*算法中建立了两个列表,一个为开启列表(用于存储所有当前点的可到点(除去已经在关闭列表中的点、障碍物点)),另一个为关闭列表(里面存储已经到过的点,已经在关闭列表中的点在下一次寻路的过程中是不会再次检查的,这也说明寻路的线路不会有相交的可能)。

\"image\"
图4

\"image\"
图5

(3)\t选择下一节点

将起点加入关闭列表,在以后的寻路过程中不再对其进行检查,接下来就是在这8个点中选择一个作为下一路径点,选择的原则是在其中寻找路径耗费最小的节点,

其权值用F表示,F=G+H

其中G表示从起点开始,沿着产生的路径,移动到指定方格上的路径耗费;如图6所示,以起点为中心其紧邻周围点有上下左右、对角线方向上的8个点,以上下左右移动路径耗费为10,对角线耗费为 $ \\sqrt{2} \\times10$,约为14。

其中H表示从路径所在的当前点到终点的移动路径耗费,计算方法为当前点到目的点之间水平和垂直的方格的数量总和,然后把结果乘以10。

从图7可以看出,起始点右边点的权值F最小,故将其作为下一路径点。

\"image\"
图6

\"image\"
图7

(4)\t继续搜索

把路径点从开启列表中删除,并添加到关闭列表中。检查与此点紧邻的8个点(忽略在关闭列表中或者不可通过的点),把他们添加进开启列表,如果存在还有点没有添加进开启列表,则将路径点作为此类点的父节点并添加进开启列表。

如果所有可行的紧邻点已经在开启列表中,对每一紧邻点检查目前这条路径到是否比上一路径点到这一紧邻点的路径耗费要小,如果不是则什么都不用做(如图8所示)从原始起点到其紧邻的右下方的点,按照新产生路径G值:G1=10+10=20,而原始路径G值G2=14,即新产生路径的G值比原始路径的G值大,而它们的H值相同(为同一点)故原始路径的F值比新产生路径的F值要小,不做任何处理,继续下一步寻路。如果是,那就把相邻方格的父节点改为目前选中的方格,说明新产生的路径的移动耗费更小。

\"image\"
图8

(5)\t重复上一搜索过程直至结束

搜寻过程结束分为两种情况:一种是目标点加入关闭列表,搜索正常结束,找到路径。另一种情况是目标点未找到但开启列表已经为空,意味着没有找到从起始点到目标点的路径,搜索结束。

搜索过程如图9所示,从中可以看出从起点到目标点之间有指针指向一致的一条路径,这便A*算法是搜寻到的路径。在路径点上添加红色点突出显示,此即为从起始点到终点的一条路径。

\"image\"
图9

整个寻路过程整理如下:

  1. 起始格加入开启列表;
  2. 重复如下的工作:
    a. 寻找开启列表中F值最低的点。我们称它为当前点;
    b. 把它加入关闭列表;
    c. 对紧邻的8格中的每一点
    • 如果它不可通过或者已经在关闭列表中,略过它。反之如下:
    • 如果它不在开启列表中,把它添加进去。把当前点作为这一格的父节点。记录这一点的F、G和H值;
    • 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样,就把这一点的父节 点改成当前点,并且重新计算这一点的G和F值。改变之后需要重新对开启列表按F值大小排序。如果不是则不需要做后面改变指针指向并重新计算G、F值的工作;
  3. 停止搜索,分为两种情况:
    • 当目标点添加入了关闭列表,这时候路径被找到,搜索正常结束;
    • 没有找到目标点,但开启列表已经空了,此时未找到合适的路径,搜索结束;
  4. 保存路径。从目标点开始,沿着每一点的指针指向移动,直到回到起始点,输出路径。

4.2 基于锁格机制的交通管制

车辆道路规划完成后,多个小车同时开始行走,多条道路小车会车的情况不可避免,会车时候车辆主要会出现跟随,相向而行,十字路口或丁字路口的情况,跟随的时候车辆前方会有传感器避免跟随碰撞,为了避免十字路和丁字路会车碰撞,会车时候采取锁格的方式,即:

(1)\t每辆小车行走一步,将前面即将行走的两步的点锁住;
(2)\t小车锁格时发现即将锁的地图的点已经被锁住,则两车协商看哪个优先级高,哪辆车先行,另一辆车停车等待;
(3)\t小车走过之后将解锁,等待的时候可以重新锁住即将行驶的点,继续往前行走;
(4)\t循环一直每一步都进行锁格操作。

4.3 全局路径规划

在规划当前小车路径时,要在考虑到道路拥堵的情况下去规划最短路径,以满足整体规划结果最优,使用A*算法,用G值为参考检查新的路径是否更好, 将地图中其他小车规划的路径的点的G值增加,即可尽量避免搜索到相同的路径,同样的道理,在车辆需要转弯的时候,也同样增加转弯下一点的G值,从而规划路径尽量避免转弯的情况出现,来达到整体效率最高,全局路径最优。
此外,由于路径规划都是静态规划的路径,车辆在行走过程中同时需要对每辆小车进行锁格的交通管制,来保证车辆不会相撞。

5. 总结

本文主要对仓库内多AGV协作的全局路径规划进行了研究,并介绍了一种可能的实现算法方案,从仓库中道路的设计,拥堵的考量等角度简单全局路径规划需要考虑的维度,对最短路径规划和交通管制策略进行的详细的分析和应用设计。

作者:董效成,苏宁易购IT总部人工智能研发中心技术经理,负责机器人项目任务匹配和路径规划算法工作。有多年的机器人算法开发经验,对轮式机器人的运动控制,路径规划等算法有深刻的理解,有丰富的机器人操作系统(ROS)开发实践经验。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

苏宁 11.11:仓库内多 AGV 协作的全局路径规划算法研究 的相关文章

随机推荐

  • Error mounting /dev/sr0 at /media/ VBox

    重新安装Linux映像 sudo apt get install reinstall linux image uname r
  • IBM WAS简介

    IBM WAS简介 IBM WAS 的全称是 IBM WebSphere Application Server 和 Weblogic 一样 是 当前主流的 App Server 应用服务器 之一 App Server 是运行 Java 企
  • DataWhale集成学习(下)——Task14 案例分析1幸福感预测

    目 录 背景介绍 数据信息 评价指标 案例 背景介绍 数据来源于国家官方的 中国综合社会调查 CGSS 文件中的调查结果中的数据 数据来源可靠可依赖 用139维的信息来预测其对幸福感的影响 数据信息 139维 8000余组 幸福感预测值为1
  • 【indemind双目惯性相机调试】sudo后找不到命令问题,环境变量问题

    问题1 报错 kanhao100 ubuntu x86 roslaunch imsee ros wrapper start launch RLException start launch is neither a launch file i
  • 深度学习_调参经验

    面对一个图像分类问题 可以有以下步骤 1 建立一个简单的CNN模型 一方面能够快速地run一个模型 以了解这个任务的难度 卷积层1 卷积核大小3 3 卷积核移动步长1 卷积核个数64 池化大小2 2 池化步长2 池化类型为最大池化 激活函数
  • leetCode热题46-51 解题代码,调试代码和思路

    前言 本文属于特定的六道题目题解和调试代码 正所谓磨刀不误砍柴功 下面我做这几篇文档对于涉及的题型或者数据结构的分析都很有帮助 贴出来仅供参考 1 69 x 的平方根 Easy 2022 12 28 101 2 22 括号生成 Medium
  • JSP核心标签库

    1 一般标签 在JSTL中 一般标签主要用在输出 设置变量值和错误处理等 这些是JSTL中使用最多的标签 1 计算一个表达式的值 然后把计算的结果输出到当前的JspWriter对象 调用的结果和Servlet中out println 语句效
  • linux 删除指定文件夹包含指定字符串的文件会把所有子文件夹包含的都删除

    需求就是在linux服务器上面删除 指定文件夹里面所有包含 delete 内容的文件 并且所有此文件夹里面的子文件夹查出来也要删除掉 使用以下脚本可以进行实现 grep r l delete data xargs rm rf 脚本说明 gr
  • 机器学习-fp16相乘

    1位符号位 5位指数位 10位尾数位 共16位 内存占2个字节 具体fp16表示法可以参照 机器学习 fp16表示 运算步骤 检查操作数中是否有0 Inf NaN NaN a Nan Inf 0 Nan Inf 0 Nan Inf a In
  • UTSim:无人机空中交通集成、控制和通信的框架和模拟器

    计算机仿真资源的可用性有利于无人机的开发和在现实应用中的集成 因为它们降低了成本 风险 开发和测试时间 并提高了安全水平 一些研究人员为自己的定制特殊无人机和应用开发了自己的模拟环境 然而 使用多个无人机仿真环境很难建立可持续的研究 因为很
  • CSAPP第三版运行时打桩Segmentation fault

    CSAPP第三版7 13 3节提到了运行时打桩机制 它可以在运行时将程序中对共享库函数的调用进行截获 替换为执行自己的代码 这个机制基于动态链接器的LD PRELOAD环境变量 如果LD PRELOAD环境变量被设置为一个共享路径名的列表
  • docker搭建registry私有仓库(centos7)

    搭建环境 master节点 registry端 192 168 1 10 node节点 客户端 192 168 1 20 关闭防火墙和selinux master和node节点都要关闭 root master systemctl stop
  • 【夜莺监控方案】04-k8s集群监控(下)(kube-state-metrics+cadvisor+prometheus+n9e及FAQ)

    文章目录 前言 4 接入prometheus 5 接入n9e 5 1 手动接入 方法一 5 2 导入模板 方法二 6 FAQ 6 1 集群数据时常取不到 现象 解决 前言 相关文档如下 03 k8s集群监控 上 4 接入prometheus
  • 【Navicat11安装教程】

    1 下载安装包 网盘地址 链接 提取码 bbqp 下载之后会得到这样的一个文件夹 2 安装 点击navicat111 mysql cs x64 exe安装软件 安装完成后 将PatchNavicat exe文件复制到安装路径下 如图 操作完
  • idea 工程目录横向变纵向【亲测可用】

    idea 目录横向变纵向往上搜好多都没啥用 下面亲测可用三步走 1 删除项目文件夹下的 idea文件夹 横向时点击 project 然后在 idea 下右击 Delete 就好了 2 关闭IDEA 3 重新用IDEA工具打开项目 然后就 O
  • Android如何配置init.rc中的开机启动进程(service)

    开篇 为什么写这篇文章 先说下我自己的情况 我是个普通的学生 之前在学校一直做Android应用开发 找实习的时候也一直想找相关的工作 来到现在这家公司以后 由于业务调整 被领导安排去做底层开发 本来我对底层的东西一无所知 加上其实并不感兴
  • Python 函数是传值还是传引用

    传递参数的时候 python不允许程序员选择采用传值还是传引用 Python参数传递采用的肯定是 传对象引用 的方式 实际上 这种方式相当于传值和传引用的一种综合 如果函数收到的是一个可变对象 比如字典或者列表 的引用 就能修改对象的原始值
  • C++中char和int型变量的一点心得

    字符字面值一般是用一对单引号来表示 char类型一般就是用字符字面值来初始化 赋值 由于char类型的是单字节长度 当给char类型的变量用字符 字面值赋值时 当单引号里面的内容超过一个字节时 系统会自动截取一个字节的内容给char变量 忽
  • JVM-了解概念

    1 什么是JVM JVM是 java Virtual Machine java虚拟机 的缩写 JVM是作用于计算设备的规范 它是一个虚构出来的计算机 是通过在实际计算机上仿真模拟各种计算机功能来实现的 java虚拟机包括一套字节码指令集 一
  • 苏宁 11.11:仓库内多 AGV 协作的全局路径规划算法研究

    本文为 InfoQ x 苏宁 2018双十一 技术特别策划系列文章之一 1 背景 随着物联网和人工智能的发展 越来越多的任务渐渐的被机器人取代 机器人逐渐在发展中慢慢进入物流领域 智能叉车 AGV Automated Guided Vehi