From 26b7de668abbb824ccb9c27c146f2f387e41239e Mon Sep 17 00:00:00 2001
From: Andrew Tridgell <tridge@samba.org>
Date: Sun, 2 Jun 2013 14:48:36 +1000
Subject: [PATCH] AP_Param: fixed parameter save bug

This bug affected parameters where the defaults are overridden in the
object constructor. For example, a PID object may have a default value
for PID_D of 0.0, but have a constructor based default of 0.2. If the
user tries to set the value to exactly 0.0, then the set wouldn't happen,
as the value matches the value in the object default var_info[]
table.

This change ensures we force a save to eeprom if the value is changing
from the current value, regardless of the var_info[] default.

Thanks to Tom Coyle for finding this bug!
---
 libraries/AP_Param/AP_Param.cpp |  4 ++--
 libraries/AP_Param/AP_Param.h   | 12 ++++++++----
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/libraries/AP_Param/AP_Param.cpp b/libraries/AP_Param/AP_Param.cpp
index 0b1b0a809..741c60ee6 100644
--- a/libraries/AP_Param/AP_Param.cpp
+++ b/libraries/AP_Param/AP_Param.cpp
@@ -650,7 +650,7 @@ AP_Param::find_object(const char *name)
 
 // Save the variable to EEPROM, if supported
 //
-bool AP_Param::save(void)
+bool AP_Param::save(bool force_save)
 {
     uint32_t group_element = 0;
     const struct GroupInfo *ginfo;
@@ -703,7 +703,7 @@ bool AP_Param::save(void)
         } else {
             v2 = PGM_FLOAT(&info->def_value);
         }
-        if (v1 == v2) {
+        if (v1 == v2 && !force_save) {
             return true;
         }
         if (phdr.type != AP_PARAM_INT32 &&
diff --git a/libraries/AP_Param/AP_Param.h b/libraries/AP_Param/AP_Param.h
index b51ef83b8..29362eee5 100644
--- a/libraries/AP_Param/AP_Param.h
+++ b/libraries/AP_Param/AP_Param.h
@@ -164,9 +164,11 @@ public:
 
     /// Save the current value of the variable to EEPROM.
     ///
+    /// @param  force_save     If true then force save even if default
+    ///
     /// @return                True if the variable was saved successfully.
     ///
-    bool save(void);
+    bool save(bool force_save=false);
 
     /// Load the variable from EEPROM.
     ///
@@ -369,8 +371,9 @@ public:
     /// Combined set and save
     ///
     bool set_and_save(const T &v) {
+        bool force = (_value != v);
         set(v);
-        return save();
+        return save(force);
     }
 
     /// Combined set and save, but only does the save if the value if
@@ -383,7 +386,7 @@ public:
             return true;
         }
         set(v);
-        return save();
+        return save(true);
     }
 
     /// Conversion to T returns a reference to the value.
@@ -464,8 +467,9 @@ public:
     /// Combined set and save
     ///
     bool set_and_save(const T &v) {
+        bool force = (_value != v);
         set(v);
-        return save();
+        return save(force);
     }
 
     /// Conversion to T returns a reference to the value.
-- 
GitLab