295 lines
18 KiB
Markdown
295 lines
18 KiB
Markdown
# EM 轨迹闭环观察与独立网页可视化设计
|
||
|
||
## 1. 背景与目标
|
||
|
||
现有 `TrajectoryObservationMovementTest` 从 MDCS 读取实时定位和带符号纵向速度,重复执行 EM 规划并显示最新轨迹。它是规划观察闭环,不向底盘、转向、电机、制动或档位接口发送命令。
|
||
|
||
EMPlanner 已修正两类纵向滚动规划语义:
|
||
|
||
1. `RollingContinuation` 的滚动视界末点不再被强制当作静止停车点。
|
||
2. jerk 变量只对应真实相邻时间节点之间的区间,不为滚动轨迹最后一个点之后不存在的后继点施加或展示虚假的 jerk 约束。
|
||
|
||
本次工作修改 MovementTest 观察任务,使实车环境可以直接验证这些语义;同时新增可复用、可独立升级的本机网页可视化类库。网页提供全局路径、方向分段、LS、ST、曲率、速度、加速度、加加速度、规划配置及周期历史。现有测试继续保持 `OBSERVE_ONLY`。
|
||
|
||
## 2. 范围与非目标
|
||
|
||
### 2.1 范围
|
||
|
||
- 保持实车定位/速度输入和滚动重规划,不增加任何车辆控制输出。
|
||
- 支持完整多方向段观察,在可靠确认车辆实际运动方向后顺序推进至下一段。
|
||
- 在鸟瞰图中显示完整全局路径,并高亮当前 EM 规划方向段及本轮时域覆盖区间。
|
||
- 增加独立 `TrajectoryPlanningVisualization` 类库,供当前及未来规划测试复用。
|
||
- 提供只监听本机回环地址的实时网页看板。
|
||
- 保留原生 Painter 作为显式可选的兼容显示方式。
|
||
- 保留用户已调整的 MovementTest 默认运行参数,并同步设置对象、测试与文档:
|
||
- `SolverTimeoutSeconds = 5.0 s`
|
||
- `MaximumOsqpIterations = 100000`
|
||
- `TimeHorizonSeconds = 2.0 s`
|
||
- `OutputTimeStepSeconds = 0.10 s`
|
||
|
||
### 2.2 非目标
|
||
|
||
- 不实现轨迹跟踪、档位控制、底盘写入或自动驾驶闭环。
|
||
- 不开放局域网或公网访问。
|
||
- 不用网页按钮强制切换方向段。
|
||
- 不记录无限历史,不默认写入磁盘,不实现实验回放文件格式。
|
||
- 不修改 EMPlanner 的约束、权重、容差或已确认的滚动规划语义。
|
||
|
||
## 3. 总体架构
|
||
|
||
新增独立类库:
|
||
|
||
```text
|
||
ClumsyPilot/TrajectoryPlanningVisualization/
|
||
├── TrajectoryPlanningVisualization.csproj
|
||
├── Contracts/ # 不可变快照、曲线、配置和状态 DTO
|
||
├── Runtime/ # 回环 HTTP/SSE 服务、最新帧和有界历史
|
||
└── Web/ # 内嵌 HTML/CSS/JavaScript 科研风前端
|
||
```
|
||
|
||
现有观察模块新增 EM 适配层:
|
||
|
||
```text
|
||
ClumsyPilot/ParkrobTrajplanner/tarjplanner_movementtest/
|
||
├── TrajectoryObservationVisualizationAdapter.cs
|
||
├── TrajectoryObservationSegmentTracker.cs
|
||
└── 现有 MovementTest、Pipeline、Contracts、Diagnostics、Presentation
|
||
```
|
||
|
||
依赖方向固定为:
|
||
|
||
```text
|
||
EM / Map / PathSmoothing / MovementTest
|
||
│
|
||
▼
|
||
TrajectoryObservationVisualizationAdapter
|
||
│ 只发布通用不可变快照
|
||
▼
|
||
TrajectoryPlanningVisualization
|
||
│
|
||
▼
|
||
localhost browser
|
||
```
|
||
|
||
可视化类库不得引用 EMPlanner、MDCS、ClumsyCore、Painter 或 MovementTest。MovementTest 负责生命周期和浏览器打开行为;类库只返回本机访问 URI。
|
||
|
||
主项目通过 `ProjectReference` 引用新类库,并排除对子项目源码的重复编译。插件发布流程必须包含新增程序集及其必要依赖。网页资源作为程序集嵌入资源发布,不依赖 CDN、Node.js 或外网。
|
||
|
||
类库和主项目均继续以 `netstandard2.0` 为目标框架并使用 C# 10。JSON 使用仓库现有的 `Newtonsoft.Json 13.0.4`;不引入 ASP.NET Core、Kestrel 或新的前端包。由于 Windows `HttpListener` 可能要求额外的 HTTP.sys URL ACL,运行时使用 `TcpListener(IPAddress.Loopback, port)` 实现本功能所需的受限 HTTP/1.1 GET 与 SSE 子集,不依赖管理员预注册。
|
||
|
||
## 4. 可视化类库公共边界
|
||
|
||
类库只暴露三个主要生命周期操作:
|
||
|
||
```csharp
|
||
visualization.Start(options);
|
||
visualization.Publish(snapshot);
|
||
visualization.Stop();
|
||
```
|
||
|
||
`Start` 返回包含随机会话令牌的完整本机 URI。`Publish` 必须是非阻塞操作:用原子替换保存最新不可变快照,不等待序列化、网络、浏览器或绘图。`Stop` 取消服务任务、关闭连接并释放端口;重复调用安全。
|
||
|
||
快照分为两类:
|
||
|
||
- 静态快照:地图边界、障碍物、全局粗路径、Local G2 路径、全部方向段、换向点和冻结后的生效配置。每次会话只生成并传输一次。
|
||
- 动态快照:实车状态、当前段、当前/上一轮轨迹、当前采样点、本轮规划结果、交接指标和诊断摘要。
|
||
|
||
服务只绑定 `127.0.0.1`。页面和事件接口均校验随机会话令牌。服务最多接受两个浏览器客户端,额外连接被拒绝。前端静态资源通过普通 HTTP 获取,动态帧通过 Server-Sent Events 发送;客户端断开或读取缓慢时丢弃旧帧,不对发布者形成反压。请求解析器只接受 `GET`,请求头上限为 `16 KiB`,首行/请求头读取超时为 `2 s`;其他方法返回 `405`,未知路径返回 `404`,令牌错误返回 `403`。
|
||
|
||
## 5. 资源与性能约束
|
||
|
||
- 默认网页刷新率为 `10 Hz`,与 `ObserverPeriodSeconds` 解耦。
|
||
- 最新动态帧容量固定为 `1`;新帧覆盖旧帧。
|
||
- 只保留当前轮和上一轮的完整轨迹点。
|
||
- 周期历史默认保留最近 `60` 轮,历史项只含摘要,不含完整轨迹。
|
||
- 地图占用信息、全局路径、方向段和配置不进入重复动态帧。
|
||
- 地图占用栅格编码为行优先 bitset(每格 `1 bit`)并由浏览器单个 Canvas 绘制;不得为每个占用格创建 JSON 对象、SVG 节点或 Painter 对象。
|
||
- 没有浏览器客户端时不重复序列化相同动态帧。
|
||
- 网页关闭或变慢不能改变重规划周期、求解器超时或规划结果。
|
||
- `EnableWebVisualization=false` 时不启动服务、不创建网页快照或历史缓冲。
|
||
- 任何网页服务、快照转换或前端异常均被隔离:记录一次中文诊断并关闭本次网页输出,规划观察继续运行。
|
||
|
||
## 6. MovementTest 配置
|
||
|
||
新增公开字段:
|
||
|
||
```text
|
||
EnableWebVisualization = false
|
||
AutoOpenWebVisualization = true
|
||
WebVisualizationPort = 0
|
||
WebRefreshRateHz = 10
|
||
VisualizationHistoryCycleLimit = 60
|
||
EnableNativePainterVisualization = false
|
||
DirectionConfirmationSpeedMetersPerSecond = 0.02
|
||
DirectionConfirmationSamples = 3
|
||
GearSwitchProjectionToleranceMeters = 0.50
|
||
GearSwitchStopHoldSeconds = 0.20
|
||
```
|
||
|
||
校验规则:开关字段不需数值校验;端口为 `0` 或 `1024..65535`;刷新率、历史容量、速度阈值、投影容差和等待时间必须为有限正值;连续确认样本数必须为正整数。
|
||
|
||
端口为 `0` 时选择空闲回环端口。启动成功后,完整带令牌 URI 同时写入 MDCS UI 状态和控制台;`AutoOpenWebVisualization=true` 时由 MovementTest 尝试打开默认浏览器。打开失败只报告地址,不中止观察。
|
||
|
||
原生 Painter 与网页独立控制。`EnableNativePainterVisualization=false` 时不取得或刷新 World、LS、ST Painter,避免与浏览器重复绘图。两种显示都关闭时,规划循环和控制台诊断仍工作。
|
||
|
||
自动打开浏览器只由 MovementTest 主机调用 `Process.Start`,类库本身不读取桌面环境或启动外部进程。该调用必须捕获异常;Windows 服务会话或无桌面环境中只打印完整 URI。
|
||
|
||
## 7. 多方向段观察状态机
|
||
|
||
现有硬编码 `segmentIndex = 0` 改为只允许顺序前进的活动段状态机。
|
||
|
||
### 7.1 正常规划
|
||
|
||
- 活动段初始为第 `0` 段。
|
||
- 每轮请求使用活动段索引、方向及同段上一条已发布轨迹。
|
||
- 只有同一 `SegmentIndex` 和 `TravelDirection` 的上一条轨迹可以作为软参考。
|
||
- 网页与原生 Painter 均从同一个活动段状态读取高亮和 LS/ST 投影对象。
|
||
|
||
### 7.2 换向确认
|
||
|
||
到达 `GearSwitchApproach` 后:
|
||
|
||
1. 车辆位姿必须能在 `GearSwitchProjectionToleranceMeters` 内投影到换向点邻域。
|
||
2. 带符号实际速度绝对值必须不超过 EM 生效配置的 `StopSpeedToleranceMetersPerSecond`,并持续至少 `GearSwitchStopHoldSeconds`。
|
||
3. 状态机进入“等待下一方向实际运动”状态。
|
||
4. 随后实际速度绝对值必须至少为 `DirectionConfirmationSpeedMetersPerSecond`,符号与下一段一致,且车辆可投影到下一段起始区域。
|
||
5. 条件连续满足 `DirectionConfirmationSamples` 次后,活动段从 `N` 切换到 `N+1`。
|
||
|
||
零速时方向不明确,状态机保持原段;瞬时反号、位置不匹配、丢失定位或不连续样本都会清零确认计数。状态机不得跳段、自动回退或跨越两个换向点。
|
||
|
||
切段时创建新的分段规划协调状态,清除可执行的旧段发布轨迹;旧轨迹仅作为网页历史证据保留,不传入新段 EM 请求。新段首次规划前网页显示“已确认换向,等待下一段首条轨迹”。
|
||
|
||
## 8. 网页信息架构与视觉规范
|
||
|
||
界面采用已确认的科研绘图风:纯白背景、浅灰细网格、细坐标轴、`0.8–1.2 px` 曲线、低饱和语义色和论文式多子图。当前轨迹为蓝色实线,上一轮为灰色虚线,交接点和换向点为橙色,红色只表示真实越界或失败。
|
||
|
||
页面说明、状态、告警、按钮和配置名称使用中文。坐标变量、单位和数学符号保留领域惯例,例如 `s (m)`、`t (s)`、`κ (m⁻¹)`、`v (m/s)`、`a (m/s²)`、`j (m/s³)`。
|
||
|
||
### 8.1 路径总览
|
||
|
||
- 地图、障碍物、粗路径、完整 Local G2 全局路径和实车位姿。
|
||
- 已完成方向段为灰色细实线,当前段为蓝色细实线,未来方向段为浅灰虚线。
|
||
- 换向点使用带顺序编号的橙色菱形。
|
||
- 当前 EM 距离/时间视界实际覆盖区间使用更深蓝色叠加。
|
||
- 当前和上一轮 EM 轨迹叠加,并以橙色标出绝对时间交接位置。
|
||
- 显示活动 `SegmentIndex`、前进/倒车方向、纵向模式、终端类型、规划耗时和轨迹年龄。
|
||
|
||
### 8.2 LS / ST
|
||
|
||
- `l(s_ref)`:将当前已发布 EM 轨迹投影到完整活动方向段后,横向偏移随共享方向段 `ReferenceS` 的变化。
|
||
- `PathS(t)`:当前规划时域内的实际局部 `PathS` 随 `TimeFromStart` 的变化,这是 ST 求解结果使用的坐标。
|
||
- 两类横轴必须使用不同标签,网页不得把方向段 `ReferenceS` 与每轮从局部起点累计的 `PathS` 混为一谈。
|
||
- 标明方向段索引、方向、边界类型和投影失败数。
|
||
- LS/ST 只展示当前活动方向段,不跨换向边界拼接。
|
||
|
||
### 8.3 曲率与运动学
|
||
|
||
- `κ(s)` 与 `κ(t)`。
|
||
- `v(t)`、`a(t)`、`j(t)` 与 `yaw rate(t)`。
|
||
- 对应生效限制以细虚线绘制。
|
||
- `j[i]` 表示真实区间 `[tᵢ,tᵢ₊₁)`;jerk 曲线点数严格为轨迹点数减一。最后一个轨迹点不绘制伪造的 `j=0`,而标注“末点后无时间区间”。
|
||
- 同图展示实际带符号车速与当前选中轨迹点速度。
|
||
|
||
纵向加速度与 jerk 由当前主程序集内的 EM Adapter 读取 `EmTrajectoryPoint` 的现有内部字段并转换成通用曲线 DTO;不为可视化修改 EMPlanner 的公共契约。
|
||
|
||
### 8.4 周期历史
|
||
|
||
最近 `VisualizationHistoryCycleLimit` 个周期展示:周期号、时间、成功/失败、是否发布、规划耗时、段索引、方向、纵向模式、终端类型、末端速度、末端加速度和失败原因摘要。
|
||
|
||
### 8.5 生效配置
|
||
|
||
配置页只展示本次冻结后真正传给规划器的值,不读取启动后的可编辑字段。每个条目包含中文名称、原始字段名、数值和单位:
|
||
|
||
- 调度:重规划周期、ST 时域、输出步长、距离视界、求解超时、交接前视时间和状态最大年龄。
|
||
- OSQP:最大外层迭代、最大 OSQP 迭代、绝对/相对/严格残差容差、warm start、polish 和 native verbose。
|
||
- 车辆与安全:长、宽、安全余量、最大曲率或最小转弯半径。
|
||
- 纵向限制与权重:前进/倒车速度、加速度、减速度、jerk、横向加速度、曲率变化率、停车速度容差、零速保持时间及全部 ST 权重。
|
||
- 横向限制、走廊参数和全部 LS 权重。
|
||
- 地图边界、分辨率、障碍物数量和快照版本。
|
||
- 当前地图、参考路径、车辆状态、当前轨迹和上一轨迹 ID。
|
||
- 可视化刷新、历史容量和换向确认参数。
|
||
|
||
## 9. 滚动规划专项诊断
|
||
|
||
网页必须把规划语义与数值结果分开显示:
|
||
|
||
- `RollingContinuation` 或 `ApproachStopBoundary`:显示“滚动末端停车硬约束:未启用”,并展示实际末端 `v/a`。滚动末速为零不单独判定失败,因为车辆状态或最优结果仍可能产生零速;关键证据是纵向模式没有启用精确停车约束。
|
||
- `ExactStopAtBoundary`:显示真实 Goal 或 GearSwitch 停车锚点、稳定段起点和零速稳定区间。
|
||
- jerk 图只显示真实区间,末点显示“不适用”,避免把缺失的末端后继区间解释为加加速度约束。
|
||
- 当前轮和上一轮按 `EffectiveAtUtc + TimeFromStart` 对齐,在交接时刻插值并展示世界坐标 `Δposition`、共享方向段上的 `ΔReferenceS`、`Δv` 和 `Δa`。不得直接比较两轮各自从局部起点累计的 `PathS`;任一轨迹无法投影到共享方向段时,`ΔReferenceS` 显示“不可用”。
|
||
- 交接指标仅作为观察诊断,不改变规划、发布或执行状态。
|
||
|
||
## 10. 错误处理与状态显示
|
||
|
||
- 可视化启动失败:记录一次中文错误,规划观察继续。
|
||
- 快照中单个字段不可用:对应值显示“不可用”,其他图继续刷新。
|
||
- 浏览器超过两个预期刷新周期没有收到新帧:显示“数据已过期”及最后时间戳,不把旧值伪装成实时状态。
|
||
- 换向确认失败:保持当前段,显示位置、停车保持、速度方向或连续样本中未满足的条件。
|
||
- EM 新周期失败:保留上一条成功轨迹,醒目显示本轮状态与未改写的原始失败原因。
|
||
- 服务或快照转换异常:本次网页输出熔断关闭,不自动循环重启。浏览器前端异常只在该标签页显示“页面绘图异常”并停止该页重绘;由于服务只接受 GET 且页面没有反向控制通道,前端异常不通知或关闭主进程服务,规划继续且服务器最终由 `TestStop()` 回收。
|
||
- `TestStop()`:取消规划观察、停止发布、关闭 HTTP/SSE、释放端口;仍连接的页面显示“会话已结束”。
|
||
|
||
## 11. 测试策略
|
||
|
||
### 11.1 独立可视化类库
|
||
|
||
新增独立验证宿主,覆盖:
|
||
|
||
- 类库不引用 MDCS、ClumsyCore、Painter 或 EMPlanner。
|
||
- 快照不可变与 JSON 序列化稳定。
|
||
- `Publish` 非阻塞且最新帧容量为 `1`。
|
||
- 历史严格受容量限制。
|
||
- 服务只监听回环地址并校验令牌。
|
||
- 原始 TCP HTTP 解析器拒绝超大请求头、非 GET 方法、未知路径和错误令牌。
|
||
- 慢客户端不阻塞发布者。
|
||
- 静态快照不重复进入动态帧。
|
||
- 启停、重复停止和端口释放。
|
||
- 内嵌页面包含中文说明、科研坐标单位和所有必需页签。
|
||
|
||
### 11.2 EM Adapter 与观察任务
|
||
|
||
扩展 `EMPlannerVerificationHost` 的 `trajectory-observation` 检查:
|
||
|
||
- 生效配置来自冻结快照,并包含本节规定的全部参数组。
|
||
- MovementTest、settings 默认值和 README 对 `5.0 s / 100000 / 2.0 s / 0.10 s` 保持一致。
|
||
- rolling、approach、exact-stop 三种模式映射正确。
|
||
- jerk 区间数等于轨迹点数减一,末点没有伪造区间。
|
||
- 当前/上一轮绝对时间对齐和 `Δposition/ΔReferenceS/Δv/Δa` 计算正确,且不直接比较两轮局部 `PathS`。
|
||
- 多方向路径完整输出,活动段和当前视界高亮。
|
||
- 换向状态机必须满足位置、停车保持和连续方向样本才顺序推进。
|
||
- 切段后不复用旧方向段轨迹。
|
||
- 可视化关闭时不启动服务或构造快照。
|
||
- 网页异常不会终止观察循环。
|
||
- 源码审计继续确认没有底盘写方法。
|
||
|
||
### 11.3 集成与实车验收
|
||
|
||
运行:
|
||
|
||
```powershell
|
||
dotnet run --project ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/TrajectoryPlanningVisualizationVerificationHost.csproj
|
||
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- trajectory-observation
|
||
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-all
|
||
dotnet build ClumsyPilot/ClumsyPilot.csproj -p:ExcludeLegacyAutoAvoidance=true
|
||
```
|
||
|
||
实车观察清单:
|
||
|
||
1. 开启网页、关闭原生 Painter,确认页面地址、令牌和中文科研风界面。
|
||
2. 确认全局路径所有方向段可见,当前段和本轮规划视界高亮。
|
||
3. 观察 `RollingContinuation -> ApproachStopBoundary -> ExactStopAtBoundary`,确认滚动末点未显示停车硬约束。
|
||
4. 确认 `j(t)` 最后一个区间结束于最后一个轨迹点之前,不出现虚假 point-21 后继区间或 `JerkLimitExceeded`。
|
||
5. 在真实换向场景确认状态机先等待停车,再以连续实际运动方向样本推进至下一段。
|
||
6. 断开或关闭浏览器,确认规划周期和耗时无异常变化。
|
||
7. 停止 MovementTest,确认服务退出、端口释放且无底盘命令。
|
||
|
||
## 12. 完成标准
|
||
|
||
- 独立类库、EM Adapter、多段观察和网页看板均按上述边界实现。
|
||
- 所有自动化验证通过,主项目构建成功。
|
||
- 页面使用中文说明和科研绘图规范,数学符号与单位准确。
|
||
- 滚动末端语义、jerk 区间语义和换向分段高亮均能由页面直接观察。
|
||
- 可视化关闭或失败时不改变 EM 规划行为。
|
||
- 源码和运行时证据均证明 `OBSERVE_ONLY` 不变。
|
||
- 插件包包含 `ClumsyPilot.dll`、`TrajectoryPlanningVisualization.dll`、固定 OSQP 运行时及许可证,且没有遗漏新增托管依赖。
|