Files
ParkingRobot/docs/superpowers/handoffs/em-full-direction-visualization/phase-02.md
T

130 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EM 完整方向段规划与可视化修复:阶段 02 交接
## 状态
阻塞。
## 阶段目标与非目标
- 目标:仅执行总实施计划 Task 3,从实际 Local G2 `PathS` 与速度/停车包络导出完整方向段的自适应 ST 优化结点和 `T_end`,并保持优化结点与发布采样分离。
- 非目标:不实现静止起步、`NoProgress`、终端世界位姿、MovementTest、Web 或 Painter 工作。
## 启动与前置核验
- 分支:`trajplanner`
- 启动 HEAD`f32560e2f1b2046f968e30def0919a7fe6bdeccd``docs: record EM full-direction phase 01 handoff`
- 阶段 01 实现提交:`f4e89b4b4fe67f4924420ba8b3e06dea1d4ccc8b``048b4f618e2237cd0cb3d257bf6ee04a1d13670b`
- 阶段 01 交接提交:`f32560e2f1b2046f968e30def0919a7fe6bdeccd`
- `git merge-base --is-ancestor` 对提示词列出的七个提交均返回退出码 0:`f4e89b4…``048b4f6…``fcf7df1…``57ea36b…``c354f11…``dff223c…``46d5f97…`
## 已进行的 TDD 与证据
1. 初始 RED
```powershell
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- longitudinal-model
```
退出码 1;预期的 CS0246/CS1501,原因是缺少 `LongitudinalKnotSchedule`、`FullDirectionSegmentScheduleBuilder` 与 PathS 包络重载。没有静止起步、终端位姿或 MovementTest 失败。
2. 在允许的阶段 02 文件中完成了未提交的最小实现尝试,模型验证一度返回退出码 0:`PASS longitudinal-model`。初始集成验证也一度返回退出码 0:`PASS longitudinal-integration`。构建始终显示项目既有两条过时 API 警告(`Lidar2dDetect2LegTray.LegWidth` 与 `MultiWheelChassis.GetSteerWheels()`)。
3. 为满足 Task 3 的发布采样独立性要求,`LongitudinalIntegrationChecks` 加入真实 `EmTrajectoryAssembler` 断言:将 `OutputTimeStepSeconds` 从 `0.10` 改为 `0.05`,优化结点数保持不变,同时发布区间数应由 2 变为 4。最新复现:
```powershell
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- longitudinal-integration
```
退出码 1;首个有效失败为:`halving publication cadence doubles emitted trajectory intervals without changing optimization knots expected 4 but was 2`,位置为 `LongitudinalIntegrationChecks.cs:106`。
## 根因、影响与已排除原因
- `TrajectorySampleSchedule.cs` 的第 2333 行以 `candidate.KnotTimes` 逐点加入发布样本;`outputTimeStepSeconds` 只在第 44–63 行计算终端稳定尾和零速 hold。`EmTrajectoryAssembler.cs:42` 仅构造该 schedule。因此 `OutputTimeStepSeconds` 不会重采样行驶区间。
- 这与 Task 3 “发布仍使用 `Scheduling.OutputTimeStepSeconds`”以及 Step 7 “0.10 改 0.05 使发布密度翻倍、但 `KnotSchedule.KnotTimes.Count` 不变”的验收要求冲突。
- 根因不在新 schedule 的结点派生:同一集成测试已确认两个 full schedule 的 `KnotTimes.Count` 相同。也不涉及静止起步、`NoProgress`、终端世界位姿、MovementTest、Web、Painter 或硬件写输出。
- 安全影响:不能将未按配置发布分辨率重采样的完整方向段轨迹宣称为阶段 02 成功;没有执行器、底盘、转向、制动、电机或档位写入被添加或调用。
## 阻塞原因与精确恢复范围
阶段 02 允许清单不包含以下必须修改的发布文件:
- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Trajectory/TrajectorySampleSchedule.cs`
- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Trajectory/EmTrajectoryAssembler.cs`
在没有用户明确授权将这两个文件加入阶段 02(或将发布重采样验收移动到另一批准阶段)的情况下,不得修改它们,也不得削弱失败断言。恢复窗口只处理此冲突:先取得书面范围决定,再在获准范围内使真实发布按 `OutputTimeStepSeconds` 重采样、保留精确终点且不改变优化结点,随后重跑模型和集成验证。不得推进到阶段 03。
## 未提交的阶段 02 工作区内容
以下都是本阶段尝试,未暂存、未提交;恢复窗口应在此基础上继续或按明确决定调整,不能误当作用户内容:
- 新建:`LongitudinalKnotSchedule.cs`、`FullDirectionSegmentScheduleBuilder.cs`
- 修改:`PathSpeedLimitBuilder.cs`、`LongitudinalPlanningInput.cs`、`LongitudinalConstraintBuilder.cs`、`LongitudinalSolutionValidator.cs`、`SequentialLongitudinalOptimizer.cs`、`LongitudinalPreviousTrajectorySeedBuilder.cs`、`EmPlanningService.cs`
- 修改测试:`LongitudinalModelChecks.cs`、`LongitudinalIntegrationChecks.cs`
尚未创建实现提交 `feat: derive adaptive full-segment ST schedule`;不得把这些未完成 hunk 暂存或提交为成功实现。
## 脏工作区与暂存保护
- 启动前和当前暂存区均为空;未使用 `git stash`、`git reset --hard`、`git checkout --`、`git add .` 或 `git add -A`。
- `EmPlannerConfiguration.cs` 的用户既有 `DistanceHorizonMeters = 500d` 与中文注释已在启动时保存 diff,未编辑、未暂存;该文件仍为脏。
- `ClumsyPilot/ParkrobTrajplanner/tarjplanner_movementtest/MovementTest.TrajectoryObservationTest.cs` 的既有修改未编辑、未暂存。
- 大量其他用户脏修改与未跟踪文件仍保留,未清理或覆盖。
## 下一步
本阶段为阻塞状态,不产生阶段 03 输入或提示词。恢复只允许处理上节的发布采样范围冲突;恢复成功后才补全阶段 02 GREEN、回归、实现提交与完成交接。
## 恢复续行记录
用户已在本交接之后明确授权将 `TrajectorySampleSchedule.cs` 和 `EmTrajectoryAssembler.cs` 纳入阶段 02。恢复窗口在前者中实现了 full scope 的按 `OutputTimeStepSeconds` 行驶段重采样,并在后者中只对 `FullDirectionSegment` 启用它;`RollingHorizon` 保留原有逐 ST-knot 发布。上述源文件仍未暂存、未提交。
发布采样 RED 已转为 GREEN`longitudinal-integration` 退出码 0,输出 `PASS longitudinal-integration`。随后新鲜 `em-core-all` 通过 `longitudinal-model`、`longitudinal-integration` 和 `trajectory`,但在 `EmPlanningServiceChecks.VerifiesFullScopePublishesItsRequestScope` 失败。
当前首个有效失败是其 `ScriptedPipelineSolver` 用 `problem.VariableCount > 100` 识别纵向 QP。极短完整方向段的自适应 schedule 合理地产生少于该阈值的 knot,夹具于是将真实纵向 QP 当作横向并返回全零 primal,最终出现:`ST candidate does not satisfy the exact initial state`。该夹具位于 `ClumsyPilot/tests/EMPlannerVerificationHost/EmPlanningServiceChecks.cs`,不在原始 Task 3 允许测试文件中,也未包含在本次两个发布源文件的授权中。
继续前必须取得用户对该一个测试文件的明确扩展授权;只允许把测试求解器的 QP 分类改为与 knot 数无关的真实结构判定,并新增或调整 full adaptive service regression。不得通过人为增加完整段 knot 数、改变资源上限或回退到滚动 schedule 来绕过夹具。取得授权后,从以下命令复现:
```powershell
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-core-all
```
## 第二次恢复续行记录
用户随后明确授权修改 `EmPlanningServiceChecks.cs`。该夹具已将纵向 QP 识别从 `VariableCount > 100` 改为布局结构判定(`4N-1` 变量及至少 `8N-2` 约束),从而不再把短完整段的纵向问题误判为横向问题。
在该修复后,真实问题暴露出来:
1. `FullDirectionSegmentScheduleBuilder` 最初在到达 `s_end/v=0` 时立即结束。为满足 Task 3 的零速保持与现有 exact-stop 稳定尾,已在该 schedule 后追加以 `MaximumOptimizationTimeStepSeconds` 切分的 `ZeroSpeedHoldSeconds` 零速 knot。
2. 该改动后,`longitudinal-model` 与 `longitudinal-integration` 都返回退出码 0`em-core-all` 已通过 `trajectory`。
3. 但 full-scope 服务回归仍失败。脚本求解器返回的现有 `CreateExactStopSeed` warm start 在自适应时间 knot 上违反实际 PathS 速度包络(例如 `S=0.006326835275506704, U=0.0328891548874453, limit=0.030034851566717233`)。
4. 为排除脚本夹具,full-scope 测试临时改用真实 OSQP:追加 hold 前它报告 infeasible;追加 hold 后在默认服务夹具预算内达到 `maximum iterations reached`4000 iterationsprimal residual `0.00018704349099181022`)。因此不能将问题归因于夹具。
这说明阶段 02 的 schedule 消费路径尚未完成:`SequentialLongitudinalOptimizer.CreateExactStopSeed` 仍按旧的固定网格 seed 假设生成候选,未能生成与自适应 `input.KnotSchedule` 和实际 PathS 速度包络同时严格一致的 exact-stop seed。继续通过调整 fixture、增大 knot 数、放宽资源上限、回退滚动模式或改变阶段 03 静止起步逻辑都不安全且不符合计划。
恢复前需要对 seed 策略作出明确技术决定:允许阶段 02 在其已授权的 `SequentialLongitudinalOptimizer.cs`、`LongitudinalConstraintBuilder.cs`、`LongitudinalSolutionValidator.cs` 和允许测试文件内,设计并实现一个由 `input.KnotSchedule.ReferencePathS/ReferenceSpeedMetersPerSecond` 驱动、严格满足动态/速度包络/终端稳定尾的 full-scope exact-stop 初始候选;或由用户批准替代的等价最小策略。恢复窗口必须只处理该策略,不得进入阶段 03。
## 第三次恢复续行记录:可行动力学 reference 的架构阻塞
本恢复窗口重新执行了系统化根因调查并新增了 `LongitudinalModelChecks.VerifiesFullDirectionScheduleCarriesAFeasibleReferenceCandidate`。它要求完整方向段 schedule 显式携带与非均匀 knot 一致、满足真实 PathS 包络和 exact-stop hold 的 `ReferenceCandidate`,并验证改变发布周期不改变优化 knot 或 hold 边界。
首个有效 RED 是缺少 `ReferenceCandidate` 与 `TerminalHoldStartIndex` 的编译错误。实现这两个 schedule 契约后,最新有效失败可稳定复现为:
```powershell
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- longitudinal-model
```
失败断言:`adaptive schedule constructs a strict reference candidate`。诊断显示尝试的完整段 jerk reference 在真实 PathS 速度包络处被拒绝,例如 `S=0.4730000000000003, U=0.09, limit=0.08987114317838311`。这不是静止起步、终端世界位姿、MovementTest、Web 或 Painter 问题。
已排除的原因与尝试:
- 不是 scripted QP 分类夹具;此前已用真实 OSQP 复现无严格 warm start 时的不可行/超时。
- 不是发布周期耦合;此前 `longitudinal-integration` 已证明 0.10/0.05 发布密度独立于优化 knot。
- 不是单个 jerk 参数;已尝试最大 jerk 巡航后制动、全程三角 jerk、提前降速并接最大 jerk 停车,均在空间包络处失败。
- 不能把 `PathSpeedLimitBuilder` 的停车包络从“最大正加速度”改为零加速度基线:既有 `VerifiesFinitePathSIndexedSpeedEnvelope` 立即失败,证明那会破坏已定义的保守停车模型契约。
根因是当前 Phase 02 schedule 只持有 `S/U` 参考,却同时要求一个严格 `S/U/A/J` candidate;而 `PathSpeedLimitBuilder` 的保守空间停止包络与任一单相/手工拼接 jerk profile 不等价。旧 `TryCreateExactJerkSeed` 也只在优化器内事后修补非均匀 schedule,不能作为 schedule 的可行性证明。继续调节 profile、容差、knot 数、资源上限或测试夹具会掩盖这一契约缺口。
安全影响:没有执行器、底盘、转向、制动、电机或档位写入被添加或调用;但在没有严格 candidate 的情况下,完整方向段不得发布为成功。
精确恢复范围:仅在 Phase 02 已授权 Longitudinal 文件内定义一个由完整 `PathSpeedLimit` 与非均匀 `KnotTimes` 联合求解的 deterministic feasibility projection(其输出为严格 `S/U/A/J` reference candidate),再由 schedule/optimizer/validator 共用该结果。该 projection 必须保留 `PathSpeedLimitBuilder` 的既有保守包络契约,不能改为零加速度包络;必须显式携带停车 hold 起点;不得实现 Phase 03 的静止起步、NoProgress 或终端世界位姿门禁。恢复前应先为该 projection 写独立 RED,而不是继续调节现有单相 profile。