diff --git a/libraries/AC_PID/AC_PID.cpp b/libraries/AC_PID/AC_PID.cpp index 78440419e5..9f3c83d12c 100644 --- a/libraries/AC_PID/AC_PID.cpp +++ b/libraries/AC_PID/AC_PID.cpp @@ -33,6 +33,25 @@ int32_t AC_PID::get_i(int32_t error, float dt) return 0; } +// This is an integrator which tends to decay to zero naturally +// if the error is zero. + +int32_t AC_PID::get_leaky_i(int32_t error, float dt, float leak_rate) +{ + if((_ki != 0) && (dt != 0)){ + _integrator -= (float)_integrator * leak_rate; + _integrator += ((float)error * _ki) * dt; + if (_integrator < -_imax) { + _integrator = -_imax; + } else if (_integrator > _imax) { + _integrator = _imax; + } + + return _integrator; + } + return 0; +} + int32_t AC_PID::get_d(int32_t input, float dt) { if ((_kd != 0) && (dt != 0)) { diff --git a/libraries/AC_PID/AC_PID.h b/libraries/AC_PID/AC_PID.h index fd2c07bb43..e01b2fae9e 100644 --- a/libraries/AC_PID/AC_PID.h +++ b/libraries/AC_PID/AC_PID.h @@ -54,6 +54,7 @@ public: int32_t get_p(int32_t error); int32_t get_i(int32_t error, float dt); int32_t get_d(int32_t error, float dt); + int32_t get_leaky_i(int32_t error, float dt, float leak_rate); /// Reset the PID integrator