
做校内机器人配送的同学多半都有过这种感觉地图看着不大全局路径却动不动输出成百上千个坐标点跑起来小车主控喘得不行稍微有点动态障碍路径一重算整条轨迹又开始抖动。这个项目要聊的6-4自动驾驶中的全局路径精简计算简单说就是在保证路径安全、可通行的前提下把全局路径上的冗余点大幅压缩让机器人拿到的不是一条“密密麻麻的坐标锁链”而是一条精练、平滑、便于局部规划器跟踪的主干路线。这个内容适合正在做园区配送、楼宇送物、校园无人小车的同学也适合想搞清楚全局规划和局部规划到底怎么衔接的工程师。先给结论全局路径精简计算不是一个单独的算法而是一整套“地图抽象 路网重构 路径点压缩 轨迹平滑”的组合拳。它不是把精度降低而是把表达方式切换成更高层、更省算力的形式。接下来我把这套东西从为什么要做、怎么拆解、参数怎么选、现场踩过哪些坑一个一个讲清楚。1. 从整片栅格到主干路网为什么非精简不可1.1 全局路径在自动驾驶里的真实地位一套典型的自动驾驶/机器人导航系统从上到下大概分四层感知、定位、全局规划、局部规划与控制。全局规划负责“我要去哪”局部规划负责“眼下这个坑怎么绕” 控制负责“轮子怎么转”。全局规划的输出就是一条从起点到终点的路径通常表达为一系列坐标点。这些点送入局部规划器后局部规划器会以此为参考结合实时障碍物信息生成短距离轨迹。这里有个很微妙的矛盾全局路径越精细理论上参考价值越高但它承担的是“战略层”职责不需要细致到每一个像素。相反全局路径如果过于稠密反而会干扰局部规划的灵活性——局部规划器想绕一个临时出现的锥桶结果全局路径密密麻麻地把所有空间都占满了局部规划器怎么算都算不出一个不碰线的解。所以在整套系统里全局路径应该被“精简”到这样程度足够描述道路走向保留路口、拐弯等关键拓扑特征让局部规划器知道大方向又不至于被细碎点绑死。1.2 校内配送场景的三大现实压力第一地图尺寸不大但栅格化之后点数量很大。一个普通的校园园区大概300m × 400m如果分辨率用5cm一格栅格总量是6000 × 8000也就是4800万个格子。就算用优化过的A*处理在这上面做全局搜索的耗时也是毫秒级到几十毫秒级而配送小车的主控往往是Jetson Nano级别资源有限。第二道路结构相对规整但动态对象多。学生上下课、电动车穿越、临时施工都会让“可通行区域”发生局部变化。全局路径需要重新规划如果每次重算都面对几千万个栅格实时性完全跟不上。第三末端执行场景精细容错率低。配送机器人要在教学楼门口、宿舍楼下一点一点挪进指定位置全局路径如果粗糙到只剩几个大拐点最后几米根本没法用必须结合前端精细坐标系。所以精简计算要同时满足三件事搜索快、主干稳、末端准。1.3 “精简计算”到底减的是什么很多朋友一听“精简”就以为是降精度、减道路信息这是最大的误解。全局路径精简计算削减的对象是这几类东西栅格地图产生的锯齿状折线段比如对角线会变成“阶梯状”的走法长直道中大量共线点这些点不提供方向变化信息纯粹撑数量小幅度曲率波动点还没到需要绕障的程度属于噪声局部规划器本可以自行处理的冗余细节例如一个0.2m的凸起全局完全不必体现。保留的则是道路拓扑、路口、转弯、目标点附近的结构关系。一个直观类比你开车出远门导航软件给你规划的“路线”是几条主干道、几个匝道口、几个红绿灯路口而不会告诉你每分钟要保持在车道内的哪几厘米位置。后者是控制层自己解决的事。全局路径的“精简”就是做前者把车的宏观意图从数千个坐标点压缩成几十个关键点。2. 地图抽象与拓扑路网重构2.1 栅格地图为什么不适合直接做全局规划栅格地图做全局规划有几个天然毛病。第一是锯齿问题。A*这类算法本质上在网格里搜索从左上到右下路径经常是“先横走几步、再竖走几步”呈阶梯状。即使同一方向也因为网格粒度产生大量微小折线。第二是计算量问题。搜索算法和栅格数量强相关。拿刚才算的校园环境几千万个栅格即便用分层搜索或预处理也扛不住频繁重算。第三是“整片可走”的语义缺失。栅格地图告诉你每个格子的通行状态但不告诉你这条路是“主干道”还是“楼间窄缝”。配送机器人走到楼与楼之间的狭窄通道和走在大路上全局路径的余量设计要求完全不同。2.2 拓扑路网的基本构建步骤把栅格地图转成拓扑路网的思路简单讲就是“降维”把二维栅格地图提炼成一张图Graph图里的节点是道路上的关键位置图里的边是两节点之间可通行的道路段。搜索算法在这张图上跑节点数量可能只有几十到一两百个计算量可以忽略不计。构建流程我在模拟项目X里是这样做的栅格地图预处理先做膨胀处理把障碍物边界向外扩一个机器人半径确保拓扑图中的边有足够的物理通行宽度。可通行区域提取用连通域标记法把隔离出来的区域找出来筛掉面积过小的噪声区域。骨架提取基于形态学细化或距离变换得到可通行区域的中心线。这一步相当于把“面”变成“线”为后续路网打基础。关键点标注在骨架图上找端点、交叉点、转折点这些关键结构位置。这一步通常用邻域分析完成。路网生成以这些关键点为节点以骨架线为连接关系建图同时给每条边附上属性长度、平均宽度、是否在室内等。最终得到的就是一张节点少、边清晰的路网可以直接拿来做路径搜索。2.3 关键节点怎么选我们试过的几种标准选点是整个路网构建里最依赖经验的一环。选点太少路网无法表达实际道路结构选点太多又失去精简的意义。我常用的节点类型有这四种端点道路末端的尽头或衔接点例如仓库大门、实验室出入口。交叉点两条以上道路的交汇处通常是一个十字路口或三岔口。转折点道路方向发生显著变化的位置用角度阈值判断一般转角大于15°到20°就落一个点。特征点电梯口、充电桩、固定取货点这类任务相关的固定点位。实际测试下来节点选点的核心法则是“以交叉点和端点为骨架以转折点为辅助以任务点为冗余兜底”。好路网的精简程度反而高。2.4 路网对于全局路径的意义路网一旦建好全局路径搜索就从“二维平面搜索”变成了“图搜索”。搜索范围大大缩减原来动辄几千万个栅格现在只剩100个节点、150条边在图上做Dijkstra或A*几乎瞬时完成。更重要的是图搜索天然避开了栅格锯齿问题。路径在一段边内部就是一条直线段到了不同边的交界处才可能出现转弯输出的原始路径天然比栅格A*路径干净好几个数量级。还有一个好处路网承载了语义信息。比如“某条边是主干道宽度3米”“某条边是楼间连廊宽度1.2米”。全局搜索可以据此自动避开太窄的通道或者优先选择更宽的主路。3. 路径点压缩道格拉斯-普克与其同行者路网搜索完成后我们会得到一条由节点组成的折线路径。这还不够——折线的每个拐点都要保留吗长直道中间的点要多少合适这就要进入路径点压缩环节。3.1 三种常见的路径点压缩思路我实际对比过三种做法各有适用场景固定间隔抽稀每隔N个点保留一个。实现最简单但缺点是直道上可能保留多余点拐弯处又可能因为间隔太大丢掉关键转弯特征。道格拉斯-普克算法DP算法基于“最大距离偏差”实现压缩。给定一个距离阈值它不断把折线拆成子线段丢掉偏离候选线段小于阈值的点。适合坐标点串的抽稀也是这个项目里效果最好的。角度阈值法逐点计算转角只保留转角大于阈值的点。问题在于直道上可能积累缓慢漂移转角很小但累计方向变化很大在全路段上体现为大偏移。综合来看推荐方案是先用DP做一次几何层抽稀再叠加角度和累加距离约束防止关键特征点被误删。单一算法都不够稳。3.2 DP算法在配送路径上的落地细节DP算法流程不复杂但落地时有几个细节容易被忽略。流程是这样的输入一串有序路径点 P0、P1、…、Pn距离阈值 epsilon。以首尾两点画一条直线段。遍历中间所有点到这条线段的垂直距离找到最大距离 dmax。如果 dmax epsilon则把该点作为“断点”将路径分成两段分别递归执行。如果 dmax ≤ epsilon则中间所有点都丢弃只保留首尾两点。在实际配送场景里epsilon怎么取我推荐取栅格分辨率的2~3倍作为下限。栅格5cm一个点epsilon取0.3m比较合理如果直接取0.5m长直道上的点会被大量压缩但小弯路可能连“弯”都被抹掉。对于校园主干道0.3~0.5m是安全区间。这里有一个特别容易踩的坑DP算法可能把“大弯”简化成“割线抄近路”的效果。比如一段U型弯道DP可能在弯曲内侧拉一条直线把原本贴着路走的路径直接穿透到路外。规避办法是折叠条件里增加一个“累计包络距离”检查当某段原始路径总长度显著大于候选直线段长度时强行走原来的曲线只做稀疏化采样不做整体拉直。3.3 转角点保护与任务点锚定就算DP算法给出一个看似漂亮的结果也不能直接相信它。因为有些点具有拓扑语义删掉了会出大事。我总结了一套“必保点清单”起点和终点这个不用解释动了起点车还没出发就错了。转弯点转弯半径本身由底盘约束决定全局路径一旦把转弯点删掉局部规划器会以为这里“直行即可”结果高速冲到路口才发现要转。道路交汇点也就是十字路口的中心参考点一般和拓扑图节点重合是重规划时的锚定目标。停靠/取货点前的最后一个点这个点是局部规划器用来做精细对准的参考必须保留。实际操作中我会先把这些必保点标记出来DP压缩完成后再把这些点重新插入并重算相邻段落。注意插入时不要简单塞回原坐标就完事还要把插入点前后的点重新检查一遍共线性否则可能把一个原本该弯的地方搞成反向折角。3.4 角度约束压缩后的路径不能“折手折脚”还有一个维度是压缩后的转弯角度。很多压缩算法只看几何距离忽略折线夹角的合理性。比如一条路径转弯点前后各保留了一个点本来角度变化是均匀的压缩后变成“两个点连过来猛拐90°再接直道”物理上跑不出来。处理办法在DP之后加一个角度过滤。计算每个保留点的转角如果某个转角超过底盘最大允许转角由车辆物理模型决定比如AGV一般不超过45°就要在转角两侧插入若干线性插值点把一次大转弯分解成多个小段保证曲率连续。这一步在做全局路径精简时尤其重要因为精简后的点少意味着每段的权重变大。你删掉的点最后都要靠局部规划器去背如果路径本身拐得太急局部规划器往往来不及做平滑就被迫急停。4. 实操环节一个配送任务从地图到精简路径的完整流程前面讲了不少原理和概念不看实操总归是悬的。这里我用一个模拟项目X的配送场景把完整流程串起来。场景是这样一台校园配送车从A栋地下车库出发前往B栋教学楼门口全程大约450m中间要过一个十字路口、一片减速带区域和一个楼前小广场。4.1 环境的栅格化第一步把预先采集的激光点云/高精度地图栅格化。我这边的地图范围是400m×300m栅格分辨率5cm最终得到一张8000×6000的栅格图。栅格图长这样0表示可通行100表示障碍物255表示未知。对地图先做一次“障碍物膨胀”膨胀半径等于机器人半径0.5m加上安全余量0.1m即0.6m。为什么要膨胀因为后面生成的路径是“中心线”如果中心线距离障碍物过近实际车体通过时就会刮蹭。膨胀就是在物理层面先让出安全空间。4.2 骨架提取与路网建图对通行区域做距离变换提取骨架线。骨架线会自然地落在道路中央位置。对骨架线做细化、去毛刺然后找端点、交叉点。这一步会得到一批候选节点。我们手动作微调把A栋停车库出口设为一个端点节点取名为node_garage_AB栋教学楼门口设为一个端点节点取名node_bdoor。过了减速带区域之后的道路交叉点自动检测为交叉节点。最终整个园区路网约120个节点230条边。相比8000×6000的栅格计算压力已经不是一个量级。4.3 全局搜索路网上算出初始全局路径接下来在路网上用A*搜索。搜索的cost来自两部分的加权一部分是边长度的欧氏距离另一部分是道路宽度的加权系数窄路的cost会更高这样搜索更倾向于选择主干道。搜索代价函数可以简单这样设计cost length k × width_factor其中width_factor在宽路为0在窄路为2.0k取0.8。实测下来配送给机器人更愿意拐远路走大路而不是挤小路后续局部避障的难度大大降低。A*在这张120个节点的图上搜索几乎瞬时返回结果。初始路径为从node_garage_A到node_bdoor的一条节点序列总计经过17个路网节点。展开成几何路径后得到一条有412个坐标点的折线。4.4 路径点的DP压缩现在开始关键一步点压缩。输入412个坐标点epsilon取0.4m。DP算法跑完点从412个降到38个。此时人工核对一下这38个保留下来的点重点检查之前提到的必保点有没有被误删。检查后发现有大约6个点分布在转弯处属于需要重新插入的“关键点”。把这些点重新插入后点数变为44个。44个点相对于原来412个点压缩比接近90%。但这些点仍有几个拐角过陡的段落需要进入平滑环节。4.5 平滑处理让局部规划器舒服地接手平滑处理我用了一种实用组合先用三次样条插值生成一条连续曲线再在曲线上按车体轨迹要求重新采样。具体地对44个关键点做三次样条插值得到一条平滑曲线然后以0.2m等间距采样又得到约230个点。这里解释一下为什么压缩完又增加点因为44个关键点是“骨架表达层”适合人读、适合存储、适合传给局部规划器做语义理解但实际轨迹跟踪时控制器需要相对密集且平滑的插值点。230个点相比原先412个点仍然少了44%但最重要的是这230个点的曲率连续性好没有锯齿没有突兀折角局部规划器几乎不需要做额外平滑就能跟踪。平滑处理之前路径折角平均在22°左右平滑之后全路径最大转角不超过9°。这个质量对配送体验的提升是肉眼可见的。4.6 下发给局部规划器时的参数精简后的路径会作为“nav_path”的参考轨迹下发给局部规划器。局部规划器会结合实时激光数据做绕障规划。下发的路径信息包含几个核心字段路径点数、总长度、路径通道宽度用于约束避障方向、每段的最大允许速度。速度这一项建议直接从全局路径的“语义”里算出来。比如在直道段允许1.5m/s在拐弯段按曲率限制在0.5m/s在末端精细停靠段限速0.2m/s。这些信息可以存成路径点属性方便局部规划器直接读取。这条链路整个走完后全局路径规划耗时从原来栅格A*的大约12ms降到了路网搜索压缩和平滑的1.5ms左右。注意这里的1.5ms是全流程包含路网搜索和点压缩。而且由于路网固定即使动态障碍导致重规划也只是在局部路网范围内做小规模修正远远比整图重算高效。5. 现场实跑效果与观察记录空谈理论没用我把这套精简路径方案接到了实车平台上在模拟项目X的校园环境里跑了几十趟。这里记录几个典型的现场表现。第一次试跑路径从仓库到东门原始栅格A*规划出的路径有超过300个折点车在转弯时会出现明显的先减速、再调整、再加速的“顿挫感”。换成路网精简计算后同样的起终点路径只有25个关键点和约100个平滑采样点每个转弯点相对均匀车几乎是平滑顺畅地过弯。第二次试跑我们模拟了一个动态障碍场景在教学楼门口临时放了一个锥桶。局部规划器在跟踪全局路径时需要局部绕障。原来的稠密全局路径完全没有给绕障留空间局部规划器甚至算不出可行局部轨迹车直接停在原地。精简路径给了足够的缓冲空间局部规划器很快在旁边算出一条侧向的小绕行轨迹车以0.6m/s依次绕过。第三次是末端停靠。目标点距离教学楼门口1m原来的全局路径在最后一米有大量冗余折点车停靠前反复修正。精简路径保留了末端锚定点局部规划器能稳定执行直线对准停靠精度从原来的±12cm提升到±5cm以内。这些数据说明一个问题全局路径精简不是简单地“把点变少”而是在“计算效率”和“控制能力”之间找到最优配合点。点太多计算和控制都被拖死点太少关键信息不够控制完不成。精简化是一个系统性的调优过程。6. 常见问题与排查技巧实录做这类项目坑一定比理论多。我把实操中遇到过的典型问题整理成一份排查速查表希望对你有直接用处。现象排查方向解决措施路径穿过墙壁或障碍物拓扑路网建图时道路宽度过宽或节点连接两两可视没有考虑中间障碍物在建边时做“可视性检查”如果边中心线与栅格障碍物相交则断开该边路径在弯道处被拉直线DP阈值设定过大或缺少累计包络距离检查将阈值降低增加U形弯保护逻辑转弯减速过猛平滑处理不佳转角分布集中在单个点用三次样条插值重采样保证转角均匀动态障碍绕不过去全局路径通道余量小于局部规划需求增加拓扑边宽度属性为局部规划留出1m以上的横向缓冲空间换一台车后路径突然变差底盘物理参数不同转角速度限制未同步全局路径保存时记录转向半径约束不同车型加载不同约束地图更新后部分路径失效新地图上拓扑节点坐标有偏移但旧路网缓存指向错误坐标做增量路网更新节点坐标已偏移的边需重新生成末端停靠不精确全局路径末端被DP误删局部无参考锚点强制保留终点前最后一个特征点6.1 路网断裂最容易被忽略的拓扑问题有一次换了一版新采集的高精度地图路网重新提取后从150个节点变成170个。当时没细查直接跑任务结果发现有一块区域全局路径绕了大圈才到达明明有一条直通的路。排查后发现两条道路的骨架线端点没有精确落在同一个点相交位置差了几十厘米于是这两段骨架在拓扑图中被判定为不连通。处理办法是做“局部去重”如果两个端点距离小于1m合并成一个节点并连接相邻的边。之后路网恢复连通路径又变得正常了。这类问题一定要在路网构建后做一次连通性自检否则全系统最终都会表现成“莫名其妙绕路”。6.2 DP压缩的“割线抄近路”事故第三版算法上线后有一次路径明显不对——原本应该沿着L形走的路直接变成“斜跨绿地到达”。头更疼的是这条斜线在空中看距离还挺近单纯对比路径长度居然比原来的路径还短一点如果只在总长度上做验证根本发现不了。这起事故的根本原因就是DP算法把L形内侧的两个中间点给压掉了直接用直线连接了转弯前和转弯后的点。最后我们补了一个判断“如果DP抽稀后的线段长短相比偏离某条内部点密集折线超过60%就回到原始折线形态仅做共线点删除不做几何抽稀”再未出现过这类问题。6.3 新地图增加了施工区动态失效某天园区临时围蔽了一侧主路地图没有变更但实际道路不可通行。全局路径仍然规划了走那条路的方案车靠近后才通过局部实时避障发现自己过不去只能原地反复尝试。后来在全局规划的输入中加入一块“临时障碍地图”叠加层通过运维更新封锁区域全局路径重新规划时会避开封锁路段。这个是纯栅格方案做起来很自然的事但路网方案必须额外实现“动态边禁用”功能。把这部分加到拓扑边上让禁用的边有两种状态不可用或用低优先级cost代替。做完这个才发现全局路径精简计算的前置能力其实比单纯算法复杂要在建图、路网、搜索、压缩四个环节都做好工程化才能真正稳。7. 几个值得写下来的优化心得第一个心得路网的“稀疏”不代表“粗”。一个好路网节点不多但每条边都带有精确的物理属性宽度、长度、限速、地面材质。精简后的路径质量七成取决于路网建得好不好只有三成取决于压缩算法本身。第二个心得DP算法在机器人路径压缩里是主力但永远要加护栏。真正的工程实现是在DP外面包了两层一层保护必保点二层保护大弯几何形态。不加护栏的DP迟早会在现场给你演一出“穿墙抄近路”。第三个心得全局路径精简之后调试难度其实会增加。因为路径点变少了控制层一旦表现异常你要判断到底是压缩算法删错了点、平滑算法把轨迹给弄糊了还是局部规划器没跟好。所以我在每个精简后的路径点上都加了“信息来源标记”这个点是原始路网节点、DP保留点、或者是重建插入点。排查问题时能顺着标记一层层追回去比摸黑试参数快得多。第四个心得多推荐一种“语义压缩”的思路。对于配送机器人这种相对规则的任务场景最高效的路径存储方式不是一堆点坐标而是结构化的“道路段动作指令”。比如路径可以表示为从node_garage_A出发沿road_ID_17行驶120m在node_junction_3左转进入road_ID_22行驶80m终点node_bdoor。每个road_ID对应路网上的一段边车到节点处按语义动作执行。这种表达几乎不占存储也天然具有可解释性对后续的多车调度、人机交互非常有价值。我在项目后期尝试做过这种语义路径。全局规划器输出的是“路网动作”序列而不是一排坐标点。局部规划器需要坐标时再动态展开road_ID对应的几何中心线。实测这个方向有两个明显优势一是路径长度和点坐标在重规划时可复用二是故障排查时可以直接读路径语义迅速知道车在哪个路段的哪个节点遇到了障碍。当然这个方案的精简能力更强但对路网的准确性要求也极高只要路网节点坐标有一丁点累计误差展开出来的路径就会有明显偏差。适合路网质量已经调试得足够稳定的场景使用。8. 最后分享一点长期实践的经验整体跑通这套全局路径精简计算回过头来最深的体会是路径精简不该被当作一个“可选优化项”而应该是配送机器人的默认基本功。很多团队一上来就沉迷于把局部规划器调得天花乱坠忽略了全局路径层面的冗余才是底层拖累。只要全局路径这一层的表达足够精简、语义足够清晰局部规划器才能把算力花在真正需要动态决策的地方。否则就像让一个短跑运动员在起跑前还要扛着一麻袋沙子在原地反复踩点又慢又乱。如果你正要做一个类似的校内配送项目我的建议是不要把重点放在寻找某个“神奇压缩算法”上当初我们也是绕了一大圈最后发现最稳的组合还是高质量路网建图、DP压缩加必保点保护、三次样条平滑。这几样做好路径点数降一个数量级的同时路径质量也许比以前更高。在校内这种道路规则、建筑固定的场景里稳定性和可解释性才是第一位的。路径精简计算的所有工作最终都是为了这两个目标服务的。做完这一层之后后续加高精度停靠、多车调度都会顺畅很多。