|
FhSim
3.1.0
Marine systems simulation
|
| ID | 0039 |
| Class | KNOWN-LIMITATION |
| Severity | 2 |
| Status | ready |
| Models | Auv/Echosounder |
| Found | 2026-09-22 |
src/auv/SensorEchosounder.cpp, SensorEchosounder::MeasureBottom:
with AltitudeOf(R, d) = R * |d[2]|. The reported Altitude is therefore the vertical component of the slant vector to the point the beam happens to hit, and SeafloorDepth is the depth of that point, not the depth of the seabed directly beneath the vehicle.
The two coincide exactly when either the beam is vertical or the seabed is locally flat. tests/AuvEchosounder_Test.cpp, Auv_EchoAltimeter, pins the flat case at both a vertical and a 20 degree beam, which is why that case cannot distinguish the two definitions; Auv_EchoBathymetry mounts the beam vertically for the same reason.
Over sloping ground with a tilted beam, or with a pitched or rolled carrier over any seabed, the published Altitude differs from the true vertical clearance Auv.Altitude by the along-slope offset of the hit point. At a 20 degree beam tilt over a 10 degree slope and 100 m of range, the hit point is some 34 m away horizontally and the error is of order 6 m.
The number reported is still the physically right one — a real single-beam altimeter has exactly this property, and a nadir beam on a level vehicle, which is the configuration every fixture and the scenario use, has no error at all. The trap is the port name: Auv/Echosounder publishes Altitude deliberately so that a sensor-in-the-loop dive controller is a one-line XML rewire against Auv.Altitude, and the two ports are only interchangeable under those conditions. A reader who rewires AuvUndulateDiveControl.Altitude while the vehicle is pitched 20 degrees on a dive leg gets a clearance that is optimistic on the way down a slope and pessimistic on the way up.
Three, in increasing cost:
StabilizeBeam parameter that casts the ray along NED down rather than along the mounted body axis, modelling a gimballed or electronically stabilised transducer. That removes the carrier attitude term, which is the larger of the two in the survey scenario, and leaves the slope term.VerticalClearance port. That is a second ray cast per ping for a quantity no real instrument measures, so it is only worth it if a controller genuinely needs truth.A fixture over a constant-gradient seabed — Bathymetry.Model = "Parametric" with a single slope primitive in its JSON config — with the transducer tilted up-slope and down-slope in turn. The present behaviour predicts Altitude differing from Auv.Altitude by gradient * R * sin(tilt) with a sign that flips between the two, and any fix must change that difference in a way the same fixture measures.
The fixture needs the parametric bathymetry JSON that increment N introduces, which is why it was not written with increments K and L.
Option 1 costs nothing. Options 2 and 3 both add a port or a parameter to a class that increment N is about to wire into a scenario, so taking either one after the scenario lands is cheaper than taking it before.