From 17ab0df8638bf5b65b86ba3b300b087d36bb2dbc 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 09:45:52 +0800 Subject: [PATCH] docs: design EM observation diagnostics --- ...08-05-em-observation-diagnostics-design.md | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-05-em-observation-diagnostics-design.md diff --git a/docs/superpowers/specs/2026-08-05-em-observation-diagnostics-design.md b/docs/superpowers/specs/2026-08-05-em-observation-diagnostics-design.md new file mode 100644 index 0000000..fe1aacb --- /dev/null +++ b/docs/superpowers/specs/2026-08-05-em-observation-diagnostics-design.md @@ -0,0 +1,58 @@ +# EM observation MovementTest diagnostics + +## Goal + +Make a failed or pending EM planning cycle understandable during an on-vehicle observation test. The test remains strictly observe-only and does not gain any chassis actuator call. + +## Scope + +`TrajectoryObservationMovementTest` will publish one shared diagnostic snapshot for every observer tick. It will contain the current planning state, whether a trajectory was published, the planner failure reason or pending marker, planning version, and elapsed planning time. The text deliberately excludes routine pose, selected-point, and command details when no trajectory exists: failure diagnostics must stay short and easy to scan. + +The snapshot is delivered through two channels: + +1. A terminal line prefixed with `[TrajectoryObserver]`, emitted at session start/stop/fault, once when each planning cycle starts, and once when each planning cycle completes. This guarantees every individual failure is recorded, while the 50 ms observer tick cannot flood the console. +2. Persistent text drawn in the World painter. The L-S and S-T empty states show a compact copy of the same planning state and reason, rather than only `No published trajectory available`. + +The existing `Hedingben.ToastText` status remains for UI users. It receives the same diagnostic text but is not the sole source of failure information. + +## Status and failure rules + +Every completed cycle prints the raw `EmPlanningStatus`, `published` flag, version, elapsed milliseconds, and the exact `FailureReason` returned by the planner. No failure reason is replaced with a generic message. Therefore the following independent failure classes remain distinguishable without adding a parallel exception hierarchy: + +- `InvalidInput`, `UnsupportedMotionMode`, `StaleVehicleState`; +- `StateDirectionMismatch`, `InvalidReferencePath`, `ProjectionFailed`; +- `CorridorInfeasible`, `LateralInfeasible`, `LongitudinalInfeasible`, `StoppingDistanceInsufficient`; +- `SolverUnavailable`, `SolverTimedOut`; +- `ValidationFailed`, `Cancelled`, `Superseded`, `Failed`. + +For example, a compact failed-cycle line is: + +```text +[TrajectoryObserver] cycle=4 status=CorridorInfeasible published=False elapsed=18ms reason=... +``` + +Before completion, the line reports `status=pending`; before the first cycle it reports `status=not-started`. If an older trajectory is still safely published while a new cycle is pending, the text reports both the pending state and that trajectory ID. + +## Data flow + +`TrajectoryObservationLoopTick` already exposes `LatestCycle`, `LatestPlanningElapsed`, and `PlanningInFlight`. A small pure formatter converts those fields plus the published trajectory state into operator text: + +- before a completed cycle: `planning=pending` or `planning=not-started`; +- completed success: status, `published=True`, version and elapsed time; +- completed failure: status, `published=False`, version, elapsed time and the unmodified `FailureReason`; +- a published older trajectory during an in-flight replan: retain its trajectory identity while stating that replanning is pending. + +Presentation consumes this formatted text independently of charts. Thus it is visible even when `PublishedTrajectory` is null and no L-S/S-T samples can be built. + +## Safety and error handling + +Only text output and painter calls are added. No `SendXYThSpeed`, motion command, brake, or wheel call is introduced. If a planning Task faults, the existing session fault path remains responsible for cleanup and its exception is printed through the same terminal/UI status mechanism. + +## Verification + +The verification host gets checks for: + +- a no-trajectory diagnostic that preserves a real failure reason and raw `EmPlanningStatus`; +- presentation empty-state text containing the diagnostic; +- one terminal record per cycle start and completion, with no duplicate 50 ms tick records; +- the existing source deny-list continuing to reject actuator calls.