docs(simulation): accept S1C live worker
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# SIM S1C live-worker runbook
|
||||
|
||||
## Scope
|
||||
|
||||
This runbook starts the first browser-visible stock Ackermann rover through the
|
||||
Mission Core control plane. It accepts only a virtual PX4/Gazebo run. It does
|
||||
not admit a physical vehicle, direct actuator setpoints, navigation or safety.
|
||||
|
||||
Runtime placement:
|
||||
|
||||
```text
|
||||
React Control Station
|
||||
-> same-origin Mission Core Polygon API
|
||||
-> mode-0600 Unix socket
|
||||
-> unprivileged Simulation Worker agent
|
||||
-> loopback-only network namespace
|
||||
-> Micro XRCE-DDS Agent + PX4 SITL + Gazebo Harmonic
|
||||
```
|
||||
|
||||
The Unix socket is ephemeral runtime coordination. Source, run journals,
|
||||
provider logs and qualification artifacts remain under
|
||||
`/mnt/d/NDC_MISSIONCORE/simulation`.
|
||||
|
||||
## Preconditions
|
||||
|
||||
- use the dedicated `MissionCore-Sim` WSL distribution;
|
||||
- stage an immutable Git archive below the reviewed D root;
|
||||
- verify its SHA-256 against the source artifact;
|
||||
- use an exact 40-character Mission Core commit;
|
||||
- confirm no PX4, Gazebo or Micro XRCE-DDS provider residue exists;
|
||||
- keep `actuator_authority=false`;
|
||||
- do not add a routed NIC to the worker namespace.
|
||||
|
||||
## Start worker agent
|
||||
|
||||
From the exact staged source generation:
|
||||
|
||||
```bash
|
||||
sudo simulation/s1/worker-agent.sh <exact-40-character-commit>
|
||||
```
|
||||
|
||||
The wrapper creates `/run/missioncore-sim` as a private runtime directory,
|
||||
enters a fresh network namespace, raises only loopback and drops to the
|
||||
`missioncore` user before importing product code.
|
||||
|
||||
Expected status through the backend gateway:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": "missioncore.simulation-worker-status/v1",
|
||||
"worker_id": "mission-gpu-s1",
|
||||
"transport": "unix",
|
||||
"mode": "simulation",
|
||||
"available": true,
|
||||
"control_available": true,
|
||||
"active_run_id": null,
|
||||
"run_state": null
|
||||
}
|
||||
```
|
||||
|
||||
## Start Mission Core
|
||||
|
||||
```bash
|
||||
export MISSIONCORE_POLYGON_RUNS_ROOT=/mnt/d/NDC_MISSIONCORE/simulation/artifacts/s1/runs
|
||||
export MISSIONCORE_POLYGON_WORKER_SOCKET=/run/missioncore-sim/worker.sock
|
||||
export MISSIONCORE_POLYGON_WORKER_CONTROL=internal-virtual-only
|
||||
export MISSIONCORE_COMMIT=<exact-40-character-commit>
|
||||
uv run uvicorn k1link.web.app:app --host 127.0.0.1 --port 8765
|
||||
```
|
||||
|
||||
Open:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:8765/?workspace=polygon-run
|
||||
```
|
||||
|
||||
The live panel must show `Worker готов`. Start/stop calls require an
|
||||
`Idempotency-Key`; the React client generates one per operator intent. Removing
|
||||
the `internal-virtual-only` environment gate must leave status visible while
|
||||
disabling lifecycle actions.
|
||||
|
||||
## Live-state contract
|
||||
|
||||
The first S1C live sample comes from:
|
||||
|
||||
```text
|
||||
/world/rover/dynamic_pose/info
|
||||
```
|
||||
|
||||
It is published to the browser as `missioncore.vehicle-state/v1` with:
|
||||
|
||||
- `frame_id=map_enu`;
|
||||
- `child_frame_id=base_link_flu`;
|
||||
- integer Gazebo simulation time;
|
||||
- bounded position and quaternion;
|
||||
- `signal=ground-truth`;
|
||||
- `quality=diagnostic`;
|
||||
- `scope=virtual-only`;
|
||||
- no navigation or safety acceptance.
|
||||
|
||||
This signal proves live presentation and frame naming only. It is not the
|
||||
accepted PX4/ROS 2 telemetry path.
|
||||
|
||||
## Acceptance checklist
|
||||
|
||||
- [ ] exact source commit and source/build SHA-256 recorded;
|
||||
- [ ] focused target tests pass from the same staged generation;
|
||||
- [ ] worker status reports loopback-only, unprivileged and D-only boundaries;
|
||||
- [ ] browser start creates one new immutable qualification run;
|
||||
- [ ] status traverses `starting -> running`;
|
||||
- [ ] both provider IDs appear only after readiness;
|
||||
- [ ] live samples advance in Gazebo time;
|
||||
- [ ] React shows run ID, sim time, ENU pose and provider list;
|
||||
- [ ] archive remains path-free and command content is not exposed;
|
||||
- [ ] browser stop reaches terminal `completed`;
|
||||
- [ ] stop records `operator-stop-clean`;
|
||||
- [ ] PX4, Gazebo and Micro XRCE-DDS leave no process residue;
|
||||
- [ ] command count remains zero until the command-delivery checker is accepted.
|
||||
|
||||
## Failure handling
|
||||
|
||||
- A missing socket returns unavailable status; it does not fall back to PX4.
|
||||
- Start/stop is `403` without the explicit backend control gate.
|
||||
- Commit drift is rejected before provider start.
|
||||
- A malformed or oversized worker message fails the gateway contract.
|
||||
- Provider readiness failure seals the run as failed and triggers supervised
|
||||
cleanup.
|
||||
- Agent termination aborts an active run and stops owned provider groups.
|
||||
- Agent restart reconciles an interrupted journal as failed; restart-safe
|
||||
cross-process PID ownership remains a separate open checker.
|
||||
Reference in New Issue
Block a user