# 粗路径搜索耗时设计 ## 目标 为粗路径规划结果增加独立的“路径搜索耗时”。它用于回答:在规划地图已经可用后,从起点到终点得到可发布最终粗路径实际花费了多久。 现有 `PlanningDiagnostics.Elapsed` 保持不变,继续表示从 `CoarsePathPlanningService.Plan` 入口开始的总耗时。 ## 计时边界 `PlanningDiagnostics.PathSearchElapsed` 的边界固定如下: - 开始:`HybridAStarPlanner` 已完成输入、起终点和初始碰撞检查,即将调用 `HybridAStarSearch.Search`。 - 包含:二维 Dijkstra 启发式预计算、Hybrid A* 节点扩展、路径回溯、路径装配、方向分段和最终碰撞复核。 - 结束:规划器准备返回对应的 `PlanningResult`。 - 不包含:地图来源读取、地图缓存查询、障碍物栅格化、距离场构建,以及门面层在进入规划器前的工作。 因此,此字段表示“地图就绪后的路径求解与发布耗时”,而不是仅 Open List 循环的耗时。 ## 数据契约 在 `PlanningDiagnostics` 新增只读 `TimeSpan PathSearchElapsed`: - 成功时记录完整路径搜索与发布阶段耗时。 - 搜索失败、无解、节点上限、超时、取消、回溯失败、装配失败或最终复核失败时,记录截至返回前已消耗的该阶段时间。 - 在进入搜索阶段前即失败(例如输入、起终点或初始碰撞检查失败)时为 `TimeSpan.Zero`。 - 该字段必须为非负值,并且不超过总耗时 `Elapsed`。 保持构造函数的现有调用兼容:新参数具有 `TimeSpan.Zero` 默认值。`HybridAStarPlanner` 是唯一写入实际计时值的边界。 ## 实现方案 推荐方案是在 `HybridAStarPlanner.Plan` 中,于调用 `_search.Search` 前创建本地 `Stopwatch`,并在所有搜索后返回路径将要构造 `PlanningResult` 时读取其 `Elapsed`。`CreateDiagnostics` 接收这个独立耗时,并写入 `PlanningDiagnostics`。 选择该方案的原因: - 不修改门面的共享总预算和取消/超时语义。 - 不让 `HybridAStarSearch` 暴露计时实现细节。 - 计时覆盖用户定义的完整粗路径产出阶段,而非只覆盖节点扩展循环。 未采用的方案: 1. 直接复用 `PlanningOperationBudget.Elapsed`:会包含建图,不满足需求。 2. 仅在 `HybridAStarSearch` 内计时:会遗漏回溯、装配和最终复核,无法表示最终粗路径产出时间。 3. 为建图、启发式、搜索、复核分别公开多组指标:诊断更细,但超出当前需求。 ## 可视化与文档 `MovementTest.CoarsePathTest` 的状态图层和 Toast 同时显示: ```text 总耗时: ms,路径搜索: ms ``` README 明确区分:总耗时覆盖建图和路径规划;路径搜索耗时仅覆盖地图就绪后的最终粗路径搜索、回溯、装配与复核。 ## 验证 自动化验证应覆盖: 1. `PlanningDiagnostics` 默认搜索耗时为零,且新字段可由调用方读取。 2. 一个真实可行规划返回非负的路径搜索耗时,且不大于总耗时。 3. 既有总预算、取消、超时和路径状态断言不改变。 4. UI 源码检查确认图层和 Toast 读取并显示新字段。 5. README 包含新字段的计时边界说明。