docs: explain full-direction EM observation

This commit is contained in:
梁薄云
2026-08-07 11:10:16 +08:00
parent 26b6246360
commit 88a66b8b2a
3 changed files with 84 additions and 33 deletions
@@ -1,6 +1,6 @@
# EM Planner 轨迹规划 # EM Planner 轨迹规划
`EMPlanner` 位于空间路径之后,针对一个已验证的前进或倒车方向段生成带时间、速度、曲率和终端语义的不可变 `EmTrajectory`。它执行静态走廊构建、LS 横向优化、ST 纵向优化、轨迹装配和独立世界空间复核;不读取 UI、定位、轮速、硬件、系统时钟或当前工作目录。 `EMPlanner` 位于空间路径之后,针对一个已验证的前进或倒车方向段生成带时间、速度、曲率和终端语义的不可变 `EmTrajectory`。它执行静态走廊构建、LS 横向优化、ST 纵向优化、轨迹装配和独立世界空间复核,并显式支持 `FullDirectionSegment``RollingHorizon` 两种规划范围;不读取 UI、定位、轮速、硬件、系统时钟或当前工作目录。
```text ```text
PlanningGridMap -> Hybrid A* CoarsePath -> Local G2 PathSmoothing PlanningGridMap -> Hybrid A* CoarsePath -> Local G2 PathSmoothing
@@ -32,7 +32,7 @@ EMPlanner/
├── README.md ├── README.md
├── Configuration/ ├── Configuration/
│ ├── EmPlannerConfiguration.cs # 不可变快照前的配置根与默认值 │ ├── EmPlannerConfiguration.cs # 不可变快照前的配置根与默认值
│ ├── SchedulingConfiguration.cs # 0.20 s 重规划、6 s / 5 m 视界和输出时间步长 │ ├── SchedulingConfiguration.cs # 0.20 s 重规划、滚动视窗、自适应 knot/发布上限和输出时间步长
│ ├── CorridorConfiguration.cs # 走廊采样、偏移和净空 │ ├── CorridorConfiguration.cs # 走廊采样、偏移和净空
│ ├── FrenetConfiguration.cs # 投影距离、分母和边界锚点容差 │ ├── FrenetConfiguration.cs # 投影距离、分母和边界锚点容差
│ ├── LateralConfiguration.cs / LateralWeights.cs │ ├── LateralConfiguration.cs / LateralWeights.cs
@@ -94,6 +94,9 @@ LS 的变量是 `l`、`dl`、`ddl` 和区间 `dddl`;它对静态走廊、导
| 静态走廊、LS、ST 或停车条件不可行 | `CorridorInfeasible``LateralInfeasible``LongitudinalInfeasible``StoppingDistanceInsufficient` | 空 | 不发布;由上层决定重试、停车或重新选路 | | 静态走廊、LS、ST 或停车条件不可行 | `CorridorInfeasible``LateralInfeasible``LongitudinalInfeasible``StoppingDistanceInsufficient` | 空 | 不发布;由上层决定重试、停车或重新选路 |
| 求解器不可用、超时、取消或发布复核失败 | `SolverUnavailable``SolverTimedOut``Cancelled``ValidationFailed``Failed` | 空 | 读取 `FailureReason`;不得使用中间轨迹 | | 求解器不可用、超时、取消或发布复核失败 | `SolverUnavailable``SolverTimedOut``Cancelled``ValidationFailed``Failed` | 空 | 读取 `FailureReason`;不得使用中间轨迹 |
| 已被更新周期替代 | `Superseded` | 空 | 由滚动协调器忽略旧结果 | | 已被更新周期替代 | `Superseded` | 空 | 由滚动协调器忽略旧结果 |
| 完整方向段无有效进度 | `NoProgress` | 空 | 不发布;仅真实终点容差内或受监督停车保持观察可合法零进度 |
| 完整方向段终端位姿超差 | `TerminalPoseMismatch` | 空 | 不发布;位置误差超过 `0.03 m` 或归一化 yaw 误差超过 `5°` |
| 自适应 knots 或发布样本超限 | `FullSegmentResourceLimitExceeded` | 空 | 不发布;不得截断轨迹或回退滚动模式 |
`FailureReason` 始终以 `map=...;reference=...;state=...;previous=...;segment=...` 开头,供调用方追踪地图、参考路径、状态、上一轨迹和方向段绑定。 `FailureReason` 始终以 `map=...;reference=...;state=...;previous=...;segment=...` 开头,供调用方追踪地图、参考路径、状态、上一轨迹和方向段绑定。
@@ -144,7 +147,8 @@ var request = new EmPlanningRequest(
segmentIndex: 0, previousTrajectory: null, segmentIndex: 0, previousTrajectory: null,
requestedAtUtc: capturedAt, effectiveAtUtc: capturedAt, requestedAtUtc: capturedAt, effectiveAtUtc: capturedAt,
outputTrajectoryId: "trajectory-42", referencePathId: "path-17", previousTrajectoryId: "", outputTrajectoryId: "trajectory-42", referencePathId: "path-17", previousTrajectoryId: "",
motionModel: EmMotionModel.NonholonomicForwardReverse); motionModel: EmMotionModel.NonholonomicForwardReverse,
planningScope: EmPlanningScope.FullDirectionSegment);
EmPlanningResult result = service.Plan(request, CancellationToken.None); EmPlanningResult result = service.Plan(request, CancellationToken.None);
if (result.Status != EmPlanningStatus.Success && result.Status != EmPlanningStatus.SuccessWithFallback) if (result.Status != EmPlanningStatus.Success && result.Status != EmPlanningStatus.SuccessWithFallback)
@@ -153,13 +157,21 @@ if (result.Status != EmPlanningStatus.Success && result.Status != EmPlanningStat
EmTrajectory trajectory = result.Trajectory; EmTrajectory trajectory = result.Trajectory;
``` ```
## Rolling longitudinal planning semantics ## 规划范围:FullDirectionSegment 与 RollingHorizon
`DistanceHorizonMeters` controls the L-S reference window. `TimeHorizonSeconds` controls the S-T output duration. `EmPlanningRequest.PlanningScope` 显式选择一次 `Plan` 的边界语义;MovementTest 默认使用 `FullDirectionSegment`
Only a real `Goal` or `GearSwitchApproach` boundary may require an exact zero-speed terminal. `RollingContinuation`
and `ApproachStopBoundary` may publish nonzero terminal speed; they do not add a synthetic zero-speed hold tail. ### FullDirectionSegment
`ExactStopAtBoundary` instead includes a real boundary anchor and a stationary S/U/A stabilization interval inside the
QP horizon. `ZeroSpeedHoldSeconds`, when configured, is appended only after that QP horizon. - 对完整活动方向段做一次优化;`s_end` 来自已选 Local G2 的实际 `PathS``T_end` 由可行加速度、巡航、jerk 限速停止和零速 hold 推导,不依赖旧的距离/时间截断窗口。
- 前进期望/硬上限为 `1.0 m/s`,倒车期望/硬上限为 `0.5 m/s`
- 成功终端必须停止,世界位置误差不超过 `0.03 m`,归一化 yaw 误差不超过 `5°`(约 `0.0873 rad`)。
- `NoProgress``TerminalPoseMismatch``FullSegmentResourceLimitExceeded` 失败均返回空轨迹,不降级为滚动或截断发布。
- `DistanceHorizonMeters``TimeHorizonSeconds` 作为兼容字段保留,但不用于截断 full 模式。
### RollingHorizon
`DistanceHorizonMeters` 控制 L-S 参考窗口,`TimeHorizonSeconds` 控制 S-T 输出时长。只有真实 `Goal` 或换向边界要求 `ExactStopAtBoundary` 零速终端;`RollingContinuation``ApproachStopBoundary` 可发布非零末端速度,不追加合成零速 hold tail。`ExactStopAtBoundary` 包含真实边界锚点和 QP 视界内的静止稳定区间,`ZeroSpeedHoldSeconds` 只在 QP 视界之后追加。
该服务不负责周期调用、版本淘汰、轨迹采样或控制命令。需要滚动运行时,将成功结果交给 [TrajectoryExecution](../TrajectoryExecution/README.md),并由调用方管理状态捕获和周期。 该服务不负责周期调用、版本淘汰、轨迹采样或控制命令。需要滚动运行时,将成功结果交给 [TrajectoryExecution](../TrajectoryExecution/README.md),并由调用方管理状态捕获和周期。
@@ -167,13 +179,13 @@ QP horizon. `ZeroSpeedHoldSeconds`, when configured, is appended only after that
### 第 1 步:冻结一致的请求快照 ### 第 1 步:冻结一致的请求快照
`EmPlanningRequest` 必须包含同一版本的 `PathSmoothingResult``PlanningGridMap`、当前 `VehicleParameters`、不可变 `VehicleMotionState`、完整 `EmPlannerConfiguration`、方向段索引、时间、ID运动模型。不要在 `Plan` 进行期间修改这些对象或从 UI/硬件重新读取值。 `EmPlanningRequest` 必须包含同一版本的 `PathSmoothingResult``PlanningGridMap`、当前 `VehicleParameters`、不可变 `VehicleMotionState`、完整 `EmPlannerConfiguration`、方向段索引、时间、ID运动模型`PlanningScope`。不要在 `Plan` 进行期间修改这些对象或从 UI/硬件重新读取值。
车辆状态中的速度带有符号:正数表示前进,负数表示倒车;速度接近配置的停车容差时按停车处理。`SequenceId`、地图快照 ID、参考路径 ID 和上一轨迹 ID 是诊断及滚动执行身份的一部分。 车辆状态中的速度带有符号:正数表示前进,负数表示倒车;速度接近配置的停车容差时按停车处理。`SequenceId`、地图快照 ID、参考路径 ID 和上一轨迹 ID 是诊断及滚动执行身份的一部分。
### 第 2 步:选择方向段与规划终端 ### 第 2 步:选择方向段与规划终端
一次请求只选择一个平滑路径方向段。服务从状态投影处开始,按配置的 `6.0 s` / `5.0 m` 视界选择精确终端:未到方向段边界时为 `RollingSafetyStop`,到换向边界前为 `GearSwitch`,最终段终点为 `Goal`。成功轨迹在终端精确停车,并以 `0.05 s` 间隔提供 `0.20 s` 同姿态、零速度 hold tail。 一次请求只选择一个平滑路径方向段,并显式传入 `EmPlanningScope``FullDirectionSegment` 从状态投影处规划到该方向段真实终点(`GearSwitch``Goal`),`s_end` 取自 Local G2 实际 `PathS``T_end` 由可行加速度/巡航/停止包络推导,不再以 `TimeHorizonSeconds` `DistanceHorizonMeters` 截断。`RollingHorizon` 才使用 legacy 视界选择 `RollingSafetyStop``GearSwitch` `Goal`;精确停车边界成功后提供同姿态、零速度 hold tail。
上一条轨迹仅能作为同方向、同方向段、位于当前视界内的 Frenet 种子。种子用于保持横向连续性,不能让规划跨过换向边界或绕过静态走廊连通性检查。 上一条轨迹仅能作为同方向、同方向段、位于当前视界内的 Frenet 种子。种子用于保持横向连续性,不能让规划跨过换向边界或绕过静态走廊连通性检查。
@@ -1,14 +1,27 @@
# EM trajectory observation MovementTest # EM trajectory observation MovementTest
`TrajectoryObservationMovementTest` is an observe-only host for the real MDCS localization and chassis-speed read `TrajectoryObservationMovementTest` is an observe-only host for the real MDCS localization and chassis-speed read
interfaces. It bootstraps the coarse path and Local G2 reference once, repeatedly plans EM trajectories, samples the interfaces. It bootstraps the coarse path and Local G2 reference once, requests one frozen full-direction-segment EM
latest published trajectory, and draws the world, L-S, and T-S/T-V layers. It does not drive, steer, brake, change gear, plan per active direction segment by default, samples the latest published trajectory, and draws the world, LS, and ST
or invoke a geometric vehicle controller. layers. It does not drive, steer, brake, change gear, or invoke a geometric vehicle controller.
Every runtime status contains `OBSERVE_ONLY: no chassis command is sent.` Treat the displayed control command as a Every runtime status contains `OBSERVE_ONLY: no chassis command is sent.` Treat the displayed control command as a
diagnostic prediction only. Goal and rolling-safety-stop commands are logged, never applied to hardware. At the end of a diagnostic prediction only. Goal and rolling-safety-stop commands are logged, never applied to hardware. At the end of a
gear-switch trajectory, the observer remains on direction segment `0` and waits for real direction confirmation; it does gear-switch trajectory, the observer remains on the current direction segment and waits for real direction confirmation;
not create or dispatch a direction-change action. it does not create or dispatch a direction-change action.
## FullDirectionSegment observation (default)
`UseFullDirectionSegmentPlanning=true` maps to `EmPlanningScope.FullDirectionSegment`. MovementTest performs one frozen
optimization for the complete remaining active direction segment, then republishes that trajectory with fresh observation
state until the real direction boundary is confirmed and the next segment becomes active. `s_end` is the actual Local G2
`PathS` at the active segment boundary; `T_end` is derived from the feasible acceleration, cruise, jerk-limited stopping,
and zero-speed hold behavior instead of being forced by a legacy time horizon.
`DistanceHorizonMeters` and `TimeHorizonSeconds` are rolling-compatible fields and do not truncate full mode. Forward
desired/hard maximum speed is `1.0 m/s`; reverse desired/hard maximum speed is `0.5 m/s`. A successful real boundary
requires a terminal stop plus world-position error no greater than `0.03 m` and normalized yaw error no greater than
`5 deg` (`5 * PI / 180 rad`).
## Rolling trajectory observation ## Rolling trajectory observation
@@ -18,39 +31,44 @@ single S-T output duration. Only a real Goal or gear-switch boundary may publish
## Configuration ## Configuration
| Field | Unit | Default | Meaning | | Field | Unit | MovementTest UI default | Meaning |
| --- | --- | ---: | --- | | --- | --- | ---: | --- |
| `GoalXmm` | world mm | `NaN` | Goal X. If X or Y is not finite, the host prompts for X, Y, and yaw. | | `GoalXmm` | world mm | `NaN` | Goal X. If X or Y is not finite, the host prompts for X, Y, and yaw. |
| `GoalYmm` | world mm | `NaN` | Goal Y. | | `GoalYmm` | world mm | `NaN` | Goal Y. |
| `GoalYawDeg` | world deg | `0` | Goal heading. | | `GoalYawDeg` | world deg | `0` | Goal heading. |
| `MapPaddingMeters` | m | `2.0` | Padding added on all sides of the start/goal bounds. | | `MapPaddingMeters` | m | `2.0` | Padding added on all sides of the start/goal bounds. |
| `MapResolutionMm` | mm | `50` | Local occupancy-grid resolution. | | `MapResolutionMm` | mm | `50` | Local occupancy-grid resolution. |
| `ReplanPeriodSeconds` | s | `0.20` | Minimum interval between EM planning cycles. | | `UseFullDirectionSegmentPlanning` | bool | `true` | Selects `FullDirectionSegment`; set `false` for legacy `RollingHorizon`. |
| `ReplanPeriodSeconds` | s | `0.20` | Minimum interval between EM planning cycles in rolling scope. |
| `ObserverPeriodSeconds` | s | `0.05` | Live-state sampling and redraw interval. | | `ObserverPeriodSeconds` | s | `0.05` | Live-state sampling and redraw interval. |
| `SolverTimeoutSeconds` | s | `5.0` | EM solver timeout frozen for the session. | | `SolverTimeoutSeconds` | s | `5.0` | EM solver timeout frozen for the session. |
| `MaximumOsqpIterations` | iterations | `100000` | OSQP iteration limit frozen for the session. | | `MaximumOsqpIterations` | iterations | `100000` | OSQP iteration limit frozen for the session. |
| `TimeHorizonSeconds` | s | `2.0` | Single ST trajectory horizon, not the observer period. | | `TimeHorizonSeconds` | s | `20.0` | Rolling-only ST trajectory horizon, not the observer period; full mode derives `T_end` instead. |
| `OutputTimeStepSeconds` | s | `0.10` | Published trajectory timestamp spacing. | | `OutputTimeStepSeconds` | s | `0.10` | Published trajectory timestamp spacing. |
| `VehicleLengthMeters` | m | `0.80` | Vehicle envelope length supplied to coarse, smoothing, and EM planning. | | `VehicleLengthMeters` | m | `0.80` | Vehicle envelope length supplied to coarse, smoothing, and EM planning. |
| `VehicleWidthMeters` | m | `0.60` | Vehicle envelope width supplied to planning. | | `VehicleWidthMeters` | m | `0.60` | Vehicle envelope width supplied to planning. |
| `SafetyMarginMeters` | m | `0.05` | Additional planning clearance outside the vehicle envelope. | | `SafetyMarginMeters` | m | `0.05` | Additional planning clearance outside the vehicle envelope. |
| `MaximumCurvaturePerMeter` | 1/m | `1 / 1.20` | Maximum allowed vehicle curvature (about `0.8333 1/m`). | | `MaximumCurvaturePerMeter` | 1/m | `1 / 1.20` | Maximum allowed vehicle curvature (about `0.8333 1/m`). |
| `EnableWebVisualization` | bool | `false` | Enables the local web dashboard session. | | `EnableWebVisualization` | bool | `true` | Enables the primary local web dashboard session. |
| `AutoOpenWebVisualization` | bool | `true` | Opens the tokenized local dashboard URI when web output is enabled. | | `AutoOpenWebVisualization` | bool | `true` | Opens the tokenized local dashboard URI when web output is enabled. |
| `WebVisualizationPort` | port | `0` | `0` selects an ephemeral port; otherwise use `1024` through `65535`. | | `WebVisualizationPort` | port | `0` | `0` selects an ephemeral port; otherwise use `1024` through `65535`. |
| `WebRefreshRateHz` | Hz | `10` | Maximum dynamic web snapshot publication rate. | | `WebRefreshRateHz` | Hz | `10` | Maximum dynamic web snapshot publication rate. |
| `VisualizationHistoryCycleLimit` | cycles | `60` | Bounded web history length. | | `VisualizationHistoryCycleLimit` | cycles | `60` | Bounded web history length. |
| `EnableNativePainterVisualization` | bool | `false` | Enables the optional native Painter fallback. | | `EnableNativePainterVisualization` | bool | `true` | Enables optional native Painter audit windows; disable unless explicitly reviewed. |
| `DirectionConfirmationSpeedMetersPerSecond` | m/s | `0.02` | Minimum signed-speed magnitude used to confirm the next direction. | | `DirectionConfirmationSpeedMetersPerSecond` | m/s | `0.02` | Minimum signed-speed magnitude used to confirm the next direction. |
| `DirectionConfirmationSamples` | samples | `3` | Strictly increasing matching-direction samples required after the stop hold. | | `DirectionConfirmationSamples` | samples | `3` | Strictly increasing matching-direction samples required after the stop hold. |
| `GearSwitchProjectionToleranceMeters` | m | `0.50` | Maximum switch-point projection distance for both adjacent segments. | | `GearSwitchProjectionToleranceMeters` | m | `0.50` | Maximum switch-point projection distance for both adjacent segments. |
| `GearSwitchStopHoldSeconds` | s | `0.20` | Continuous real-stop duration required before direction samples count. | | `GearSwitchStopHoldSeconds` | s | `0.20` | Continuous real-stop duration required before direction samples count. |
The four vehicle fields are public editable MovementTest inputs. They, the map/timing fields, goal, and manual obstacles `TrajectoryObservationSettings` contract defaults are `PlanningScope=FullDirectionSegment`,
are validated and copied into a frozen input snapshot before the background session starts. Later edits cannot change an `TimeHorizonSeconds=2.0`, `EnableWebVisualization=true`, and `EnableNativePainterVisualization=false`; the MovementTest
active session. The live pose and actual longitudinal speed are then read once per observer tick. UI currently exposes the values above. All public fields are validated and copied into a frozen input snapshot before
EM planning runs asynchronously with at most one planning cycle in flight. Every observer tick still captures fresh the background session starts. Later edits cannot change an active session. The live pose and actual longitudinal speed
state, samples the currently published trajectory, redraws all three layers, and emits a session-guarded status; a slow are then read once per observer tick.
In full scope, EM planning runs once per active segment with one attempt in flight. In rolling scope, EM planning
respects `ReplanPeriodSeconds` with at most one planning cycle in flight. Every observer tick still captures fresh
state, samples the currently published trajectory, redraws all layers, and emits a session-guarded status; a slow
planner therefore does not reduce the configured observation cadence. planner therefore does not reduce the configured observation cadence.
## Manual obstacles ## Manual obstacles
@@ -84,14 +102,20 @@ for driving and has no driving capability; any future execution mode requires a
网页默认以 `10 Hz` 发布不可变动态快照,网页关闭、断开或慢客户端只会丢弃网页帧,绝不会阻塞、序列化等待或改变 网页默认以 `10 Hz` 发布不可变动态快照,网页关闭、断开或慢客户端只会丢弃网页帧,绝不会阻塞、序列化等待或改变
规划周期。 规划周期。
`EnableNativePainterVisualization=true` 才会为本会话创建 `TrajectoryObserver.World``LS``ST` Painter;默认关闭 `EnableNativePainterVisualization=true` 才会为本会话创建 `TrajectoryObserver.World``LS``ST` Painter。网页是主
网页与 Painter 可以同时开启,也可全部关闭:全部关闭时仍保留 `OBSERVE_ONLY` 规划、控制台和 UI 状态。网页的启动、 观察界面,Painter 仅作为可选的正确性/审计输出;受监督车辆清单执行前应显式关闭 Painter,除非另行审查。网页与
快照或服务出现异常时会只记录一次中文诊断并熔断本次网页输出,不自动循环重启,也不会停止规划观察。 Painter 可以同时开启,也可全部关闭:全部关闭时仍保留 `OBSERVE_ONLY` 规划、控制台和 UI 状态。网页的启动、快照或
服务出现异常时会只记录一次中文诊断并熔断本次网页输出,不自动循环重启,也不会停止规划观察。
网页采用中文说明配合科研绘图约定:白底、细灰网格和细曲线;当前轨迹为蓝色实线,上一轮为灰色虚线,换向与交接点 网页采用中文说明配合科研绘图约定:白底、细灰网格和细曲线;当前轨迹为蓝色实线,上一轮为灰色虚线,换向与交接点
为橙色,红色仅表示实际越界或失败。路径总览把已完成方向段画为灰色细实线、活动段画为蓝色细实线、未来段画为浅灰 为橙色,红色仅表示实际越界或失败。路径总览把已完成方向段画为灰色细实线、活动段画为蓝色细实线、未来段画为浅灰
虚线,并以深蓝覆盖当前规划视界。页面的 `ReferenceS (m)` 是将轨迹投影到**完整活动方向段**后的共享参考站; 虚线,并以深蓝覆盖当前规划视界。页面的 `ReferenceS (m)` 是将轨迹投影到**完整活动方向段**后的共享参考站;
`PathS (m)`每轮 ST 求解使用、从该局部起点累计的实际路径弧长,二者不可互相替代或跨直接相减。 `PathS (m)` 是 ST 求解使用、从该局部起点累计的实际路径弧长,二者不可互相替代或跨直接相减。
所有图表轴标签与单位由实际快照提供:世界 `X/Y (m)``ReferenceS (m)``PathS (m)``t (s)``l (m)`
`v (m/s)``a (m/s²)``j (m/s³)``κ (m⁻¹)``ω (rad/s)``ls` 的横轴是 `ReferenceS (m)`、纵轴是 `l (m)`
`st` 的横轴是 `t (s)`、纵轴是 `PathS (m)`。每张图支持鼠标滚轮以指针为中心缩放、拖拽框选局部放大、`重置视图`
`全屏`;这些操作只改变本地视口,不修改原始快照,也不向规划器发送参数。
运动学页中 `j[i]` 仅表示真实区间 `[tᵢ, tᵢ₊₁)`,所以 jerk 只有 `N-1` 个样本;末点之后没有虚构的 `j=0` 运动学页中 `j[i]` 仅表示真实区间 `[tᵢ, tᵢ₊₁)`,所以 jerk 只有 `N-1` 个样本;末点之后没有虚构的 `j=0`
状态页将滚动续航、接近停车边界和精确停车边界分别标为 `RollingContinuation` 状态页将滚动续航、接近停车边界和精确停车边界分别标为 `RollingContinuation`
@@ -113,6 +137,8 @@ Before starting:
cannot be read. cannot be read.
3. Set a finite goal X/Y/yaw (or be ready to enter them when prompted), then enter zero to twenty manual obstacles. 3. Set a finite goal X/Y/yaw (or be ready to enter them when prompted), then enter zero to twenty manual obstacles.
Each obstacle must remain inside the configured start/goal rectangle plus map padding. Each obstacle must remain inside the configured start/goal rectangle plus map padding.
4. Keep `EnableWebVisualization=true` and set `EnableNativePainterVisualization=false` unless the Painter audit output is
explicitly required and reviewed for this vehicle session.
To start, select the entry in the vehicle UI and start the MovementTest. Confirm the status begins with To start, select the entry in the vehicle UI and start the MovementTest. Confirm the status begins with
`OBSERVE_ONLY: no chassis command is sent.`, then review the bootstrap status and the `OBSERVE_ONLY: no chassis command is sent.`, then review the bootstrap status and the
@@ -22,7 +22,7 @@ visualization.Stop();
`Start` 只传输一次静态快照。`Publish` 只校验并以原子交换写入最新动态帧,绝不序列化、等待 socket、浏览器或绘图;旧帧会被丢弃,因此最新帧槽的 **capacity 1** 是有意的。默认刷新率为 **10 Hz**,周期摘要默认保留 60 条;完整轨迹只属于当前最新帧和调用方快照,不进入历史。 `Start` 只传输一次静态快照。`Publish` 只校验并以原子交换写入最新动态帧,绝不序列化、等待 socket、浏览器或绘图;旧帧会被丢弃,因此最新帧槽的 **capacity 1** 是有意的。默认刷新率为 **10 Hz**,周期摘要默认保留 60 条;完整轨迹只属于当前最新帧和调用方快照,不进入历史。
重复 `Start` 会返回已有会话信息;重复 `Stop` 安全。正常 `Stop` 最多尝试 100 ms 发送 `event: end`(“会话已结束”),之后关闭 SSE 和监听端口。 重复 `Start` 会返回已有会话信息;重复 `Stop` 安全。正常 `Stop` 最多尝试 100 ms 发送 `event: end`(“会话已结束”),之后关闭 SSE 和监听端口。关闭或断开浏览器只会丢弃网页帧,不会停止宿主观察;由 MovementTest/宿主在停止时统一回收 HTTP/SSE、端口和可选 Painter。
## 路由与性能模型 ## 路由与性能模型
@@ -37,8 +37,21 @@ visualization.Stop();
页面包含“路径总览”、“LS / ST”、“曲率与运动学”和“周期历史与生效配置”四个页签。八个稳定 chart ID 为 `ls``st``curvature-s``curvature-t``velocity-t``acceleration-t``jerk-t``yaw-rate-t`。说明文本为中文;轴标签保留输入快照提供的科学变量、数学符号和 SI 单位。 页面包含“路径总览”、“LS / ST”、“曲率与运动学”和“周期历史与生效配置”四个页签。八个稳定 chart ID 为 `ls``st``curvature-s``curvature-t``velocity-t``acceleration-t``jerk-t``yaw-rate-t`。说明文本为中文;轴标签保留输入快照提供的科学变量、数学符号和 SI 单位。
`ls` 的横轴是活动方向段的 `ReferenceS (m)``st` 的横轴是每轮局部 `PathS (m)`;两者不混用。jerk 的 `j[i]` 仅表示真实区间 `[tᵢ,tᵢ₊₁)`,数量为轨迹点数减一,最后一个轨迹点不补造 `j=0`,页面明确标注“末点后无时间区间”。 | 图表 | X 轴 | Y 轴 |
| --- | --- | --- |
| `ls` | `ReferenceS (m)` | `l (m)` |
| `st` | `t (s)` | `PathS (m)` |
| `curvature-s` | `s (m)` | `κ (m⁻¹)` |
| `curvature-t` | `t (s)` | `κ (m⁻¹)` |
| `velocity-t` | `t (s)` | `v (m/s)` |
| `acceleration-t` | `t (s)` | `a (m/s²)` |
| `jerk-t` | `t (s)` | `j (m/s³)` |
| `yaw-rate-t` | `t (s)` | `ω (rad/s)` |
`st` 的纵轴是真实 `PathS (m)``ls` 的横轴是活动方向段的共享 `ReferenceS (m)`;两者不混用。jerk 的 `j[i]` 仅表示真实区间 `[tᵢ,tᵢ₊₁)`,数量为轨迹点数减一,最后一个轨迹点不补造 `j=0`,页面明确标注“末点后无时间区间”。
路径总览按语义分层:粗路径、Local G2、方向段、上一轮、当前轨迹、`s_end`/换向/终点/车辆标记,并保持世界 `X/Y` 等比例。每张 SVG 支持滚轮以指针为中心缩放、拖拽框选局部放大、重置和全屏;这些操作只改变浏览器本地视口,不修改原始快照,也不向规划器发送参数。
## 适配器责任 ## 适配器责任
适配器应在外部项目中冻结配置、构造 `PlanningVisualizationStaticSnapshot`,并在每个观察周期构造 `PlanningVisualizationDynamicSnapshot`。它可以在启动后使用 `info.Uri` 由宿主决定是否打开浏览器;本类库不会读取桌面环境或启动进程。快照、服务或前端异常应被宿主隔离为一次中文诊断,不得改变规划周期、求解结果或任何车辆控制行为。 适配器应在外部项目中冻结配置、构造 `PlanningVisualizationStaticSnapshot`,并在每个观察周期构造 `PlanningVisualizationDynamicSnapshot`MovementTest 默认以 `FullDirectionSegment` 提供完整方向段快照;本类库本身不决定规划范围。它可以在启动后使用 `info.Uri` 由宿主决定是否打开浏览器;本类库不会读取桌面环境或启动进程。快照、服务或前端异常应被宿主隔离为一次中文诊断,不得改变规划周期、求解结果或任何车辆控制行为。