# TrapMap 分层建图修订设计

## 目标

修正 `MovementTest.Trapmaptest.cs` 中“必须先检测到轮胎才能建立地图”的依赖倒置，并将随车固定窗口改为任务级世界坐标栅格。基础地图只依赖合法的车辆位姿、车辆尺寸、工作站世界坐标和地图参数；轮胎检测是可选障碍物输入，不再决定地图是否存在。

本次仍是一次性地图测试，不扩展 `TrajPlanner`，也不引入尚不存在的通用障碍物点云接口。该地图覆盖当前车辆到目标工作站的任务范围，不宣称覆盖整个停车场的永久 SLAM 全局地图。

## 地图范围

目标工作站使用与 `DetourInterface.getCartLocation()` 完全相同的绝对世界坐标系，单位为 mm。第一版默认可调参数为：

- `WorkstationX = 10000 mm`
- `WorkstationY = 0 mm`
- `MapMarginX = 3000 mm`
- `MapMarginY = 3000 mm`

读取车辆几何中心 `(CarX, CarY)` 后，地图边界按以下方式计算：

```text
XMin = min(CarX, WorkstationX) - MapMarginX
XMax = max(CarX, WorkstationX) + MapMarginX
YMin = min(CarY, WorkstationY) - MapMarginY
YMax = max(CarY, WorkstationY) + MapMarginY
```

工作站坐标和 X/Y 冗余必须可配置，不能继续用一个随车半边长参数控制地图。边界采用世界坐标轴对齐矩形，保证车辆点、工作站点及四周冗余都在地图内。

实现必须校验坐标、冗余、计算后的边界、行列数与总栅格数量，拒绝非有限值、负冗余、退化边界和可能造成异常内存分配的超大地图。

## 分层模型

地图按职责分为以下逻辑层：

1. 基础层：按车辆—工作站包围矩形及 X/Y 冗余创建任务级世界坐标栅格，当前所有单元初始化为 `Free`。
2. 自车层：按照车辆长度、宽度、朝向标记本车占用区域。
3. 目标层：记录并可视化工作站位置；目标点不是障碍物，不写入占用栅格。
4. 轮胎层：调用现有 `TwoLegDetect`，成功时将两个端点转换至世界坐标并膨胀为占用栅格。
5. 点云障碍层：仅作为未来扩展边界，本次不实现、不虚构输入来源。

当前 `Free` 的准确含义是“此栅格没有被本次已接入的占用来源标记”，并不表示传感器已经确认该区域不存在其他障碍物。代码注释必须明确这一限制，以便未来引入点云及 `Unknown` 状态。

## 数据流与执行顺序

1. 校验地图分辨率、工作站坐标、X/Y 冗余及车辆尺寸。
2. 从 `DetourInterface.getCartLocation()` 读取车辆世界位姿。
3. 根据车辆点和工作站点计算包围矩形，校验最终尺寸和栅格总量。
4. 立即创建任务级世界坐标栅格地图。
5. 标记自车占用层并记录工作站目标层。
6. 尝试读取轮胎检测结果：
   - 检测成功：转换并标记两个轮胎端点。
   - 未检测到目标：轮胎层保持为空，地图仍然成功。
   - 配置缺失、检测异常或坐标非法：轮胎层保持为空，地图仍然成功，但记录降级状态和具体原因。
7. 可视化并发布地图，同时输出边界、工作站、各层状态和统计信息。

地图的创建和发布不再等待轮胎输入。轮胎检测只影响轮胎层内容和传感器状态。

## 状态与错误语义

以下情况属于建图失败，不能发布地图：

- 地图分辨率、范围或安全距离非法。
- 工作站世界坐标或 X/Y 冗余非法。
- 计算后的行列数或总栅格数量超过安全上限。
- 车辆长度或宽度非法。
- 车辆世界位姿不是有限值。
- 基础地图创建、必要的自车标记或结果发布失败。

以下情况属于轮胎层降级，不导致建图失败：

- 未配置轮胎检测雷达。
- `TwoLegDetect` 没有检测到目标。
- 检测调用抛出异常。
- 返回的端点或转换后的世界坐标非法。

输出应区分：

- `Succeeded`：基础地图是否成功生成。
- `InputSource`：本次实际启用的障碍来源。
- 轮胎层状态：已标记、未检测到或检测异常。
- 轮胎层状态说明：未标记或异常的具体原因。

“未检测到目标”与“检测器异常”都产生空轮胎层，但日志语义不能混同：前者表示本次没有轮胎投影，后者表示轮胎信息不可用。

## 数据结构边界

本次可以继续使用最终合并后的 `GridMapData.Cells`，无需提前实现完整的多层栅格容器。分层通过独立的填充步骤、来源状态和统计实现，避免为尚未接入的点云设计过度复杂的数据模型。

未来点云接入时，应新增独立的点云转换/栅格化步骤，再合并到最终占用结果；不得把原始点云读取逻辑塞入轮胎检测函数。

## 测试要求

至少覆盖以下行为：

1. 位姿、工作站和地图参数合法、轮胎检测无目标时，地图成功且轮胎障碍数为零。
2. 轮胎检测配置缺失或调用异常时，地图仍成功，并记录降级原因。
3. 轮胎检测成功时，两个端点被转换并投影为占用栅格。
4. 边界严格由车辆点、工作站点及各轴冗余计算，并同时包含两个点。
5. 工作站可视化但不增加占用栅格数量。
6. 位姿、工作站、冗余、地图参数或总栅格数量非法时，地图失败且不发布半成品。
7. 源码契约确认建图发生在轮胎检测之前，且不存在实车模式模拟障碍回退。
8. 注释明确当前 `Free` 不等于传感器确认无障碍，并标明未来点云/`Unknown` 扩展方向。

## 非目标

- 不实现持续更新或历史地图融合。
- 不读取或声称生成完整停车场 SLAM 静态地图；本次“全局”仅指车辆和工作站共享的世界坐标任务范围。
- 不接入未经现有代码验证的点云 API。
- 不修改或展开 `TrajPlanner`。
- 不发送车辆运动或停止指令。
