Files
ParkingRobot/docs/superpowers/specs/2026-07-22-trap-map-image-and-console-design.md
T

112 lines
5.3 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.
# TrapMap完整图片导出与终端日志开关设计
## 目标
`MovementTest.Trapmaptest.cs`增加两个相互独立的测试开关:
- 成功建图后,将完整栅格地图独立渲染为300 DPI PNG,不依赖Clumsy当前视口、缩放或其他Painter。
- 控制TrapMap调试信息是否同步打印到宿主进程终端,同时始终保留`DLog`日志。
现有`TrapMapTest` Painter初始化和清理已经使用世界坐标调用`UI.GetPainter("TrapMapTest")`,本次不重复修改。两腿检测ROI继续使用车体局部Painter及`false`参数。
## 用户开关与默认值
`TrapMapTest`手动编辑区增加:
```csharp
private const bool _saveFullMapImage = true;
private const bool _enableTerminalDebugLog = true;
```
两个值传入`TrapMapBuilder`或共享日志/导出组件。关闭图片开关时不得创建目录、临时文件或PNG。关闭终端开关时只抑制`Console.WriteLine`,不得抑制`DLog`和必要的UI提示。
## 图片内容
图片从最终发布的`GridMapData`离屏渲染,包含完整地图边界而不是屏幕截图:
- 白色背景。
- 浅灰色完整栅格线,确保每个小格可见。
- 红色占用栅格。
- 蓝色车辆轮廓、几何中心和朝向。
- 绿色工作站目标标记。
- 黑色地图外边界。
- 标题/图例区域,显示世界边界、分辨率、行列数、占据率、障碍物数量、轮胎层状态和输入来源。
世界X轴在图片中向右;世界Y轴向上,因此从`Cells[row,col]`映射到位图时反转图像Y方向。工作站仅绘制标记,不写入占用数据。
## 图片尺寸与文件约束
- 每个栅格使用`4×4`像素。
- PNG水平和垂直DPI都设置为`300`
- 包含边距和标题后,任一图片边长不得超过`4000`像素。
- 最终PNG文件大小不得超过`50 * 1024 * 1024`字节。
尺寸在分配RGBA像素缓冲区前检查。若超过4000像素,跳过导出并报告明确原因。编码先写入同目录临时文件,完成后检查实际字节数;超过50MB时删除临时文件,不留下超限最终文件。只有所有检查通过后,才原子移动/重命名为最终PNG。
典型`327×139`地图的栅格主体约为`1308×556`像素,另加标题和边距。
## 保存位置与命名
输出根目录使用宿主进程当前工作目录:
```text
TrapMapExports\TrapMap_yyyyMMdd_HHmmss_fff.png
```
毫秒时间戳避免同一秒多次测试覆盖。目录只在图片开关打开且地图成功后创建。临时文件使用同目录、同文件名加`.tmp`后缀,以保证最终重命名不跨磁盘。
## 日志行为
引入TrapMap专用日志入口,其行为为:
```text
所有消息 -> DLog.Log(message, "TrapMapTest")
终端开关开启 -> 额外Console.WriteLine("[TrapMapTest] " + message)
```
至少覆盖测试开始、输入参数、Detour位姿、车辆尺寸、地图边界/尺寸、轮胎层状态、图片保存成功/跳过/失败、最终统计和测试停止。图片错误不得因终端开关关闭而静默,仍必须进入`DLog`
## 组件边界
图片导出放在独立文件`ClumsyPilot/TrapMapImageExporter.cs`,避免继续扩大已经较长的MovementTest文件。组件只消费不可变的导出请求数据:地图、车辆位姿、工作站、轮胎层元数据和目标文件路径;它不读取Detour、雷达或UI,也不修改栅格。
`MovementTest.Trapmaptest.cs`负责开关、调用时机、日志和错误降级。导出发生在地图成功生成之后;导出失败不改变`TrapMapBuilder.Succeeded``GridMap`
实现使用内部纯C# RGBA光栅器绘制栅格、车辆、工作站和5×7位图文字,再由精确版本`StbImageWriteSharp` 1.16.7编码PNG。编码后立即在`IHDR`后插入`pHYs=11811/11811/unit1`,以保留300 DPI元数据。运行时不依赖平台绘图程序集或原生图形资产;除单个托管Stb编码程序集外,光栅、元数据和文件流程均只使用BCL。
## 错误处理
以下情况只导致图片导出失败,不导致建图失败:
- 图片开关关闭。
- 图片尺寸超过4000像素。
- 输出目录创建失败。
- RGBA缓冲区创建、绘制或PNG编码异常。
- 临时文件超过50MB。
- 临时文件重命名失败。
异常路径必须尽力删除本次临时文件,不得删除已有的成功PNG。
## 验证要求
至少验证:
1. 图片开关关闭时不创建文件和目录。
2. 小型已知栅格导出的PNG由BCL测试解码器重新读取;所有chunk CRC有效,`IHDR`为RGBA8`pHYs`表示300 DPI,像素尺寸符合4像素/格及布局规则。
3. PNG中占用格、车辆和工作站采样位置颜色正确,Y轴没有上下颠倒。
4. 超过4000像素的请求在RGBA缓冲区分配前失败。
5. 最终路径使用毫秒时间戳且不覆盖旧文件。
6. 成功文件严格小于或等于50MB,超限临时文件被删除。
7. 终端开关开启时消息同时进入DLog和终端;关闭时仍进入DLog但不写终端。
8. 图片失败时地图仍为成功状态。
9. 现有源码契约、栅格行为、生命周期测试及`ClumsyPilot`编译继续通过。
## 非目标
- 不截取Clumsy/CycleGUI窗口。
- 不保存紫色UI背景、小车3D模型、绿色两腿ROI或橙色检测猜测线。
- 不改变栅格数据格式或地图边界计算。
- 不接入新的点云来源。
- 不修改`TrajPlanner`
- 不提交或暂存本次工作区改动。