docs(simulation): record Ackermann motion acceptance

This commit is contained in:
DCCONSTRUCTIONS 2026-07-24 23:00:07 +03:00
parent 49b0f47fea
commit bc61331604
4 changed files with 145 additions and 13 deletions

View File

@ -192,6 +192,26 @@ residue. The run contained zero commands, so this result does not yet prove
rover motion, PX4 command delivery, watchdog/failsafe behavior, navigation or rover motion, PX4 command delivery, watchdog/failsafe behavior, navigation or
safety acceptance. safety acceptance.
S1D exact code generation `49b0f47` closes the first virtual Ackermann command
and motion slice. React sends bounded speed/steering intents through the
same-origin Mission Core API and private worker socket. The worker journals each
accepted command before mapping it to PX4 rover-level Offboard setpoints:
`RoverThrottleSetpoint` is calibrated against the stock model's
`RO_MAX_THR_SPEED=3.1`, `RoverSteeringSetpoint` carries normalized steering,
and PX4 retains arming, Offboard loss handling and control allocation. No
`ActuatorMotors` or `ActuatorServos` topic is exposed or published by Mission
Core.
The immutable D-only generation passed 40 focused target tests. Its first cold
start completed in one request after 32.08 seconds. Run
`s1c-49b0f47-20260724t195259z-62edd2` proved 3.74 m straight motion, a curved
turn, reverse motion, 44.6 ms sampled command admission, a 250 ms TTL transition
(`ttl_expired_count` 4 -> 5), stable stopped pose and clean provider shutdown
with no PX4/Gazebo/XRCE residue. This does not accept calibrated closed-loop
speed tracking, Differential Rover, canonical PX4/ROS 2 telemetry,
pause/step/reset, heartbeat/offboard/link-loss cases, Nav2, perception or safety
behavior. Real actuator authority remains false.
Start the worker from the exact immutable D source generation: Start the worker from the exact immutable D source generation:
```bash ```bash
@ -215,11 +235,11 @@ http://127.0.0.1:8765/
The direct `?workspace=polygon-run&run=<qualification-run-id>` URL remains a The direct `?workspace=polygon-run&run=<qualification-run-id>` URL remains a
compatible evidence deep-link. The archive API remains GET-only. The worker API compatible evidence deep-link. The archive API remains GET-only. The worker API
adds status/live GETs and explicit start/stop POSTs; POSTs remain `403` unless adds status/live GETs and explicit start, command and stop POSTs; POSTs remain
the backend has the `internal-virtual-only` gate and an exact commit. Missing `403` unless the backend has the `internal-virtual-only` gate and an exact
configuration, transport drift and corrupt evidence fail closed. The browser commit. Missing configuration, transport drift and corrupt evidence fail
receives no Unix socket, D root, artifact bytes, PX4 endpoint or direct provider closed. The browser receives no Unix socket, D root, artifact bytes, PX4
command. endpoint or direct provider command.
See the [Polygon product/SRS](docs/12_SIMULATION_POLYGON_PRODUCT_AND_SRS.md), See the [Polygon product/SRS](docs/12_SIMULATION_POLYGON_PRODUCT_AND_SRS.md),
[ADR 0015](docs/adr/0015-simulation-polygon-qualification-boundary.md), [ADR 0015](docs/adr/0015-simulation-polygon-qualification-boundary.md),

View File

@ -24,7 +24,7 @@ Each gate produces evidence and an explicit GO, PAUSE or BLOCKED result.
| Plugin isolation | GO (laboratory control plane) — vendor backend/frontend and optional scene controls are plugin-owned; manifest/runtime descriptor parity, versioned handshake, lifecycle health and transport correlation fail closed while execution remains in-process | | Plugin isolation | GO (laboratory control plane) — vendor backend/frontend and optional scene controls are plugin-owned; manifest/runtime descriptor parity, versioned handshake, lifecycle health and transport correlation fail closed while execution remains in-process |
| K1 application control | GO (physical staged cycle) — after fixing the PCAP-proven `sint64` time field, one explicit UI launch completed all 14 canonical operations on one control session, reached live `SCANNING + project + init_ready`, displayed real points, then one explicit STOP returned K1 to unbound `READY`. No retry or fallback command was sent. Native-project reuse through LixelGO/USB remains an independent verification | | K1 application control | GO (physical staged cycle) — after fixing the PCAP-proven `sint64` time field, one explicit UI launch completed all 14 canonical operations on one control session, reached live `SCANNING + project + init_ready`, displayed real points, then one explicit STOP returned K1 to unbound `READY`. No retry or fallback command was sent. Native-project reuse through LixelGO/USB remains an independent verification |
| Stage 8 product storage | PAUSE — retention, replication, encryption, capacity monitoring and long-run browser/WASM stress remain deployment gates | | Stage 8 product storage | PAUSE — retention, replication, encryption, capacity monitoring and long-run browser/WASM stress remain deployment gates |
| Simulation Polygon | SIM S0 GO; S1A complete; S1B lifecycle PASS; S1C registered live worker PASS; UI-2 browser surface PASS — exact commit `60e7916` passed 35 focused tests on the immutable D-only generation, 157 frontend tests and the 705-test backend suite. A capability-gated `Полигон` root now opens one direct workspace with a procedural 3D Ackermann Rover, 360° azimuth orbit, bounded vertical orbit, zoom, pan and live diagnostic ENU state. UI-driven run `s1c-60e7916-20260724t182006z-2f164e` reached `completed` after 27.74 seconds of Gazebo time with eight events, zero commands and zero provider residue. PX4 command delivery/motion, canonical PX4/ROS 2 telemetry, pause/step/reset, watchdog/failsafe, navigation/safety acceptance, shared-deployment auth/RBAC and real actuator authority remain absent | | Simulation Polygon | SIM S0 GO; S1A complete; S1B lifecycle PASS; S1C registered live worker PASS; UI-2 browser surface PASS; S1D Ackermann command/motion slice PASS — exact code generation `49b0f47` passed 40 focused tests on the immutable D-only generation. The capability-gated `Полигон` root owns one procedural 3D Ackermann Rover workspace with full azimuth/vertical orbit, zoom, pan, follow/reset and live diagnostic ENU state. Cold start completed in one request after 32.08 s. Run `s1c-49b0f47-20260724t195259z-62edd2` proved 3.74 m straight motion, a curved turn, reverse, 44.6 ms sampled command admission, 250 ms TTL expiry and clean zero-residue stop through PX4 rover-level Offboard throttle/steering setpoints. Differential Rover, calibrated closed-loop speed, canonical PX4/ROS 2 telemetry, pause/step/reset, heartbeat/offboard/link-loss cases, navigation/safety acceptance, shared-deployment auth/RBAC and real actuator authority remain absent |
USB project copying remains optional ground truth rather than a blocker for the USB project copying remains optional ground truth rather than a blocker for the
now-verified network path. Owner-operated LixelGO traffic verifies the MQTT now-verified network path. Owner-operated LixelGO traffic verifies the MQTT
@ -168,9 +168,21 @@ top-level product root and replaces the diagnostic 2D marker with a
browser-native Three.js Ackermann Rover scene. The exact D-only generation browser-native Three.js Ackermann Rover scene. The exact D-only generation
passed 35 target tests and one UI-driven provider run with diagnostic Gazebo passed 35 target tests and one UI-driven provider run with diagnostic Gazebo
`VehicleState`, eight persisted lifecycle events, terminal `completed` and zero `VehicleState`, eight persisted lifecycle events, terminal `completed` and zero
process residue. Its zero-command stationary rover does not close PX4 command process residue.
delivery, canonical PX4/ROS 2 telemetry, pause/step/reset, heartbeat/watchdog or
failsafe checkers; these remain the next S1 increments. S1D exact code generation `49b0f47` adds the bounded
`missioncore.ackermann-command/v1` browser-to-worker path and the first physical
motion evidence. Mission Core keeps the external command in metres per second
plus normalized steering, journals it append-only, applies a 250 ms TTL and
maps it on the worker to stock-model PX4 rover Offboard throttle/steering
setpoints. PX4 still owns arming, Offboard state and control allocation; Mission
Core does not publish direct actuator topics. The exact D-only target passed 40
focused tests. Its first cold start took 32.08 seconds, and run
`s1c-49b0f47-20260724t195259z-62edd2` proved straight, turn, reverse, TTL stop
and zero-residue lifecycle shutdown. This closes only the primary Ackermann
command/motion slice. Differential Rover, calibrated speed tracking, canonical
PX4/ROS 2 telemetry, pause/step/reset, heartbeat/offboard/link-loss and
failsafe cases remain open before S1 can pass.
The archival surface consumes the same append-only run repository through The archival surface consumes the same append-only run repository through
`GET /api/v1/polygon/runs` and `GET /api/v1/polygon/runs` and

View File

@ -89,6 +89,20 @@ Polygon is now a parallel product branch. As of this document:
persisted events, 27.74 seconds of Gazebo time and zero provider residue; persisted events, 27.74 seconds of Gazebo time and zero provider residue;
it contained zero commands and therefore does not prove rover motion or PX4 it contained zero commands and therefore does not prove rover motion or PX4
command delivery; command delivery;
- S1D exact code generation `49b0f47` adds the admitted Ackermann
speed/steering command route from React through Mission Core and the private
worker gateway. The worker journals before delivery and translates the
bounded intent to PX4 rover-level Offboard `RoverThrottleSetpoint` plus
`RoverSteeringSetpoint`; the stock-model conversion uses
`RO_MAX_THR_SPEED=3.1`, while direct actuator topics remain prohibited;
- the exact D-only generation passed 40 focused target tests. Its first cold
start completed in one request after 32.08 seconds. Run
`s1c-49b0f47-20260724t195259z-62edd2` proved 3.74 m straight motion, a curved
turn, reverse motion, 44.6 ms sampled command admission, 250 ms TTL expiry,
stable stopped pose and clean shutdown with no provider residue;
- this is not a calibrated closed-loop speed controller acceptance and does
not close Differential Rover, canonical PX4/ROS 2 telemetry,
heartbeat/offboard/link-loss, failsafe, navigation or safety checkers;
- `actuator_authority=false`; - `actuator_authority=false`;
- `navigation_or_safety_accepted=false`. - `navigation_or_safety_accepted=false`.
@ -716,6 +730,37 @@ orbit and zoom, observed advancing Gazebo time and stopped
`s1c-60e7916-20260724t182006z-2f164e` cleanly at 27.74 seconds of simulation `s1c-60e7916-20260724t182006z-2f164e` cleanly at 27.74 seconds of simulation
time with eight events, zero commands and zero provider residue. time with eight events, zero commands and zero provider residue.
S1D code generation `49b0f47fea0ae29c977bbd60808696b85a9380cd`
accepts the first Ackermann command/motion slice. Its exact source archive
SHA-256 is
`30aad33664a536f2a6cb87bc172a5dae111ae479d5899723832a1abc17c4517b`;
the xattr-free Control Station build archive SHA-256 is
`014724896c8c2169a89b0ed6971b285b6e80da918d892509e9e93568efb99f25`.
The target imported product code from the immutable source generation before
the D-only dependency site and passed 40 focused tests.
The browser contract remains speed in metres per second plus normalized
steering. On this stock PX4 v1.17.0 model, the worker's S1 adapter converts speed
to `RoverThrottleSetpoint` using `RO_MAX_THR_SPEED=3.1` and publishes
`RoverSteeringSetpoint` under Offboard `thrust_and_torque`, which retains PX4
arming and control allocation. It never publishes `ActuatorMotors` or
`ActuatorServos`. This adapter is sufficient for causal motion qualification
but is not evidence of calibrated closed-loop speed tracking.
The first cold start completed in one request after 32.08 seconds. Run
`s1c-49b0f47-20260724t195259z-62edd2` moved from `(0.00, 0.00)` to
`(3.74, -0.00)` in the straight case, then to `(5.11, 2.13)` through a turn and
to `(5.58, 0.67)` in reverse. One sampled command completed in 44.6 ms. A
single non-zero command expired at the 250 ms boundary and incremented
`ttl_expired_count` from 4 to 5; two following one-second-separated live
samples had identical X/Y. Explicit stop disarmed the virtual rover, completed
the run and left no PX4, Gazebo or Micro XRCE-DDS process residue.
This evidence checks the primary Ackermann command item only. S1 stays open for
Differential Rover, deceleration/emergency-stop profiles, accepted PX4/ROS 2
telemetry, reset/repeatability, heartbeat/offboard/link-loss, full failsafe and
navigation/safety cases.
### S2 ### S2
- Gazebo LiDAR/odometry feed the ROS 2/Nav2 baseline. - Gazebo LiDAR/odometry feed the ROS 2/Nav2 baseline.

View File

@ -2,9 +2,10 @@
## Scope ## Scope
This runbook starts the first browser-visible stock Ackermann rover through the This runbook starts and commands the first browser-visible stock Ackermann rover
Mission Core control plane. It accepts only a virtual PX4/Gazebo run. It does through the Mission Core control plane. It accepts only a virtual PX4/Gazebo
not admit a physical vehicle, direct actuator setpoints, navigation or safety. run. It does not admit a physical vehicle, direct actuator setpoints, navigation
or safety.
Runtime placement: Runtime placement:
@ -82,6 +83,11 @@ deep-link. The live panel must show `Worker готов`. Start/stop calls requir
the `internal-virtual-only` environment gate must leave status visible while the `internal-virtual-only` environment gate must leave status visible while
disabling lifecycle actions. disabling lifecycle actions.
Cold PX4/Gazebo/ROS 2 startup is expected to take roughly 3060 seconds on the
reviewed worker. The lifecycle request remains bounded at the gateway and the
controller fails closed if ROS publication or armed Offboard admission is not
confirmed.
## Live-state contract ## Live-state contract
The first S1C live sample comes from: The first S1C live sample comes from:
@ -104,6 +110,33 @@ It is published to the browser as `missioncore.vehicle-state/v1` with:
This signal proves live presentation and frame naming only. It is not the This signal proves live presentation and frame naming only. It is not the
accepted PX4/ROS 2 telemetry path. accepted PX4/ROS 2 telemetry path.
## S1D command contract
While the run is `running`, the React controls submit:
```text
POST /api/v1/polygon/worker/runs/<run-id>/commands
Idempotency-Key: <unique operator intent>
{"speed_mps": 1.0, "steering_normalized": -0.6}
```
Mission Core validates the S1 envelope, assigns a monotonic sequence and
250 ms simulation-time TTL, and durably journals the command before worker
delivery. The worker keeps the external speed/steering contract but maps the
stock model to PX4 rover-level Offboard control:
- `RoverThrottleSetpoint.throttle_body_x = speed_mps / 3.1`;
- `RoverSteeringSetpoint.normalized_steering_setpoint` carries steering;
- `OffboardControlMode.thrust_and_torque=true`;
- `OffboardControlMode.direct_actuator=false`;
- no `ActuatorMotors` or `ActuatorServos` message is published by Mission Core.
The browser repeats a held directional intent fast enough to renew TTL. Release,
the explicit `Стоп` control, stale command TTL or run stop all drive the
setpoint to zero. The `3.1 m/s` factor is the stock PX4 model's
`RO_MAX_THR_SPEED`; S1D motion acceptance must not be described as calibrated
closed-loop speed tracking.
## Acceptance checklist ## Acceptance checklist
- [ ] exact source commit and source/build SHA-256 recorded; - [ ] exact source commit and source/build SHA-256 recorded;
@ -118,7 +151,29 @@ accepted PX4/ROS 2 telemetry path.
- [ ] browser stop reaches terminal `completed`; - [ ] browser stop reaches terminal `completed`;
- [ ] stop records `operator-stop-clean`; - [ ] stop records `operator-stop-clean`;
- [ ] PX4, Gazebo and Micro XRCE-DDS leave no process residue; - [ ] PX4, Gazebo and Micro XRCE-DDS leave no process residue;
- [ ] command count remains zero until the command-delivery checker is accepted. - [ ] straight, turn and reverse commands produce causal pose changes;
- [ ] one isolated non-zero command expires at 250 ms and produces a stable
stopped pose;
- [ ] command acceptance reports armed Offboard and remains below TTL;
- [ ] command count and command journal sequences match submitted intents.
## Accepted S1D evidence
- code commit:
`49b0f47fea0ae29c977bbd60808696b85a9380cd`;
- source archive SHA-256:
`30aad33664a536f2a6cb87bc172a5dae111ae479d5899723832a1abc17c4517b`;
- Control Station archive SHA-256:
`014724896c8c2169a89b0ed6971b285b6e80da918d892509e9e93568efb99f25`;
- 40 focused tests passed from the exact source-first D-only generation;
- cold start: one request, 32.08 seconds;
- run: `s1c-49b0f47-20260724t195259z-62edd2`;
- straight endpoint: `(3.74, -0.00)` m from origin;
- turn endpoint: `(5.11, 2.13)` m;
- reverse endpoint: `(5.58, 0.67)` m;
- sampled command admission: 44.6 ms;
- TTL evidence: counter 4 -> 5 and identical following X/Y samples;
- explicit stop: no PX4, Gazebo or Micro XRCE-DDS residue.
## Failure handling ## Failure handling