# 双轨安装头空轨路径扩展设计

## 背景

当前项目中的 `PathType.Rail` 语义实际等同于“轨下悬挂运输”：

- 基准路径来自空轨下表面中心线
- 动画默认将物体沿世界 `Z` 方向向下偏移一个物体高度
- 通行空间也默认按“路径点在物体上方”渲染

这套模型无法准确表达新的双轨安装头场景：

- 轨道为两根平行轨道
- 安装头在两轨中间滑动
- 箱型构件与安装头刚性连接
- 构件以顶面中心或底面中心与安装头对接
- 安装头支持轨上、轨下两种安装方式
- 轨道支持斜向上、斜向下

## 目标

将现有“空轨路径”升级为“轨道导向装配运输路径”，支持以下 4 种基本构型：

1. 轨上 + 斜向上
2. 轨上 + 斜向下
3. 轨下 + 斜向上
4. 轨下 + 斜向下

并支持两种构件对接方式：

1. 顶面中心对接安装头
2. 底面中心对接安装头

## 设计原则

1. 不再以“轨下中心线”作为 Rail 路径的唯一几何语义。
2. 路径数据应表达“安装头中心的参考路径”。
3. 构件实际动画位置和碰撞包络，应从“参考路径 + 安装构型”推导。
4. 对斜轨路径，偏移和姿态必须基于轨道局部坐标系，而不是简单沿世界 `Z` 轴处理。
5. 保持旧 Rail 路径可加载，并为旧数据提供默认兼容语义。

## 新数据模型

### RailMountMode

```csharp
public enum RailMountMode
{
    UnderRail = 0,
    OverRail = 1
}
```

含义：安装头位于双轨参考平面的下方或上方。

### RailPayloadAnchorMode

```csharp
public enum RailPayloadAnchorMode
{
    TopCenter = 0,
    BottomCenter = 1
}
```

含义：构件以顶面中心或底面中心与安装头刚性对接。

### RailPathDefinitionMode

```csharp
public enum RailPathDefinitionMode
{
    LegacyBottomCenterLine = 0,
    InstallationHeadCenterLine = 1
}
```

含义：

- `LegacyBottomCenterLine` 用于兼容旧空轨路径
- `InstallationHeadCenterLine` 表示新的安装头中心参考路径

### PathRoute 新增字段

建议为 `PathRoute` 增加以下字段：

```csharp
public RailMountMode RailMountMode { get; set; }
public RailPayloadAnchorMode RailPayloadAnchorMode { get; set; }
public RailPathDefinitionMode RailPathDefinitionMode { get; set; }
public double RailHeadToPayloadAnchorOffset { get; set; }
public double RailGaugeCenterOffset { get; set; }
```

说明：

- `RailHeadToPayloadAnchorOffset`
  - 安装头中心到构件对接中心的距离
  - 使用模型单位
  - 用于精确表达安装头结构厚度和连接件高度
- `RailGaugeCenterOffset`
  - 双轨中心线到安装头中心线的附加偏移
  - 默认通常为 `0`
  - 为后续非对称安装场景留扩展位

## 局部坐标系

每一段 Rail 路径在采样时建立局部坐标系：

- `T`：沿轨道方向的单位向量
- `N`：轨道平面法向，用于区分轨上 / 轨下
- `B`：横向向量，满足右手系

建议约束：

- 双轨所在平面由轨道主方向和全局竖直方向共同确定
- 当轨道接近竖直时，仍应优先走显式异常，而不是隐式回退

构件实际锚点位置：

```text
PayloadAnchorPosition = RailReferencePoint + sign(mountMode) * N * offset
```

其中：

- `sign(UnderRail) = -1`
- `sign(OverRail) = +1`

构件几何中心再根据 `TopCenter` / `BottomCenter` 与物体高度换算得到。

## 参考路径定义

### 旧逻辑

当前 `RailGeometryHelper` 输出的是：

- 空轨下表面中心线

### 新逻辑

建议升级为输出：

- 双轨中间的安装头参考中心线

实现上分两层：

1. `ExtractRailReferencePath`
   - 负责提取轨道导向参考线
2. `ResolvePayloadPath`
   - 根据安装构型计算构件实际运动参考路径

## 兼容策略

### 历史路径

旧路径未包含 `RailMountMode`、`RailPayloadAnchorMode` 等信息时，按以下默认值兼容：

```text
RailMountMode = UnderRail
RailPayloadAnchorMode = TopCenter
RailPathDefinitionMode = LegacyBottomCenterLine
RailHeadToPayloadAnchorOffset = 0
RailGaugeCenterOffset = 0
```

兼容语义：

- 保持旧项目行为尽量不变
- 旧路径仍按“轨下悬挂”解释

### 新路径

新创建的 Rail 路径统一采用：

```text
RailPathDefinitionMode = InstallationHeadCenterLine
```

## 需要修改的模块

### 1. 模型层

文件：

- `src/Core/PathPlanningModels.cs`
- `src/Commands/CreateAerialPathCommand.cs`

工作：

- 增加 Rail 相关枚举
- 为 `PathRoute` 增加 Rail 构型字段
- 新建 Rail 路径时写入默认配置

### 2. Rail 几何提取

文件：

- `src/PathPlanning/RailGeometryHelper.cs`

工作：

- 将“下表面中心线”抽象为“参考路径提取”
- 区分旧路径提取和新路径提取
- 为双轨场景预留“轨道中心参考线”提取接口

### 3. 交互吸附

文件：

- `src/Core/PathPlanningManager.cs`
- `src/UI/WPF/ViewModels/PathEditingViewModel.cs`

工作：

- 用户点击继续吸附到 Rail 参考路径
- 新建 Rail 路径时允许指定安装构型

### 4. 渲染

文件：

- `src/Core/PathPointRenderPlugin.cs`

工作：

- 将 `PathType.Rail` 的固定“向上/向下 Z 偏移”改为局部法向偏移
- 通行空间不再假定路径点永远位于物体顶部

### 5. 动画

文件：

- `src/Core/Animation/PathAnimationManager.cs`

工作：

- 将 Rail 路径下的构件位置计算改为：
  - 先得到安装头参考点
  - 再根据 `RailMountMode` 和 `RailPayloadAnchorMode` 推导物体位置
- 后续增加 pitch/roll 对齐能力

### 6. 导出

文件：

- `src/Core/PathDataManager.cs`

工作：

- 将 `suspension` 语义调整为更中性的 rail-guided aerial path
- 视下游格式能力决定是否补充导出字段

## 分阶段实现建议

### Phase 1：最小可用版本

目标：先支持 4 种构型的碰撞检测和动画位置正确。

范围：

- 增加 Rail 构型字段
- Rail 动画和通行空间偏移改为基于安装构型计算
- 继续沿用现有参考线提取，但将其抽象为“参考路径”

限制：

- 暂不处理完整 pitch/roll 姿态
- 暂不精确重建双轨实体几何关系

### Phase 2：几何语义升级

目标：把参考路径从“轨下中心线”升级为“安装头中心线”。

范围：

- 重构 `RailGeometryHelper`
- 为双轨模型提取真正的中线
- 新旧路径分别兼容

### Phase 3：姿态精化

目标：对斜轨和长臂构件提供更真实的空间姿态。

范围：

- 动画支持 pitch / roll
- 构件包络与局部坐标系一致
- 提升碰撞检测准确性

## 当前建议

本次开发先从 Phase 1 开始：

1. 先把路径模型改为可表达 4 种构型
2. 先把渲染和动画从“世界 Z 偏移”改成“构型驱动偏移”
3. 再进入轨道参考线提取的升级

这样风险更低，也更容易验证。
