← WRITING
Control 2026-09 · 6 min read

The sign flip that nearly sent it to +20 meters

Closing the depth loop for the first time surfaced the largest standing unknown in the project — and a boundary where two correct conventions, read together, meant the opposite of either alone.

The largest unresolved warning in the project's own documentation read: "the depth loop has never run closed." Every mission primitive closes it implicitly — even a plain forward move — and an in-air test proves nothing, because at roughly zero metres, target and measurement already agree by default. The only real test was against a dynamics plant with actual feedback, for the first time the depth-control firmware had ever run against anything but open air.

Two correct conventions, read together, wrong

Three attempts flew the simulated hull to +20 metres before the cause surfaced. Inside the firmware, depth is positive metres down — the setpoint is clamped non-negative, and a SURFACE command sets it to zero. But the vehicle's telemetry channel reports depth as negative below the surface. Both conventions are internally correct. Neither function was wrong on its own. Passing one straight into a caller that expected the other read as "the vehicle is 20 metres above the water" to a controller that then tried to make that true.

Fixed, the loop closes at 17 mm of steady-state error at 0.5 m, 1.5 m and 3.0 m setpoints — three different targets, the same tight residual. The integral term earns its place in that number: a real hull is never exactly neutrally buoyant, and against ±2 N of standing buoyancy error, the loop still settles at exactly 1.500 m with 0.000 m measured error.

The mission number underneath the steady-state one is a distance, not a percentage.

Overshoot behaves the way a physical system should, and it's worth recording as a real number rather than a shape: target 0.5 m produced 0.202 m of overshoot at 0.42 m/s peak descent rate; target 1.0 m produced 0.307 m. Two boundary conditions, one honest instrument reading the same physical loop both times.