# UTTC_MS11 Legacy Fit 计划

## 目标

把 `Rvbust/前两个点正常 飞拍失败的运行` 中的旧 1x 轨迹拟合逻辑收敛到当前 replacement 实现里，让 `UTTC_MS11` 在新系统中尽量复现旧系统的轨迹时间轴和中间点形状。

当前已确认的事实：

- `Config/RobotConfig.json` 里的 `UTTC_MS11` 示教点与旧样本一致。
- 旧 `1倍速度 角度坐标点/waypoint.txt` 已给出 20 个示教点的 legacy 时间节点。
- 旧 1x 的节点时间与当前规划时间存在稳定比例，约为 `0.742277`。
- 当前运行时 `ApplySmoothStartStopTiming` 会再次改写时间轴，这会破坏旧 waypoint time 的拟合结果。

## 拟合策略

优先分两层处理，不把不同问题混成一个旋钮：

1. 时间轴拟合
   - 先把 `UTTC_MS11` 的规划时间拉回旧 1x 的节点时间。
   - 通过 `planning_speed_scale` 复现旧 `waypoint.txt` 的时间比例。
   - 对 legacy-fit 轨迹，禁止运行时二次平滑起停时间重映射。

2. 空间曲线拟合
   - 保持原始示教点不变。
   - 先用当前插补器 + legacy 时间轴做第一版对齐。
   - 如果中间点仍和旧轨迹差异明显，再用旧 `JointDetialTraj.txt` 在 knot 附近反推速度/加速度，升级为 Hermite 拟合。

## 计划分解

### 1. 配置层

- 为 `RobotConfig.json` 增加明确的 legacy-fit 运行开关。
- 当前现场的 `UTTC_MS11` 显式启用：
  - `planning_speed_scale = 0.742277`
  - `smooth_start_stop_timing = false`
- 保留默认行为为兼容旧实现，以免影响其他轨迹。

### 2. 编排层

- `ControllerClientTrajectoryOrchestrator` 读取运行配置后，按开关决定是否调用 `ApplySmoothStartStopTiming`。
- 缓存键必须包含该开关，避免 legacy-fit 和普通飞拍共用一份结果。
- `saveTrajectory` / `IsFlyshotTrajectoryValid` 仍然输出规划结果，只是 legacy-fit 轨迹不再被二次改写时间轴。

### 3. 运行层

- `FanucControllerRuntime` 继续使用 8ms 物理发送周期。
- DenseSend 实发点数仍按 `duration / (8ms * speedRatio)` 计算。
- 终点要保留完整落点，不因为非整周期而丢掉最后一个点。

### 4. 测试层

- 增加配置测试，确认新开关可解析，默认值不破坏旧行为。
- 增加编排测试，确认 UTTC_MS11 的规划时刻与旧 `waypoint.txt` 一致。
- 增加运行测试，确认 legacy-fit 目录能写出稳定的 DenseSend 诊断文件。
- 继续保留原有平滑起停测试，作为“显式开启平滑时”的回归保护。

## 验收标准

- `UTTC_MS11` 的 waypoint time 与旧 `waypoint.txt` 对齐。
- `UTTC_MS11` 运行时不再额外套一层平滑重映射。
- DenseSend 输出稳定，且不再受旧 bin 目录残留影响。
- 现有默认轨迹和非 UTTC 场景不被破坏。

## 后续可能的第二阶段

如果时间轴对齐后，中间点仍和旧轨迹有明显偏差，再做第二阶段：

- 从旧 `JointDetialTraj.txt` 提取 knot 附近速度/加速度。
- 用 Hermite / quintic Hermite 继续逼近旧曲线形状。
- 将空间曲线拟合与时间轴拟合分开验收。
