br3ttb/Arduino-PID-AutoTune-Library — pull request #11 by t0mpr1c3 (2013-10-31 13:08:49+00:00)
Title: New tuning rules, peak detection method, etc.

Brett, there's a lot here so if you want to pull in just a specific feature let me know and I can create a new fork with just that change that you can pull from. The peak detection I think is an improvement because it uses information from both minima and maxima, instead of maxima only, so it potentially converges half a cycle sooner as well as being more accurate if the minima are variable. Lots of variations on Ziegler-Nichols. Slightly different but still a relay tuning method is AMIGOf, a robust algorithm for tuning PI controllers, although the tuning is slower to complete than other methods. Relay bias is useful sometimes so I have put it as a compile option.

* changes to the peak convergence method
- peak times and values now recorded for both minima and maxima
in array peakTime[] and longer array peaks[]
- new method of assessing convergence for peaks based on
amplitude over last 1.5 cycles rather than levels of recent maxima
- new variable inputCount counts number of inputs in lastInputs[]
so that peaks are not called before lastInputs[] has been filled
- convergence criterion set by PEAK_AMPLITUDE_TOLERANCE

* finite state machine
- new private variable enum AutoTunerState state records current
state of algorithm
- Runtime() initiates autotuner immediately first time around
instead of waiting until next sampleTime

* enumerated types
- tuning algorithms selected by enum Control type
- enum AutoTuneState state used instead of flag variable running
to indicate autotuner state
- enum PeakType used to describe whether peaks are maxima or minima
- enum Mode used to describe whether under Automatic or Manual control
- enum Direction used to describe sign of gain
- enum Mode and Direction break dependency with original PID library
(although this can easily be fixed)

* changes to private methods and variables
- minimum value of nLookBack set to 20 in method SetLookbackSec()
- int variables nLookBack, peakCount changed to byte
- peakTime[] changed to lastPeakTime[], made shorted, and indexed the same way
as lastInputs[], etc.
- got rid of private variable justevaled whose value was never checked
- private variables justchanged, isMin, isMax, absMax, absMin made
local to Runtime()
- private method FinishUp() inlined so that phaseLag and inducedAmplitude
can be local to Runtime()

* new tuning rules
- new tuning rules selectable by setting enum Control type
- new private variables Kp, Ti, Td for calculation of gain parameters
- private variables Ku, Kp made local to FinishUp();
- induced amplitude calculated as average over previous 1.5 or 2 cycles
used instead of difference between most extreme values ever observed

* new variables and methods used by the AMIGOF_PI algorithm:
- private variable K_process estimates the process gain from the steady
state response to a step up in output
- private variable originalNoiseBand saves value of noiseBand,
which is tuned by the AMIGOF_PI algorithm
- private method CheckStable() checks whether the values in lastInputs[]
have converged to values within noiseBand of each other

* implementation of relay bias for non-linear processes/to counter load disturbance
- compile option to use relay bias code is set to undefined (i.e. do not use relay bias) by default
- symmetry requirement for relay steps set by STEP_ASYMMETRY_TOLERANCE, tested using
private variables avgStep1 and avgStep2
- private arrays lastStepTime[], sumInputSinceLastStep[] and variable stepCount used
to calculate offset in process variable over last 2 relay cycles
- process variable offset returned from private method processVariableOffset
- private variable relayBias calculated from offset in process variable

* failure cases
- autotune terminates without setting tuning parameters after 20 peaks or
after timing out (too long since last peak identification or relay step)
- time out period set by MAX_WAIT_MINUTES

* dither
- may be useful for quantized inputs
- compile option set undefined (i.e. do not use dither) by default