blockPID

P, PI, PD, and PID controller

Information

PID controller in the standard form

yu = k/r   (e(t) + 1 ⁄ Ti   ∫ e(τ) dτ + Td d⁄dt e(t)),

where yu is the control signal before output limitation, e(t) = us(t) - um(t) is the control error, with us being the set point and um being the measured quantity, k is the gain, Ti is the time constant of the integral term, Td is the time constant of the derivative term, and r is a scaling factor, with default r=1. The scaling factor should be set to the typical order of magnitude of the range of the error e. For example, you may set r=100 to r=1000 if the control input is a pressure of a heating water circulation pump in units of Pascal, or leave r=1 if the control input is a room temperature.

Note that the units of k are the inverse of the units of the control error, while the units of Ti and Td are seconds.

The actual control output is

y = min( ymax, max( ymin, y)),

where ymin and ymax are limits for the control signal.

P, PI, PD, or PID action

Through the parameter controllerType, the controller can be configured as P, PI, PD or PID controller. The default configuration is PI.

Reverse or direct action

Through the parameter reverseActing, the controller can be configured to be reverse or direct acting. The above standard form is reverse acting, which is the default configuration. For a reverse acting controller, for a constant set point, an increase in measurement signal u_m decreases the control output signal y (Montgomery and McDowall, 2008). Thus,

  • for a heating coil with a two-way valve, leave reverseActing = true, but
  • for a cooling coil with a two-way valve, set reverseActing = false.

If reverseAction=false, then the error e above is multiplied by -1.

Anti-windup compensation

The controller anti-windup compensation is as follows: Instead of the above basic control law, the implementation is

yu = k   (e(t) ⁄ r + 1 ⁄ Ti   ∫ (-Δy + e(τ) ⁄ r) dτ + Td ⁄ r d⁄dt e(t)),

where the anti-windup compensation Δy is

Δy = (yu - y) ⁄ (k Ni),

where Ni > 0 is the time constant for the anti-windup compensation. To accelerate the anti-windup, decrease Ni.

Note that the anti-windup term (-Δy + e(τ) ⁄ r) shows that the range of the typical control error r should be set to a reasonable value so that

e(τ) ⁄ r = (us(τ) - um(τ)) ⁄ r

has order of magnitude one, and hence the anti-windup compensation should work well.

Reset of the controller output

Note that this controller implements an integrator anti-windup. Therefore, for most applications, the controller output does not need to be reset. However, if the controller is used in conjuction with equipment that is being switched on, better control performance may be achieved by resetting the controller output when the equipment is switched on. This is in particular the case in situations where the equipment control input should continuously increase as the equipment is switched on, such as a light dimmer that may slowly increase the luminance, or a variable speed drive of a motor that should continuously increase the speed. In this case, the controller Buildings.Controls.OBC.CDL.Reals.PIDWithReset that can reset the output should be used.

Approximation of the derivative term

The derivative of the control error d ⁄ dt e(t) is approximated using

d⁄dt x(t) = (e(t)-x(t)) Nd ⁄ Td,

and

d⁄dt e(t) ≈ Nd (e(t)-x(t)),

where x(t) is an internal state.

Guidance for tuning the control gains

The parameters of the controller can be manually adjusted by performing closed loop tests (= controller + plant connected together) and using the following strategy:

  1. Set very large limits, e.g., set ymax = 1000.
  2. Select a P-controller and manually enlarge the parameter k (the total gain of the controller) until the closed-loop response cannot be improved any more.
  3. Select a PI-controller and manually adjust the parameters k and Ti (the time constant of the integrator). The first value of Ti can be selected such that it is in the order of the time constant of the oscillations occurring with the P-controller. If, e.g., oscillations in the order of 100 seconds occur in the previous step, start with Ti=1/100 seconds.
  4. If you want to make the reaction of the control loop faster (but probably less robust against disturbances and measurement noise) select a PID-controller and manually adjust parameters k, Ti, Td (time constant of derivative block).
  5. Set the limits yMax and yMin according to your specification.
  6. Perform simulations such that the output of the PID controller goes in its limits. Tune Ni (Ni Ti is the time constant of the anti-windup compensation) such that the input to the limiter block (= lim.u) goes quickly enough back to its limits. If Ni is decreased, this happens faster. If Ni is very large, the anti-windup compensation is not effective and the controller works bad.

References

R. Montgomery and R. McDowall (2008). "Fundamentals of HVAC Control Systems." American Society of Heating Refrigerating and Air-Conditioning Engineers Inc. Atlanta, GA.

Parameters

TypeNameDefaultDescription
Buildings.Controls.OBC.CDL.Types.SimpleControllercontrollerTypeBuildings.Controls.OBC.CDL.Types.SimpleController.PIType of controller
Realr1Typical range of control error, used for scaling the control error
BooleanreverseActingtrueSet to true for reverse acting, or false for direct acting control action
Control gains
Realk1Gain of controller
RealTi0.5Time constant of integrator block
RealTd0.1Time constant of derivative block
Limits
RealyMax1Upper limit of output
RealyMin0Lower limit of output
Advanced › Integrator anti-windup
RealNi0.9Ni*Ti is time constant of anti-windup compensation
Advanced › Derivative block
RealNd10The higher Nd, the more ideal the derivative block
Advanced › Initialization
Realxi_start0Initial value of integrator state
Realyd_start0Initial value of derivative output

Connectors

TypeNameDefaultDescription
Buildings.Controls.OBC.CDL.Interfaces.RealInputu_sSetpoint input signal
Buildings.Controls.OBC.CDL.Interfaces.RealInputu_mMeasurement input signal
Buildings.Controls.OBC.CDL.Interfaces.RealOutputyActuator output signal

Components

TypeNameDefaultDescription
Buildings.Controls.OBC.CDL.Reals.SubtractcontrolErrorControl error (set point - measurement)
Buildings.Controls.OBC.CDL.Reals.MultiplyByParameterPGain for proportional control action
Buildings.Controls.OBC.CDL.Reals.IntegratorWithResetIIntegral term
Buildings.Controls.OBC.CDL.Reals.DerivativeDDerivative term
Buildings.Controls.OBC.CDL.Reals.SubtracterrPP error
Buildings.Controls.OBC.CDL.Reals.SubtracterrDD error
Buildings.Controls.OBC.CDL.Reals.SubtracterrI1I error (before anti-windup compensation)
Buildings.Controls.OBC.CDL.Reals.SubtracterrI2I error (after anti-windup compensation)
Buildings.Controls.OBC.CDL.Reals.LimiterlimLimiter

Revisions

  • April 13, 2026, by Michael Wetter:
    Added value for nominal attribute for integrator state I.y
    This is for IBPSA, issue 2106.
  • October 23, 2023, by Michael Wetter:
    Added value of control output y to icon.
  • May 20, 2022, by Michael Wetter:
    Refactored implementation to use new derivative block from CDL package.
    This is for Buildings, issue 3022.
  • May 6, 2022, by Michael Wetter:
    Corrected wrong documentation in how the derivative of the control error is approximated.
    This is for Buildings, issue 2994.
  • November 12, 2020, by Michael Wetter:
    Reformulated to remove dependency to Modelica.Units.SI.
    This is for Buildings, issue 2243.
  • October 15, 2020, by Michael Wetter:
    Added scaling factor r, removed set point weights wp and wd. Revised documentation.
    This is for Buildings, issue 2182.
  • August 4, 2020, by Jianjun Hu:
    Removed the conditional inputs trigger and y_rest_in. Refactored to internally implement the derivative block.
    This is for Buildings, issue 2056.
  • June 1, 2020, by Michael Wetter:
    Corrected wrong convention of reverse and direct action.
    This is for Buildings, issue 1365.
  • April 23, 2020, by Michael Wetter:
    Changed default parameters for limits yMax from unspecified to 1 and yMin from -yMax to 0.
    This is for Buildings, issue 1888.
  • April 7, 2020, by Michael Wetter:
    Reimplemented block using only CDL constructs. This refactoring removes the no longer use parameters xd_start that was used to initialize the state of the derivative term. This state is now initialized based on the requested initial output yd_start which is a new parameter with a default of 0. Also, removed the parameters y_start and initType because the initial output of the controller can be set by using xi_start and yd_start. This is a non-backward compatible change, made to simplify the controller through the removal of options that can be realized differently and are hardly ever used. This refactoring also removes the parameter strict that was used in the output limiter. The new implementation enforces a strict check by default.
    This is for Buildings, issue 1878.
  • March 9, 2020, by Michael Wetter:
    Corrected unit declaration for gain k.
    See Buildings, issue 1821.
  • March 2, 2020, by Michael Wetter:
    Changed icon to display dynamically the output value.
  • February 25, 2020, by Michael Wetter:
    Changed icon to display the output value.
  • October 19, 2019, by Michael Wetter:
    Disabled homotopy to ensure bounded outputs by copying the implementation from MSL 3.2.3 and by hardcoding the implementation for homotopyType=NoHomotopy.
    See Buildings, issue 1221.
  • November 13, 2017, by Michael Wetter:
    Changed default controller type from PID to PI.
  • November 6, 2017, by Michael Wetter:
    Explicitly declared types and used integrator with reset from CDL.
  • October 22, 2017, by Michael Wetter:
    Added to CDL to have a PI controller with integrator reset.
  • September 29, 2016, by Michael Wetter:
    Refactored model.
  • August 25, 2016, by Michael Wetter:
    Removed parameter limitsAtInit because it was only propagated to the instance limiter, but this block no longer makes use of this parameter. This is a non-backward compatible change.
    Revised implemenentation, added comments, made some parameter in the instances final.
  • July 18, 2016, by Philipp Mehrfeld:
    Added integrator reset. This is for Buildings, issue 494.
  • March 15, 2016, by Michael Wetter:
    Changed the default value to strict=true in order to avoid events when the controller saturates. This is for Buildings, issue 433.
  • February 24, 2010, by Michael Wetter:
    First implementation.