Stonefish

Stonefish native station hold

A Girona 500 underwater vehicle moves 1.5 m north, 1.0 m east and 1.5 m deeper, turns to heading 045 and holds that station for 15 seconds in the Stonefish marine simulator.

This is an authored variant of the upstream Tests/UnderwaterTest example, with the example’s ocean currents disabled.

Upstream ships no controller, success check or reward for this test. The controller and the pass criteria were written for this site.

Native video · Native verification · Reproduction notes (repository access required)

What the recording establishes

Pinned Stonefish example, native capture and independent command replay.
ItemRecorded evidence
Upstream exampleStonefish 1.5.0 at commit 7d526737, Tests/UnderwaterTest. At this commit PARSED_SCENARIO is commented out, so the programmatic branch of BuildScenario is what compiles: one Girona 500 with a four-joint arm, a heightfield seabed, one cylinder and two lights. The parsed scenario file with several vehicles is not read by this binary.
Authored changesCurrents disabled; fixed 0.005 s stepping in place of the wall-clock thread; a world-fixed native camera; a fixed seed for sensor noise; a four-axis PID controller on the native Odometry sensor; the start-up console thread replaced by a no-op; journals. Upstream source files, meshes, textures, masses, thruster models and sensor placement are unchanged.
Why currents are disabledThe compiled scenario has a 1 m/s current toward north and a 5 m/s jet. With zero command the vehicle drifted 17.9 m in 20 s. With both surge thrusters at full astern for 10 s it was still moving north at 0.65 m/s over ground. The compiled thrusters cannot hold station in the compiled current.
Declared criteriaFrozen before any controller run: at every physics step from 25 s to 40 s, horizontal error ≤0.10 m, depth error ≤0.10 m, heading error ≤0.0873 rad and speed ≤0.10 m/s; over the whole 40 s, zero contact points, depth ≥0.8 m, roll and pitch ≤0.35 rad, all values finite.
Measured holdPassed. Maxima over the 3,001 hold-window physics steps: horizontal error 0.0355 m, depth error 0.0128 m, heading error 0.0127 rad, speed 0.0163 m/s. Over the whole run: zero contact points, minimum depth 1.914 m, maximum roll or pitch 0.211 rad. The vehicle is positively buoyant; at the end each heave thruster holds about 48 N.
Independent replayA fresh native process with no controller and no camera applied the 2,000 recorded command rows at their recorded physics steps. All 380,108 compared scalars (108,108 in 1,001 samples and 272,000 in 8,000 physics-step rows) are exactly equal; the declared tolerance was 1e-9. The predicate evaluates to the same result on the replayed journal.
Video1,001 native RGB frames, 960 × 540, 25 fps; 2,904,552-byte H.264 file lasting 40.04 s. Every decoded frame was compared with its native frame; minimum PSNR 42.95 dB against a 35 dB floor.
Counted asOne simulation recording. Zero upstream registered tasks, learned-policy evaluations, benchmark scores or browser world assemblies.

Controller and what it may read

The controller is a PID on four axes: north, east, down and heading. It reads only the vehicle’s native Odometry sensor.

The compiled scenario sets no noise on that sensor, so the controller sees exact simulator position, body velocity, attitude and yaw rate. That is privileged state, not an estimated navigation solution.

The noisy pressure, DVL, IMU, compass and GPS channels are recorded but not used for control.

Efforts are clamped to [-1, 1], mixed to the five thrusters and passed through a signed square root before being written as normalized thruster setpoints.

Gains were chosen in one grid of eight development runs, all scored with the already frozen criteria. Six met them and two did not.

The set with the smallest hold error was frozen, then the single capture was made.

The protocol file lists every development run, including eleven open-loop runs used to read thruster signs and authority.

Time, state and commands

Physics runs at 200 Hz as in the upstream main.cpp. Commands are issued at 50 Hz and held for four physics steps.

Sample 0 is the state after the native initial-condition solve, before any command. Sample i and camera frame i follow physics step 8·i.

State and camera clocks are therefore 25 Hz, and encoded frame i has presentation time i/25 s.

The 40-second horizon is authored. No reward or end signal is recorded because the source defines none.

Native samples keep the vehicle origin pose and velocity and six scalar sensors: Odometry, pressure, DVL, IMU, compass and GPS.

They also keep per-thruster setpoint, rotor speed, thrust and torque, arm servo state, water velocity at the vehicle and contact counts.

Physics-step rows keep pose, velocity, thrusters and contacts for all 8,000 steps. The outcome is computed from these.

Command rows keep each issued setpoint with the controller’s error, integral and effort terms.

Stonefish works in NED: x north, y east, z down, metres and radians, with xyzw body-to-world quaternions. Those values are published unchanged.

The generic body pose used by the player is the same frame rotated 180 degrees about x: x north, y west, z up, wxyz order.

The conversion was checked against the rotation-matrix form for all 1,001 poses; maximum difference 0.

Original inputs

The pinned Stonefish tree supplies 951 verified files / 126,959,720 bytes, extracted from Git objects into a tree the build only reads.

The input receipt keeps Git identities, modes, sizes and SHA-256 hashes.

It binds the 15 data files the compiled branch names: 11 OBJ meshes, three textures and the seabed heightmap, 13,061,051 bytes in all.

No geometry was exported or converted. Meshes and textures stay in the native checkout.

The build uses the pinned CMake defaults (Release, C++20) with SDL2 2.30.0 and GLM 0.9.9.8 under a task-local prefix. No system package was installed or upgraded.

Rendering used an OpenGL 4.3 core context on an NVIDIA RTX 4090 (driver 580.173.02) through VirtualGL 3.1.3’s EGL back end. Xvfb supplied only the X11 window.

The pinned CMake file links OpenMP but does not compile with it, so the library’s parallel loops run serially in this build.

Faults worked around

Two faults were observed and worked around without editing upstream files.

Counts and the fault traces are in the runtime record.

The unchanged upstream binary’s start-up log and window capture are kept as an upstream check. A start-up earns no recording credit.

Attribution and limits

Stonefish is written by Patryk Cieślak and contributors and is licensed under GPL-3.0-or-later.

Its 3rdparty folder bundles other code with its own notices. The receipt counts notices per file.

The pinned tree contains no licence or attribution statement specific to the Girona 500 model, its meshes and textures, or the two bundled fonts. Those terms are not stated here.

This site generated the video and measured-state recording. It does not redistribute Stonefish, its binaries or its model files.

One authored hold in still water with a controller that reads exact simulator state does not establish station keeping in a current, navigation from real sensors, or any benchmark result.

Replay equality is established for this host, build and seed.