Repository navigation
Correct saving of parameters in the face of runtime defaults - #34813
peterbarker wants to merge 2 commits into
Conversation
…() moved it save_sync() skips writing a new value equal to the var_info default, on the basis that the parameter comes back as that value on reboot. Once set_default() has changed the default that no longer holds: a non-forced save (e.g. scripting's param:set_and_save() or a MAVFTP param upload) of the var_info default was dropped, and the set_default() value came back after a reboot. Always save when the runtime default differs from the var_info default. Builds without AP_PARAM_DEFAULTS_ENABLED don't record runtime defaults and keep the old behaviour.
For contrast, param set RNGFND1_SCALING 3 from MAVProxy in step 4 would stick even on master. A GCS PARAM_SET forces the save when the value |
Global Size Summary (Total Flash delta in bytes)Built from 280f396 rebased onto dc78bc5
|
Previous review (2026-10-19)Automated review note — AI-generated (Claude+Codex), validated against the live diff. Please sanity-check before acting. Reviewed at head Thanks for the reproduction steps. The AP_Param fix works: I reran the new test in SITL, and with only AP_Param.cpp reverted to the merge-base it fails on the last check (want 3, got 0.0254). The new test is what makes sitltest-copter-tests1d fail, though. In that bucket all tests share one eeprom. AC_Avoidance_Proximity_AVOID_ALT_MIN runs first and puts RNGFND1_SCALING back to 3 with a PARAM_SET that changes the value. That save is forced, so 3 gets stored, set_default(0.0254) doesn't apply, and the first assertion here fails with want=0.025400 got=3.000000 (https://github.com/ArduPilot/ardupilot/pull/34813/files#diff-a9490928a9e9ea35ce280aac604533d4d0ce04482033429a1a5e5e947ebe849dR13200). Running just those two tests reproduces it. It passes on its own only because each test.Copter.X argument starts a fresh SITL. Adding Minor, no change needed here: check_default() now walks default_list from the IO thread with no lock against purge_defaults_list_overrides(). master already does the same with param_overrides via get_default_value(), and I found no reachable interleaving on firmware. |
With a MaxSonar serial rangefinder configured, RNGFND1_SCALING's default moves from 3 to 0.0254. Save 3 with Lua's param:set_and_save(), which doesn't force the save, and check it survives a reboot.
4b69e92 to
280f396
Compare
|
Automated review note — AI-generated (Claude+Codex), validated against the live diff. Please sanity-check before acting. Reviewed at head The head has moved since my last note, from 4b69e92 to 280f396. Thanks for adding the wipe. I reran AC_Avoidance_Proximity_AVOID_ALT_MIN followed by ParamSaveAfterRuntimeDefault in one SITL session at the new head, and both pass. With only AP_Param.cpp reverted to the merge-base, the test still fails on the last check (https://github.com/ArduPilot/ardupilot/pull/34813/files#diff-a9490928a9e9ea35ce280aac604533d4d0ce04482033429a1a5e5e947ebe849dR13220): want 3, got 0.0254, so it still catches the bug. sitltest-copter-tests1d is green at this head. The one red job, sitltest-quadplane-tests1c, doesn't run this test, and it fails on master often too. A local run of that bucket at this head passed. I couldn't see which test failed in CI, because the log isn't public. Not checked: MAVFTP param upload, other firmware set_and_save() callers, and hardware. |
Summary
Fixes a non-forced parameter save being silently dropped when the value equals the parameter's compiled-in default but
set_default()has changed the default at runtime. After a reboot the parameter came back as the runtime default rather than the saved value.Classification & Testing (check all that apply and add your own)
Checked by a human programmer
Non-functional change
No-binary change
Infrastructure change (e.g. unit tests, helper scripts)
Automated test(s) verify changes (e.g. unit test, autotest)
Tested manually, description below (e.g. SITL)
Tested on hardware
Logs attached
Logs available on request
New
test.Copter.ParamSaveAfterRuntimeDefaultautotest:SERIAL4_PROTOCOL9,RNGFND1_TYPE13), the backend's constructor callsparams.scaling.set_default(0.0254f), soRNGFND1_SCALINGcomes up as 0.0254 rather than its compiled-in 3.param:set_and_save(), which doesn't force the save.Without the fix it fails: "parameter RNGFND1_SCALING want=3.000000 got=0.025400". With it, it passes.
Run on this branch (current master plus these two commits).
test.Copter.ParameterChecks, next to the new test, also passes.Not tested on hardware.
Description
AP_Param::save_sync()doesn't write a new parameter record when the value equals the default fromvar_info(get_default_value()). The reasoning is that an unsaved parameter comes back as that default on reboot. Onceset_default()has changed the default, that no longer holds: an unsaved parameter comes back as the runtime default instead. A non-forced save of the compiled-in default was therefore dropped, and the runtime default returned after a reboot.GCS
PARAM_SETisn't affected, because it forces the save whenever the value changes. Non-forced saves are:param:set_and_save();@PARAM/param.pckuploads (AP_Filesystem_Param.cppcallssave_sync(false, false));AP_Param::set_and_save_by_name()and theset_and_save()calls made by firmware code.This affects any parameter given a runtime default with
set_default(). The tree has about 80 such calls; the rangefinder'sRNGFNDx_SCALINGused by the test is one. #19132 adds backend defaults for RNGFNDx_MIN/MAX, which makes the problem easier to hit, e.g. scripting saving RNGFND1_MAX=7 on a TF02 whose default is now 10.The fix: before the skip check,
save_sync()looks up the runtime default with the existingcheck_default(). If it differs from thevar_infodefault, the save is forced.AP_PARAM_DEFAULTS_ENABLED(which followsHAL_GCS_ENABLED) don't record runtime defaults, so they keep the old behaviour.check_default()walks the runtime-defaults list, and only when a parameter with no stored record is saved.This PR was prepared with AI assistance (Claude), which found the save path, wrote the fix and test, and ran the SITL testing described above. The issue was first reported by an AP-Review round on #19132.