4.2 KiB
规划操作预算与诊断收尾设计
目标
在进入 P1 的 UI 集成前,使一次 CoarsePathPlanningService.Plan 调用的取消与超时语义覆盖完整链路:地图创建、距离场构建、二维 Dijkstra 启发式和 Hybrid A* 搜索。同时让现有 PlanningDiagnostics 中的 Open List 陈旧条目数与峰值容量反映真实搜索数据。
成功、无解、输入无效和碰撞安全语义不改变;任何取消或超时结果均不得发布部分路径或部分地图。
方案选择
采用一个内部共享的、基于单调 Stopwatch 的 PlanningOperationBudget。它保存调用方的 CancellationToken、整次调用开始时刻与总超时,并在每个耗时循环中返回三态结果:继续、已取消、已超时。
不采用“只在 Dijkstra 前后检查”的方案,因为大图 Dijkstra 和 EDT 仍可能长时间无响应;也不替换 Dijkstra 启发式,避免在收尾阶段改变 Hybrid A* 的搜索特性。
边界与数据流
CoarsePathPlanningService.Plan(job, token)
-> PlanningOperationBudget(token, job.Configuration.SearchTimeout)
-> PlanningMapFactory.Create(mapRequest, budget)
-> EnvironmentMapBuilder / PlanningMapAdapter / EDT
-> HybridAStarPlanner.Plan(planningRequest, budget)
-> GridDijkstraHeuristic
-> HybridAStarSearch Open List
-> PlanningResult + PlanningDiagnostics
PlanningOperationBudget 放在不依赖 Map 或 CoarsePath 的公共工具层,仅暴露中立的停止原因。Map 与粗规划分别把该原因映射到自己的结果类型,避免 Map 反向依赖 CoarsePath。
地图构建结果增加明确的终止状态(成功、普通构建失败、取消、超时)。CoarsePathPlanningService 将地图阶段的取消映射为 PlanningStatus.Cancelled,地图阶段的超时映射为 PlanningStatus.SearchTimeout;两种结果都保留地图构建诊断但路径和分段为空。
现有不带预算参数的 PlanningMapFactory.Create、HybridAStarPlanner.Plan 和 GridDijkstraHeuristic 入口保持可用,作为不受取消限制的兼容包装;业务门面只使用带共享预算的内部入口。
响应与一致性规则
- 每个耗时循环在开始处及每处理最多 256 个工作单元后检查预算;检查不改变正常情况下的栅格、启发式或 Open List 排序。
- 等待地图工厂创建锁时使用可轮询的获取方式,以便取消和超时也能中断排队等待。
- 缓存命中仍立即返回原有不可变快照;预算已停止时优先返回取消/超时,不能借缓存绕过调用方停止请求。
- 已被取消或超时的地图构建不得写入任何缓存,也不得发布部分
PlanningGridMap。 - 规划器总耗时从门面开始计时;搜索器不重新开始独立的 5 秒窗口。
诊断
HybridAStarSearchResult 增加陈旧 Open List 条目数和 Open List 峰值。每次丢弃失效的普通节点时递增陈旧计数;每次成功入堆后更新峰值。HybridAStarPlanner 原样将这两个统计写入 PlanningDiagnostics。
目标候选仍保留其当前规则:不受普通离散键的 best-G 压制,出队时复核。它们占用 Open List 容量,因此计入峰值;不因候选自身而计为陈旧条目。
测试与验收
- 在大于一个检查批次的地图上,Dijkstra 预计算期间取消,断言返回
Cancelled、空路径和有限响应时间。 - 使用足以覆盖 Dijkstra 工作的极短总超时,断言返回
SearchTimeout、空路径,且总耗时不超出预算一个检查批次的合理余量。 - 在地图适配器/EDT 处理中取消和超时,断言地图结果带对应状态、没有地图快照且缓存未被污染。
- 使用产生失效 Open List 条目的场景,断言陈旧数大于零;任意正常搜索断言峰值至少为一,并与最终
PlanningDiagnostics一致。 - 重新运行 Debug 构建、所有既有 P0 地图/粗规划检查,以及新增取消、超时和诊断检查。
非目标
- 不修改运动原语、碰撞保守性、代价公式、目标候选排序或路径装配。
- 不在本次收尾中实现 UI、Painter、场景工厂或 Release 性能门槛;这些仍属于 P1。