test: verify rolling EM execution

This commit is contained in:
梁薄云
2026-08-04 13:28:13 +08:00
parent 3c84e36893
commit 4058230eb8
6 changed files with 322 additions and 16 deletions
@@ -343,3 +343,105 @@ PASS longitudinal-integration
PASS trajectory
PASS em-planning-service
```
## Rolling execution ownership and deployment
The first-version boundary has three independently testable layers:
```text
caller snapshots -> EmPlanningCoordinator -> immutable published EmTrajectory
-> TrajectoryExecutor -> TrajectoryControlCommand
```
- `EmPlanningService` remains a pure, synchronous, one-shot planner. It consumes only the request snapshot and never
reads a clock, current directory, UI, localization, wheel speed, or hardware object.
- The caller owns state capture, map/reference-path version selection, the replan clock, and any hardware-specific
action after it receives a generic command. `IVehicleStateProvider.Capture()` belongs to this execution boundary and
returns a `VehicleMotionState` snapshot; it is not a planner dependency.
- `EmPlanningCoordinator` owns latest-wins cycle cancellation and atomic publication. A cycle binds
`MapSnapshotId`, `ReferencePathId`, vehicle-state `SequenceId`, `PreviousTrajectoryId`, and `SegmentIndex`; a
result publishes only when that complete identity and its version are still current. The default update cadence is
`0.20 s` (with the configured `6.0 s` / `5.0 m` planning horizons).
- `TrajectoryExecutor` only samples the immutable published trajectory with caller-provided time and measured state.
It never extrapolates beyond the final point. A failed replan leaves the last complete published trajectory in
service through its exact zero-speed safety tail.
### Handoff and gear changes
A normal replan may use a future sample from the prior trajectory only when it is within the configured age and
position/yaw/speed tracking tolerances, remains in the same segment and direction, and does not cross a gear boundary.
Unsafe tracking, stale data, a terminal boundary, or any segment/direction mismatch causes a deterministic reset to
the caller-supplied measured state with no trajectory seed.
At an exact `GearSwitchApproach` boundary the executor follows this sequence:
```text
Following -> ApproachingGearSwitch -> HoldingZero
-> RequestingDirectionChange (one request) -> AwaitingDirectionConfirmation -> Following
```
Measured absolute speed must remain below `0.01 m/s` continuously for `0.20 s` before the single direction-change
request. Every holding, direction-confirmation, rolling-stop, and goal-completion command is zero speed and zero yaw
rate. `Goal` and `RollingSafetyStop` leave the executor completed while braking is held.
### Trajectory telemetry and generic command
Every `EmTrajectoryPoint` retains these fields for execution telemetry and independent validation:
```text
X, Y, Yaw,
SignedLongitudinalVelocity, Speed, VelocityX, VelocityY, YawRate, VehicleCurvature,
TimeFromStart,
SegmentIndex, SegmentLocalS, PathS, Direction, BoundaryType,
LongitudinalAcceleration, LongitudinalJerk
```
`SignedLongitudinalVelocity` is authoritative: `Speed = abs(signedV)`, world `VelocityX/Y` are derived from vehicle
yaw, and `YawRate = signedV * VehicleCurvature`. Pose, world velocity, speed, and curvature stay available in
`TrajectoryExecutionState.SelectedPoint`; they are monitoring telemetry, not controller inputs.
`TrajectoryControlAdapter` produces only the controller-neutral immutable command below:
```text
SignedLongitudinalVelocity
YawRate
Direction
RequestDirectionChange
HoldBrake
IsTrajectoryComplete
```
There is intentionally no body-lateral-velocity, crab-motion, in-place-rotation, UI, or hardware field. A later
hardware adapter may map this command only after that controller's field semantics are independently confirmed.
### Windows x64 plugin package
The build output carries the pinned OSQP runtime and notices. Create the deployable plugin tree from a built managed
assembly with an explicit destination that is neither a drive root nor the repository root:
```powershell
& .\ClumsyPilot\scripts\Publish-ClumsyPilotPlugin.ps1 `
-ManagedDll .\ClumsyPilot\bin\Debug\netstandard2.0\ClumsyPilot.dll `
-OutputDirectory C:\deploy\ParkingRobot
```
The transactional publisher verifies a 64-bit PowerShell host, the OSQP PE machine type, and the pinned
`ThirdParty/OSQP/SHA256SUMS` hash before staging and renaming exactly:
```text
plugins/ClumsyPilot.dll
plugins/osqp.dll
plugins/licenses/OSQP-LICENSE.txt
plugins/licenses/OSQP-NOTICE.txt
plugins/licenses/OSQP-VERSION.txt
```
Run the complete first-version gate from the repository root:
```powershell
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- em-all
```
Dynamic-obstacle prediction, time-space occupancy, following/yielding/overtaking behavior, dynamic rerouting,
body-lateral motion, in-place rotation, UI integration, and hardware integration are explicitly deferred and are not
implemented by this first version.