PIDLoop

The PIDLoop has multiple constructors available. Valid syntax can be seen here:

// Create a loop with default parameters
// kp = 1, ki = 0, kd = 0
// maxoutput = maximum number value
// minoutput = minimum number value
SET PID TO PIDLOOP().

// Other constructors include:
SET PID TO PIDLOOP(KP).
SET PID TO PIDLOOP(KP, KI, KD).
// you must specify both minimum and maximum output directly.
SET PID TO PIDLOOP(KP, KI, KD, MINOUTPUT, MAXOUTPUT).

// remember to update both minimum and maximum output if the value changes symmetrically
SET LIMIT TO 0.5.
SET PID:MAXOUTPUT TO LIMIT.
SET PID:MINOUTPUT TO -LIMIT.

// call the update suffix to get the output
SET OUT TO PID:UPDATE(TIME:SECONDS, IN).

// you can also get the output value later from the PIDLoop object
SET OUT TO PID:OUTPUT.

Please see the bottom of this page for information on the derivation of the loop’s output.

Note

New in version 0.18: While the PIDLOOP structure was added in version 0.18, you may feel free to continue to use any previously implemented PID logic. This loop is intended to be a basic and flexible PID, but you may still find benefit in using customized logic.

structure PIDLoop
Suffix Type Description
LASTSAMPLETIME scalar decimal value of the last sample time
KP scalar The proportional gain factor
KI scalar The integral gain factor
KD scalar The derivative gain factor
INPUT scalar The most recent input value
SETPOINT scalar The current setpoint
ERROR scalar The most recent error value
OUTPUT scalar The most recent output value
MAXOUTPUT scalar The maximum output value
MINOUTPUT scalar The maximum output value
ERRORSUM scalar The time weighted sum of error
PTERM scalar The proportional component of output
ITERM scalar The integral component of output
DTERM scalar The derivative component of output
CHANGERATE scalar (/s) The most recent input rate of change
RESET none Reset the integral component
UPDATE(time, input) scalar Returns output based on time and input
PIDLoop:LASTSAMPLETIME
Type:scalar
Access:Get only

The value representing the time of the last sample. This value is equal to the time parameter of the UPDATE method.

PIDLoop:KP
Type:scalar
Access:Get/Set

The proportional gain factor.

PIDLoop:KI
Type:scalar
Access:Get/Set

The integral gain factor.

PIDLoop:KD
Type:scalar
Access:Get/Set

The derivative gain factor

PIDLoop:INPUT
Type:scalar
Access:Get only

The value representing the input of the last sample. This value is equal to the input parameter of the UPDATE method.

PIDLoop:SETPOINT
Type:scalar
Access:Get/Set

The current setpoint. This is the value to which input is compared when UPDATE is called. It may not be synced with the last sample.

PIDLoop:ERROR
Type:scalar
Access:Get only

The calculated error from the last sample (setpoint - input).

PIDLoop:OUTPUT
Type:scalar
Access:Get only

The calculated output from the last sample.

PIDLoop:MAXOUTPUT
Type:scalar
Access:Get/Set

The current maximum output value. This value also helps with regulating integral wind up mitigation.

PIDLoop:MINOUTPUT
Type:scalar
Access:Get/Set

The current minimum output value. This value also helps with regulating integral wind up mitigation.

PIDLoop:ERRORSUM
Type:scalar
Access:Get only

The value representing the time weighted sum of all errrors. It will be equal to ITERM / KI. This value is adjusted by the integral windup mitigation logic.

PIDLoop:PTERM
Type:scalar
Access:Get only

The value representing the proportional component of OUTPUT.

PIDLoop:ITERM
Type:scalar
Access:Get only

The value representing the integral component of OUTPUT. This value is adjusted by the integral windup mitigation logic.

PIDLoop:DTERM
Type:scalar
Access:Get only

The value representing the derivative component of OUTPUT.

PIDLoop:CHANGERATE
Type:scalar
Access:Get only

The rate of change of the INPUT during the last sample. It will be equal to (input - last input) / (change in time).

PIDLoop:RESET()
Returns:none

Call this method to clear the ERRORSUM and ITERM components of the PID calculation.

PIDLoop:UPDATE(time, input)
Parameters:
  • time – (scalar) the decimal time in seconds
  • input – (scalar) the input variable to compare to the setpoint
Returns:

scalar representing the calculated output

Upon calling this method, the PIDLoop will calculate the output based on this this basic framework (see below for detailed derivation): output = error * kp + errorsum * ki + (change in input) / (change in time) * kd. This method is usually called with the current time in seconds (TIME:SECONDS), however it may be called using whatever rate measurement you prefer. Windup mitigation is included, based on MAXOUTPUT and MINOUTPUT. Both integral components and derivative components are guarded against a change in time greater than 1s, and will not be calculated on the first iteration.

PIDLoop Update Derivation

The internal update method of the PIDLoop structure is the equivalent of the following in kerboscript

// assume that the terms LastInput, LastSampleTime, ErrorSum, Kp, Ki, Kd, Setpoint, MinOutput, and MaxOutput are previously defined
declare function Update {
    declare parameter sampleTime, input.
    set Error to Setpoint - input.
    set PTerm to error * Kp.
    set ITerm to 0.
    set DTerm to 0.
    if (LastSampleTime < sampleTime) {
        set dt to sampleTime - LastSampleTime.
        // only calculate integral and derivative if their gain is not 0.
        if Ki <> 0 {
            set ITerm to (ErrorSum + Error * dt) * Ki.
        }
        set ChangeRate to (input - LastInput) / dt.
        if Kd <> 0 {
            set DTerm to -ChangeRate * Kd.
        }
    }
    set Output to pTerm + iTerm + dTerm.
    // if the output goes beyond the max/min limits, reset it and adjust ITerm.
    if Output > MaxOutput {
        set Output to MaxOutput.
        // adjust the value of ITerm as well to prevent the value
        // from winding up out of control.
        if (Ki <> 0) and (LastSampleTime < sampleTime) {
            set ITerm to Output - min(Pterm + DTerm, MaxOutput).
        }
    }
    else if Output < MinOutput {
        set Output to MinOutput.
        // adjust the value of ITerm as well to prevent the value
        // from winding up out of control.
        if (Ki <> 0) and (LastSampleTime < sampleTime) {
            set ITerm to Output - max(Pterm + DTerm, MinOutput).
        }
    }
    set LastSampleTime to sampleTime.
    set LastInput to input.
    if Ki <> 0 set ErrorSum to ITerm / Ki.
    else set ErrorSum to 0.
    return Output.
}