chore: save current workspace progress
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
# Local G2 五次 Hermite 路径平滑算法说明
|
||||
|
||||
> 文档定位:说明当前 Local G2 五次 Hermite 路径平滑任务的算法结构、输入、输出和实现边界。
|
||||
> 证据范围:截至 2026-07-31 的实现计划、代码结构和已运行专项检查。
|
||||
|
||||
## 1. 目标、位置与非目标
|
||||
|
||||
### 1.1 它要解决什么问题
|
||||
|
||||
Hybrid A* 粗路径由离散运动基元连接而成。它能提供可行的车辆空间路径,但相邻基元交界处可能出现车辆曲率的突变。曲率突变会使后续连续优化或控制模块得到不够平滑的初值。
|
||||
|
||||
Local G2 五次 Hermite 预平滑的目标,是只在这些局部曲率突变附近,用一小段五次 Hermite 曲线替换原有几何,使连接处的位置、切向趋势和曲率更连续,并且不牺牲车辆碰撞安全、净空和方向切换拓扑。
|
||||
|
||||
### 1.2 它在系统中的位置
|
||||
|
||||
成功的 Hybrid A* 粗路径
|
||||
↓
|
||||
Local G2 五次 Hermite 预平滑
|
||||
↓
|
||||
后续 SQP 或时间参数化模块的空间初始路径
|
||||
|
||||
这里的 Local 表示只修改必要的局部窗口;G2 表示曲线连接处不仅位置相连、切向连续,还要让曲率连续;五次 Hermite 表示每一小段曲线由两端的位置、一阶导数和二阶导数确定。
|
||||
|
||||
### 1.3 本算法不做什么
|
||||
|
||||
- 不重新搜索 Hybrid A*,不改变其代价、地图模型或运动基元生成策略。
|
||||
- 不跨越前进/倒车换向点做曲率计算或曲线拼接。
|
||||
- 不做 SQP 求解、速度规划、加速度规划、轮速分解或动态障碍物预测。
|
||||
- 不承诺当前代码已经把 Local G2 结果正式发布给下游。当前完成的是候选构造和评价层;专用发布流水线仍待接入。
|
||||
|
||||
## 2. 输入:进入算法前必须具备什么
|
||||
|
||||
Local G2 的业务入口设计基于一个路径平滑请求。它需要的输入如下。
|
||||
|
||||
| 输入 | 作用 | 关键要求 |
|
||||
|---|---|---|
|
||||
| 成功的 Hybrid A* 粗路径 | 给出原始空间轨迹与每个点的车辆曲率 | 路径点数值有限,弧长非递减 |
|
||||
| 路径方向段 | 将前进段、倒车段隔离 | 段索引连续,段内方向一致,换向点不被跨越 |
|
||||
| 地图 | 用于完整车体碰撞和净空复核 | 地图查询可用 |
|
||||
| 车辆参数 | 提供车体外形、曲率上限和安全边界 | 曲率约束有效 |
|
||||
| LocalG2QuinticOptions | 控制窗口、偏移、质量门和候选上限 | 所有参数通过有限值与范围校验 |
|
||||
| 公共平滑配置 | 控制输出采样、碰撞步长、净空余量 | 输出采样和碰撞步长必须为正 |
|
||||
| 取消令牌 | 允许耗时计算被安全取消 | 每个候选和区域循环均应检查 |
|
||||
|
||||
### 2.1 坐标和单位
|
||||
|
||||
- 位置、路径长度、窗口长度、偏移和净空:米 m。
|
||||
- 航向:弧度 rad。
|
||||
- 车辆曲率 κ:1/m。
|
||||
- 曲率导数 dκ/ds:1/m²,表示沿路径走一米时曲率变化得有多快。
|
||||
|
||||
### 2.2 Local G2 的默认安全参数
|
||||
|
||||
| 参数 | 默认值 | 含义 |
|
||||
|---|---:|---|
|
||||
| 最小 / 偏好 / 最大窗口长度 | 0.20 / 0.50 / 0.80 m | 单个局部替换允许的长度范围 |
|
||||
| 最大局部偏移 | 0.10 m | 候选曲线不得偏离原始窗口过远 |
|
||||
| 曲率跳变阈值 | max(0.001,0.05 × 最大车辆曲率) | 过滤数值噪声,只处理足够明显的跳变 |
|
||||
| 峰值 dκ/ds 最低改善 | 20% | 候选必须明显降低曲率变化尖峰 |
|
||||
| 曲率变化代价容差 | 2% | 不允许用新的高频摆动换取表面平滑 |
|
||||
| 每区域候选上限 | 12 | 保证计算量与结果可重复 |
|
||||
| 输出采样 / 碰撞检查步长 | 0.025 / 0.025 m | 统一几何分析与连续车体复核的精度 |
|
||||
| 最小净空余量 | 0.02 m | 候选与障碍物必须保留的安全距离 |
|
||||
|
||||
## 3. 模块架构:每个模块负责什么
|
||||
|
||||
| 模块 | 职责 | 当前状态 |
|
||||
|---|---|---|
|
||||
| PathSmoothingPreprocessor | 校验粗路径,将其拆成不跨换向点的方向段,并保留真实起始车辆曲率 | 已实现 |
|
||||
| PathGeometryAnalyzer | 统一重采样,恢复航向,计算 κ、dκ/ds、曲率变化代价等指标 | 已实现 |
|
||||
| CurvatureTransitionDetector | 在同一方向段内检测相邻粗路径点的曲率跳变 | 已实现 |
|
||||
| LocalG2WindowPlanner | 为跳变规划受限局部窗口,并合并可能相互影响的事件 | 已实现 |
|
||||
| QuinticHermiteCurve2D | 由两端的位置、切向导数、二阶导数构造二维五次 Hermite 曲线 | 已实现 |
|
||||
| LocalG2CandidateBuilder | 生成有限数量的候选曲线,处理前进/倒车曲率符号 | 已实现 |
|
||||
| LocalG2PathSplicer | 将一个局部候选替换进完整方向段,同时保持换向拓扑 | 已实现 |
|
||||
| LocalG2CandidateEvaluator | 执行偏移、曲率、碰撞、净空、改善度和确定性排序检查 | 已实现 |
|
||||
| SmoothedPathValidator | 以完整车体模型复核候选路径和相邻点扫掠安全 | 已实现 |
|
||||
| LocalG2PreSmoothingPipeline | 顺序处理全部区域、局部回退、全局回滚并发布最终结果 | 尚未实现 |
|
||||
| PathSmoothingService 的 Local G2 分派 | 将 LocalG2Quintic 请求送入专用流水线 | 尚未接入 |
|
||||
|
||||
## 4. 数据流:从粗路径到候选安全路径
|
||||
|
||||
### 步骤 1:预处理与方向隔离
|
||||
|
||||
粗路径先按前进和倒车拆成方向段。换向点两侧允许同一车辆位姿重复出现,但绝不被当作同一条连续曲线的一部分。这样可以避免把停车换向误判为需要平滑的几何折点。
|
||||
|
||||
### 步骤 2:检测曲率跳变
|
||||
|
||||
检测器只比较同一方向段内相邻粗路径点的车辆曲率。当差值达到阈值时,记录曲率事件:它所在的段、左右点、局部弧长、车辆航向,以及跳变前后的曲率。
|
||||
|
||||
### 步骤 3:规划局部窗口
|
||||
|
||||
窗口规划器围绕每个事件产生不同长度和左右分配的窗口方案。相邻事件若可能相互影响,会被归入同一个区域;每个区域最多输出 12 个确定性窗口/尺度组合,避免随机结果。
|
||||
|
||||
### 步骤 4:构造五次 Hermite 候选
|
||||
|
||||
对一个窗口,候选构造器在窗口两端以及必要的内部曲率事件处建立边界节点。每个节点包含位置、车辆航向、车辆曲率和导数尺度。对每对相邻节点构造一段五次 Hermite 曲线并按 0.025 m 左右的空间间距采样。
|
||||
|
||||
直观理解:原始路径像由短直线和圆弧拼出的折线化轨迹;五次 Hermite 曲线像在局部用一条可控的柔性曲线接住两边,使方向和转弯程度逐步过渡。
|
||||
|
||||
### 步骤 5:拼接候选
|
||||
|
||||
拼接器保留窗口之前和之后的原始点,用精确插值得到窗口端点,再插入候选点。随后重新计算该方向段的局部弧长,保持段首、段尾和换向标志不变。
|
||||
|
||||
### 步骤 6:统一几何分析和完整车体验证
|
||||
|
||||
候选路径与原始窗口都通过同一个几何分析器计算指标,再由完整车体碰撞检查器验证每个姿态和相邻姿态之间的扫掠。这样“看起来更圆滑”的曲线不会绕过实际车体安全检查。
|
||||
|
||||
### 步骤 7:质量门与选优
|
||||
|
||||
一个候选只有同时通过以下检查,才可被接受:
|
||||
|
||||
1. 不超过车辆曲率上限,也不超出原始局部曲率范围。
|
||||
2. 到原始窗口折线的最大偏移不超过 0.10 m。
|
||||
3. 完整路径碰撞检查通过,最小净空不少于 0.02 m。
|
||||
4. 峰值 dκ/ds 至少降低 20%。
|
||||
5. 曲率变化代价不比原始窗口增加超过 2%。
|
||||
|
||||
若多个候选合格,按最大偏移、峰值 dκ/ds、曲率变化代价、路径长度变化和候选索引依次排序,确保结果可重复。
|
||||
|
||||
## 5. 输出:路径、段、指标、区域报告与状态
|
||||
|
||||
### 5.1 候选层已经能够产生的结果
|
||||
|
||||
候选评价层可以得到一条经过完整车体复核的候选安全路径,以及对应的方向段和局部指标。每个输出路径点包含:
|
||||
|
||||
- 位置、航向、展开航向和全局弧长;
|
||||
- 前进或倒车方向;
|
||||
- 几何曲率、车辆曲率、车辆曲率导数 dκ/ds;
|
||||
- 重新计算的车体净空;
|
||||
- 是否为换向点,以及该点来自原始锚点、插值点或 Local G2 过渡点。
|
||||
|
||||
每个方向段则记录其段号、方向、路径点的起止索引,以及换向拓扑标志。
|
||||
|
||||
### 5.2 计划中的正式发布结果
|
||||
|
||||
公共契约已为 Local G2 预留以下最终状态:
|
||||
|
||||
| 状态 | 计划含义 |
|
||||
|---|---|
|
||||
| NotNeeded | 未检测到需要处理的曲率跳变,发布已验证的原始路径 |
|
||||
| Complete | 所有区域都得到有效改善 |
|
||||
| PartialImprovement | 只有部分区域得到有效改善,其余区域保留原样 |
|
||||
| Unchanged | 检测到事件,但没有候选能安全通过质量门 |
|
||||
|
||||
正式结果还应包含每个区域的报告:窗口范围、候选数、被选候选、原始/结果峰值 dκ/ds、曲率变化代价、最大偏移、最小净空和保留原路径的原因。
|
||||
|
||||
### 5.3 当前输出边界
|
||||
|
||||
上述最终状态和区域报告的契约已经存在,但负责顺序处理多个区域、必要时全局回滚、并由服务发布结果的 LocalG2PreSmoothingPipeline 尚未实现。因此,当前代码的准确描述是“可生成和评价局部 G2 候选”,而不是“已经对外发布完整 Local G2 平滑路径”。
|
||||
|
||||
## 6. 安全与质量门
|
||||
|
||||
Local G2 的核心原则不是尽可能把曲线画圆,而是在严格约束下只接受确实更好的局部替换。
|
||||
|
||||
- **方向安全**:不跨换向点,前进/倒车的曲率符号转换只做一次。
|
||||
- **几何安全**:候选端点必须与原始窗口精确对应,避免拼接留下缝隙或重复点。
|
||||
- **车辆安全**:逐点与逐段扫掠检查完整车体,而不是只检查轨迹中心线。
|
||||
- **净空安全**:以本次检查的净空为准,不信任候选输入自带的净空值。
|
||||
- **平滑质量**:以 dκ/ds 的峰值和曲率变化代价衡量改善,避免引入新的摆动。
|
||||
- **确定性**:固定窗口、固定导数尺度顺序和固定排序规则,便于复现与诊断。
|
||||
|
||||
## 7. 当前实现进度与边界
|
||||
|
||||
实施计划共 9 个任务。任务 1 至任务 7 已完成公共契约、真实起始曲率保留、统一 dκ/ds 分析、事件检测、窗口规划、五次 Hermite 几何、候选拼接和质量评价。
|
||||
|
||||
已重新执行并通过的专项检查包括:
|
||||
|
||||
- 路径平滑契约检查;
|
||||
- 粗路径集成与搜索检查;
|
||||
- 路径平滑几何、验证器、服务和比较检查;
|
||||
- Local G2 跳变检测、五次曲线和候选质量检查。
|
||||
|
||||
任务 8 的专用流水线、服务分派和 Local G2 端到端夹具检查尚未实现;任务 9 的完整回归与主路线文档也尚未完成。另有一个共享原始基线回归会在第二份报告中单独说明:RectangleDetour 场景在进入 G2 前的基线复验失败。
|
||||
|
||||
## 8. 证据索引
|
||||
|
||||
- Local G2 实施计划:docs/superpowers/plans/2026-07-30-local-g2-path-presmoothing.md
|
||||
- Local G2 设计说明:docs/superpowers/specs/2026-07-30-local-g2-path-presmoothing-design.md
|
||||
- Local G2 实现目录:ClumsyPilot/ParkrobTrajplanner/PathSmoothing/LocalG2/
|
||||
- 统一几何分析:ClumsyPilot/ParkrobTrajplanner/PathSmoothing/Processing/PathGeometryAnalyzer.cs
|
||||
- 完整车体验证:ClumsyPilot/ParkrobTrajplanner/PathSmoothing/Validation/SmoothedPathValidator.cs
|
||||
- 专项检查:ClumsyPilot/tests/verify_path_smoothing_local_g2_detection.ps1、verify_path_smoothing_local_g2_curve.ps1、verify_path_smoothing_local_g2_candidates.ps1
|
||||
@@ -0,0 +1,185 @@
|
||||
# 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
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
# Local G2 最小曲率越界可行性验证报告
|
||||
|
||||
> 文档定位:记录 Local G2 最小曲率越界(curvature excursion)受控探测的结论、改动边界和后续动作,供路径平滑模块的日常协作查阅。
|
||||
>
|
||||
> 证据边界:本报告只摘要正式证据报告中的固定 SingleTurn 场景结果。它不是生产发布说明,也不把一次性 probe 中的测量改动描述为共享生产代码改动。
|
||||
|
||||
对应可视化附录:[03-local-g2-curvature-excursion-feasibility-visualization.html](03-local-g2-curvature-excursion-feasibility-visualization.html)。
|
||||
|
||||
## 1. 结论摘要
|
||||
|
||||
本轮最小曲率越界可行性探测的最终状态是 **QUALITY_RED**。它给出的授权结论很明确:**不修改生产 evaluator(候选评估器)**。
|
||||
|
||||
这不是因为运行超时,也不是因为证据无效。候选搜索、性能和重复运行均完成了预定验证;问题在于,没有候选同时满足严格接纳条件,因此没有可发布的替换路径。
|
||||
|
||||
| 项目 | 本轮结果 | 正确解读 |
|
||||
| --- | --- | --- |
|
||||
| 严格合格候选 | 0 | 原始严格范围条件下没有可接纳候选。 |
|
||||
| 物理约束合格候选 | 3 | 仅说明它们满足该层物理约束,不能等同于最终接受。 |
|
||||
| 曲率越界合格候选 | 0 | 没有可报告的最小可行越界值。 |
|
||||
| 管线输出 | Unchanged | 原路径没有被替换。 |
|
||||
| 性能超限 | False | 本轮未因性能失败。 |
|
||||
| 证据有效性 | valid | 本轮结论可复核,但结论是不能修改 evaluator。 |
|
||||
|
||||
## 2. 本轮做了什么
|
||||
|
||||
本轮不是在共享生产源码中直接“放宽曲率”,而是在一次性、可丢弃的 probe core 中回答一个更小的问题:
|
||||
|
||||
> 在不改变严格生产接纳语义的前提下,是否存在一个能消除局部曲率突变、并以最小必要越界满足全部质量门的候选?
|
||||
|
||||
验证分为两条互相隔离的路径:
|
||||
|
||||
1. **Strict 路径**:保持共享 evaluator 的原始严格语义,判定候选能否被正式接纳。
|
||||
2. **Measurement 路径**:仅为了记录被严格 raw 曲率范围提前阻断后的后续质量门状态,允许诊断继续走到后面的检查点。它不是生产实现,也不改变 Strict 路径的结论。
|
||||
|
||||
这样可以把“候选的几何和车辆物理约束是否可行”与“候选是否允许进入正式输出”分开观察,避免为了得到绿色结果而直接放宽生产门槛。
|
||||
|
||||
## 3. 本轮修改范围
|
||||
|
||||
| 范围 | 改动内容 | 边界与结果 |
|
||||
| --- | --- | --- |
|
||||
| 一次性 probe core | 增加受控搜索、候选账本、严格审计和证据生成能力。 | 只用于本轮验证,不回写共享生产源码。 |
|
||||
| Measurement root | 仅改动 LocalG2CandidateEvaluator.cs 中 raw 范围提前返回后的测量延续与 trace 捕获。 | 用于定位后续质量门;不是生产 evaluator 改动。 |
|
||||
| 严格 root | 保持 evaluator 与共享基线一致。 | 严格结论仍是 0 个可接纳候选。 |
|
||||
| 共享分支 | 发布正式证据报告。 | 没有提交 probe 源码,也没有修改生产 evaluator。 |
|
||||
| 本日报目录 | 新增本 Markdown 摘要和对应离线 HTML 可视化。 | 仅整理结论与证据入口,不改变路径平滑行为。 |
|
||||
|
||||
相关身份如下:
|
||||
|
||||
| 身份 | 提交 |
|
||||
| --- | --- |
|
||||
| 共享基线 | da9157b17a7e4206ed4cdebd1985ee2577fae480 |
|
||||
| 冻结 core / Strict | 3006aa0fd8dac8e4665ff3b89b7cda139e88e940 |
|
||||
| Measurement | c92c9c5b8e1995f61d4685f9a6ee23a6f8d5f825 |
|
||||
| 共享分支正式证据报告 | 67f86581a06f754ae166c6145478f454afefbf17 |
|
||||
|
||||
## 4. 候选搜索结果
|
||||
|
||||
固定 SingleTurn 场景中的搜索预算和结果如下:
|
||||
|
||||
| 指标 | 结果 |
|
||||
| --- | ---: |
|
||||
| 规划窗口数 | 8 |
|
||||
| 已尝试组合数 | 24 |
|
||||
| solver 调用数 | 30 |
|
||||
| 已生成候选数 | 6 |
|
||||
| 失败组合数 | 18 |
|
||||
| 最大 interval 数 | 2 |
|
||||
| 搜索停止原因 | None |
|
||||
| 严格合格 / 物理约束合格 / 越界合格 | 0 / 3 / 0 |
|
||||
|
||||
因此,本轮不是“没有生成任何曲线”。相反,系统生成了 6 个候选,其中 3 个通过了车辆物理约束层;但没有一个通过严格接纳层,也没有一个成为可报告的最小曲率越界方案。
|
||||
|
||||
## 5. 为什么最终没有路径变得更平滑
|
||||
|
||||
结论不能简化为“候选曲率一定比原路径更大”。更准确的过程是:
|
||||
|
||||
1. 候选生成器确实构造了局部替换曲线。
|
||||
2. Strict 路径先检查 raw 曲率范围。候选没有满足这一严格范围条件,因此严格合格数为 0。
|
||||
3. Measurement 路径只为观察决策链而继续记录后续门。3 个物理约束合格候选仍在净空门被阻断,未进入最终质量评价和接受流程。
|
||||
4. 没有候选被选中,预平滑管线保持 Unchanged,原路径不替换。
|
||||
|
||||
这里有两个不同层次的概念:
|
||||
|
||||
| 层次 | 回答的问题 | 本轮状态 |
|
||||
| --- | --- | --- |
|
||||
| 车辆物理约束 | 车辆最大曲率、接缝、偏移等基础几何约束是否可行? | 有 3 个候选通过。 |
|
||||
| 严格接纳与质量门 | 候选是否能在现有生产语义下安全、完整地替换原路径? | 没有候选通过。 |
|
||||
|
||||
所以“物理约束合格”不是“平滑方案已经有效”。当前实际效果是:**候选层被执行并留下可复核证据,但没有改变输出路径。**
|
||||
|
||||
## 6. 性能与确定性
|
||||
|
||||
性能验证先进行 5 次预热,再进行 30 次测量运行。30 次测量只得到 1 个确定性签名,说明在该固定场景与固定环境下结果没有随机漂移。
|
||||
|
||||
| 指标 | 中位数 | 最坏值 | 限制 | 结果 |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| Solver 时间 | 4.93545 ms | 7.7368 ms | 10 / 25 ms | 通过 |
|
||||
| Region 时间 | 10.09185 ms | 23.2227 ms | 25 / 50 ms | 通过 |
|
||||
|
||||
性能通过只说明这次受控探测没有超过时间预算;它不能覆盖严格接纳失败,也不能把 QUALITY_RED 转为可发布状态。
|
||||
|
||||
## 7. 这份结果说明什么,不说明什么
|
||||
|
||||
| 可以说明 | 不能说明 |
|
||||
| --- | --- |
|
||||
| 当前固定 SingleTurn 场景中,严格语义下不存在可接纳的最小曲率越界候选。 | 所有地图、所有转弯或全部 Local G2 场景都不可行。 |
|
||||
| 结果不是因超时或随机性造成。 | 只要放宽 evaluator 就应当发布。 |
|
||||
| Measurement 路径有助于定位 raw 范围之后的净空阻断。 | Measurement 改动已经进入生产 evaluator。 |
|
||||
| 当前授权边界是“不修改 evaluator”。 | 前两份报告中的基线、窗口语义和多区域弧长风险已经解决。 |
|
||||
|
||||
特别需要保留的边界是:前两份日报中记录的 RectangleDetour 基线复验、窗口合并语义和多区域弧长定位问题,不会因为本次单场景 probe 结束而自动关闭。
|
||||
|
||||
## 8. 后续动作
|
||||
|
||||
1. 保持 QUALITY_RED 的授权边界:不把 Measurement 改动复制到生产 evaluator。
|
||||
2. 不以“变绿”为目的放宽 raw 曲率范围、净空或其他质量门。
|
||||
3. 继续按已有优先级处理基线复验、窗口长度语义和多区域弧长定位风险。
|
||||
4. 若要评估新的几何策略或新的场景范围,应另起独立计划,重新定义候选、质量门和验收证据,而不是从本次结果直接推导发布结论。
|
||||
|
||||
## 9. 证据索引
|
||||
|
||||
| 证据 | 用途 |
|
||||
| --- | --- |
|
||||
| docs/superpowers/reports/2026-08-01-local-g2-minimum-curvature-excursion-feasibility-report.md | 本日报所有数值和最终授权边界的正式来源。 |
|
||||
| 3006aa0fd8dac8e4665ff3b89b7cda139e88e940 | 冻结 core 与 Strict 验证身份。 |
|
||||
| c92c9c5b8e1995f61d4685f9a6ee23a6f8d5f825 | Measurement 专用、可丢弃的 evaluator trace 身份。 |
|
||||
| 67f86581a06f754ae166c6145478f454afefbf17 | 共享分支上发布正式证据报告的提交。 |
|
||||
| 03-local-g2-curvature-excursion-feasibility-visualization.html | 本报告的离线交互式可视化附录。 |
|
||||
+616
@@ -0,0 +1,616 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Local G2 最小曲率越界可行性验证|结果可视化</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--ink: #172a36;
|
||||
--muted: #62727b;
|
||||
--paper: #f4f7f6;
|
||||
--panel: #ffffff;
|
||||
--line: #c8d4d5;
|
||||
--teal: #126d70;
|
||||
--teal-pale: #e0f1ef;
|
||||
--green: #257a4d;
|
||||
--green-pale: #e7f4eb;
|
||||
--amber: #9b5f13;
|
||||
--amber-pale: #fff1dc;
|
||||
--red: #b1373e;
|
||||
--red-pale: #fbe9ea;
|
||||
--slate: #596b75;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--paper);
|
||||
color: var(--ink);
|
||||
font: 16px/1.6 system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
width: min(1120px, 100%);
|
||||
margin: 0 auto;
|
||||
padding: 32px 24px 48px;
|
||||
}
|
||||
|
||||
header {
|
||||
border-bottom: 2px solid var(--ink);
|
||||
padding-bottom: 22px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 6px;
|
||||
color: var(--teal);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
h1, h2, h3, p { margin-top: 0; }
|
||||
|
||||
h1 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 2.25rem;
|
||||
line-height: 1.18;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 12px;
|
||||
font-size: 1.45rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 6px;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
max-width: 780px;
|
||||
margin-bottom: 16px;
|
||||
color: var(--muted);
|
||||
font-size: 1.03rem;
|
||||
}
|
||||
|
||||
.badges {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
border: 1px solid currentColor;
|
||||
border-radius: 6px;
|
||||
padding: 4px 9px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.badge.red { color: var(--red); background: var(--red-pale); }
|
||||
.badge.green { color: var(--green); background: var(--green-pale); }
|
||||
.badge.teal { color: var(--teal); background: var(--teal-pale); }
|
||||
|
||||
.report-nav {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
|
||||
button {
|
||||
min-height: 44px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 6px;
|
||||
padding: 9px 12px;
|
||||
color: var(--ink);
|
||||
background: var(--panel);
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover { border-color: var(--teal); }
|
||||
button:focus-visible { outline: 3px solid #f0b535; outline-offset: 2px; }
|
||||
button[aria-pressed="true"] { border-color: var(--teal); color: #ffffff; background: var(--teal); }
|
||||
|
||||
.visual-band {
|
||||
margin-top: 16px;
|
||||
border-top: 1px solid var(--line);
|
||||
border-bottom: 1px solid var(--line);
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.view-copy {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: 20px;
|
||||
align-items: end;
|
||||
padding: 22px 22px 12px;
|
||||
}
|
||||
|
||||
.view-copy p {
|
||||
margin-bottom: 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.view-state {
|
||||
margin: 0;
|
||||
color: var(--teal);
|
||||
font-weight: 800;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.visual-stage { padding: 0 22px 24px; }
|
||||
|
||||
.visual-view { display: none; }
|
||||
[data-view="funnel"] .visual-view[data-view="funnel"],
|
||||
[data-view="gates"] .visual-view[data-view="gates"],
|
||||
[data-view="performance"] .visual-view[data-view="performance"] { display: block; }
|
||||
|
||||
.funnel {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
align-items: stretch;
|
||||
gap: 10px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.funnel li {
|
||||
position: relative;
|
||||
min-height: 142px;
|
||||
border: 1px solid var(--line);
|
||||
border-top: 5px solid var(--slate);
|
||||
border-radius: 6px;
|
||||
padding: 16px 12px;
|
||||
background: #fbfcfc;
|
||||
}
|
||||
|
||||
.funnel li:not(:last-child)::after {
|
||||
position: absolute;
|
||||
top: 58px;
|
||||
right: -9px;
|
||||
z-index: 1;
|
||||
width: 17px;
|
||||
color: var(--muted);
|
||||
background: var(--panel);
|
||||
content: "→";
|
||||
font-size: 1.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.funnel li.physical { border-top-color: var(--green); }
|
||||
.funnel li.blocked { border-top-color: var(--red); }
|
||||
.funnel li.final { border-top-color: var(--slate); }
|
||||
|
||||
.metric {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
color: var(--ink);
|
||||
font-size: 2.25rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.funnel strong, .funnel small { display: block; }
|
||||
.funnel small { margin-top: 4px; color: var(--muted); }
|
||||
|
||||
.gate-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.gate {
|
||||
min-height: 154px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
background: #fbfcfc;
|
||||
}
|
||||
|
||||
.gate .step {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: var(--muted);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.gate p { margin-bottom: 0; color: var(--muted); }
|
||||
.gate.accepted { border-top: 5px solid var(--green); }
|
||||
.gate.blocked { border-top: 5px solid var(--red); }
|
||||
.gate.measurement { border-top: 5px solid var(--amber); }
|
||||
.gate.output { border-top: 5px solid var(--slate); }
|
||||
|
||||
.gate-result {
|
||||
display: inline-block;
|
||||
margin-top: 12px;
|
||||
border-radius: 5px;
|
||||
padding: 3px 7px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.gate-result.green { color: var(--green); background: var(--green-pale); }
|
||||
.gate-result.red { color: var(--red); background: var(--red-pale); }
|
||||
.gate-result.amber { color: var(--amber); background: var(--amber-pale); }
|
||||
.gate-result.slate { color: var(--slate); background: #e9eef0; }
|
||||
|
||||
.measurement-note {
|
||||
margin: 14px 0 0;
|
||||
border-left: 4px solid var(--amber);
|
||||
padding: 10px 12px;
|
||||
color: #6e4915;
|
||||
background: var(--amber-pale);
|
||||
}
|
||||
|
||||
.performance-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 250px;
|
||||
gap: 28px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.timing-list {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.timing-row {
|
||||
display: grid;
|
||||
grid-template-columns: 132px minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.timing-label { font-weight: 800; }
|
||||
|
||||
.timing-bar {
|
||||
display: grid;
|
||||
grid-template-columns: var(--median) var(--worst) 1fr;
|
||||
min-height: 40px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 5px;
|
||||
background: #f6f8f8;
|
||||
}
|
||||
|
||||
.timing-bar span {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-width: 0;
|
||||
padding: 3px;
|
||||
color: #ffffff;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.timing-bar .median { background: var(--teal); }
|
||||
.timing-bar .worst { background: var(--green); }
|
||||
.timing-bar .remaining { color: var(--muted); background: #edf2f1; }
|
||||
|
||||
.determinism {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
border-left: 1px solid var(--line);
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.determinism strong {
|
||||
display: block;
|
||||
color: var(--teal);
|
||||
font-size: 2.85rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.determinism p { margin: 8px 0 0; color: var(--muted); }
|
||||
|
||||
.section {
|
||||
padding: 30px 0;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.section-intro {
|
||||
max-width: 780px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.facts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.fact {
|
||||
border-left: 4px solid var(--teal);
|
||||
padding: 4px 0 4px 14px;
|
||||
}
|
||||
|
||||
.fact:nth-child(2) { border-left-color: var(--red); }
|
||||
.fact:nth-child(3) { border-left-color: var(--amber); }
|
||||
.fact p { margin-bottom: 0; color: var(--muted); }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
th, td {
|
||||
border-bottom: 1px solid var(--line);
|
||||
padding: 11px 12px;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th { color: var(--muted); font-size: 0.9rem; }
|
||||
tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.actions {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
counter-reset: action;
|
||||
}
|
||||
|
||||
.actions li {
|
||||
counter-increment: action;
|
||||
position: relative;
|
||||
padding-left: 42px;
|
||||
}
|
||||
|
||||
.actions li::before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 50%;
|
||||
color: var(--teal);
|
||||
background: var(--panel);
|
||||
content: counter(action);
|
||||
font-weight: 800;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding-top: 24px;
|
||||
color: var(--muted);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
main { padding: 24px 14px 38px; }
|
||||
h1 { font-size: 1.85rem; }
|
||||
.report-nav, .facts { grid-template-columns: 1fr; }
|
||||
.view-copy, .performance-layout { grid-template-columns: 1fr; }
|
||||
.view-state { text-align: left; }
|
||||
.funnel, .gate-grid { grid-template-columns: 1fr; }
|
||||
.funnel li:not(:last-child)::after {
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: -16px;
|
||||
left: calc(50% - 9px);
|
||||
content: "↓";
|
||||
}
|
||||
.determinism {
|
||||
border-top: 1px solid var(--line);
|
||||
border-left: 0;
|
||||
padding-top: 20px;
|
||||
padding-left: 0;
|
||||
}
|
||||
.timing-row { grid-template-columns: 1fr; gap: 5px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main id="excursion-report" data-view="funnel">
|
||||
<header>
|
||||
<p class="eyebrow">离线结果可视化 · Local G2</p>
|
||||
<h1>最小曲率越界探测:没有新的可采纳路径</h1>
|
||||
<p class="subtitle">固定 SingleTurn 场景中,候选搜索、性能和确定性验证均已完成;但严格接纳条件下没有候选通过,预平滑管线保持原样。</p>
|
||||
<div class="badges" aria-label="结论状态">
|
||||
<span class="badge red">QUALITY_RED</span>
|
||||
<span class="badge green">性能通过</span>
|
||||
<span class="badge teal">生产 evaluator 不变</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav class="report-nav" aria-label="选择结果视图">
|
||||
<button type="button" class="view-button" data-view="funnel" aria-pressed="true">候选结果漏斗</button>
|
||||
<button type="button" class="view-button" data-view="gates" aria-pressed="false">质量门阻断链路</button>
|
||||
<button type="button" class="view-button" data-view="performance" aria-pressed="false">性能与确定性</button>
|
||||
</nav>
|
||||
|
||||
<section class="visual-band" aria-live="polite">
|
||||
<div class="view-copy">
|
||||
<div>
|
||||
<h2 id="view-title">候选已经生成,但没有进入最终输出</h2>
|
||||
<p id="view-description">6 个候选中有 3 个达到车辆物理约束层;严格 raw 曲率范围合格数仍为 0,因此不能把任何候选当作可发布的平滑路径。</p>
|
||||
</div>
|
||||
<p id="view-state" class="view-state">结果:Unchanged</p>
|
||||
</div>
|
||||
|
||||
<div class="visual-stage">
|
||||
<div class="visual-view" data-view="funnel">
|
||||
<ol class="funnel" aria-label="候选审核结果漏斗">
|
||||
<li><span class="metric">6</span><strong>已生成候选</strong><small>30 次 solver 调用</small></li>
|
||||
<li class="physical"><span class="metric">3</span><strong>物理约束合格</strong><small>基础几何层</small></li>
|
||||
<li class="blocked"><span class="metric">0</span><strong>严格范围合格</strong><small>raw 曲率范围</small></li>
|
||||
<li class="blocked"><span class="metric">0</span><strong>越界合格</strong><small>无最小值可报告</small></li>
|
||||
<li class="final"><span class="metric">0</span><strong>替换输出</strong><small>管线 Unchanged</small></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="visual-view" data-view="gates">
|
||||
<div class="gate-grid" aria-label="严格与测量路径的质量门状态">
|
||||
<article class="gate accepted">
|
||||
<span class="step">步骤 1</span>
|
||||
<h3>候选生成</h3>
|
||||
<p>局部替换曲线被构造并进入审核。</p>
|
||||
<span class="gate-result green">6 个候选</span>
|
||||
</article>
|
||||
<article class="gate blocked">
|
||||
<span class="step">步骤 2</span>
|
||||
<h3>Strict raw 曲率范围</h3>
|
||||
<p>严格路径首先判定候选是否保持原有接纳语义。</p>
|
||||
<span class="gate-result red">0 个严格合格</span>
|
||||
</article>
|
||||
<article class="gate measurement">
|
||||
<span class="step">步骤 3</span>
|
||||
<h3>Measurement trace</h3>
|
||||
<p>只为取证而继续记录后续质量门,不改变 Strict 结论。</p>
|
||||
<span class="gate-result amber">一次性测量路径</span>
|
||||
</article>
|
||||
<article class="gate output">
|
||||
<span class="step">步骤 4</span>
|
||||
<h3>净空与最终输出</h3>
|
||||
<p>3 个物理约束合格候选在净空门阻断,未被接受。</p>
|
||||
<span class="gate-result slate">原路径保持</span>
|
||||
</article>
|
||||
</div>
|
||||
<p class="measurement-note">Measurement 的作用是把阻断位置记录完整,不是放宽生产质量门。它不能授权修改 evaluator,也不能让候选进入正式输出。</p>
|
||||
</div>
|
||||
|
||||
<div class="visual-view" data-view="performance">
|
||||
<div class="performance-layout">
|
||||
<div class="timing-list" aria-label="性能汇总,单位为毫秒">
|
||||
<div class="timing-row">
|
||||
<span class="timing-label">Solver 中位 / 限制</span>
|
||||
<div class="timing-bar" style="--median: 49%; --worst: 0%;">
|
||||
<span class="median">4.94 ms</span>
|
||||
<span class="worst"></span>
|
||||
<span class="remaining">限制 10 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timing-row">
|
||||
<span class="timing-label">Solver 最坏 / 限制</span>
|
||||
<div class="timing-bar" style="--median: 31%; --worst: 0%;">
|
||||
<span class="median">7.74 ms</span>
|
||||
<span class="worst"></span>
|
||||
<span class="remaining">限制 25 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timing-row">
|
||||
<span class="timing-label">Region 中位 / 限制</span>
|
||||
<div class="timing-bar" style="--median: 40%; --worst: 0%;">
|
||||
<span class="median">10.09 ms</span>
|
||||
<span class="worst"></span>
|
||||
<span class="remaining">限制 25 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timing-row">
|
||||
<span class="timing-label">Region 最坏 / 限制</span>
|
||||
<div class="timing-bar" style="--median: 46%; --worst: 0%;">
|
||||
<span class="median">23.22 ms</span>
|
||||
<span class="worst"></span>
|
||||
<span class="remaining">限制 50 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<aside class="determinism">
|
||||
<strong>1</strong>
|
||||
<p>个确定性签名<br>5 次预热 + 30 次测量<br>性能超限:False</p>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>如何理解“平滑方案效果”</h2>
|
||||
<p class="section-intro">本次结果不是“完全没有曲线”,也不能直接写成“所有候选曲率都比原路径更大”。真正的结论是,候选在不同质量层的状态不同,且没有一个最终满足现有严格接纳条件。</p>
|
||||
<div class="facts">
|
||||
<article class="fact">
|
||||
<h3>候选层确实执行</h3>
|
||||
<p>系统生成了 6 个局部候选,并对它们完成了有界搜索和账本审计。</p>
|
||||
</article>
|
||||
<article class="fact">
|
||||
<h3>严格接纳没有通过</h3>
|
||||
<p>raw 曲率范围严格合格数为 0,因此不能把任何候选写成可发布的路径平滑结果。</p>
|
||||
</article>
|
||||
<article class="fact">
|
||||
<h3>输出没有变化</h3>
|
||||
<p>Measurement 继续记录后,候选仍被净空门阻断;管线最终保持 Unchanged。</p>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>本轮修改边界</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>范围</th><th>改动</th><th>结论</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>一次性 probe core</td><td>候选搜索、账本、严格审计与证据生成。</td><td>只用于验证,不回写生产源码。</td></tr>
|
||||
<tr><td>Measurement root</td><td>LocalG2CandidateEvaluator.cs 的测量延续与 trace 捕获。</td><td>只用于取证,不是生产 evaluator 变更。</td></tr>
|
||||
<tr><td>共享分支</td><td>发布正式证据报告。</td><td>没有提交 probe 源码,也没有修改 evaluator。</td></tr>
|
||||
<tr><td>本日报目录</td><td>新增本页及对应 Markdown 摘要。</td><td>仅整理事实与证据入口,不改变路径平滑行为。</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>后续边界</h2>
|
||||
<ol class="actions">
|
||||
<li>保持 QUALITY_RED 对应的授权结论:不把 Measurement 改动复制到生产 evaluator。</li>
|
||||
<li>不为了得到绿色结果而放宽 raw 曲率范围、净空或其他质量门。</li>
|
||||
<li>继续按已有优先级处理基线复验、窗口长度语义与多区域弧长定位风险。</li>
|
||||
<li>新的几何策略或场景范围需要独立计划和新的验收证据,不能从本次 SingleTurn 结果直接推导发布结论。</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
对应主报告:03-local-g2-curvature-excursion-feasibility-report.md。数据来源:docs/superpowers/reports/2026-08-01-local-g2-minimum-curvature-excursion-feasibility-report.md。单文件离线 HTML,无外部资源依赖。
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const views = Object.freeze({
|
||||
funnel: Object.freeze({
|
||||
title: '候选已经生成,但没有进入最终输出',
|
||||
description: '6 个候选中有 3 个达到车辆物理约束层;严格 raw 曲率范围合格数仍为 0,因此不能把任何候选当作可发布的平滑路径。',
|
||||
state: '结果:Unchanged'
|
||||
}),
|
||||
gates: Object.freeze({
|
||||
title: '严格路径阻断,测量路径只补全证据',
|
||||
description: 'Strict 保持共享 evaluator 语义并在 raw 曲率范围处拒绝候选。Measurement 仅为追踪后续质量门,不能改变严格结论或生产代码。',
|
||||
state: '授权:不修改 evaluator'
|
||||
}),
|
||||
performance: Object.freeze({
|
||||
title: '时间预算与结果确定性均通过',
|
||||
description: '5 次预热和 30 次测量均在既定性能阈值内完成,且只产生 1 个确定性签名;这些结果不覆盖严格接纳失败。',
|
||||
state: '性能超限:False'
|
||||
})
|
||||
});
|
||||
|
||||
const buttons = Array.from(document.querySelectorAll('.view-button'));
|
||||
|
||||
function selectView(viewId) {
|
||||
const view = views[viewId];
|
||||
if (!view) return;
|
||||
const root = document.getElementById('excursion-report');
|
||||
root.dataset.view = viewId;
|
||||
document.getElementById('view-title').textContent = view.title;
|
||||
document.getElementById('view-description').textContent = view.description;
|
||||
document.getElementById('view-state').textContent = view.state;
|
||||
buttons.forEach((button) => button.setAttribute('aria-pressed', String(button.dataset.view === viewId)));
|
||||
}
|
||||
|
||||
buttons.forEach((button) => button.addEventListener('click', () => selectView(button.dataset.view)));
|
||||
selectView('funnel');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user