# Local G2 路径平滑问题分析与后续措施

> 文档定位：记录当前 Local G2 五次 Hermite 任务在进入正式服务接入前发现的问题、证据边界和下一步行动。  
> 核心原则：专项测试通过，说明某个局部能力有效；它不自动等同于真实场景下的端到端功能已经完成。

## 1. 阅读本报告前：证据等级说明

本报告使用三种证据等级，避免把不同确定性的结论混在一起。

| 证据等级 | 含义 | 本报告中的问题 |
|---|---|---|
| 已复现故障 | 已通过实际构建和测试命令稳定观察到失败 | 问题一 |
| 静态分析确认的逻辑缺口 | 从当前代码的输入、约束和控制流可以直接推导出不一致 | 问题二 |
| 待验证集成风险 | 当前代码结构在未来接入流程中可能导致错误，但尚无完整流水线可实际复现 | 问题三 |

已经通过的专项检查包括：Local G2 契约、曲率导数、跳变检测、五次曲线、候选构造、候选质量门，以及共享的粗路径与平滑基础检查。本报告不否定这些检查的价值，而是说明它们尚未覆盖的组合场景。

## 2. 问题一：RectangleDetour 原始基线复验失败

### 2.1 现象

这是一个 **已复现故障**。

在端到端检查中，RectangleDetour 场景的 Hybrid A* 粗路径规划成功；但平滑模块建立“原始粗路径基线”时失败，结果从预期的 Success 变成 InvalidInput。实际测试输出为：

    Raw baseline RectangleDetour must remain a feasible, verified copy of the coarse path.
    Expected=Success Actual=InvalidInput

失败发生在 Local G2 候选生成之前。因此当前不能说“G2 平滑失败了”；更准确的说法是：这条真实粗路径还没有通过进入任何平滑算法前的统一基线复验。

### 2.2 生动例子

把路径平滑想成给一条已经规划出的山路做局部铺装。

RectangleDetour 这条山路的导航系统已经证明车辆能走到终点，相当于 Hybrid A* 已经找到了路。但在铺装前，工程人员用更严格的尺子重新测量道路的弯曲程度和车身扫过的范围。测量门禁认为这段路有不满足要求的地方，于是道路在进入铺装工序前被拦下。

此时不应强行开始铺装，也不应为了让它通过而降低安全门禁；先要查清是哪一个测量点、哪一种曲率或几何计算触发了拒绝。

### 2.3 为什么会出现这个现象

任务 3 将原始粗路径也接入与候选曲线相同的几何分析器和完整车体验证器，这是为了实现公平比较。当前链路为：

    粗路径 → 预处理与方向分段 → 统一重采样和曲率分析
           → 完整车体/扫掠复验 → 原始基线

当前配置把输出采样间距设为 0.025 m；基线会在该间距下重新计算曲率和曲率导数，再进行车辆曲率、姿态和扫掠检查。已取得的诊断只说明“平滑路径包含非法数值或超限车辆曲率”，还没有定位到具体样本、具体方向段或根本原因。

因此可以确认的是“基线复验失败”；尚不能确认是原始粗路径本身超限、重采样的端点处理问题，还是某个几何分析/验证边界条件的问题。

### 2.4 影响

- RectangleDetour 无法进入 Local G2，也无法进入其他依赖同一基线的平滑比较流程。
- 任务 8 的专用流水线应把已验证原始基线视为前提，因此此问题必须优先解决。
- 如果简单放松基线检查，可能把真正不可执行的路径传给后续 SQP 或控制模块，风险不可接受。

### 2.5 下一步措施

1. 为 RectangleDetour 建立最小诊断复现：记录每个方向段的原始点、重采样点、最大绝对车辆曲率、车辆曲率上限、最小净空和验证失败位置。
2. 对同一粗路径比较原始点序列与 0.025 m 重采样后的几何结果，定位第一次超限或非有限值出现的位置。
3. 根据证据只修复源头：若粗路径本身确实违反车辆约束，修复粗路径输出或场景；若重采样/端点分析失真，修复分析器并保留完整安全门。
4. 将该场景加入专门回归，防止以后再次出现“规划成功但基线不可用”的断链。

### 2.6 验收条件

- RectangleDetour 的粗路径仍需保持规划成功。
- 原始基线必须回到 Success，且仍经过相同的完整车体和扫掠复验。
- 诊断测试能够指出首次异常的方向段和样本，而不是只返回笼统的 InvalidInput。
- 不通过放宽曲率、碰撞或净空门限来获得绿色结果。

## 3. 问题二：窗口合并范围与候选长度上限不一致

### 3.1 现象

这是一个 **静态分析确认的逻辑缺口**。

窗口规划器用“事件位置左右各扩展最大窗口长度”的包络判断两个事件是否合并。默认最大窗口长度为 0.8 m，因此合并判断可使用约 1.6 m 宽的影响范围。

但实际生成候选窗口时，候选的总长度又被限制为不超过 0.8 m。于是两个相距较远、但仍落入合并包络的事件可能被合并为一个区域；合并后却没有一条长度不超过 0.8 m 的窗口能够同时覆盖它们，最终该区域没有合法候选。

### 3.2 生动例子

想象道路上有两个需要修补的小坑：

- 第一个坑在 0.4 m 处；
- 第二个坑在 1.4 m 处；
- 两坑相距 1.0 m。

系统先用一个很大的“可能影响范围”判断两坑会互相影响，于是把它们装进同一个维修任务。随后维修车被规定一次只能铺 0.8 m 长的补丁。要同时盖住相距 1.0 m 的两个坑，补丁至少要 1.0 m 长，因此没有任何合法补丁。

本来可以分别处理两个坑，结果因为过早合并，两者都没有被处理。

### 3.3 为什么会出现这个现象

当前窗口规划存在两套长度语义：

- 合并阶段的最大影响范围使用 event ± 0.8 m；
- 候选阶段的最大总窗口长度使用 0.8 m。

如果“0.8 m”定义为总窗口长度，这两套语义不一致。合并阶段把每一侧都当作可以扩展 0.8 m，而候选阶段只能让左右两侧合计为 0.8 m。

现有检测测试覆盖了两个非常接近、确实应该合并的事件；尚未覆盖“会被合并，但无法被一个最大长度窗口同时覆盖”的中间距离场景。

### 3.4 影响

- 某些本可分别平滑的局部曲率跳变会被整体保留。
- 任务 8 若直接消费空候选区域，可能把它报告为候选生成失败，掩盖真正的窗口规划逻辑问题。
- 不同场景下的改善率可能不稳定：不是因为曲线质量差，而是因为区域边界定义不一致。

### 3.5 下一步措施

1. 先明确 0.8 m 的唯一语义：它是候选总长度，还是允许每一侧各 0.8 m。现有配置和候选生成逻辑均把它当作总长度。
2. 增加窗口规划回归：两个相距 1.0 m 的事件在默认参数下应保持为两个可独立处理的区域，或在明确允许更长联合窗口时生成实际可用的联合候选。
3. 让合并包络依据真实可生成的最大窗口范围计算，而不是使用大于候选总长度的宽泛包络。
4. 对区域中候选数为零的情况提供稳定诊断，区分“没有可行曲线”和“窗口规划把可处理事件合并过度”。

### 3.6 验收条件

- 新增的 1.0 m 间距回归测试稳定通过。
- 每个检测到的区域要么有至少一个符合长度约束的候选窗口，要么有明确且正确的不可用原因。
- 既有重叠事件合并测试、近起点非对称窗口测试仍通过。

## 4. 问题三：连续处理多个区域时的弧长定位风险

### 4.1 现象

这是一个 **待验证集成风险**，不是已经在完整 Local G2 流水线中复现的故障。

局部拼接后，拼接器会根据新的几何形状重新计算整个方向段的局部弧长。候选评价器则会使用候选保存的起止弧长在当前路径中提取窗口。未来任务 8 需要顺序处理多个区域；若前一个区域改变了长度，后一个区域若仍使用原始弧长坐标，就可能定位到错误的位置。

### 4.2 生动例子

一条道路上有区域 A 和区域 B：

- 原始道路中，区域 A 位于 1.0–1.5 m；
- 区域 B 位于 3.0–3.5 m；
- 修补区域 A 后，道路局部变长了 0.06 m。

如果系统仍在“新道路”的 3.0–3.5 m 处寻找区域 B，它实际上会比原始区域 B 早 0.06 m 找到位置。轻则候选端点对不上而被拒绝，重则替换到了错误的局部区间。

上面的 0.06 m 只是帮助理解的示意数值，并非已经测得的实际误差。

### 4.3 为什么会出现这个现象

候选构造使用原始方向段和原始窗口的起止弧长。拼接器替换一处后会重算当前方向段内所有点的弧长。候选评价器随后从当前路径按候选的旧起止弧长提取窗口，并尝试再次拼接。

任务 8 的设计本身要求顺序保留已接受的早期替换，因此它必须明确回答一个问题：后续区域应使用原始参考弧长，还是当前路径弧长？当前候选层尚没有负责这类坐标映射的专用机制。

### 4.4 影响

- 同一方向段含多个彼此分离的曲率事件时，后续区域可能不能被正确处理。
- 结果可能依赖区域处理顺序，破坏确定性。
- 即使每个单独候选都能通过专项检查，组合处理时仍可能出现端点错配、错误替换或不必要回退。

### 4.5 下一步措施

1. 在任务 8 之前定义稳定坐标策略：可以保留原始参考弧长并建立“原始弧长到当前路径位置”的映射，也可以在每次成功拼接后重新定位剩余区域和重新生成候选。
2. 新增双区域顺序替换回归：同一方向段内两个不重叠区域，第一处替换必须产生可观测长度变化，第二处仍必须命中原始语义上的正确窗口。
3. 在测试中重复运行两次，比较状态、路径点坐标、区域报告和被选候选索引，验证处理顺序和结果确定性。
4. 只有上述回归通过后，才实现任务 8 的多区域发布与全局回滚。

### 4.6 验收条件

- 区域 A 被接受且路径长度变化后，区域 B 的窗口端点仍与其原始参考位置对应。
- 两区域替换后，完整路径通过相同的碰撞、净空、曲率和拓扑验证。
- 同一输入连续运行两次，输出状态、点数、坐标和区域报告一致。

## 5. 进入任务 8 前的行动顺序与验收条件

| 优先级 | 行动 | 原因 | 完成标志 |
|---|---|---|---|
| P0 | 定位并修复 RectangleDetour 原始基线复验 | 没有可信原始基线，任何 G2 发布都失去安全前提 | 场景基线 Success，诊断可定位问题来源 |
| P1 | 补充窗口合并边界回归并统一 0.8 m 语义 | 防止可独立平滑的事件被错误合并后放弃 | 1.0 m 间距场景有正确区域/候选结果 |
| P1 | 补充双区域顺序替换回归并确定弧长坐标策略 | 防止多区域处理发生错位 | 第二个区域命中正确语义窗口且结果确定 |
| P2 | 实现 LocalG2PreSmoothingPipeline 和服务分派 | 将候选层能力变为可发布的完整空间初始路径 | Local G2 端到端夹具、服务和完整回归全部通过 |

在 P0、P1 未完成前，不应把 Local G2 标为“可供下游正式消费”的平滑主路线。

## 6. 证据索引

- 端到端失败检查：ClumsyPilot/tests/verify_path_smoothing_integration.ps1
- 原始基线构建：ClumsyPilot/ParkrobTrajplanner/PathSmoothing/Processing/RawPathBaselineBuilder.cs
- 窗口规划：ClumsyPilot/ParkrobTrajplanner/PathSmoothing/LocalG2/LocalG2WindowPlanner.cs
- 局部拼接：ClumsyPilot/ParkrobTrajplanner/PathSmoothing/LocalG2/LocalG2PathSplicer.cs
- 候选评价：ClumsyPilot/ParkrobTrajplanner/PathSmoothing/LocalG2/LocalG2CandidateEvaluator.cs
- Local G2 实施计划：docs/superpowers/plans/2026-07-30-local-g2-path-presmoothing.md
