From 2eb7902bc3e10429c2bf37488c399ae3e4cb143b 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 20:46:58 +0800 Subject: [PATCH] docs: hand off EM rolling planning phase three --- ...6-08-05-em-longitudinal-rolling-phase-3.md | 110 +++++++++++++ ...6-08-05-em-longitudinal-rolling-phase-4.md | 153 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 docs/superpowers/handoffs/2026-08-05-em-longitudinal-rolling-phase-3.md create mode 100644 docs/superpowers/prompts/2026-08-05-em-longitudinal-rolling-phase-4.md diff --git a/docs/superpowers/handoffs/2026-08-05-em-longitudinal-rolling-phase-3.md b/docs/superpowers/handoffs/2026-08-05-em-longitudinal-rolling-phase-3.md new file mode 100644 index 0000000..fbdd9cf --- /dev/null +++ b/docs/superpowers/handoffs/2026-08-05-em-longitudinal-rolling-phase-3.md @@ -0,0 +1,110 @@ +# EM Longitudinal Rolling Planning — Phase 3 Handoff + +## Scope and commits + +- Phase 3 implementation baseline: `59d13e5` (`feat: seed rolling and exact-stop ST profiles`) +- Task 6: `4159ae0` (`feat: publish rolling trajectories without stop tails`) +- Task 7 / phase 3 code end: `6cfbaf6` (`feat: reuse prior trajectory in longitudinal planning`) + +Only original-plan Tasks 6 and 7 were implemented. Task 8, Task 9, and Task 10 have not been started. This handoff and the companion phase-4 prompt are documentation-only follow-up artifacts; they do not change the phase-3 code end above. + +The preceding Task 3 and Task 4 fixups remain separate commits, `dbc7b7c` and `26bd822`, because the shared dirty worktree prevented autosquash. Preserve them as part of the actual history; do not rebase, reset, clean, or stash user files merely to rewrite it. + +## Delivered behavior + +### Task 6: mode-aware publication and validation + +`EmTrajectoryMetadata` now carries `EmLongitudinalMode`, supplied by `EmPlanningService`. `TrajectorySampleSchedule` is mode-aware: + +- `RollingContinuation` and `ApproachStopBoundary` publish exactly the ST candidate knots, without an artificial zero-speed hold or a terminal boundary anchor. +- `ExactStopAtBoundary` locates the internal stable tail with `LongitudinalTerminalSchedule.GetStabilizationStartIndex`, requires its constant `PathS`, `U=0`, `A=0`, and zero tail jerk, marks only its first point as the boundary anchor, then appends `ZeroSpeedHoldSeconds` after the QP horizon with strictly increasing timestamps. + +`EmTrajectoryAssembler` marks an anchor only for the first exact stable-tail knot. `EmTrajectoryValidator` retains finite-value, ordinary kinematics, jerk, and collision checks for every mode, but applies terminal-anchor, zero terminal speed/acceleration/yaw, and static-tail requirements only to `ExactStopAtBoundary`. It now reports `TerminalAccelerationNotZero` when appropriate. No validation, solver, acceleration, or jerk threshold was relaxed, and `OBSERVE_ONLY` behavior is unchanged. + +Task 6 changed only: + +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Contracts/EmTrajectoryMetadata.cs` +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Trajectory/TrajectorySampleSchedule.cs` +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Trajectory/EmTrajectoryAssembler.cs` +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Validation/EmTrajectoryValidator.cs` +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Facade/EmPlanningService.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/TrajectoryChecks.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/TrajectoryObservationChecks.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/ExecutorChecks.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/CoordinatorChecks.cs` + +### Task 7: previous-trajectory longitudinal soft reference + +`LongitudinalPreviousTrajectorySeed` and `LongitudinalPreviousTrajectorySeedBuilder` were added. The builder samples a compatible previous `EmTrajectory` at `newEffectiveAtUtc + knotTime`, linearly interpolates world position and signed speed, monotonically projects the position onto the current `LateralPath`, and publishes non-negative progress speed. Missing trajectories, incompatible segment/direction, malformed input, and out-of-range sampling return `LongitudinalPreviousTrajectorySeed.Empty`; none of those conditions throw into the service publication path. + +After lateral planning succeeds, `EmPlanningService` creates the current ST knot times, builds the seed with the prior trajectory/current path/effective time/segment/direction, and passes its `PathS` and `ProgressSpeedMetersPerSecond` arrays into the existing explicit-mode `LongitudinalPlanningInput`. These arrays activate the existing previous-S and previous-U objective terms only as soft references. They are not terminal constraints. LS slicing remains based on `WindowEndReferenceS`. + +Task 7 changed only: + +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Longitudinal/LongitudinalPreviousTrajectorySeedBuilder.cs` (new) +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/Facade/EmPlanningService.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/LongitudinalModelChecks.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/EmPlanningServiceChecks.cs` + +The service test fixture now captures the emitted ST quadratic program to prove that valid seeds add nonzero previous-S/previous-U objective terms, while an invalid seed adds neither and planning still succeeds. Its scripted solver now returns the supplied warm start for normal longitudinal QPs, allowing phase-1/2 constraints and the phase-3 soft reference to be exercised without fabricating an incompatible primal solution. + +## Interfaces the next phase must preserve + +- `EmLongitudinalMode`: `RollingContinuation`, `ApproachStopBoundary`, `ExactStopAtBoundary` +- `LongitudinalTerminalSchedule.GetStabilizationStartIndex` +- Explicit-mode `LongitudinalPlanningInput`, including `PreviousPathS` and `PreviousProgressSpeedMetersPerSecond` +- `PathUpperBoundS`, `StopBoundaryPathS`, and `PathSpeedLimit.HasStopBoundary` +- `EmTrajectoryMetadata.LongitudinalMode` +- `LongitudinalPreviousTrajectorySeed.PathS`, `ProgressSpeedMetersPerSecond`, and `Empty` +- `LongitudinalPreviousTrajectorySeedBuilder.Build(EmTrajectory, LateralPath, DateTimeOffset, IReadOnlyList, int, TravelDirection)` + +`TerminalPathS` remains compatibility-only. Use `PathUpperBoundS` for the LS/path-window upper bound; use `StopBoundaryPathS` only for an actual Goal or GearSwitch stop boundary. + +## Verification evidence + +All commands below exited `0` at the stated checkpoint: + +```powershell +# Before Task 6 commit 4159ae0 +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- trajectory +# PASS trajectory +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- coordinator +# PASS coordinator +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- executor +# PASS executor +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- trajectory-observation +# PASS trajectory-observation + +# Before Task 7 commit 6cfbaf6 +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- longitudinal-model +# PASS longitudinal-model +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-planning-service +# PASS em-planning-service + +# Fresh phase-end checks after Task 7 +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- trajectory +# PASS trajectory +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-planning-service +# PASS em-planning-service +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- coordinator +# PASS coordinator +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- executor +# PASS executor + +git diff --check +# exit 0 +``` + +The fresh `trajectory` run emitted two pre-existing obsolete-API warnings from `MovementTests.TireFollowing.cs` and `TireFollowing.cs`; no failure resulted. `git diff --check` returned success but printed CRLF conversion notices for extensive unrelated dirty user files. + +At phase end, `git log -5 --oneline` began with `6cfbaf6`, `4159ae0`, `72592f0`, `59d13e5`, and `26bd822`. The worktree still contains many unrelated modified, deleted, and untracked files in PathSmoothing, CoarsePath, Map, reports, configuration, and other user work. They were not staged or committed. Preserve them exactly: do not run reset, checkout, clean, stash, `git add .`, or `git add -A`. + +## Phase 4 boundary + +Phase 4 is original-plan Tasks 8, 9, and 10 only: + +1. Add service-level multi-cycle regressions for `RollingContinuation -> ApproachStopBoundary -> ExactStopAtBoundary`, including Goal/GearSwitch and independent 5 m / 2 s horizon semantics. +2. Add observation diagnostics and documentation for mode, terminal state, and jerk-limited stopping capability while retaining `OBSERVE_ONLY`. +3. Run the complete regression/build set and the target-machine real-OSQP probe. If the current machine lacks the native dependency, record that as pending target-machine verification rather than changing longitudinal logic or thresholds. + +Do not alter the phase-3 behavior to make the new Task 8 fixtures easier. In particular, rolling and approach are allowed to end with nonzero speed, only exact stops carry a boundary anchor/static tail, `ZeroSpeedHoldSeconds` is outside QP time, and previous-trajectory references remain soft only. diff --git a/docs/superpowers/prompts/2026-08-05-em-longitudinal-rolling-phase-4.md b/docs/superpowers/prompts/2026-08-05-em-longitudinal-rolling-phase-4.md new file mode 100644 index 0000000..6ef40c2 --- /dev/null +++ b/docs/superpowers/prompts/2026-08-05-em-longitudinal-rolling-phase-4.md @@ -0,0 +1,153 @@ +# New Window Prompt: EM Longitudinal Rolling Planning — Phase 4 + +Work in `D:\Users\Desktop\项目\prakrobot\ParkingRobot`. This is an implementation task, not a design discussion. Before editing, read these files completely: + +- `docs/superpowers/specs/2026-08-05-em-longitudinal-rolling-planning-design.md` +- `docs/superpowers/plans/2026-08-05-em-longitudinal-rolling-planning.md` +- `docs/superpowers/plans/2026-08-05-em-longitudinal-rolling-four-phase-roadmap.md` +- `docs/superpowers/handoffs/2026-08-05-em-longitudinal-rolling-phase-3.md` + +The phase-3 code end is `6cfbaf6` (`feat: reuse prior trajectory in longitudinal planning`); Task 6 is `4159ae0`. Earlier Task 3/4 fixups `dbc7b7c` and `26bd822` intentionally remain separate because the shared worktree was already dirty and Git refused autosquash. Keep the actual interfaces from the phase-3 handoff, particularly `EmLongitudinalMode`, `LongitudinalTerminalSchedule`, explicit-mode `LongitudinalPlanningInput`, `PathUpperBoundS`, `StopBoundaryPathS`, `PathSpeedLimit.HasStopBoundary`, `EmTrajectoryMetadata.LongitudinalMode`, and `LongitudinalPreviousTrajectorySeed`. + +Execute only original-plan Tasks 8, 9, and 10. Use `executing-plans`, TDD for every behavior change, `systematic-debugging` for every unexpected build/test failure, and `verification-before-completion` before each commit and the final handoff. Do not re-run brainstorming. Do not create chassis behavior: `OBSERVE_ONLY` remains mandatory. + +Start by recording: + +```powershell +git branch --show-current +git status --short +git log -10 --oneline +git show --stat --oneline 6cfbaf6 +``` + +The branch is `trajplanner` and the worktree contains substantial unrelated user changes. Never reset, checkout, clean, broadly stage, stash user files, use `git add .`, or use `git add -A`. Before every commit stage only that task's listed files, then run `git diff --cached --name-only` and `git diff --cached --check`. + +## Task 8 — service mode flow, Goal/GearSwitch, and multi-cycle regression + +Files: + +- `ClumsyPilot/tests/EMPlannerVerificationHost/EmPlanningServiceChecks.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/LongitudinalIntegrationChecks.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/EmFixtureFactory.cs` + +Write and observe the failing tests first. With a sufficiently long unobstructed straight path, call `EmPlanningService.Plan` across three physical states and assert the published metadata flows in this exact order: + +```csharp +Verification.Equal(EmLongitudinalMode.RollingContinuation, + rolling.Trajectory.Metadata.LongitudinalMode, "cycle 1 rolls"); +Verification.True(rolling.Trajectory.Points[rolling.Trajectory.Points.Count - 1] + .SignedLongitudinalVelocity != 0d, "cycle 1 has nonzero terminal speed"); + +Verification.Equal(EmLongitudinalMode.ApproachStopBoundary, + approach.Trajectory.Metadata.LongitudinalMode, "cycle 2 approaches"); + +Verification.Equal(EmLongitudinalMode.ExactStopAtBoundary, + exact.Trajectory.Metadata.LongitudinalMode, "cycle 3 stops"); +Verification.NearlyEqual(0d, exact.Trajectory.Points[exactAnchor] + .SignedLongitudinalVelocity, "goal speed is zero"); +Verification.True(exact.Trajectory.Points.Count > exactAnchor + 1, + "goal anchor is followed by a QP stabilization point"); +Verification.NearlyEqual(exact.Trajectory.Points[exactAnchor].PathS, + exact.Trajectory.Points[exactAnchor + 1].PathS, + "goal stabilization keeps the stop position"); +Verification.NearlyEqual(0d, exact.Trajectory.Points[exactAnchor + 1] + .SignedLongitudinalVelocity, "goal stabilization speed is zero"); +``` + +Repeat the exact-stop assertion using `CreateGearPairReferencePath()` and verify that the published trajectory contains no point from the following direction segment. Add an independent semantic regression with: + +```csharp +configuration.Scheduling.DistanceHorizonMeters = 5d; +configuration.Scheduling.TimeHorizonSeconds = 2d; +configuration.Scheduling.OutputTimeStepSeconds = 0.1d; +configuration.Longitudinal.MaximumForwardSpeedMetersPerSecond = 0.2d; +``` + +It must publish 21 points, end before `PathS=5m`, have nonzero terminal speed, and pass publication validation. This proves distance is the LS window and time is the single ST horizon. + +Run the new test first: + +```powershell +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-core-all +``` + +Before fixture work, at least one assertion may fail because an old fake solver assumes every trajectory stops. If a production failure is exposed, repair it only in the original owning Task 1–7 scope and rerun its targeted tests; Task 8 itself is fixture/regression work and must not weaken production validation. Update scripted fixtures by mode: + +- rolling and approach return nonzero terminal velocity and no hold tail; +- exact returns the real boundary anchor and its QP-internal `S/U/A` static tail, with only a later optional external hold. + +The phase-3 service fixture already uses a realistic longer direct path and captures the longitudinal QP for prior-trajectory soft-reference coverage. Preserve that coverage while adding the new mode-flow assertions. + +Required checks and commit: + +```powershell +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-core-all +git add -- ClumsyPilot/tests/EMPlannerVerificationHost/EmPlanningServiceChecks.cs ClumsyPilot/tests/EMPlannerVerificationHost/LongitudinalIntegrationChecks.cs ClumsyPilot/tests/EMPlannerVerificationHost/EmFixtureFactory.cs +git diff --cached --name-only +git diff --cached --check +git commit -m "test: cover rolling-to-stop EM planning flow" +``` + +Expected: `PASS longitudinal-model`, `PASS longitudinal-integration`, `PASS trajectory`, and `PASS em-planning-service` as part of `PASS em-core-all`. + +## Task 9 — observation diagnostics and documentation + +Files: + +- `ClumsyPilot/ParkrobTrajplanner/tarjplanner_movementtest/TrajectoryObservationDiagnostics.cs` +- `ClumsyPilot/tests/EMPlannerVerificationHost/TrajectoryObservationChecks.cs` +- `ClumsyPilot/ParkrobTrajplanner/EMPlanner/README.md` +- `ClumsyPilot/ParkrobTrajplanner/tarjplanner_movementtest/README.md` + +Write failing observation tests first. The one-time configuration diagnostic must include: + +```text +maximumJerkLimitedStopDistance= +maximumJerkLimitedStopDuration= +requiredDistanceHorizon= +``` + +Every successful trajectory summary must include: + +```text +longitudinalMode=RollingContinuation +terminalSpeed= +terminalAcceleration= +``` + +Failure diagnostics must include at least `longitudinalMode=`, `remainingToBoundary=`, `minimumStoppingDistance=`, `minimumStoppingDuration=`, and `maximumStoppedReachableDistance=`. Use the worst forward/reverse speed to print the maximum jerk-limited stopping capability once per session, not inside a per-frame UI redraw block. Preserve `OBSERVE_ONLY` and do not issue a chassis command. + +Update `EMPlanner/README.md` to state exactly that `DistanceHorizonMeters` controls the LS reference window, `TimeHorizonSeconds` controls ST output duration, only Goal/GearSwitchApproach may require an exact zero-speed terminal, and rolling/approach may publish nonzero terminal speed. Update the MovementTest README to state that rolling trajectory observation remains `OBSERVE_ONLY` and never commands the chassis. + +Required checks and commit: + +```powershell +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- trajectory-observation +git add -- ClumsyPilot/ParkrobTrajplanner/tarjplanner_movementtest/TrajectoryObservationDiagnostics.cs ClumsyPilot/tests/EMPlannerVerificationHost/TrajectoryObservationChecks.cs ClumsyPilot/ParkrobTrajplanner/EMPlanner/README.md ClumsyPilot/ParkrobTrajplanner/tarjplanner_movementtest/README.md +git diff --cached --name-only +git diff --cached --check +git commit -m "docs: explain rolling longitudinal planning diagnostics" +``` + +Expected: `PASS trajectory-observation`. + +## Task 10 — complete regression and target-machine OSQP verification + +Task 10 is verification-only: do not modify files and do not create an empty commit. Run: + +```powershell +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-core-all +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- coordinator +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- executor +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- trajectory-observation +dotnet build ClumsyPilot/ClumsyPilot.csproj -p:ExcludeLegacyAutoAvoidance=true +dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- longitudinal-real-osqp-probe +``` + +Then perform the manual `TrajectoryObservationMovementTest` observation-only probe with the current manual parameters. Confirm one startup configuration print, rolling with nonzero terminal speed and no hold when far from Goal, approach near Goal, exact stop with `U=0,A=0`, no point-21 `JerkLimitExceeded`, and recurring `OBSERVE_ONLY: no chassis command is sent.` + +The real-OSQP probe must run on a machine with the required native dependency. If this window cannot load it, record the result precisely as pending target-machine verification; do not bypass it by modifying longitudinal code, solver residuals, or any validation threshold. Finish with `git diff --check`, `git status --short`, and `git log --oneline -12`, preserving all unrelated dirty work. + +After Task 10, use `writing-plans` to create `docs/superpowers/handoffs/2026-08-05-em-longitudinal-rolling-final.md`, record all command results and target-machine status, stage and commit only that final handoff document, and stop. + +Global semantics are non-negotiable: `DistanceHorizonMeters` is only an LS look-ahead window; `TimeHorizonSeconds` is only one ST horizon; only actual Goal/GearSwitch boundaries permit exact zero speed; `ZeroSpeedHoldSeconds` is outside QP time; previous-trajectory arrays remain objective soft references; never loosen jerk, acceleration, solver, or validation thresholds; and never add chassis commands.