From c354f113060a5f95aa3b06c6f2b0be2d0c7d5da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E8=96=84=E4=BA=91?= Date: Thu, 6 Aug 2026 17:59:23 +0800 Subject: [PATCH] docs: design full-direction EM trajectory visualization repair --- ...ion-segment-visualization-repair-design.md | 282 ++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-06-em-full-direction-segment-visualization-repair-design.md diff --git a/docs/superpowers/specs/2026-08-06-em-full-direction-segment-visualization-repair-design.md b/docs/superpowers/specs/2026-08-06-em-full-direction-segment-visualization-repair-design.md new file mode 100644 index 0000000..78557e8 --- /dev/null +++ b/docs/superpowers/specs/2026-08-06-em-full-direction-segment-visualization-repair-design.md @@ -0,0 +1,282 @@ +# EM 完整方向段轨迹规划与观察界面定点修复设计 + +**日期:** 2026-08-06 + +**状态:** 已批准设计 + +**适用范围:** EM 轨迹规划、MovementTest 只读观察、Web 观察页面与 Native Painter 语义修正 + +## 1. 背景与问题定性 + +部署机的 MovementTest 观察证据同时暴露了规划端与显示端的真实问题,不能把所有异常归因为“绘图错了”: + +1. 静止起步时,纵向包络的种子速度直接取实车初速度。初速度为 `0` 时,全零 `PathS/v/a/j` 轨迹可满足当前不后退和上限约束,且目标函数没有足够的前进或巡航速度驱动。结果可被错误地标记为 `Success` 并发布。 +2. 旧模式同时暴露 `DistanceHorizonMeters` 和 `TimeHorizonSeconds`,操作者必须手动把两者调大才能“看到整段”。这两个值本质上是滚动视窗的截断参数,不应成为完整方向段的输入目标。 +3. 当前终点验证只检查了终端 `PathS`、速度、加速度和横摆角速度,没有验证世界坐标下的终点位置与 yaw。`yawRate = 0` 不等于终点朝向正确。 +4. Web 的分页隐藏状态被 CSS `display` 规则覆盖,因此“LS / ST”与“曲率与运动学”会同时显示,造成两个按钮内容相同的假象。 +5. Web 图表只生成 x 轴数值,y 轴网格没有对应数值刻度;单位、线型和图层语义也不够清晰。 +6. 路径总览里的粗路径、平滑路径、当前轨迹和 horizon 使用过于接近的线型,且动态构建器可以把同一条轨迹重复发布为两个图层,导致规划结果被遮挡或无法辨认。 +7. Native Painter 中显眼的大黑三角本质上是姿态的终端朝向箭头,尺寸与语义不匹配,会覆盖路径数据。 +8. 现有 Web 测试主要检查静态字符串,无法证明分页、SVG 刻度、图层和缩放交互真正在 DOM 中正确渲染。 + +因此,截图中水平的 ST 线不只是坐标轴问题:它很可能如实显示了一条被错误接受的零进度轨迹。本设计要分别修正轨迹生成、验证和可视化,不使用前端伪造运动数据。 + +## 2. 目标 + +### 2.1 规划目标 + +- 新增明确的 `FullDirectionSegment` 规划范围:以粗路径分割出的“当前完整方向段”为边界,一次得到该段的完整 LS 和 ST。 +- 静止起步时,若路径可行且尚未抵达终点,轨迹必须从 `v = 0` 自动加速,而不是用零速度填满整段。 +- 在曲率、加速度、减速度和 jerk 约束内尽快趋近期望巡航速度,并根据终点停车包络自动决定何时开始减速。 +- 完整方向段模式的 `s_end` 由 Local G2 平滑后实际路径的弧长决定,总时长 `T_end` 由该段的可行速度/停车包络决定。操作者不再手动输入一对可能相互矛盾的距离和时间窗口。 +- 终点必须同时满足进度、停车、世界位姿与朝向边界。 + +### 2.2 观察目标 + +- 保留现有四个 Web 分页和白底论文风格,只修复错误、缺失数据、坐标刻度、图层语义与局部查看能力。 +- 中文标题保持中文,数学符号保留 `S`、`s_end`、`κ`、`Δ`、`ω` 等标记。 +- 让粗路径、完整 Local G2 路径、当前方向段、当前完整轨迹、历史轨迹、车辆位姿、`s_end` 和换向点在语义上可区分。 +- 图表的缩放只改变观察视域,不改变、重采样或回写规划数据。 + +### 2.3 安全目标 + +- MovementTest 始终为 `OBSERVE_ONLY`,不产生底盘、转向、制动、电机或档位写输出。 +- 规划失败、零进度、终点不匹配或资源超限时,结果不得以 `Success` 发布。 + +## 3. 非目标 + +- 本阶段不实现动态障碍物重规划、执行中滚动精化或实车跟踪控制。 +- 不用一条轨迹跨越前进/后退换向边界。 +- 不把 Web 页面重做为新布局,不更换已批准的视觉风格,不用粗线、渐变或装饰性元素掩盖数据。 +- Native Painter 不做美化工程;只修正坐标、等比例、标记尺寸和语义。 +- 不通过增大手动 `DistanceHorizonMeters` / `TimeHorizonSeconds` 来伪装完整方向段模式。 +- 不在本阶段扩大修改到粗路径搜索、Local G2 算法重构或无关 UI 功能。 + +## 4. 规划范围与配置语义 + +### 4.1 独立的规划范围 + +引入显式的规划范围选择: + +- `RollingHorizon`:保留现有滚动视窗行为。`DistanceHorizonMeters` 和 `TimeHorizonSeconds` 只在此模式下表示当前局部视窗。 +- `FullDirectionSegment`:对粗路径的当前完整同向段做一次完整规划。此模式忽略旧的距离/时间视窗作为截断边界,而不是要求用户将它们设置为“足够大”。 + +MovementTest 的完整轨迹观察入口默认选择 `FullDirectionSegment`。旧的滚动模式保留为明确的兼容选项,不与新模式隐式混用。 + +`FullDirectionSegment` 在方向段激活时只规划一次,后续观察周期重复发布同一份冻结规划及新的观察状态,不根据每周期实时状态重做 ST。只有显式重启观察任务、当前方向段切换,或本次规划失败后由上层明确发起新请求,才能创建新的完整轨迹。“按实时状态滚动精化”留给后续独立阶段。 + +如果 MovementTest 在车辆已位于某方向段中部时启动,则以启动快照在该段 Local G2 路径上的最近合法投影作为 `s = 0`,一次规划剩余路径到真实方向边界。它不回到该段历史起点,也不穿过该段终点。 + +### 4.2 速度配置 + +此阶段采用以下可配置默认值: + +| 方向 | 期望巡航速度 | 硬速度上限 | +| --- | ---: | ---: | +| 前进 | `1.0 m/s` | `1.0 m/s` | +| 后退 | `0.5 m/s` | `0.5 m/s` | + +期望速度是优化目标,不是必须在任何路径上达到的硬下限。曲率、障碍物、加速度、减速度、jerk 和终点停车包络可以将可行速度降低。方向符号在发布轨迹时保留;包络计算可在方向段的正向弧长坐标中完成。 + +### 4.3 终端边界 + +对非空且尚未抵达的方向段,成功结果必须同时满足: + +- `PathS = s_end`,允许数值离散对应的小容差,但不允许提前截断后声称到达。 +- 终端 `v = 0`、`a = 0`、`ω = 0`,均按现有数值验证容差检查。 +- 终端世界位置与该方向段目标位置的欧氏距离不大于 `0.03 m`。 +- 终端 yaw 与该方向段目标 yaw 的归一化角度差不大于 `5°`。角度差必须归一化到 `[-π, π]`,避免 `+π/-π` 跨界时误判。 + +`s_end` 取自已选中的 Local G2 实际路径弧长,世界位姿目标取自当前方向段的真实边界姿态。两者必须指向同一个边界,不得一个来自粗路径全局终点,另一个来自局部截断点。 + +## 5. 完整方向段数据流 + +### 5.1 方向段分割 + +1. 粗路径按前进/后退符号的真实变化分割为方向段。 +2. 当前方向段的规划起点是方向段激活快照的真实起点或合法投影点,终点是下一个真实换向点;若不再换向,则是全路径终点。 +3. Local G2 在该完整方向段上建立连续 LS,其输出的实际弧长定义 `s_end`。 +4. ST 只使用该段的 `s ∈ [0, s_end]`,不会穿过换向点。 + +### 5.2 空间速度上限 + +对 LS 路径的每个有效位置建立空间速度上限,取以下限制的最小值: + +- 当前方向的硬速度上限; +- 由曲率和横向加速度上限推导的速度上限; +- 障碍物或安全规则产生的局部速度上限; +- 真实换向点或全路径终点的零速度边界。 + +终点停车不由固定的“提前几米”决定。算法从 `s_end` 反向传播可行减速/jerk 包络,得到每个 `s` 处为了最终停住而允许的最大速度。 + +### 5.3 静止起步与完整 ST + +纵向规划不再把“当前速度”当成“整段目标速度”。它必须区分: + +- 初始边界:来自实时状态的 `s0/v0/a0`; +- 巡航目标:当前方向的期望速度; +- 可行上限:空间速度上限与加速度/jerk 包络; +- 终端边界:`s_end/v=0/a=0`。 + +从初始状态正向传播起步可达包络,从终点反向传播停车可达包络,再与空间速度上限取交集。纵向优化目标跟踪该交集内的期望速度,并对无正当原因的零进度给予明确的前进代价。 + +`T_end` 是满足上述包络后走完 `s_end` 的结果,不是用户给定的强制到达时间。如果一条 5 m 路径按约束需要 7 s,则完整 ST 的结束时间约为 7 s;不会因为某个旧配置写着 2 s 就强制 2 s 到达,也不会因为写着 10 s 就在到达后虚构多余运动。 + +### 5.4 自适应优化网格与发布采样 + +“完整方向段”不等于“将整段按 0.1 s 全部塞进优化器”。优化结点和对外发布样本分离: + +- 优化网格覆盖完整 `[0, s_end]` / `[0, T_end]`,并在起步、减速、曲率上限变化、停车和换向边界附近自适应加密。 +- 发布层在优化成功后按已批准的时间分辨率(当前为 `0.1 s`)重采样,并强制包含精确终点样本。 +- jerk 定义在相邻轨迹点之间的 `N-1` 个时间区间上;终点之后不生成额外 jerk 点。 +- 自适应加密必须同时满足配置的最大空间步长、最大时间步长和边界变化误差。如果在配置的最大优化结点数内无法同时满足这些条件,则明确失败,不降级为截断轨迹。 + +这种分离保证用户看到的是完整 ST,同时避免优化问题的规模与展示样本数直接绑定。 + +## 6. 换向边界 + +每个方向段独立规划和发布: + +1. 当前 N 段的 `s_end` 是真实换向边界时,其终端必须连续停车,不得把 N+1 段接到同一条轨迹中。 +2. 沿用现有受监督的交接条件:连续停车保持,并且得到 3 个方向符号正确的速度样本后,才将观察高亮从 N 切换到 N+1。 +3. 等待期间,Web 和 Native Painter 必须明确显示“N+1 段交接条件未满足”,而不是预先显示下一段已激活。 +4. 条件满足后,以 N+1 方向段的初始状态进行新的一次完整规划。这不是对 N 段的滚动重规划。 + +## 7. Web 观察页面定点修复 + +### 7.1 结构与状态 + +- 保留“路径总览”、“LS / ST”、“曲率与运动学”、“周期历史与生效配置”四个现有分页。 +- 修正 CSS/DOM 隐藏规则,任一时刻只显示被选中分页的内容。 +- 路径总览没有可绘制数据时,在绘图区内显示具体缺失项(例如“未收到 Local G2 路径”),不留下无解释的大块空白。 +- 页面顶部、控制台和数据状态中继续明确显示 `OBSERVE_ONLY`。 + +### 7.2 坐标轴、刻度与单位 + +每张图同时绘制 x/y 两轴的数值刻度,刻度值由实际数据域生成,不使用与数据无关的固定范围。轴名与单位统一为: + +| 数据 | 轴标记 | +| --- | --- | +| 参考弧长 | `ReferenceS (m)` | +| 路径弧长 | `PathS (m)` | +| 时间 | `t (s)` | +| 横向偏移 | `l (m)` | +| 速度 | `v (m/s)` | +| 加速度 | `a (m/s²)` | +| 加加速度 | `j (m/s³)` | +| 曲率 | `κ (m⁻¹)` | +| 横摆角速度 | `ω (rad/s)` | + +零线、上下限和轨迹线使用不同线型,但线宽保持论文图表的纤细比例。当数据范围为常数时,在该值周围生成小而可读的对称范围,不将一条非零常数线误画成“看起来是零”。 + +### 7.3 路径总览图层 + +图层按以下顺序从底到顶绘制: + +1. 粗路径:浅灰、半透明、细虚线; +2. 完整 Local G2 路径:深灰、细实线; +3. 当前方向段:轻量蓝色高亮,不覆盖底层形状; +4. 前一条已发布轨迹:灰色细虚线; +5. 当前完整规划轨迹:蓝色细实线,置于路径线之上。 + +“当前轨迹”和“当前 horizon”不得在指向同一组样本时重复绘制。如果滚动模式真的同时存在完整轨迹和局部 horizon,才使用两个语义明确的不同图层。 + +车辆实时位姿使用按世界坐标等比例绘制的小车轮廓和细朝向线;计划起点使用独立的小型记号。两者均不得按固定大像素覆盖轨迹。 + +### 7.4 `s_end`、换向点与高亮 + +- 世界路径图、LS 和 ST 都标记当前方向段的 `s_end`。 +- 如果 `s_end` 是换向边界,使用橙色小菱形并标注“换向点 N / `s_end`”;如果是最终目标,使用不同的终点记号,不混用换向语义。 +- 周期交接等待时,高亮留在 N 段,并展示还缺失的停车保持/带符号速度样本条件。 + +### 7.5 局部放大 + +每张 SVG 图提供相同的轻量观察操作: + +- 拖拽框选局部放大; +- 鼠标滚轮以指针位置为中心缩放; +- 双击或“重置”恢复完整数据域; +- “全屏”只放大当前图表容器。 + +缩放状态属于浏览器本地视图,新 SSE 周期到达时不改写原始数据,也不向规划器发送参数。 + +## 8. Native Painter 语义修正 + +Native Painter 仅作为辅助审计界面,修改范围限于: + +- 世界路径按 x/y 等比例绘制,避免因视口拉伸误判曲率和轨迹形状; +- LS 的横轴为有定义的 `ReferenceS` 或 `PathS`,ST 的纵轴为真实 `PathS`,不使用屏幕像素或局部索引假冒弧长; +- 终端朝向不再使用遮挡图像的大黑三角,改为小车轮廓与细朝向箭头; +- 使用与 Web 一致的 `s_end`、换向点、最终目标和当前方向段语义; +- 保留现有风格和交互,不引入新主题或重排整个界面。 + +## 9. 错误处理与发布门禁 + +至少增加以下可诊断失败: + +- `NoProgress`:方向段长度超过终点容差,又不是真实停车/换向保持状态,但输出在整个区间内没有有效正进度。 +- `TerminalPoseMismatch`:终端世界位置误差超过 3 cm,或归一化 yaw 误差超过 5°。 +- `FullSegmentResourceLimitExceeded`:为满足完整方向段的离散精度或计算预算,所需优化规模超过已配置上限。 + +上述失败、求解器失败、约束违反或数据缺失都必须: + +1. 保留首个有效失败原因和可复现诊断; +2. 将该周期标记为失败且 `published = false`; +3. 在 Web、控制台和周期历史显示同一错误语义; +4. 不把轨迹截断、缩短或改回滚动模式后当作完整方向段成功。 + +零进度只在以下情况是合法的:当前已在终点位姿容差内,或正在真实换向边界执行只读的停车保持观察。障碍物导致无解时应返回无可行解,不应返回零轨迹 `Success`。 + +## 10. 验证策略 + +### 10.1 规划器自动验证 + +1. **静止起步:** 无障碍、非零方向段、`v0 = 0` 时,输出在起步后产生正进度和正确带符号速度,且最终停在 `s_end`。 +2. **完整边界:** 完整模式不受旧距离/时间视窗截断,发布轨迹包含精确终点样本。 +3. **自动时长:** 短路径在约束内提前完成,长路径自动得到更长 `T_end`,不把配置时间当作强制抵达时间。 +4. **终点停车:** 高初速度和长直线场景中,减速起点由 jerk/减速包络推导,终端满足 `v/a/ω = 0`。 +5. **终点位姿:** 位置 3 cm、yaw 5° 边界内成功,边界外返回 `TerminalPoseMismatch`;yaw 跨 `+π/-π` 时按归一化角度差判定。 +6. **速度与曲率:** 前进直线场景可趋近 1.0 m/s,后退直线场景可趋近 0.5 m/s;急弯场景中根据曲率自动降速,不超过对应硬上限。 +7. **换向分段:** 前进-后退路径产生两条独立完整轨迹,第一条在换向点停止,未满足交接条件前不激活第二条。 +8. **零进度门禁:** 非终点、非停车保持的全零轨迹返回 `NoProgress` 且不发布。 +9. **资源上限:** 通过测试中的小型配置上限稳定触发 `FullSegmentResourceLimitExceeded`,确认没有静默截断或滚动降级。 +10. **结点分离:** 优化结点数与 0.1 s 发布样本数独立,加密发布采样不改变优化问题规模;jerk 样本始终为轨迹点数减一。 + +### 10.2 Web 与 Painter 自动验证 + +1. 使用真实 DOM/SVG 渲染测试,验证切换分页后只有目标 panel 可见,而不是只检查源码字符串。 +2. 给定已知的非零 ST 数据,验证折线的 y 坐标随 `PathS` 增长,x/y 数值刻度、轴名和单位存在且与数据域一致。 +3. 验证路径图层顺序、线型、透明度和去重,确保当前轨迹不被粗路径遮挡。 +4. 验证 `s_end`、换向点、最终目标、实车位姿和计划起点分别使用正确语义,不出现大黑三角覆盖数据。 +5. 验证框选、滚轮缩放、重置和全屏;缩放前后原始轨迹数组及服务端数据保持不变。 +6. 空数据状态显示可操作的缺失原因,不呈现无说明空白画布。 +7. Native Painter 使用非方形窗口测试世界 x/y 等比例,并验证 LS/ST 坐标的弧长语义。 + +### 10.3 MovementTest 与安全审计 + +- 使用固定场景执行只读观察,同时对日志、依赖边界和源码进行审计,证明全过程没有底盘、转向、制动、电机或档位写输出。 +- 打开页面、慢客户端、关闭浏览器都不得阻塞规划观察周期。 +- 停止 MovementTest 后,HTTP/SSE、端口和可选 Native Painter 必须全部回收。 +- 实车验收仍只能在有人监督且环境安全时执行;不得通过操作真实底盘来“帮助”观察条件成立。 + +## 11. 兼容与迁移 + +- 现有 `RollingHorizon` 算法和观察语义保留,但不得被完整方向段入口隐式调用。 +- `DistanceHorizonMeters` 和 `TimeHorizonSeconds` 继续作为滚动模式配置;完整方向段模式不删除它们,但在生效配置面板中明确标注“本模式不用于截断”。 +- 现有 0.1 s 轨迹发布间隔保持,但不再决定优化结点数。 +- 旧 Web/SSE 消费者保留现有字段;新增的边界类型、规划范围、位姿误差和失败码以向后兼容字段发布。 + +## 12. 完成标准 + +只有同时满足以下条件,才能声称本设计实现完成: + +1. MovementTest 可通过一个明确开关选择 `FullDirectionSegment`,无需手动把距离和时间视窗调大。 +2. 静止、无障碍的非零方向段产生从静止加速、必要时巡航、再在终点前减速至停止的完整 ST,不再发布全零成功轨迹。 +3. 前进/后退速度目标与上限分别为 1.0/0.5 m/s,且轨迹始终满足加速度、jerk、曲率和安全限制。 +4. 终端停车、位置 3 cm 和 yaw 5° 条件全部通过;否则不发布。 +5. 每个换向方向段独立规划,交接高亮严格遵守停车保持和 3 个正确带符号速度样本。 +6. Web 四个分页不再重叠,路径总览有数据则正确绘制、无数据则显示原因,所有图表具有正确的双轴刻度和单位。 +7. 粗路径、Local G2、当前轨迹、车辆位姿、`s_end` 和换向点在原有论文风格中可清晰比较,没有粗线或大三角遮挡。 +8. 每张图可局部放大、重置和全屏,且操作不修改规划数据。 +9. 规划、Web 和 Painter 的自动回归验证全部通过,并完成 `OBSERVE_ONLY` 无硬件写输出审计。 +10. 在有人监督的安全环境中重新执行受影响的阶段 8 实车观察清单;任何未安全执行项都必须保持为未完成。