Table of Contents

Pid

Namespace
ZCore
FUNCTION_BLOCK Pid

Simple PID implementation (as seen on: https://en.wikipedia.org/wiki/PID_controller#Pseudocode) but with integrated Anti-Windup.

A proportional–integral–derivative controller (PID controller or three-term controller) is a control loop mechanism employing feedback that is widely used in industrial control systems and a variety of other applications requiring continuously modulated control. A PID controller continuously calculates an error value e(t) as the difference between a desired setpoint (SP) (set with SetSetPoint and a measured process variable (PV) (set with SetInput and applies a correction based on proportional, integral and derivative terms (denoted P, I, and D respectively) and also respecting the anti windup methodology.

PIDs come in different configurations. This implementation offers

What follows is a short example how the Pid can be used in practice. In the example we control the AnalogOutput _io.FanPower in a way to keep a temperature, which is measured by an AnalogInput _io.Temperature, at _setpoint. Initialization of said I/Os is not covered in the example, for this, please refer to the I/O documentation. The control parameters _kp,_ki,_kd are yet to be found, but in the comments we describe a way how to do this experimentally. We also enable anti-windup by setting limits, which the PID's output is clamped in.

// Construction (in a VAR block)
_pid : ZCore.Pid(0); // the parameter for the cycle time is set to 0 for now
_rt : ZAux.RealTime(); // used to retrieve the cycle time of the current task in initalization
_kp : LREAL := 1E-6; // start with a small value gain, then increase manually until the system oscillates
_ki : LREAL := 0; // start without integration part, when the oscillation gain has been found, set to 0.6 * kp and optimize further
_kd : LREAL; := 0; // start without derivative part, when the oscillation gain has been found, set to 0.125 * kp and optimize further
_setpoint : LREAL := ?;
_minOutput : LREAL := ?;
_maxOutput : LREAL := ?;

----------------------------------

// Initialization (i.e. in a _step.OnEntry() condition)
_pid.SetCycleTime(_rt.CycleTimeInSeconds());
_pid.SetSetPoint(_setpoint);
_pid.SetControllerParameters(_kp, _ki, _kd);
_pid.EnableAntiWindup(TRUE, _minOutput, _maxOutput);
_pid.Reset(); // Optional to reset the integral and derivative parts

----------------------------------

// To be called cyclically (i.e. in a step outside of the OnEntry condition)
_pid.SetInput(_io.Temperature.Value);
_pid.Cyclic();
_io.FanPower.Value := _pid.Output;

Constructor

FB_init

METHOD FB_init (
 [input] bInitRetains : BOOL,
 [input] bInCopyCode : BOOL,
 [input] cycleTime : LREAL) : BOOL

Inputs

bInitRetains BOOL

if TRUE, the retain variables are initialized (warm start / cold start)

bInCopyCode BOOL

if TRUE, the instance afterwards gets moved into the copy code (online change)

cycleTime LREAL

Cycle time in seconds of the PID controller loop in milliseconds (Attention: if not called every plc cycle, enter the actual cycle time of the Cyclic-method here)

Returns

BOOL

Properties

ActualIntegral

PROPERTY ActualIntegral : LREAL

Returns the actual integral value of the integral part of the PID controller if parametrized accordingly. This can sometimes be useful to enable proper anti windup parameters by EnaleAntiWindup

Property Value

LREAL

AntiWindupEnabled

PROPERTY AntiWindupEnabled : BOOL

Returns TRUE if the AntiWindup function was enabled before by passing on:=TRUE with EnableAntiWindup.

Property Value

BOOL

AntiWindupType

PROPERTY AntiWindupType : PidAntiWindupType

Controls the method that is used if AntiWindup is enabled.

Note

For backwards compability the default anti-windup method is IntegralLimitation. However, in practice this method has a worse timing behavior when recovering from saturation and should no longer be used for new applications.

Property Value

PidAntiWindupType

MaxOutput

PROPERTY MaxOutput : LREAL

Returns the last set MaxOutput Value set with EnableAntiWindup method. To check if AntiWindup is enabled test AntiWindupEnabled property.

Property Value

LREAL

MinOutput

PROPERTY MinOutput : LREAL

Returns the last set MinOutput Value set with EnableAntiWindup method. To check if AntiWindup is enabled test AntiWindupEnabled property.

Property Value

LREAL

Methods

Cyclic

METHOD Cyclic ()

This method has to be cyclically called by the PLC program in order to let this Pid work properly For very slow plants (processes and actuators) it is no necessary to call this method every PLC cycle, but always make sure to parameterize the right cycle time However, it is not recomended to call this method randomly

EnableAntiWindup

METHOD EnableAntiWindup (
 [input] on : BOOL,
 [input] minOutput : LREAL,
 [input] maxOutput : LREAL)

This method should be used to limit the PIDs output to physical relevant values. For instance, of a temperature should be controlled within some giving window, the user should supply the PID with this values. For instance, a heating device can not cool. Here a negative output should be cut off by setting minOutput to zero.

If anti windup is enabled, the integral part as well as the controllers output is limited to the windup parameters. The integral part is limited in the cyclic method and the controllers output is limited in the output method, respectively.

Inputs

on BOOL

TRUE if anti windup should be generally enabled and FALSE if not

minOutput LREAL

maximum value for the integral term to get summed up by the algorithm (in most cases its a negative value)

maxOutput LREAL

minimum value for the integral term to get summed up by the algorithm (in most cases its a positive value)

IsAntiWindupEnabled

METHOD IsAntiWindupEnabled () : BOOL

Returns TRUE if the AntiWindup function was enabled before by passing on:=TRUE with EnableAntiWindup.

Returns

BOOL

Output

METHOD Output () : LREAL

Returns the calculated control output based on the parameters given to the proportional, integral and derivative terms of the PID controller. If antiwindup is enabled, the windup constants set with EnableAntiWindup are used to limit the controllers output;

Returns

LREAL

Reset

METHOD FINAL Reset ()

This method resets the integral and derivative part of the PID, the method should in most cases be called after the controller parameters changed by calling SetControllerParametersParallel or SetControllerParameters.

SetAntiWindupType

METHOD SetAntiWindupType (
 [input] antiWindupType : PidAntiWindupType)

Controls the method that is used if AntiWindup is enabled.

Note

For backwards compability the default anti-windup method is IntegralLimitation. However, in practice this method has a worse timing behavior when recovering from saturation and should no longer be used for new applications.

Inputs

antiWindupType PidAntiWindupType

SetControllerParameters

METHOD PUBLIC SetControllerParameters (
 [input] kp : LREAL,
 [input] tn : LREAL,
 [input] tv : LREAL)

This method is used to set the control parameters for the PID. The parameters that are passed with this method consider a PID in semi-parallel configuration, where P is in series with the I and D part, which are in turn parallel to each other.

This method can be called while the controller is active, but may cause unwanted side-effects. Usually a seperate call to Reset should be performed to reset the (old) integral and derivative parts.

Inputs

kp LREAL

gain

tn LREAL

integral time (in s)

tv LREAL

derivative time (in s)

SetControllerParametersParallel

METHOD PUBLIC SetControllerParametersParallel (
 [input] kp : LREAL,
 [input] ki : LREAL,
 [input] kd : LREAL)

This method is used to set the control parameters for the PID. The parameters that are passed with this method consider a PID in parallel configuration, where P, I and D are all in parallel to each other. The advantage when parametrizing this kind of PID is that all parameters are independent from each other.

  • The proportional part (kp) determines how aggressively the controller reacts to the current amount of error.
  • The integral part (ki) determines how aggressively the controller reacts to the error over time.
  • The derivative part (kd) determines how aggressively the controller reacts to the change in error. This parameter helps to 'slow' down if the input is approaching the set-point too fast.

A common way (trail-and-error method) to tune a PID is

  1. Set ki=kd=0 and increase kp until the system starts to oscillate
  2. Set ki=0.6 kp and kd=0.125 kp

This can be called while the controller is active, but may cause unwanted side-effects. Usually a seperate call to Reset should be performed to reset the (old) integral and derivative parts.

Inputs

kp LREAL

gain

ki LREAL

integral gain

kd LREAL

derivative gain

SetCycleTime

METHOD SetCycleTime (
 [input] cycleTime : LREAL)

This method overwrite the default cycle time of the PID that is the cycle time of the task. Use this method if you are not calling setInput on every cycle of the task, but only every x. cycle. cycleTime should be the elapsed time (in seconds) between calls to SetInput and Cyclic, respectively.

Inputs

cycleTime LREAL

in seconds

SetInput

METHOD SetInput (
 [input] value : LREAL)

This method should be called once every cycle to update the input value for the PID. This input parameter combined with the control parameters of the PID yield the output that should be set for this cycle.

Inputs

value LREAL

SetSetPoint

METHOD SetSetPoint (
 [input] value : LREAL)

This method should be called to specify the set point of this PID.

Inputs

value LREAL