FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
0036 — Environment.RandomSeed defaults to a wall-clock seed, so any fixture with a default seafloor is irreproducible
ID 0036
Class TEST
Severity 2
Status ready
Models
Found 2026-09-22
Decision needed

Evidence

fhsim_environment/src/environment/util/EnvironmentSettings.cpp:77 reads

creator->GetIntParam("RandomSeed", &randomSeed, static_cast<int>(time(nullptr)));

so an Environment that does not set RandomSeed is seeded from the wall clock. That seed reaches the seafloor: fhsim_environment/src/environment/util/parameters.cpp:173-188 builds the default bathymetry as marenv::seafloor::BathymetryWaves(depth, nStruct, maxHeight, minLen, maxLen, randomSeed) with nStruct = 10, maxHeight = 3.0, minLen = 10.0 and maxLen = 100.0. The default seabed is therefore ten random bumps up to 3 m high, redrawn on every run, not the flat bottom that Bathymetry.Depth suggests.

tests/in/CenterWeight/CenterWeight_in.xml:3-12 sets Bathymetry.Depth = "55" and no RandomSeed, and Trawl/CenterWeight takes seafloor forces (src/trawl/CenterWeight.cpp:188-191), so it lands on a different seabed every run.

Measured at aa39979 plus the increment G working tree, six invocations of SimObject.CenterWeight a second apart, reporting the regression RMS of C/Pos_0 against the committed baseline:

Run As committed With RandomSeed = "1" added
1 1.264930e+01 1.274191e+01
2 1.259474e+01 1.274191e+01
3 1.273791e+01 1.274191e+01
4 1.265492e+01 1.274191e+01
5 1.267812e+01 1.274191e+01
6 1.266141e+01 1.274191e+01

One line of XML turns six different trajectories into six identical ones.

This is the non-determinism recorded in 0030 — CenterWeight regression baseline fails after a dependency update, and is not run-to-run reproducible, whose "third session, runs 1-5 identical, run 6 different" pattern is explained by several invocations falling inside the same wall-clock second: the suite runs in under a second, so consecutive runs often share a seed and occasionally do not.

It was found while building increment G's undulation fixtures, one of which sits close to a switching threshold and flipped its behaviour when the random seabed moved across it. Any fhsim_fishery fixture that touches the seafloor has the same exposure.

Effect

Two separate costs.

Regression baselines that involve the seafloor cannot be recorded. The recorded CSV freezes one draw of a random seabed, so the case fails on most later runs. That is the state CenterWeight is in and the reason 0030 — CenterWeight regression baseline fails after a dependency update, and is not run-to-run reproducible is blocked.

A fixture near a threshold is intermittently wrong rather than reliably red. A ±3 m seabed moves a measured Altitude by ±3 m, which is enough to push a controller across a limit in one run out of several and not in the others.

Possible fix

  1. Set RandomSeed explicitly in every regression input under tests/in/ that instantiates an Environment, and set Bathymetry.NumStructures = "0" wherever the fixture means a flat bottom. This is what the three new tests/in/Auv/Auv_Undulate*_in.xml fixtures do. It is local to this repository and needs no upstream change.
  2. Re-record tests/in/CenterWeight/CenterWeight_ref.csv in the same commit as the RandomSeed line, which unblocks 0030 — CenterWeight regression baseline fails after a dependency update, and is not run-to-run reproducible. Not done here, because this increment was told to record no baselines, and because re-recording is the owner's call.
  3. Upstream, in fhsim_environment: make the default seed a fixed constant rather than the wall clock, and let a scenario opt in to a time-based seed explicitly. A simulator that is irreproducible unless you remember to say otherwise is the wrong default. That is a behaviour change for every consumer, so it belongs in fhsim_environment's own tracker.

Test that would prove it

Run SimObject.CenterWeight twenty times, a second apart, and compare the output CSVs byte for byte: they currently differ. Add RandomSeed = "1" to tests/in/CenterWeight/CenterWeight_in.xml and repeat: all twenty then agree. Six of each were run for the table above; twenty is what 0030 — CenterWeight regression baseline fails after a dependency update, and is not run-to-run reproducible asks for before re-recording.

Risk

Fixing the seed changes the trajectory of every affected case, so every seafloor-touching baseline has to be re-recorded in the same commit. Doing option 1 without option 2 leaves CenterWeight red, but red for a knowable reason instead of an intermittent one.