From ccd8eaacec35a8ab3b5fbb58abb3160929df032c Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 15 Aug 2026 20:54:29 +1000 Subject: [PATCH] SITL: save the shove duration when the shove finishes add_shove_forces() clears SIM_SHOVE_TIME when the shove has run for its duration, so it does not fire again. It cleared the live value only, leaving storage still holding the duration which asked for the shove. Nothing notices until a reboot. A GCS - or the test suite putting parameters back at the end of a test - reads the live value, finds the zero it wanted, and has no reason to write anything; storage keeps the old duration, and the next reboot loads it and shoves again. In autotest this crossed between tests: ThrowDoubleDrop asks for a 30s shove, and GainBackoffTakeoff, the next test to reboot, came up with SIM_SHOVE_TIME back at 30000 without having touched it. Co-Authored-By: Claude Opus 5 (1M context) --- libraries/SITL/SIM_Aircraft.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/SITL/SIM_Aircraft.cpp b/libraries/SITL/SIM_Aircraft.cpp index 3f8cf3e8b26..87da157a213 100644 --- a/libraries/SITL/SIM_Aircraft.cpp +++ b/libraries/SITL/SIM_Aircraft.cpp @@ -1266,7 +1266,13 @@ void Aircraft::add_shove_forces(Vector3f &rot_accel, Vector3f &body_accel) body_accel.z += sitl->shove.z; } else { sitl->shove.start_ms = 0; - sitl->shove.t.set(0); + // save as well as set: the parameter was written to storage to + // ask for the shove, so clearing only the live value leaves + // storage still asking for one. A GCS - or the test suite + // putting parameters back after a test - then sees the live + // value already at zero and has no reason to write, and the + // next reboot loads the old duration and shoves again. + sitl->shove.t.set_and_save(0); } }