From f6f16c280859e51f97bcb54bf8e196f8a3e58756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E8=96=84=E4=BA=91?= Date: Wed, 5 Aug 2026 15:12:29 +0800 Subject: [PATCH] docs: design EM observation planning diagnostics --- ...observation-planning-diagnostics-design.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-05-em-observation-planning-diagnostics-design.md diff --git a/docs/superpowers/specs/2026-08-05-em-observation-planning-diagnostics-design.md b/docs/superpowers/specs/2026-08-05-em-observation-planning-diagnostics-design.md new file mode 100644 index 0000000..071238b --- /dev/null +++ b/docs/superpowers/specs/2026-08-05-em-observation-planning-diagnostics-design.md @@ -0,0 +1,130 @@ +# EM Observation Planning Diagnostics Design + +Date: 2026-08-05 + +## Goal + +Improve the `tarjplanner_movementtest` observation-only diagnostics so an operator can confirm the effective planning configuration once when a session starts and can understand every later planning failure without changing planner behavior. + +## Operator contract + +### One configuration block per session + +After input validation and construction of the session-local `EmPlannerConfiguration`, but before the first EM planning cycle starts, the terminal prints exactly one configuration block. Values come from the effective configuration passed to the planner, not directly from mutable public `MovementTest` fields. + +The block contains: + +- `timeHorizon`: ST future time horizon in seconds. +- `distanceHorizon`: configured maximum reference-distance horizon in metres. It is a limit, not a promise that every trajectory has this length. +- `outputTimeStep`: adjacent output timestamp interval in seconds. +- `outputFrequency`: `1 / outputTimeStep`, in hertz. +- `trajectoryKnots`: `ceil(timeHorizon / outputTimeStep) + 1`, excluding terminal zero-speed hold samples. +- `maximumOsqpIterations`: maximum native OSQP iterations for one QP solve. +- `solverTimeout`: total longitudinal/lateral solve budget configured for a planning attempt, in seconds. +- `replanPeriod`: requested interval between planning attempts, in seconds. + +Example: + +```text +[TrajectoryObserver] planning configuration: +timeHorizon=3.50s +distanceHorizon=5.00m +outputTimeStep=0.10s +outputFrequency=10.00Hz +trajectoryKnots=36 +maximumOsqpIterations=60000 +solverTimeout=1.00s +replanPeriod=0.20s +``` + +This block is not repeated for each planning cycle and is not embedded in the repeatedly redrawn UI status. + +### Planning-cycle output + +The existing per-cycle pending and completion messages remain. They do not repeat configuration values. + +Every failed cycle reports: + +- cycle number, status, publication flag, and elapsed time; +- the planner stage or validation failure code when available; +- the original failure reason without losing planner-supplied identity fields; +- numerical evidence supplied by the failing validation rule. + +For `JerkLimitExceeded`, the publication validator reports at least: + +- failed point index and `TimeFromStart`; +- current interval duration; +- previous and current finite-difference accelerations; +- calculated finite-difference jerk; +- configured jerk limit; +- signed excess above the limit; +- the nearby stored longitudinal jerk values needed to compare ST output with publication-time finite differences. + +The detailed values are included in the existing failure reason, because a failed publication intentionally returns no public `EmTrajectory` from `EmPlanningResult`. + +Every successful published cycle reports a compact trajectory summary containing trajectory ID, point count, actual duration, actual PathS length, and observed maximum speed, finite-difference acceleration, and finite-difference jerk. Actual trajectory length is reported only after a trajectory exists and is distinct from the configured `distanceHorizon`. + +### UI behavior + +The UI continues to show only the latest planning status and failure reason. It does not repeat the session configuration block. Detailed failure evidence remains visible because it is part of the latest failure reason. + +## Design + +### Effective configuration snapshot + +`TrajectoryObservationController` owns the session-local `EmPlannerConfiguration`. It exposes a read-only diagnostic snapshot or already-formatted diagnostic input derived from that effective configuration. The runner logs this snapshot once after controller construction and before entering the observation loop. + +The diagnostic snapshot contains values, not references to mutable configuration objects. Formatting uses `InvariantCulture` so logs from different computers are comparable. + +### Formatting boundary + +Pure formatting helpers in the trajectory-observation diagnostics area produce: + +1. the one-time configuration block; +2. the existing planning-cycle summary; +3. a successful-trajectory summary. + +The runner decides when to print; formatters do not write to the console or UI. This keeps the log contract directly testable. + +### Validation evidence + +`EmTrajectoryValidator` continues to independently recompute acceleration and jerk from published point velocities. When a jerk check fails, it calculates the diagnostic values once and puts them into the rejection message. It does not relax the jerk limit, change tolerances, or switch to trusting the stored `LongitudinalJerk` field. + +The calculation remains: + +```text +currentAcceleration = (currentSpeed - previousSpeed) / currentDt +finiteDifferenceJerk = (currentAcceleration - previousAcceleration) / currentDt +``` + +Nearby stored ST jerk values are evidence only; they do not change the validation decision. + +### Successful trajectory metrics + +Successful metrics are calculated from immutable `EmTrajectory.Points`. Empty or malformed trajectories are not expected from a successful planner result; the formatter nevertheless handles missing trajectories without throwing from the logging path. Derived acceleration and jerk use the same finite-difference convention as publication validation. + +## Error handling + +- Diagnostic formatting must never cause a successful planning cycle to fail. +- Non-finite diagnostic values are rendered explicitly rather than silently replacing planner state. +- Invalid configuration continues to be rejected before the observation session starts. +- No actuator command is added; the MovementTest remains `OBSERVE_ONLY`. +- No solver, motion-limit, horizon-selection, or publication-acceptance behavior changes in this work. + +## Tests + +Tests are added before production changes and cover: + +1. Effective non-default settings appear in the one-time configuration block, including distance horizon, frequency, and knot count. +2. Per-cycle diagnostics do not repeat the configuration block. +3. A deterministic jerk-limit violation contains point/time, both accelerations, calculated jerk, limit, excess, and nearby stored jerk evidence. +4. A successful trajectory summary contains ID, point count, duration, actual PathS length, and maximum kinematic values. +5. Existing observation-only actuator-token checks and all EM planner verification checks remain green. + +## Out of scope + +- Relaxing jerk, solver, or residual tolerances. +- Changing the ST QP formulation or horizon selector. +- Publishing rejected candidate trajectories. +- Sending commands to the chassis. +- Building a general-purpose multi-stage planner trace system.