ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

三台AGV路径规划实战:A*算法落地与多车调度踩坑全记录

三台AGV路径规划实战:A*算法落地与多车调度踩坑全记录 AGV小车的项目心得做AGV小车这个项目前前后后折腾了大半年从最开始只有一台底盘加一个工控机到最后三台AGV在产线上多工位来回跑、配合机械臂上下料整个过程踩过的坑比想象中多得多。尤其是在路径规划这一块我们一开始直接套用了最基本的A算法跑到后面发现“三条AGV基本A算法”这个场景里藏着大量细节问题——不是算法本身不行而是你想得太简单了。这篇文章不打算讲教科书式的原理而是把我在实际项目里怎么做选型、怎么搭架构、怎么把A*算法调出可用的效果、以及现场联调时遇到的那些让人头大的问题全部整理出来。不管你是学生、刚入行做AGV相关的工程师还是公司里负责机器人项目的技术负责人只要你准备接触或者已经在做AGV调度导航这块这篇文章应该都能帮上忙。因为它不是纯理论也不是纯粹软文而是从一个真实落地的项目视角讲清楚“这些方案为什么这么选”和“遇到问题了怎么快速判断”。1. 项目整体设计与思路拆解1.1 项目背景与需求分析这个项目来自一个内部的离散制造示范线面积大概800平划分为原料区、加工区、检测区、成品暂存区四个大的功能分区。任务很简单三台AGV负责把物料从原料区送到三个加工工位再把加工完的半成品送到检测区最后由一台AGV把检测合格的成品拉到成品暂存区。听起来很常规但实际需求里有几个硬约束现场有多台数控机床加工节拍不固定AGV必须在收到呼叫后尽可能短的时间内去接料。通道狭窄最窄的回转通道只有1.2米但AGV车体宽度0.6米不能双向会车。三台AGV同时运行共用一段“主干道”怎么避免阻塞和死锁是调度系统必须解决的。现场有大量金属机柜和电机WiFi信号干扰严重无线通信不能完全依赖单一方案。我们的AGV底盘是自研的差速驱动采用SLAM导航加二维码辅助修正的方案对接门的开合、托盘举升等动作都通过IO信号和上位机联动。整体系统由四部分组成AGV单车含工控机、驱动、传感器、调度系统也叫任务管理系统、地图服务、外围设备对接模块。这里多讲一句为什么选这个方案组合。纯磁条导航部署快、稳定但后期改线麻烦纯激光SLAM在建图简单的大空间很好用但通道窄、环境存在金属干扰时容易飘二维码导航精度高但需要密集铺设。我们把激光SLAM作为主定位二维码只做特征点修正相当于一个“成本适中的折中方案”。再加上三台车跑公共通道完全靠单车自主绕行不现实最终决定采用“中央调度单车自主避障”的混合架构。1.2 整体架构与系统分工整个系统的分工是这样的单车端跑的是ROS 2的导航栈负责建图、定位、局部规划、避障。调度端跑在独立工控机上负责全局任务分配、路径规划、交通管制。两端的交互通过MQTT协议实现任务消息和状态回传都是JSON格式。为什么不用ROS原生的通信直接打通因为现场还有MES系统的对接和多台设备联动MQTT更容易和产线现有系统集成而且断线重连机制比ROS自带的话题通信要成熟得多。三台AGV分别叫AGV-01、AGV-02、AGV-03每台车都维护一张全局栅格地图地图上是静态障碍物信息。调度端也维护同一张地图的拓扑结构但不需要完整的栅格而是把可行区域抽象成节点和边。也就是说单车端负责“我怎么过去”调度端负责“你该走哪条路线过去”职责清晰调试方便。在实际跑起来之前我花了很多时间在调度端和单车端之间的数据同步上。地图更新、临时禁行区、任务优先级这些信息如果两端不同步就会出现调度端说“走A路”单车说“A路被我局部地图里检测到障碍物挡住”然后就原地打转。我们最后加了版本号机制每次地图更新调度端广播新版本号各AGV确认后再下发任务这个问题才算彻底解决。1.3 导航方案选型与取舍导航方案是整个项目的根基。我们评估过的方案包括磁条、反光板激光、自然导航激光SLAM、视觉SLAM、混合导航。磁条和反光板方案最稳尤其是反光板定位精度可以做到毫米级但需要预先布置和维护物理标记后期改造产线时极其痛苦。纯视觉SLAM在纹理丰富的室内环境效果不错但我们现场有一些区域是白墙加金属架视觉特征少而且光照变化大不适合作为主力方案。最终选定“激光SLAM二维码修正”的混合导航这个方案单台车硬件成本适中调试工作量也不算特别大关键是在精度上能满足我们的对接要求。有一个细节值得注意二维码不能铺太密也不能太稀。太密了增加维护成本太稀了定位修偏不及时。我们在实践中找到一个经验值二维码之间的间距8到10米比较合适在转弯前后和对接工位前必须放。这样AGV在没有二维码的路段靠激光SLAM走误差累积到一定程度就会被二维码拉回真实位置整体横向误差控制在了±2厘米以内、纵向误差±3厘米以内可以稳定对接举升机构和机械臂。2. 核心硬件与底盘细节解析2.1 传感器配置与融合单车上的传感器包括2D激光雷达主导航雷达扫描频率20Hz量程30米装在车体前后对角位置用于SLAM建图和实时定位。3个超声波传感器分别装在前方、后方、侧方用于近距离低矮障碍物的补充检测。激光雷达的扫描平面离地25厘米低于这个高度的障碍物比如地面上的工装板、拖链它扫不到超声波刚好补上这个盲区。2个光电传感器专门识别二维码站点的到位标记配合地面磁钉做定位修正。IMU用于估算航向角和角速度在快速加减速时抑制激光匹配产生的跳变。传感器融合方面我们用的是ROS 2中的robot_localization包把激光里程计、轮式里程计、IMU放在一个扩展卡尔曼滤波器里做融合。这里有一个常见误区——轮式里程计在AGV上精度很差打滑、轮胎磨损都会引入误差如果直接拿轮式里程计和激光直接融合定位飘起来很快。正确做法是降低轮式里程计在融合权重中的信任度让激光占主导轮式只在激光短暂失效时兜底。超声波数据的处理也很关键。直接把它发布成障碍物点云参与代价地图更新虽然原理上没问题但容易在车体转向时产生误报。我们最后是把超声波检测结果经过一个长6米、宽2米的“安全走廊”滤波只在走廊内检测到障碍物才触发减速这样有效减少了急停误触发的次数。2.2 底盘运动学与控制参数底盘是差速驱动两个主动轮在后轴前面两个万向随动轮。这种结构的特点是控制简单、转弯灵活、可以在原地自旋但直线行驶时如果左右轮转速不完全一致车会跑偏。所以小车在空载高速和满载低速时的PID参数必须分开标定。我记录了一组参考数据空载时最高速度1.2m/s加速度0.6m/s²满载时最高速度降到0.8m/s加速度0.4m/s²。PID速度环的比例增益在空载时的典型值为12满载时要降到8左右。如果不换参数满载启动或刹车时会出现明显过冲严重时直接把托盘上的料甩下来。控制周期统一是20ms底层驱动器接收目标速度指令内部做电流环和速度环双闭环。另一个容易忽略的问题是充换电时序。AGV电量低于30%时要自动上报调度端调度端停止给它派任务并安排它回到充电点。如果电量低于15%才上报车可能在半路没电尤其在重载上坡路段断电瞬间会让托盘举升机构突然下降非常危险。所以我们在控制逻辑里设了三级低电量保护在25%时执行“不可取消的强制回充任务”。2.3 电气与通信架构通信架构看起来是小事但在产线现场非常关键。车间里有数控机床、变频器、焊机电磁环境复杂初期只靠WiFi通信AGV经常出现“车还在跑调度端却显示离线”的情况。排查后发现路由器漫游切换时间达到了2到3秒而AGV在1.2m/s速度下1秒就能跑1.2米这个时间足够它冲出安全区域了。我们最终采用了“主通信WiFi备用通信5.8G点对点”的双链路方案两条链路同时传输状态心跳调度端约定连续丢包3次即切换备用链路。同时把ROS 2节点中的DDS发现协议改为静态发现关闭了多播减少了广播报文在WiFi环境下的冲突。这样调整之后通信掉线率明显下降一周运行数据里掉线次数从每天十几次降到了一两次。另外必须给每台AGV装独立的急停按钮和声光报警器这不是可选项。现场任何时候都可能有人突然出现在车前方安全策略不能只依赖软件。3. 三条AGV环境下的A*路径规划实现3.1 A*算法的基本逻辑项目里调度的核心路径搜索算法用的是A*这是导航路径规划里最常见、最基础、也最可靠的一种启发式搜索算法。网上关于A*的文章特别多但多数停留在“八数码”或者“小地图寻路”的层面真正放到AGV场景里你需要考虑的东西要多得多。先记住A*最核心的公式F G H。G是起点到当前节点的实际代价H是当前节点到终点的估计代价F就是综合代价。算法每次从开放列表里取F值最小的节点扩展同时更新它周围节点的G值和父节点直到终点被找到为止。这个逻辑很简单但不同的代价定义方式会导致完全不同的路径结果。在你的自动驾驶小车或者AGV项目里G值一般不只是“走了多少米”而是“走了多少米乘以这条路段的通行难度系数”。比如主干道的通行系数是1.0窄通道是2.5转弯处额外加0.8这样A*搜索时自然会优先走宽阔平坦的路而不是盲目选最短的直线路径。H值通常用欧几里得距离或者曼哈顿距离来算。我们在AGV场景里建议用曼哈顿距离因为AGV的行驶路径基本都是横平竖直的多段线曼哈顿距离和实际代价更接近搜索效率也更高。如果用欧几里得距离H值会低估真实代价导致搜索扩展更多节点性能下降。3.2 启发函数与地图栅格化A里的启发函数决定了算法的“激进程度”。如果H值始终是0A就退化成Dijkstra算法搜索结果一定是全局最短路径但计算量大在大地图里可能把CPU跑满。如果H值过大搜索会非常快但得到的路径可能偏长。实际项目中我们一般让H值略小于真实代价也就是允许A*优先朝终点方向搜索同时保留一定的安全性后备。以三台AGV的场景举例我把全局地图栅格化成5cm的分辨率共1200×1600个栅格约192万个节点。如果直接在这个栅格上跑A*单次路径规划耗时在50毫秒到200毫秒之间看起来可以接受但三台车同时请求路径、加上拓扑地图抽象CPU压力依然很大。后来我们做了一个分层规划第一层在拓扑地图上搜索选出途经的关键站点序列第二层在每个站点间用栅格A*做精细路径。这样计算量降低了大概70%响应时间稳定在30毫秒以内。启发函数我建议乘一个系数α让H α × 曼哈顿距离α取1.05到1.15之间比较合适。太大会导致搜索过度保守路径明显绕路太小会感觉搜索变慢。我们实际取1.1路径综合质量最好。另一个优化点是“转向惩罚”。A如果只考虑距离很容易规划出贴着障碍物边缘反复左拐右拐的锯齿状路径AGV跟着这种路径走不仅体验差还会频繁减速。我在A扩展节点时会对相邻三个节点走向不一致的情况额外增加一次代价相当于“尽量保持直线”。这招特别有用路径明显更平滑AGV行驶速度也稳定了。3.3 三条AGV的路径冲突处理这是整个项目里最烧脑的部分。三条AGV如果各自独立跑A*不考虑其他车的存在最后大概率会在主干道上互相堵死。我们用了“预留时间窗”的方式来处理。具体的做法是调度端为每条路径段比如从节点A到节点B长度按实际距离算分配一个时间窗口记录哪台车在什么时间段通过这个路段。每台新车的路径规划完成后检查自己的时间窗口和已有窗口是否重叠。如果重叠就等待或者重新规划一条绕行路径。听起来不复杂但实际调的时候有很多细节。比如车的加减速过程不是瞬时完成的车头和车尾通过同一个路段的时间差要考虑进去否则窗口预留得太紧实际运行时还是会追尾。我们的办法是在时间窗里增大一个“安全余量”每段路径的占用时间按车辆实际行驶时间乘以1.3倍来计算宁可让车等一下也不要让两台车同时挤进窄通道。还有一种情况是三台车互相让路导致整体死锁。比如AGV-01在窄通道里准备右转AGV-02在通道另一头准备直行AGV-03在岔路口等待结果三台车谁都无法前进。我们最后在调度逻辑里加了“优先级超时抢占”机制不同任务类型有不同的默认优先级搬运空托盘的任务优先级低给加工中心送料的优先级高当检测到死锁时低优先级任务主动后退让路腾出空间。这个机制上线后现场死锁频率从最初的一天几次降到了几乎为零。3.4 路径平滑与减速点设计A*规划出来的是折线段AGV在转向时如果直接按折线行驶速度稍快就会有明显的“点头”现象车载托盘上的物料容易位移。我们加上B样条平滑后转向轨迹从直角折线变成了可控的平滑曲线但前提是平滑后的路径不能离原始路径太远否则会撞到障碍物。实现方法很直接把A*路径的拐点抽取出来用n个控制点做三次B样条拟合在平滑时把最大偏移量限制在0.3米以内。如果单次平滑后路径和障碍物的最近距离小于0.2米就放弃平滑退回原始路径并降低转弯速度。这个“平滑失败自动回退”的逻辑比一味调平滑参数更可靠。减速点的设计同样重要。AGV接近转弯、站点、对接位置、交叉路口前需要提前减速。我们把减速逻辑放在路径跟踪模块里根据前方路径曲率动态计算目标速度公式很简单距离转弯点还剩3米时开始减速速度从1.0m/s线性降到0.3m/s出弯后慢慢加速回来。遇到二维码修正点前2米也会强制减速到0.4m/s保证定位修正的刷新准确率。4. 实操过程与核心环节实现4.1 建图与定位调试建图是整个项目起步最枯燥也最容易返工的阶段。我们用cartographer算法进行离线建图小车推着跑一圈激光数据配合轮式里程计生成栅格地图。地图质量好不好直接影响后面所有导航调试。我总结了几条建图实操经验建图时车速保持0.3m/s以内太快了激光帧与帧之间的匹配容易失败地图出现重影。在通道拐角、门口、柱脚等特征稀疏的地方要重点停留一下让雷达“多看一会儿”丰富特征信息。地图边界最好留20厘米以上的“余白”否则后续添加临时障碍物时会被裁剪掉。建图完成后必须人工检查一遍地图把杂点、镜像畸变区域手动清理干净再重新保存并验证定位。定位调试方面刚开机时AGV不知道自己在哪需要给出初始位置或者通过二维码位置估算初始位姿。启动后跟踪一段观察激光点云和地图的重合度。如果出现“错位重影”常见原因是IMU零偏未校正或者车轮打滑导致里程计跳变。我们每次开机都会让AGV原地旋转一圈自动采集IMU零偏数据这个简单的动作让初始定位成功率从70%提到了95%以上。4.2 调度系统触发与任务分配调度系统采用python写的核心是一套状态机加队列。整个系统的输入是“呼叫事件”比如工人按下工位旁的呼叫按钮或者MES系统发送一条任务请求。调度端收到请求后根据任务的优先级和当前AGV的位置、电量、忙闲状态选择一个最合适的AGV去执行。这里有一个细节派单不只是找“最近的车”。还要考虑回程。如果让一台车送完A点再绕一大圈去B点不如让另一台顺路的车去。我们在评分函数里综合考虑了“距离工位的距离、执行完任务后的返回距离、当前电量、任务优先级”等因素用加权评分选择最优车。实际测试下来这个策略比纯最近优先策略减少了大约18%的空驶里程。任务下发后AGV收到任务消息先本地做一遍路径检查确认自己在当前状态下能安全到达目标点回复“确认”然后才开始动作。这个“先检查后应答”的握手机制避免了一台车在报错状态下还硬着头皮接任务。4.3 现场联调的先后顺序现场联调一定不要一步到位要分级验证。我建议按以下顺序来第一步单车闭环测试。只让一台AGV在简单路线上跑验证定位、路径跟踪、避障逻辑基本正常。这一步不急着上调度把车的问题都暴露出来解决掉。第二步单车任务流程测试。给一台AGV下发单任务包含取料、举升、行走、对接、放下几个动作验证外围设备的IO联动和时间配合。第三步双车避让测试。重点看两台车在窄通道相遇时动作逻辑是否符合预期。这一步能暴露大部分时间窗和道路锁定的bug。第四步三车满负荷测试。三台车同时跑多个工位观察调度端任务分配和系统吞吐量排查死锁和任务堆积问题。我们前前后后跑了将近三周才把整个流程稳定下来。最让人崩溃的就是三车满负荷测试阶段经常出现“哪台车都没坏但是整体就是跑不起来”的诡异现象后来发现是调度端存在一个变量覆盖问题任务分配列表被并发修改导致两台车接到了同一个任务。加了一个带锁的线程安全队列这个问题立刻就好了。5. 常见问题与排查技巧实录5.1 定位漂移问题遇到过好几次AGV开着开着位置突然“跳”到地图外然后急停报警。排查步骤是这样的先看激光点云和地图是不是能对得上。如果对不上先检查现场是不是有堆放的物料或者临时围挡改变了环境的几何特征。如果有把新障碍物加入地图或者划定禁行区。如果点云正常但定位仍然漂移检查IMU数据。我之前踩过的坑是启动时没有做好IMU静止初始化导致航向角有一个微小偏差在小范围看不出来但直线走30米之后横向偏差就能累计到半米多。后来加了开机自动校零和温度补偿这个问题基本消除了。还有一种情况车轮打滑。当地面有油污、水渍或者粉末时轮式里程计会突然多报一段位移在窄通道里尤其明显。解决方法是提高激光匹配结果在融合权重中的比例同时把轮式里程计单帧差值的异常上限限制在0.1米超过就认为里程计异常直接丢弃。5.2 路径规划与死锁排查三台车同时跑时最难查的是死锁。排查工具要提前做好不要等到现场出了问题再翻日志。我在调度端加了一个图形化的实时界面显示三台车的位置、目标点、当前路径、每个路段的占用窗口。一旦出现“车卡住不动”的情况截图看锁定的路段是谁占的、优先级是谁让的基本一眼就能看出死锁原因。最常见的原因是两个第一时间窗计算太多保守。之前为了保险把占用时间乘以1.5结果两台车在交叉路口前互相等待明明谁都不挡谁但逻辑上认为“要等对方完全走完才动”。后来把系数从1.5降到1.3同时在确认对向车已经通过交叉点后立即解除等待整个系统的吞吐量直接上来了。第二死锁检测-恢复机制没有覆盖“三台车互让”的场景。刚开始只实现了两台车的抢占逻辑三台车的场景下存在逻辑漏洞导致所有车都进入“让行”状态。后来增加了一个超时强制命令某个任务等待超过30秒调度端强制把优先级最低的那台车设置成“后退模式”回到上一个安全节点再重新规划路径。这个方案简单粗暴但有效。5.3 通信丢失与指令重发前面提过WiFi在金属机柜多的车间里信号衰减很厉害。我们做了一次全区域信号热力图测试发现车间角落有一个区域的信号强度低于-80dBm正好是原料区天天有AGV在这里掉线报错。后来在原料区增加了一个工业AP并把漫游阈值调低才把这个问题解决。如果你也遇到通信不稳定的情况先做一个基础排查用手机或者笔记本在AGV作业路径上走一遍记录各位置的信号强度和延迟。低于-70dBm的区域需要重点优化。检查AP的频宽设置。2.4G带宽设置为20MHz比40MHz抗干扰能力更好。检查AGV工控机有没有定时做ARP广播之类的网络请求避免网卡因为省电策略而“打瞌睡”。另一个必须做的是指令重发机制。调度端发送任务后如果3秒内没收到确认必须重发并且最多重发3次。如果仍然失败让现场人员人工介入不允许AGV“自作主张”继续执行。这个规则看起来很原始但在现场非常有用能防止单次通信故障导致整个流程错乱。5.4 执行机构故障与传感器脏污AGV上的举升顶升机构、夹抱机构都是纯机械部件运行时间长了动作时间会变长。我们用了一个轻量级的“动作超时监测”举升动作正常耗时1.5秒超过3秒就报故障并自动禁止AGV继续行进。这样就不会出现“托臂没完全放下、AGV已经开走了”的危险场面。还有一个小但很关键的问题二维码脏污。车间灰尘大地面上贴的二维码容易磨损和脏污导致二次定位精度下降。我们的处理是每周定期清理一次二维码将近一个月统一检查一次码是否破损。这个维护工作要写进日常点检表里不然时间一长定位精度就悄悄变差直到突然某一天对接失败才会被发现。6. 一点个人体会做完这个三台AGV的项目我最明显的感觉是硬件可以买算法可以调但真正决定项目成败的往往是那些不起眼的工程细节。比如时间窗余量系数、IMU开机校正、通信双链路心跳、二维码定期清理这些东西在论文里几乎没有但在产线上每一个都可能让整个系统停摆。如果你也要做类似的项目我建议先把“安全”和“可维护性”放在第一位再考虑效率和算法复杂度。A算法本身是几十年前的东西了它很好用但要让三台AGV在一个真实的车间里默契配合你需要花大量精力在调度策略、冲突解决和现场调试上。“基本A算法”只是入场券能不能把它用好、让它适应真实世界里的不确定性才是真正拉开差距的地方。希望这些经验对你有帮助。
返回列表