
先交代一下背景这个项目是一条1:6缩尺无人船验证平台主要拿来跑多障碍场景下的自主避碰collision avoidance技术验证。去年年底到今年上半年我在这套平台上投入了大半年时间把从算法选型、仿真验证到实船调参的整个链路完整走了一遍。这篇东西不打算复述论文也不打算贴一堆公式吓人只讲工程落地过程中那些论文里不会写的事为什么选这套方案、哪些参数最敏感、实船测试到底踩了多少坑。如果你正在做无人船、无人艇或者类似的自主航行项目尤其在做多障碍避碰这篇应该能帮你省不少弯路。1. 为什么水面多障碍避碰比想象中难先弄清问题边界1.1 水面环境没有标准答案每条路径都要同时满足安全和规则无人船的避碰和无人车的避碰看起来都是从A点到B点、避开障碍物但水面环境的约束完全不同。陆地上有明确车道线、交通信号灯和人行横道障碍物的运动规律也相对可预测水面上什么都没有一条河、一片湖、一个港池处处可走但又处处不能乱走。你不仅要避开静态障碍浮标、桥墩、码头、浅滩还要避开动态障碍其他船只、漂浮物、游泳区域甚至要预测这些动态目标未来十几秒内的运动趋势。多障碍场景真正的难点在于障碍物数量上来之后决策空间会爆炸。单障碍避碰算法可以找到一条漂亮的绕行轨迹三个障碍同时出现在航道前方彼此还会形成夹击态势这时候最优解往往不是一个明确的绕行方向而是一组需要权衡的候选方案。再加上水面运动受风、浪、流的持续干扰你算出来的轨迹可能下一秒就被水流推偏了。所以无人船避碰从来不是能不能碰到的问题而是在什么时间窗口内、以什么方式让开的问题。1.2 传感器视野受限、执行器响应慢留给决策的时间窗口很短无人车用激光雷达加视觉基本可以做到厘米级的环境感知无人船差得远。水面环境空旷特征稀疏视觉在逆光和雾气下经常失效毫米波雷达在水面上有大量杂波激光雷达虽然能测障碍但距离通常只有几十米对小型漂浮物还容易漏检。我在项目里用到的感知组合是RTK定位、激光雷达、视觉和AIS船舶自动识别系统融合但每一种都有明显的短板。更麻烦的是执行器的响应延迟。无人船靠螺旋桨和舵转向船体本身具有大惯性和非线性水动力特性指令下达之后要经过一段时间才能建立转向角速度。缩尺模型相对好一些但同样存在打了舵船头才开始转的延迟。这个延迟直接压缩了避碰决策的反应窗口。假如船速2米/秒感知系统有0.3秒延迟决策计算加执行机构响应又占掉1秒那么留给规划系统的真实距离窗口可能只剩几米。很多算法在仿真里跑得很好一上实船就撞根子就在这。1.3 COLREGs规则约束避碰不只要安全还要合规水面航行有一套国际通用的规则即海上避碰规则COLREGs。它对对遇、追越、交叉会遇三种态势下的让路责任做了明确界定对遇时双方各自向右转向追越时前方船保持航向航速后方船让路交叉相遇时有他船在本船右舷一侧的本船通常需要让路或减速。无人船做避碰不能像无人机那样随便挑一个方向绕开必须在规则框架内行动。这个约束很烦人但必须遵守。举个例子两个障碍物分别位于本船左前方和右前方单纯从几何安全角度看向左绕行或许距离更短但如果右前方那艘船是交叉相遇态势下的来船规则要求你向右或减速让行简单抄近路就会把一个本来合规的避让动作变成违规行为。更麻烦的是多障碍场景下不同障碍物对应的会遇态势可能互相矛盾——对一艘船要右转对另一艘船右转反而迎头撞上去。这时候避碰算法就得分出优先级在规则和安全之间找平衡点。这个问题我在仿真阶段完全没意识到直到实船测试被一艘按规则航行的真船教育了才彻底重视起来。2. 我最终采用的避碰框架分层决策与速度障碍法的取舍2.1 候选算法横向对比没有银弹只有最合适的组合先把我实际调研过的几类方案摆在一起对比方便你快速理解它们的差异。下面是基于这个项目的经验总结每个方案都有它的适用边界不存在一个万能算法。算法核心思路优点缺点本项目中的表现人工势场法APF目标点产生引力障碍物产生斥力沿合力方向运动原理简单、计算量极小容易陷入局部极小值目标附近振荡单障碍还行多障碍会卡死弃用动态窗口法DWA在速度空间采样根据预测轨迹评价安全性与效率直观、可处理动态障碍采样粒度影响性能前瞻距离敏感作为局部执行层保留速度障碍法VO求解速度空间中的碰撞锥选择锥外速度动态障碍建模清晰实时性好对测量噪声敏感规则约束弱作为主决策层改进后采用模型预测控制MPC以预测模型为基础滚动优化控制序列能显式处理约束效果好计算量大对模型精度要求高作为高精方案验证未上实船深度强化学习DRL通过奖励函数学习避碰策略无需显式建模泛化潜力大训练成本高安全性难保证只做了仿真探索未部署这个表不是让你直接照着选而是想说不同算法解决的是不同层面的问题。APF适合静态地图上的局部调整DWA适合近距离反应VO适合对动态障碍做速度级避让MPC适合精确控制DRL适合长期策略学习。单独拿哪一个出来做多障碍避碰都会在某些场景失效。2.2 分层结构全局规划管方向、局部避碰管动作、应急制动管保命最后落地的框架分三层。第一层是全局航线规划在水域地图上预先规划一条从起点到终点的参考航线只考虑静态障碍和禁航区这一步相对简单因为水面环境变化慢不需要高频更新。第二层是局部避碰层以本船为中心利用激光雷达和融合感知获取周边障碍物的实时状态通过改进的速度障碍法生成避碰速度指令同时用DWA做最终的可行性校验确保生成的速度在船体动力学允许范围内。第三层是应急制动层当探测到障碍物进入安全距离、且局部避碰无法及时脱困时直接执行停车、倒车甚至原地等待优先保证不发生碰撞。这个分层结构的核心逻辑是把决策频率从低到高分开全局层的计算周期是秒级局部层是十赫兹级应急层则是毫秒级独立看门狗。这样即使某层出问题其他层也不会立刻崩溃。比如全局航线规划卡了一个周期局部避碰仍然能自主规避局部避碰因为某个传感器数据异常失效应急层还能做最后的刹停动作。这个设计帮我扛住了后续一大堆实船测试的突发状况如果没有应急层至少有两次测试会直接撞上码头边缘。2.3 为什么没有直接上深度强化学习现在很多论文都在推深度强化学习DRL做无人船避碰我也花过不少时间在仿真环境里跑DRL相关实验但最终没有把它部署到实船上原因有三点。第一安全可解释性不足。DRL策略是一个黑箱船一旦进入从未见过的状态你无法预测它会输出什么动作也无法向监管方或者验收方解释为什么在这个关键时刻选择了这个转向角度。对于实验平台可以容忍对于要实际航行的系统这是硬伤。第二训练场景和实船环境之间存在巨大gap。仿真里可以用完美传感器模型水流恒定向障碍物匀速直线实船上有噪声、有延迟、有风浪流突变策略很容易过拟合仿真。第三实船数据获取成本太高。DRL要想覆盖足够多的边界情况需要大量失败样本而每次失败都可能意味着碰撞事故。目前我更倾向于把DRL用在策略建议、参数自动调节这类辅助环节主线还是用可解释的规则加优化方法。3. 从会遇态势判断到转向决策COLREGs的真正落地难点3.1 先把障碍物归成三类决策才有针对性多障碍避碰的第一步不是算轨迹而是给障碍物分类。我把本船感知范围内的障碍物分成三类静态障碍包括浮标、桥墩、固定码头和浅滩这类障碍物位置基本不变处理起来最简单动态航行船包括其他机动船只它们受COLREGs约束行为相对有规律可以通过AIS和运动预测建模突发事件目标包括漂流的木头、小划艇、游泳区域边缘等这类目标速度慢、运动方向不稳定但风险很高必须用更大的安全距离去对待。分类之后每个障碍物会附加上不同的属性标签包括最小安全半径、最高风险等级、是否受COLREGs约束。在速度障碍法计算碰撞锥时这些属性会直接影响膨胀半径和预测时间窗口的大小。比如对一艘横向行驶的货船我给它设定的是30米的感知膨胀半径和20秒的预测窗口对一个缓慢漂移的浮标膨胀半径15米、预测窗口只给8秒。分类的意义在于不会让一个无关紧要的浮标和一条动态船占据同样的决策权重。3.2 会遇态势判断用速度向量和相对方位算责任边界会遇态势判断是COLREGs落地的第一个难关。工程上我不会去读复杂的航海图直接用两个核心参数来做判断相对方位角他船相对本船方位与船艏向的夹角和本船相对他船的速度向量。以本船为中心建立一个运动坐标系根据这两个参数把会遇情形分成对遇、追越、左交叉、右交叉等类别每一类对应一组默认避让动作。我对接实船数据时发现了一个之前没太在意的细节态势判断必须持续稳定不能频繁跳变。如果某个目标正好处于两种态势的边界附近比如相对方位在交叉和对遇之间摇摆决策系统就可能一会儿输出向右转、一会儿输出保向导致船走成S形。解决办法是给态势判断加一个滞回区间也就是状态切换必须连续满足多个周期且角速度方向一致。这个做法跟信号处理里的消抖一个思路代价是判断延迟增加几百毫秒但换来的是决策稳定性值。3.3 速度障碍法VO实际落地从碰撞锥到可航行速度域速度障碍法的核心思想不复杂把本船视为一个膨胀的圆假设障碍物在未来一段时间内按当前速度运动那么本船哪些速度向量会导致撞上它在速度空间里就会构成一个碰撞锥。只要选择一个落在碰撞锥之外的速度向量就能在预测时间内避开这个障碍。多障碍场景变成多个碰撞锥的叠加我们的任务是在速度空间里找到一块同时避开所有碰撞锥的区域。实际工程中有三个改进点。第一把碰撞锥的预测时间设为可变化对近处的动态障碍物用短预测窗口反映其当前运动趋势对远处障碍物用长窗口过滤掉瞬时抖动。第二引入时间优先机制——如果两个碰撞锥重合优先处理TCPA最短会遇时间更小的那个障碍物因为它是真正的紧急威胁。第三速度选择不能只求避开碰撞锥还要靠近目标方向并保持稳定转向所以我在VO之后接了一个代价评价函数把偏离航线的代价转向角速度的代价与障碍物最小距离的代价加权求和选出最优速度。加了这个评价层之后船的轨迹明显比纯VO输出的要平滑很多。3.4 多障碍优先级仲裁当规则和规则打架时怎么办多障碍场景最棘手的问题是优先级冲突。典型情况本船前方左侧是静态桥墩前方右侧是一艘交叉相遇且负有让路义务的动态船。如果按COLREGs处理动态船应该向右转向但向右又会撞向桥墩。这时候算法必须在让路责任和物理安全之间做出取舍。我的处理原则是安全优先、规则次之但不完全抛弃规则。具体做法是把每个候选速度向量都做两层过滤第一层排除所有会导致碰撞的向量无论规则上多么正确物理上可能撞船的动作一律不用第二层在剩余的安全向量里优先选择满足COLREGs语义的那个方向。如果规则要求的动作恰好撞向静态障碍则退而求其次选择一个既避开静态障碍、又能在后续适当时机回归规则动作的向量。这个先安全后合规、尽量兼顾的策略在仿真和实船测试中都跑得很顺也比较好向监管方解释。4. 多障碍场景的参数标定与仿真验证过程4.1 仿真平台搭建不能完全依赖场景库要自己加变态场景我在仿真阶段用了主流机器人仿真环境自行搭建了一套水面场景。规划了一块长500米、宽200米的水域在其中随机布置了8到16个不同类型的障碍物包括固定浮标、运动船只、随机漂移物还加了一段狭窄航道。之所以不用纯随机布置是因为避碰算法必须在有结构的场景里才看得出问题狭窄航道两侧有静态障碍中间有一条运动船对向而来这种场景才能逼出进退两难的局面。仿真平台的输出不止是轨迹我还要记录本船每一时刻的速度指令、障碍物预测位置、决策标记是保向、转向还是减速以及最小会遇距离。这样每一帧都能回放定位问题时能看到是感知丢了目标还是决策没算出来还是执行没跟上。我的一个建议是仿真环境里至少加两类极端场景一类是障碍物突然出现比如从转弯盲区冲出另一类是动态障碍物突然改变航向。这两种情况最容易暴露算法在预测模型和响应时间上的弱点。4.2 关键参数标定膨胀半径、预测窗口、采样频率、权重系数参数标定是避碰算法从能跑到跑得好的分水岭。我这里把最关键的几组参数列出来并说明它们是怎么影响行为的。参数作用标定结论标定方法障碍物膨胀半径决定本船距离障碍物的安全距离船宽的2.5倍到3倍之间最合适实船测试从大到小试预测时间窗口决定VO算法看多远的未来动态目标10到20秒静态目标6到10秒根据船速和制动距离推算局部规划频率每个避碰决策周期的时间间隔10赫兹即可再高船体跟不上对比轨迹平滑度转向角速度限幅最大允许的转向速率限制在船体能达到的最大角速度的70%实测动力模型安全距离阈值触发应急制动的条件当前速度下需要的最小停船距离制动实验测量膨胀半径这个参数很有意思设得太小船贴着障碍物擦过去看起来效率高但一旦有风浪扰动或者水流突变就直接撞设得太大狭窄航道又过不去误报率飙升。我的最终策略是让膨胀半径与当前船速挂钩速度越快膨胀越大速度降到接近零时膨胀半径收缩到船宽加一个固定余量。这个动态膨胀既保安全又不牺牲通过性。4.3 评价指标与仿真结果选对指标问题才暴露得出来评价避碰算法不能只看有没有撞上我用四个指标碰撞次数、最小会遇距离DCPA、最短会遇时间TCPA和路径偏离度。前两个反映安全性第三个反映决策的时效性第四个反映效率。在仿真阶段随机场景跑了300组同样场景分布、不同随机种子最终碰撞次数为0所有场景的最小会遇距离都大于3倍船宽TCPA低于3秒的情况没有出现过。但仿真成绩好恰恰是最危险的信号。我后来复盘发现仿真里障碍物模型是纯数学的没有传感器噪声没有水面反射也没有水动力延迟所以算法很容易表现得太完美。真正有效的验证方式是带噪声仿真给障碍物位置加上1米左右的高斯噪声给速度测量加10%的随机误差重新跑同一批场景碰撞率立刻从0升到平均每百次1.2次。这套带噪声测试后来成了我的标准配置也让算法在实船测试前的可靠性提升了一大截。5. 实船测试踩坑记录传感器、动力延迟与安全兜底5.1 传感器层面的坑逆光、水花、雷达近距杂波实船和仿真最大的不同是你要面对一个不干净的传感器世界。第一次上实船时视觉检测在逆光方向直接失效水面变成一片白茫茫浮标完全消失。后来加了偏振镜片选在非逆光时段测试但治标不治本真正解决还是要靠多传感器融合视觉丢掉的目标激光雷达能补回来激光雷达漏掉的近距离漂浮物视觉又能及时报出来。另一个坑是水花。船高速行驶时溅起的水花会打湿激光雷达镜头造成大范围误报。我测试时出现过一次前方出现一整面弧形障碍墙的假象差点触发应急制动。排查下来是水花正好在雷达扫描平面内形成了连续反射点。解决思路是给雷达加装挡水罩同时在驱动层加一个最小有效距离的滤波逻辑对距离突变的目标做时长校验只有持续存在足够多扫描周期的目标才被认为有效。这个方法牺牲了一部分真实紧急情况的响应速度但换来的误报率下降非常明显。5.2 动态障碍预测偏差运动模型太简单会害死人我在预测动态障碍物时最初用的是恒定速度模型也就是假设他船在未来一段时间保持当前速度和航向。这个模型在开阔水域对付正常航行船基本够用但一旦遇到他船开始转弯预测轨迹和实际轨迹会迅速分离。仿真里我很少遇到这种情况实船上却经常出现他船突然向右转本船还以为它继续直行直到预测位置和实际位置差出十几米才反应过来。痛定思痛之后我引入了机动检测机制。不断用实际观测数据和预测轨迹做对比如果连续若干周期内偏差超过设定阈值就判定他船正在机动立刻丢弃旧预测、重新初始化预测模型同时将本船的安全距离阈值临时上调30%。这样做的代价是会让避碰动作变得更加保守但实船测试中我宁可保守也不能赌对面会按直线航行。5.3 动力模型失配与修正振荡船的响应真的慢半拍在仿真里我给速度指令加了一个一阶延迟模型自以为已经考虑到了船体惯性。实船一跑才发现真实的水动力特性比一阶延迟复杂得多低速时舵效差船头转得慢高速时惯性大转弯半径明显变大再加上侧向风和水流的作用实际航向和期望航向的偏差经常超过20度。局部避碰算法如果只看期望速度不看当前船体状态就会导致过度修正——左转没转过来就右转补偿船在水面上走出一条明显振荡的蛇形轨迹。解决方法是把船体运动模型嵌入到DWA的轨迹预测里。每次采样候选速度时不只是做纯运动学外推而是用一个简化水动力模型预测未来2秒内船的实际航向变化再计算候选轨迹是否会撞到障碍。这个改动让避碰动作的预判性好很多船的轨迹也平滑了不少。但我也明白这个简化模型在浪大时依然不准所以又加了一条规则当船体横摇和航向偏差同时超过阈值时自动降低允许的最大船速给决策留出更多反应时间。5.4 安全兜底不可少应急制动和人工接管的最后防线不管算法做得多完善工程上总要有最后一道防线。我在系统里单独实现了一个应急制动模块独立于局部避碰逻辑运行。它持续监控最近障碍物的距离和相对速度如果计算出的剩余碰撞时间低于设定安全阈值会直接发送制动指令同时暂停所有避碰规划输出。这个模块逻辑极简没有复杂的判断就是为了确保在最极端情况下能停下来。此外系统保留了远程人工接管通道。实船测试期间无论算法运行得多稳定我都会让操作员保持在遥控器附近测试区域也划定在开阔水域、留足缓冲距离。项目结束前的一次偶发通信断链让我彻底意识到本地看门狗的重要性当遥控链路断开时船端的自主系统必须在几十毫秒内接管否则船会按最后一次指令盲目航行。我把通信状态监控、本地自主接管和应急制动串成了一条完整的安全链之后的测试才真正踏实。结语一点个人体会如果你问我在这个项目里收获最大的是什么我会说不是某个算法调得有多好而是彻底理解了算法只是避碰系统的一小部分。真正决定能不能安全航行的是感知的可信度、决策的可解释性、执行的鲁棒性以及系统整体的安全兜底。多障碍自主避碰没有一个放之四海而皆准的方案任何论文里的算法到了实船上都会露出原型。最稳的路径永远是先在带噪声的仿真环境里把边界试探清楚再拿着保守的参数上实船逐步放宽每放宽一个参数都要用跑过的场景复盘。这套方法论比任何单一算法都更值得花时间去打磨。