Basic but robust PID library
Dependents: ESP8266_pid_mtrPos_webserver_SDcard_v2 ESP8266_pid_mtrSpeed_Webserver_SDcard ESP8266_pid_spd_and_pos_webserver_SDcard ESP8266_pid_redbot_webserver ... more
Revision 3:6c2c985408df, committed 2015-11-24
- Comitter:
- electromotivated
- Date:
- Tue Nov 24 02:28:24 2015 +0000
- Parent:
- 2:07397aa513c6
- Child:
- 4:4ed1f5bccac8
- Commit message:
- Bug Fix: Flush i_accumulator in start() method to prevent output from hanging. Read comments in start() method in .cpp file for more info
Changed in this revision
| PID.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/PID.cpp Tue Nov 24 00:17:55 2015 +0000
+++ b/PID.cpp Tue Nov 24 02:28:24 2015 +0000
@@ -23,10 +23,51 @@
void PID::start(){
// Start up such we avoid bumps... (see "Initialization" section in
// the reference link found in the header file).
- last_feedback = *_feedback; // Eliminate derivative kick at start/restart
+ last_feedback = *_feedback; // Eliminate derivative kick at start/restart
i_accumulator = clip(*_output, _output_lower,
_output_upper); // P and D terms are zero, thus
// i term is used to keep output unchanged
+ /*
+ If Ki is set to zero we must "flush" the intergral accumulator.
+
+ Reason:
+ If we don't "flush", i_accumulator will hold the output value from line
+ above, and because Ki is now zero only zeros will be added to
+ i_accumulator in the sample method, and thus i_accumulator is left
+ unchanged from here on out. i_accumulator is now a constant of value
+ output from line above and will ALWAYS appear in the output. i.e.
+
+ Here is the BUG if we DON'T FLUSH
+
+ _ki = 0; // User set ki = zero using PID::set_parameters()
+
+ THEN when PID::set_parameters() calls PID::start() (this method)
+
+ i_accumulator = output; // From line above
+
+ Then when PID::sample() is called everytime...
+
+ sample(){
+ i_accumulator += _ki * error; // Now this is equivalent to
+ // i_accumulator = output + 0
+ // which always equals output
+ // value from line above
+
+ i_accumulator = clip(i_accumulator, _output_lower, _output_upper);
+
+ // Run it!
+ *_output = _kp*error + i_accumulator - _kd*(*_feedback - last_feedback);
+ // i_accumulator is fixed at value output from line above
+ // i.e. i_accumulator = clip(*_output, _output_lower,
+ _output_upper) = output;
+ last_feedback = *_feedback;
+ // Clamp Output
+ *_output = clip(*_output, _output_lower, _output_upper);
+ // Here *_output will always be offset by "output" value
+ // from line above
+ }
+ */
+ if(-0.00001 <= _ki && _ki <= 0.00001) i_accumulator = 0;
sample_timer.attach(this, &PID::sample, _Ts);
}