# javaTest 有界绕行与冲突感知路径规划设计 **日期:** 2026-08-06 **状态:** 已完成方案讨论,等待书面确认 **适用范围:** `javaTest` 历史任务中心调度仿真与调度路径审计页面 ## 1. 背景 当前 `javaTest` 使用 `GridPathPlanner` 在完整地图上执行 BFS,得到边数最少且结果确定的路径。 历史 `path_info` 只用于结果对照,不参与重新规划。240 条历史任务的初步结果为 137 条路径序列 发生变化,但该数字不能直接证明路径优化有效: - 130 条历史路径的首尾与解析后的物理业务端点不一致; - 2 条历史路径含未知或非邻接段; - 剩余 108 条可公平比较的任务中,103 条完全相同,4 条路线不同但边数相同,只有 1 条更短; - 可比较任务的平均边数仅从 10.14 降到 10.12。 因此,本设计不再用“路径是否不同”或受故障影响的实际完成时间证明优化效果,而是在最短物理 距离附近选择交通冲突更少、路线重叠更少、转弯更少的候选路线,并提供完整、可解释的决策证据。 ## 2. 目标与非目标 ### 2.1 目标 1. 接近路径和服务路径都允许在最短物理距离 110% 范围内绕行。 2. 只使用当前活动任务、节点占用、边预约和走廊方向判断交通风险,不使用历史热度。 3. 按固定业务优先级比较候选路线,不使用难以解释和调参的加权总分。 4. 同一交通资源连续造成 3 个调度周期 HOLD 后,从车辆当前位置重新规划剩余路线。 5. 路线切换必须保持当前占用和预约安全,不能因重规划产生资源空窗。 6. 将路线质量、交通执行和故障恢复分开统计。 7. 相同地图、输入和交通快照必须产生相同结果。 ### 2.2 非目标 1. 不用实际行驶时间或最终任务完成时间给路径质量打分。 2. 不使用历史 `path_info` 约束新路线。 3. 不在本次改造中改变现有车辆资格、低电量和车辆选择业务规则。 4. 不把 PLC 失败、断线、低电量或车辆故障当成交通 HOLD。 5. 不接入生产数据库、真实 PLC、真实 WMS 或实时交通服务。 ## 3. 业务术语 - **接近路径:** 重新选中的车辆当前位置到任务物理起点 A 的路线。 - **服务路径:** 任务物理起点 A 到物理终点 B 的路线。 - **基准最短距离 D:** 在永久禁行条件下,起终点间可达路线的最小坐标距离。 - **有界候选路线:** 物理距离不超过 `D * 1.10` 的无环路线。 - **交通快照:** 某次调度决策时的车辆占用节点、边预约、走廊方向和其他活动路线。 - **交通 HOLD:** 下一步因节点、边、对向或走廊方向冲突而暂时不能安全推进。 - **相同阻塞:** 任务、车辆、阻塞资源标识和交通 HOLD 原因均相同。 ## 4. 总体架构 ### 4.1 `RouteCandidatePlanner` 职责:根据完整 `GridMap`、起点、终点和永久禁行资源生成确定性的有界候选路线。 输入: - `GridMap` - 起点、终点 - 永久禁行节点或边 - `RoutePlanningPolicy` 输出: - 基准最短距离 - 最短路线 - 不超过 110% 的候选路线 - 是否命中候选数量上限 该模块不读取车辆状态、交通预约、历史路径或任务优先级,只负责生成地图上合法的路线候选。 ### 4.2 `RouteQualityEvaluator` 职责:使用同一时刻的 `TrafficRouteSnapshot` 对候选路线进行可解释的业务排序。 输入:候选路线、交通快照、当前任务和车辆。 输出:每条路线的 `RouteQuality` 以及最终 `RoutePlanDecision`。 ### 4.3 `TrafficRouteSnapshot` 职责:为一次规划决策提供不可变交通证据,避免候选路线使用不同时间点的数据。 包含: - 车辆当前占用节点及归属车辆; - 已预约的有向边、方向和归属任务; - 走廊方向预约及归属任务; - 其他活动任务尚未完成的剩余路线; - 当前任务和车辆自身已经合法持有的资源。 ### 4.4 `HoldReroutePolicy` 职责:只累计交通 HOLD,并在同一阻塞连续出现 3 个调度周期时触发重规划。 ### 4.5 `RouteDecisionEvidence` 职责:保存候选生成、路线评分、HOLD 触发、资源替换和最终选择的可审计证据,供 JSON 报告和 HTML 页面展示。 ## 5. 物理距离与候选路线 ### 5.1 边距离 当前完整地图共有 8 层、1239 条边,不存在跨层边。相邻站点边距离按地图坐标的欧氏距离计算: ```text edgeDistance = sqrt((to.x - from.x)^2 + (to.y - from.y)^2) pathDistance = sum(edgeDistance) ``` 距离单位是地图坐标单位,不宣称为米。未来如增加跨层边,必须由地图元数据显式提供该边距离; 不得根据楼层编号虚构垂直距离。 ### 5.2 候选生成算法 采用确定性的 K 最短无环路径方案: 1. 使用 Dijkstra 计算基准最短路线和距离 `D`; 2. 按距离从小到大生成无环候选路线; 3. 下一候选距离超过 `D * 1.10` 时停止; 4. 最多保留 32 条候选; 5. 距离相同时按完整站点序列排序; 6. 未知节点、永久封闭道路和静态禁行资源不进入候选; 7. 当前临时占用和预约不从地图删除,只在质量评价阶段计入风险。 候选上限 32 是性能边界,不是业务评分。达到上限时在证据中写入 `candidateLimitReached=true`,但仍从已生成候选中作出确定性选择。 ### 5.3 接近路径与服务路径 现有 `VehicleAssignmentService` 继续负责车辆资格和选车,不在本设计中改变选车规则。选车完成后: 1. 为选中车辆计算“当前位置到任务起点”的有界接近路径; 2. 独立计算“任务起点到任务终点”的有界服务路径; 3. 分别保存两段路线的最短距离、候选数量和选择原因; 4. 交通预约仍对拼接后的完整执行路线申请。 这样可以优化两段路线,同时避免本次改造无意改变已经验证过的自动选车行为。 ## 6. 路线质量排序 每条候选路线生成以下固定顺序的比较元组: ```text ( oppositeDirectionConflictCount, occupiedNodeCount, incompatibleReservedEdgeCount, activeRouteOverlapEdgeCount, turnCount, physicalDistance, canonicalPath ) ``` 排序为字典序,前一项不同时不再比较后一项。 ### 6.1 指标定义 - `oppositeDirectionConflictCount`:候选有向边与其他任务已预约方向相反的数量。 - `occupiedNodeCount`:候选未来节点中被其他车辆占用或独占预约的数量;当前车辆自身起点不计。 - `incompatibleReservedEdgeCount`:候选边与现有容量或方向规则不兼容的预约数量;已计为对向冲突 的边不重复计数。 - `activeRouteOverlapEdgeCount`:候选无向边与其他活动任务剩余路线重合的数量;这是未来竞争风险, 不等同于已经发生的资源冲突。 - `turnCount`:相邻两条同层边的方向向量发生变化的次数。 - `physicalDistance`:第 5 节定义的坐标距离。 - `canonicalPath`:用完整站点序列作最终稳定决胜。 安全规则仍由交通资源裁决执行。质量评价只决定优先尝试哪条路线,不能绕过节点容量、边方向或 走廊预约。 ## 7. HOLD 后重规划 ### 7.1 触发条件 仅以下原因进入连续 HOLD 计数: - 下一节点被其他车辆占用或独占预约; - 下一条边不可申请; - 存在对向换边风险; - 走廊方向预约冲突。 键为: ```text (simulationTaskId, vehicleId, blockingResourceId, holdReason) ``` 连续第 1、2 次只保持 HOLD;连续第 3 次产生 `REROUTE_TRIGGER`。车辆发生移动、阻塞资源或原因 改变、HOLD 消失、车辆被重新分配时清零。 PLC 发送失败或未 ACK、低电量、车辆故障和断线不进入该计数。 ### 7.2 重规划范围 - 尚未到达任务起点:重新计算“当前位置到起点”的接近路径,同时基于同一交通快照重新评价 “起点到终点”的服务路径。 - 已进入服务路径:只计算“当前位置到任务终点”的剩余服务路径。 ### 7.3 防止路线抖动 满足以下条件才允许切换: 1. 新剩余路线与当前剩余路线不同; 2. 新路线不超过对应最短距离 110%; 3. 新路线的质量元组严格优于当前路线; 4. 新路线的路线级走廊预约能够安全替换; 5. 上次成功换路后车辆已经至少移动一个节点,或当前路线出现永久失效。 找不到严格更优路线时产生 `REROUTE_REJECTED` 并继续 HOLD,不关闭任务。 ## 8. 预约替换与资源释放 新增原子语义的路线级走廊预约替换操作: ```text 保留车辆当前占用节点和已进入边 → 以当前任务旧预约为可替换资源,试算新剩余路线的走廊方向 → 在不暴露中间状态的前提下提交走廊预约替换 → 成功后提交新 remainingPath → 释放旧路线不再使用的走廊预约 ``` 如果试算或替换失败,旧路线和现有合法资源保持不变。不得先释放旧预约再申请新路线。 节点和边不因重规划而整条路线预占,仍由现有交通控制器在车辆移动前逐段申请,并在车辆通过后 逐段释放。重规划不能释放车辆当前节点、正在通过的边或其他任务资源。该边界既保留现有安全 语义,也避免因整条路线预占扩大资源等待和死锁风险。 ## 9. 失败与降级规则 - 完整地图永久不可达:任务关闭为 `NO_ROUTE`。 - 存在地图路线但所有候选都有临时冲突:选择风险最小候选,交给交通裁决决定 GRANT/HOLD。 - 候选达到 32 条上限:从已有候选选择并记录上限证据。 - HOLD 后无更优路线:保持当前路线和 HOLD。 - PLC 失败或未 ACK:沿用原有协议重试,不触发路径重规划。 - 车辆故障或断线:沿用重新选车流程;新车辆确定后重新规划接近路径和服务路径。 - 低电量:车辆不再接收新任务;不把低电量伪装成交通冲突。 ## 10. 事件与审计证据 保留现有事件,并新增: - `REROUTE_TRIGGER`:包含连续 HOLD 次数、阻塞资源和原因; - `REROUTE`:包含旧剩余路线、新剩余路线、两者质量元组和选择原因; - `REROUTE_REJECTED`:包含没有更优候选、超出 110% 或预约替换失败原因。 每次初始规划和重规划输出: - `shortestPhysicalDistance` - `selectedPhysicalDistance` - `detourRatio` - `candidateCount` - `candidateLimitReached` - 质量元组各项指标 - `decisionReason` - `pathVersion` - `planningStage`:`APPROACH` 或 `SERVICE` 浏览器继续显示完整地图、历史路径、新规划路径和实际轨迹,并在检查器中分别显示接近路径和 服务路径的选择证据。实际时间、完成时间和 PLC 重试放在“运行与故障恢复”区域,不进入路线评分。 ## 11. 历史路线比较口径 每条历史任务先分类: - `COMPARABLE`:历史路径首尾与物理业务端点一致,且所有连续边都存在于权威地图; - `ENDPOINT_MISMATCH`:历史首尾与物理业务端点不一致; - `INVALID_HISTORY_PATH`:包含未知节点或非邻接段。 只有 `COMPARABLE` 任务进入路线质量统计。统计分类为: - 完全相同; - 物理距离更短; - 距离相同但冲突或转弯更少; - 距离在 110% 内略长但冲突更少; - 新路线质量更差。 `pathChanged` 继续保留节点序列语义以兼容现有报告,但不能再单独作为“优化成功”指标。 ## 12. 验收门禁 ### 12.1 路线算法门禁 1. 所有选中路线距离不超过对应最短物理距离 110%。 2. 最终路线必须是已生成候选中的字典序最优质量元组。 3. 临时冲突不能导致错误的 `NO_ROUTE`。 4. 同一输入、地图和交通快照重复运行必须得到相同路线和原因。 5. 历史端点不一致或存在无效段时不得计入优化比例。 ### 12.2 HOLD 与资源门禁 1. 同一交通冲突连续 1、2 次不重规划,第 3 次触发。 2. PLC 失败、低电量、故障和断线不能误触发交通重规划。 3. 找不到严格更优路线时保持原路线。 4. 路线切换失败不能丢失旧预约。 5. 车辆移动前后节点、边和走廊资源均保持单一合法归属。 6. 节点双占、资源超容量、对向换边和死锁为 0。 ### 12.3 业务闭环门禁 1. 基准 240 条历史任务全部进入终态,不遗留活动或等待任务。 2. 所有完成任务归档一次且仅一次。 3. WMS 重复投递不产生重复业务效果。 4. 失败任务必须有明确、可审计的失败原因。 ## 13. 测试策略 ### 13.1 单元测试 - 坐标距离和路线距离; - 110% 边界内外候选过滤; - 无环候选和 32 条数量上限; - 固定质量元组排序; - 转弯、重叠、占用和对向冲突计数; - 相同输入的确定性; - 历史路线三类可比性判定。 ### 13.2 集成测试 - 最短路线有冲突,10% 内存在无冲突绕行,必须选择绕行; - 无冲突绕行超过 10%,必须保留允许范围内的最优路线; - 所有候选有临时冲突时保持可调度而非 `NO_ROUTE`; - 连续第 3 次相同交通 HOLD 重规划; - 阻塞资源变化后计数重新开始; - 成功换路后移动一个节点前不再次普通重规划; - 新预约失败时旧预约保持完整; - PLC 重试和车辆故障不污染交通 HOLD 计数。 ### 13.3 历史负载和浏览器验收 - 重新执行 240 条历史任务并输出 `COMPARABLE/ENDPOINT_MISMATCH/INVALID_HISTORY_PATH`; - 报告接近路径和服务路径的候选、质量、绕行比例和重规划证据; - 在完整地图中显示初始路线、HOLD 点和重规划后的剩余路线; - 验证所有路线切换均能从事件和资源证据追溯; - 验证归档、WMS 幂等和所有安全门禁。 ## 14. 性能与兼容性 - 不新增生产依赖,保持 Java 8 编译目标。 - 候选数量固定上限为 32,避免历史批量回放搜索量失控。 - 现有 `plannedPath`、`pathChanged` 和历史证据字段保持兼容;新增字段只扩展 JSON。 - 当前 BFS 行为保留为基准测试和最短边数对照,不再承担最终冲突感知选路职责。 - 本设计只修改 `javaTest`,不直接替换生产 WCS 调度实现。