过弯检测 CornerTurnCheckHelper 代码正确(maxLength 均为正), 但 6 个测试期望值与公式不符(7e71387 改算法时测试未同步)。 已按公式修正测试:补充 maxLength 断言,调整长度阈值。 另修复 FreePathTests 一处断言(斜路径 forward/up 分量)。 并将 FreePathTests.cs 显式加入 UnitTests.csproj(此前未编译运行)
141 lines
4.8 KiB
Markdown
141 lines
4.8 KiB
Markdown
# 自由路径(Free Path)设计方案
|
||
|
||
> 分支:`feature/free-path`
|
||
> 创建日期:2026-06-30
|
||
> 状态:实施中(详见下方"实施进度跟踪")
|
||
>
|
||
> **已确认决策**:
|
||
> - 决策点1(旋转姿态):方案1 —— forward=路径切线,up=世界up投影正交化
|
||
> - 决策点2(旧数据迁移):方案A —— 自动转换 IsTwoPointVertical → Free
|
||
|
||
---
|
||
|
||
## 一、背景与问题
|
||
|
||
### 1.1 现状
|
||
|
||
当前路径类型 `PathType`:
|
||
|
||
| 值 | 类型 | 说明 |
|
||
|----|------|------|
|
||
| 0 | Ground | 地面路径 |
|
||
| 1 | Rail | 空轨路径 |
|
||
| 2 | Hoisting | 吊装路径 |
|
||
|
||
**2点路径**:是 Hoisting 上的 `IsTwoPointVertical` 特殊标志,非独立类型。语义混乱:
|
||
|
||
| | 起点 | 终点 |
|
||
|----|------|------|
|
||
| 动画帧循环 | 底面中心对齐(`ResolveGroundTrackedCenter`) | 几何中心(`p2` 原始点) |
|
||
| 终点诊断 | — | 底面中心对齐(又一种) |
|
||
|
||
**问题**:起点用底面中心对齐、终点用几何中心对齐,**对齐语义不一致**;
|
||
且 2 点路径被绑死在吊装逻辑中,无法作为通用路径使用。
|
||
|
||
### 1.2 需求
|
||
|
||
1. 2 点路径改为**自由路径(Free)**,从吊装路径中剥离
|
||
2. 与地面、空轨、吊装等路径**并列**为一级路径类型
|
||
3. **统一包围盒中心对齐**:每个路径点 = 物体几何中心
|
||
4. 支持**任意多个自由路径点**
|
||
|
||
---
|
||
|
||
## 二、目标
|
||
|
||
1. 新增一级 `PathType.Free`
|
||
2. 统一包围盒中心对齐(轨迹即物体中心)
|
||
3. 支持任意多点自由路径
|
||
4. 从吊装剥离,废弃 `IsTwoPointVertical` 特殊逻辑
|
||
5. 温和迁移旧 2 点吊装路径数据
|
||
|
||
---
|
||
|
||
## 三、核心设计
|
||
|
||
### 3.1 PathType 枚举
|
||
|
||
```csharp
|
||
public enum PathType
|
||
{
|
||
Ground = 0,
|
||
Rail = 1,
|
||
Hoisting = 2,
|
||
Free = 3 // 新增
|
||
}
|
||
```
|
||
|
||
- `GetDisplayName()` 增加 `case PathType.Free: return "自由";`
|
||
- DB 存储为整数,**追加枚举值向后安全**,无需 schema 迁移
|
||
|
||
### 3.2 动画语义(关键)
|
||
|
||
自由路径的每个路径点**就是物体包围盒中心**:
|
||
|
||
```csharp
|
||
framePosition = 路径点直接插值; // 不加任何半高偏移
|
||
```
|
||
|
||
- 起点/终点/中间点**统一**用几何中心对齐(无起点/终点不对称)
|
||
- 天然满足"矢量任意方向"——不依赖哪个面是底
|
||
|
||
### 3.3 旋转姿态策略(决策点1 → 方案1)
|
||
|
||
**方案1(已确认)**:forward = 路径切线方向,up = 世界 up 投影正交化。
|
||
|
||
- 复用 `RailPathPoseHelper` 的三维姿态计算
|
||
- 物体保持"上"朝世界,像车沿坡道走
|
||
- 通用且符合物流车语义
|
||
|
||
### 3.4 创建流程(UI)
|
||
|
||
- 新增"自由路径"创建模式,与地面/空轨/吊装并列
|
||
- 用户连续点击任意 3D 点(即物体中心轨迹)
|
||
- 无地面约束、无提升/下降段逻辑
|
||
- 支持任意点数,最后设终点完成
|
||
|
||
### 3.5 渲染
|
||
|
||
- 自由路径按普通多点线渲染(去掉吊装特殊逻辑)
|
||
- 通行空间以路径点为中心扩展
|
||
|
||
### 3.6 碰撞检测
|
||
|
||
framePosition 即物体中心,现有碰撞盒计算直接正确(无需改动)。
|
||
|
||
---
|
||
|
||
## 四、兼容与迁移
|
||
|
||
### 4.1 旧数据迁移(决策点2 → 方案A)
|
||
|
||
**方案A(已确认):自动转换**
|
||
|
||
加载旧库时,`IsTwoPointVertical=true` 的吊装路径:
|
||
- 转换为 `PathType.Free`
|
||
- 路径点坐标直接作为物体几何中心
|
||
- 注意:旧 2 点路径终点是"提升点"(lift 高度),转换时作为物体中心需确认合理性
|
||
|
||
---
|
||
|
||
## 五、实施步骤与进度跟踪
|
||
|
||
| # | 步骤 | 状态 | 备注 |
|
||
|----|------|------|------|
|
||
| 1 | `PathType` 加 `Free` + `GetDisplayName` | ✅ | 枚举值3,显示"自由" |
|
||
| 2 | 动画管理器:新增 Free 分支(统一中心对齐 + 方案1姿态) | ✅ | `TryCreateFreePathRotationForFrame/AtStart`,复用 CanonicalRailPoseBuilder |
|
||
| 3 | 渲染插件:Free 普通渲染 | ✅ | 通行空间垂直偏移0(路径=中心) |
|
||
| 4 | 路径管理器:`StartCreatingNewRoute`/`FinishEditing` 支持 Free | ✅ | 状态消息 + 设终点逻辑 |
|
||
| 5 | UI:新增自由路径创建入口 | ✅ | PathEditingView 按钮 + `NewFreePathCommand` + `ExecuteNewFreePathAsync` |
|
||
| 6 | 数据库:枚举扩展(无 schema 变更) | ✅ | 存 int,Free=3 自动映射 |
|
||
| 7 | 旧数据迁移(方案A) | ✅ | 加载时 IsTwoPointVertical→Free |
|
||
| 8 | 补单测(中心对齐 + 姿态 + 多点) | ✅ | 新增 FreePathTests(6个) |
|
||
| 9 | 编译 + 单测 + 部署 + 手动验证 | 🔄 | 需部署后手动验证 |
|
||
|
||
> ✅ 附带修复:`CornerTurnCheckHelperTests` 6个 pre-existing 失败
|
||
> - 根因:代码正确,测试期望值与公式不符(`7e71387` 改算法时测试未同步)
|
||
> - 已修正测试期望值 + 补 maxLength 断言
|
||
> - 另将 `FreePathTests.cs` 显式加入 UnitTests.csproj(此前未编译)
|
||
|
||
> 进度图例:☐ 未开始 / 🔄 进行中 / ✅ 完成
|