Files
FT546-WCS/docs/superpowers/specs/2026-08-06-javaTest-bounded-conflict-aware-routing-design.md

14 KiB
Raw Blame History

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 条边,不存在跨层边。相邻站点边距离按地图坐标的欧氏距离计算:

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. 路线质量排序

每条候选路线生成以下固定顺序的比较元组:

(
  oppositeDirectionConflictCount,
  occupiedNodeCount,
  incompatibleReservedEdgeCount,
  activeRouteOverlapEdgeCount,
  turnCount,
  physicalDistance,
  canonicalPath
)

排序为字典序,前一项不同时不再比较后一项。

6.1 指标定义

  • oppositeDirectionConflictCount:候选有向边与其他任务已预约方向相反的数量。
  • occupiedNodeCount:候选未来节点中被其他车辆占用或独占预约的数量;当前车辆自身起点不计。
  • incompatibleReservedEdgeCount:候选边与现有容量或方向规则不兼容的预约数量;已计为对向冲突 的边不重复计数。
  • activeRouteOverlapEdgeCount:候选无向边与其他活动任务剩余路线重合的数量;这是未来竞争风险, 不等同于已经发生的资源冲突。
  • turnCount:相邻两条同层边的方向向量发生变化的次数。
  • physicalDistance:第 5 节定义的坐标距离。
  • canonicalPath:用完整站点序列作最终稳定决胜。

安全规则仍由交通资源裁决执行。质量评价只决定优先尝试哪条路线,不能绕过节点容量、边方向或 走廊预约。

7. HOLD 后重规划

7.1 触发条件

仅以下原因进入连续 HOLD 计数:

  • 下一节点被其他车辆占用或独占预约;
  • 下一条边不可申请;
  • 存在对向换边风险;
  • 走廊方向预约冲突。

键为:

(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. 预约替换与资源释放

新增原子语义的路线级走廊预约替换操作:

保留车辆当前占用节点和已进入边
→ 以当前任务旧预约为可替换资源,试算新剩余路线的走廊方向
→ 在不暴露中间状态的前提下提交走廊预约替换
→ 成功后提交新 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 调度实现。