Buildings.Controls.Continuous

Package with models for discrete time controls

Information

This package contains component models for continuous time controls. For additional models, see also Modelica.Blocks.Discrete.

Extends from Modelica.Icons.Package (Icon for standard packages).

Package Content

Name Description
Buildings.Controls.Continuous.LimPID LimPID P, PI, PD, and PID controller with limited output, anti-windup compensation and setpoint weighting
Buildings.Controls.Continuous.NumberOfRequests NumberOfRequests Outputs the number of signals that are above/below a certain threshold
Buildings.Controls.Continuous.OffTimer OffTimer Records the time since the input changed to false
Buildings.Controls.Continuous.SignalRanker SignalRanker Ranks output signals such that y[i] >= y[i+1]
Buildings.Controls.Continuous.Examples Examples Collection of models that illustrate model use and test models
Buildings.Controls.Continuous.Validation Validation Collection of validation models

Buildings.Controls.Continuous.LimPID Buildings.Controls.Continuous.LimPID

P, PI, PD, and PID controller with limited output, anti-windup compensation and setpoint weighting

Buildings.Controls.Continuous.LimPID

Information

PID controller in the standard form

y = k   ( e(t) + 1 ⁄ Ti   ∫ e(s) ds + Td de(t)⁄dt ),

where y is the control signal, e(t) = us - um 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 and Td is the time constant of the derivative term.

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.

For detailed treatment of integrator anti-windup, set-point weights and output limitation, see Modelica.Blocks.Continuous.LimPID.

Options

This controller can be configured as follows.
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.

Direct or reverse acting

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,

Reset of the controller output

The controller can be configured to enable an input port that allows resetting the controller output. The controller output can be reset as follows:

Note that this controller implements an integrator anti-windup. Therefore, for most applications, keeping the default setting of reset = Buildings.Types.Reset.Disabled is sufficient. 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.

References

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

Extends from Modelica.Blocks.Interfaces.SVcontrol (Single-Variable continuous controller).

Parameters

TypeNameDefaultDescription
SimpleControllercontrollerTypeModelica.Blocks.Types.Simple...Type of controller
Realk1Gain of controller
TimeTi0.5Time constant of Integrator block [s]
TimeTd0.1Time constant of Derivative block [s]
RealyMax1Upper limit of output
RealyMin0Lower limit of output
Realwp1Set-point weight for Proportional block (0..1)
Realwd0Set-point weight for Derivative block (0..1)
RealNi0.9Ni*Ti is time constant of anti-windup compensation
RealNd10The higher Nd, the more ideal the derivative block
BooleanreverseActingtrueSet to true for reverse acting, or false for direct acting control action
Initialization
InitinitTypeModelica.Blocks.Types.Init.I...Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)
Realxi_start0Initial or guess value value for integrator output (= integrator state)
Realxd_start0Initial or guess value for state of derivative block
Realy_start0Initial value of output
Integrator reset
ResetresetBuildings.Types.Reset.DisabledType of controller output reset
Realy_resetxi_startValue to which the controller output is reset if the boolean trigger has a rising edge, used if reset == Buildings.Types.Reset.Parameter
Advanced
Booleanstricttrue= true, if strict limits with noEvent(..)

Connectors

TypeNameDescription
input RealInputu_sConnector of setpoint input signal
input RealInputu_mConnector of measurement input signal
output RealOutputyConnector of actuator output signal
input BooleanInputtriggerResets the controller output when trigger becomes true
input RealInputy_reset_inInput signal for state to which integrator is reset, enabled if reset = Buildings.Types.Reset.Input

Modelica definition

block LimPID "P, PI, PD, and PID controller with limited output, anti-windup compensation and setpoint weighting" extends Modelica.Blocks.Interfaces.SVcontrol; output Real controlError = u_s - u_m "Control error (set point - measurement)"; parameter Modelica.Blocks.Types.SimpleController controllerType= Modelica.Blocks.Types.SimpleController.PI "Type of controller"; parameter Real k(min=0) = 1 "Gain of controller"; parameter Modelica.Units.SI.Time Ti(min=Modelica.Constants.small) = 0.5 "Time constant of Integrator block"; parameter Modelica.Units.SI.Time Td(min=0) = 0.1 "Time constant of Derivative block"; parameter Real yMax(start=1)=1 "Upper limit of output"; parameter Real yMin=0 "Lower limit of output"; parameter Real wp(min=0) = 1 "Set-point weight for Proportional block (0..1)"; parameter Real wd(min=0) = 0 "Set-point weight for Derivative block (0..1)"; parameter Real Ni(min=100*Modelica.Constants.eps) = 0.9 "Ni*Ti is time constant of anti-windup compensation"; parameter Real Nd(min=100*Modelica.Constants.eps) = 10 "The higher Nd, the more ideal the derivative block"; parameter Modelica.Blocks.Types.Init initType=Modelica.Blocks.Types.Init.InitialState "Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)"; // Removed as the Limiter block no longer uses this parameter. // parameter Boolean limitsAtInit = true // "= false, if limits are ignored during initialization" // annotation(Evaluate=true, Dialog(group="Initialization")); parameter Real xi_start=0 "Initial or guess value value for integrator output (= integrator state)"; parameter Real xd_start=0 "Initial or guess value for state of derivative block"; parameter Real y_start=0 "Initial value of output"; parameter Boolean strict=true "= true, if strict limits with noEvent(..)"; parameter Boolean reverseActing = true "Set to true for reverse acting, or false for direct acting control action"; parameter Buildings.Types.Reset reset = Buildings.Types.Reset.Disabled "Type of controller output reset"; parameter Real y_reset=xi_start "Value to which the controller output is reset if the boolean trigger has a rising edge, used if reset == Buildings.Types.Reset.Parameter"; Modelica.Blocks.Interfaces.BooleanInput trigger if reset <> Buildings.Types.Reset.Disabled "Resets the controller output when trigger becomes true"; Modelica.Blocks.Interfaces.RealInput y_reset_in if reset == Buildings.Types.Reset.Input "Input signal for state to which integrator is reset, enabled if reset = Buildings.Types.Reset.Input"; Modelica.Blocks.Math.Add addP(k1=revAct*wp, k2=-revAct) "Adder for P gain"; Modelica.Blocks.Math.Add addD(k1=revAct*wd, k2=-revAct) if with_D "Adder for D gain"; Modelica.Blocks.Math.Gain P(k=1) "Proportional term"; Utilities.Math.IntegratorWithReset I( final reset=if reset == Buildings.Types.Reset.Disabled then reset else Buildings.Types.Reset.Input, final y_reset=y_reset, final k=unitTime/Ti, final y_start=xi_start, final initType=if initType == Modelica.Blocks.Types.Init.SteadyState then Modelica.Blocks.Types.Init.SteadyState else if initType == Modelica.Blocks.Types.Init.InitialState or initType == Modelica.Blocks.Types.Init.InitialState then Modelica.Blocks.Types.Init.InitialState else Modelica.Blocks.Types.Init.NoInit) if with_I "Integral term"; Modelica.Blocks.Continuous.Derivative D( final k=Td/unitTime, final T=max([Td/Nd,1.e-14]), final x_start=xd_start, final initType=if initType == Modelica.Blocks.Types.Init.SteadyState or initType == Modelica.Blocks.Types.Init.InitialOutput then Modelica.Blocks.Types.Init.SteadyState else if initType == Modelica.Blocks.Types.Init.InitialState then Modelica.Blocks.Types.Init.InitialState else Modelica.Blocks.Types.Init.NoInit) if with_D "Derivative term"; Modelica.Blocks.Math.Add3 addPID( final k1=1, final k2=1, final k3=1) "Adder for the gains"; protected constant Modelica.Units.SI.Time unitTime=1; final parameter Real revAct = if reverseActing then 1 else -1 "Switch for sign for reverse or direct acting controller"; parameter Boolean with_I = controllerType==Modelica.Blocks.Types.SimpleController.PI or controllerType==Modelica.Blocks.Types.SimpleController.PID "Boolean flag to enable integral action"; parameter Boolean with_D = controllerType==Modelica.Blocks.Types.SimpleController.PD or controllerType==Modelica.Blocks.Types.SimpleController.PID "Boolean flag to enable derivative action"; Modelica.Blocks.Sources.Constant Dzero(final k=0) if not with_D "Zero input signal"; Modelica.Blocks.Sources.Constant Izero(final k=0) if not with_I "Zero input signal"; Modelica.Blocks.Interfaces.RealInput y_reset_internal "Internal connector for controller output reset"; Modelica.Blocks.Math.Add3 addI( final k1=revAct, final k2=-revAct) if with_I "Adder for I gain"; Modelica.Blocks.Math.Add addSat( final k1=+1, final k2=-1) if with_I "Adder for integrator feedback"; Modelica.Blocks.Math.Gain gainPID(final k=k) "Multiplier for control gain"; Modelica.Blocks.Math.Gain gainTrack(k=1/(k*Ni)) if with_I "Gain for anti-windup compensation"; Limiter limiter( final uMax=yMax, final uMin=yMin, final strict=strict) "Output limiter"; Modelica.Blocks.Sources.RealExpression intRes( final y=y_reset_internal/k - addPID.u1 - addPID.u2) if reset <> Buildings.Types.Reset.Disabled "Signal source for integrator reset"; // The block Limiter below has been implemented as it is introduced in MSL 3.2.3, but // not all tools include MSL 3.2.3. // See https://github.com/ibpsa/modelica-ibpsa/pull/1222#issuecomment-554114617 block Limiter "Limit the range of a signal" parameter Real uMax(start=1) "Upper limits of input signals"; parameter Real uMin= -uMax "Lower limits of input signals"; parameter Boolean strict=false "= true, if strict limits with noEvent(..)"; parameter Boolean limitsAtInit=true "Has no longer an effect and is only kept for backwards compatibility (the implementation uses now the homotopy operator)"; extends Modelica.Blocks.Interfaces.SISO; equation assert(uMax >= uMin, "Limiter: Limits must be consistent. However, uMax (=" + String(uMax) + ") < uMin (=" + String(uMin) + ")"); if strict then y = smooth(0, noEvent(if u > uMax then uMax else if u < uMin then uMin else u)); else y = smooth(0,if u > uMax then uMax else if u < uMin then uMin else u); end if; end Limiter; initial equation if initType == Modelica.Blocks.Types.Init.InitialOutput then gainPID.y = y_start; end if; equation assert(yMax >= yMin, "LimPID: Limits must be consistent. However, yMax (=" + String(yMax) + ") < yMin (=" + String(yMin) + ")"); if initType == Modelica.Blocks.Types.Init.InitialOutput and (y_start < yMin or y_start > yMax) then Modelica.Utilities.Streams.error("LimPID: Start value y_start (=" + String(y_start) + ") is outside of the limits of yMin (=" + String(yMin) +") and yMax (=" + String(yMax) + ")"); end if; // Equations for conditional connectors connect(y_reset_in, y_reset_internal); if reset <> Buildings.Types.Reset.Input then y_reset_internal = y_reset; end if; connect(u_s, addP.u1); connect(u_s, addD.u1); connect(u_s, addI.u1); connect(addP.y, P.u); connect(addD.y, D.u); connect(addI.y, I.u); connect(P.y, addPID.u1); connect(D.y, addPID.u2); connect(I.y, addPID.u3); connect(addPID.y, gainPID.u); connect(gainPID.y, addSat.u2); connect(gainPID.y, limiter.u); connect(limiter.y, addSat.u1); connect(limiter.y, y); connect(addSat.y, gainTrack.u); connect(gainTrack.y, addI.u3); connect(u_m, addP.u2); connect(u_m, addD.u2); connect(u_m, addI.u2); connect(Dzero.y, addPID.u2); connect(Izero.y, addPID.u3); connect(trigger, I.trigger); connect(intRes.y, I.y_reset_in); end LimPID;

Buildings.Controls.Continuous.NumberOfRequests Buildings.Controls.Continuous.NumberOfRequests

Outputs the number of signals that are above/below a certain threshold

Buildings.Controls.Continuous.NumberOfRequests

Information

Block that outputs the number of inputs that exceed a threshold. The parameter kind is used to determine the kind of the inequality. The table below shows the allowed settings.

Value of parameter kind Output signal incremented by 1 for each i ∈ {1, ..., nin} if
0 u[i] > threShold
1 u[i] ≥ threShold
2 u[i] ≤ threShold
3 u[i] < threShold

This model may be used to check how many rooms exceed a temperature threshold.

Extends from Modelica.Blocks.Icons.Block (Basic graphical layout of input/output block).

Parameters

TypeNameDefaultDescription
Integernin Number of inputs
RealthreShold0Threshold
Integerkind Set to 0 for u>threShold, to 1 for >=, to 2 for <= or to 3 for <

Connectors

TypeNameDescription
output IntegerOutputyNumber of input signals that violate the threshold
input RealInputu[nin]Input signals

Modelica definition

block NumberOfRequests "Outputs the number of signals that are above/below a certain threshold" extends Modelica.Blocks.Icons.Block; parameter Integer nin "Number of inputs"; parameter Real threShold = 0 "Threshold"; parameter Integer kind "Set to 0 for u>threShold, to 1 for >=, to 2 for <= or to 3 for <"; Modelica.Blocks.Interfaces.IntegerOutput y "Number of input signals that violate the threshold"; Modelica.Blocks.Interfaces.RealInput u[nin] "Input signals"; algorithm y := 0; for i in 1:nin loop if kind == 0 then if u[i] > threShold then y := y+1; end if; end if; if kind == 1 then if u[i] >= threShold then y := y+1; end if; end if; if kind == 2 then if u[i] <= threShold then y := y+1; end if; end if; if kind == 3 then if u[i] < threShold then y := y+1; end if; end if; end for; end NumberOfRequests;

Buildings.Controls.Continuous.OffTimer Buildings.Controls.Continuous.OffTimer

Records the time since the input changed to false

Buildings.Controls.Continuous.OffTimer

Information

Timer that starts at the initial time with a value of 0, and gets reset each time the input signal switches to false.

For example, if the simulation starts at t = 10 and at t=11, the input becomes false, then the timer outputs y=t-10 for t < 11, and y=t-11 afterwards, unless the input becomes false again.

Extends from Modelica.Blocks.Icons.PartialBooleanBlock (Basic graphical layout of logical block).

Connectors

TypeNameDescription
input BooleanInputuConnector of Boolean input signal
output RealOutputyConnector of Real output signal

Modelica definition

model OffTimer "Records the time since the input changed to false" extends Modelica.Blocks.Icons.PartialBooleanBlock; Modelica.Blocks.Interfaces.BooleanInput u "Connector of Boolean input signal"; Modelica.Blocks.Interfaces.RealOutput y "Connector of Real output signal"; protected discrete Modelica.Units.SI.Time entryTime "Time instant when u became true"; initial equation pre(entryTime) = time; equation when (not u) then entryTime = time; end when; y = time - entryTime; end OffTimer;

Buildings.Controls.Continuous.SignalRanker Buildings.Controls.Continuous.SignalRanker

Ranks output signals such that y[i] >= y[i+1]

Buildings.Controls.Continuous.SignalRanker

Information

Block that sorts the input signal u[:] such that the output signal satisfies y[i] >= y[i+1] for all i=1, ..., nin-1.

This block may for example be used in a variable air volume flow controller to access the position of the dampers that are most open.

Extends from Modelica.Blocks.Interfaces.MIMO (Multiple Input Multiple Output continuous control block).

Parameters

TypeNameDefaultDescription
Integernin1Number of inputs
IntegernoutninNumber of outputs

Connectors

TypeNameDescription
input RealInputu[nin]Connector of Real input signals
output RealOutputy[nout]Connector of Real output signals

Modelica definition

block SignalRanker "Ranks output signals such that y[i] >= y[i+1]" extends Modelica.Blocks.Interfaces.MIMO(final nout=nin); equation y = Modelica.Math.Vectors.sort(u, ascending=false); end SignalRanker;

Buildings.Controls.Continuous.LimPID.Limiter Buildings.Controls.Continuous.LimPID.Limiter

Limit the range of a signal

Buildings.Controls.Continuous.LimPID.Limiter

Information

Extends from Modelica.Blocks.Interfaces.SISO (Single Input Single Output continuous control block).

Parameters

TypeNameDefaultDescription
RealuMax Upper limits of input signals
RealuMin-uMaxLower limits of input signals
Advanced
Booleanstrictfalse= true, if strict limits with noEvent(..)
Dummy
BooleanlimitsAtInittrueHas no longer an effect and is only kept for backwards compatibility (the implementation uses now the homotopy operator)

Connectors

TypeNameDescription
input RealInputuConnector of Real input signal
output RealOutputyConnector of Real output signal

Modelica definition

block Limiter "Limit the range of a signal" parameter Real uMax(start=1) "Upper limits of input signals"; parameter Real uMin= -uMax "Lower limits of input signals"; parameter Boolean strict=false "= true, if strict limits with noEvent(..)"; parameter Boolean limitsAtInit=true "Has no longer an effect and is only kept for backwards compatibility (the implementation uses now the homotopy operator)"; extends Modelica.Blocks.Interfaces.SISO; equation assert(uMax >= uMin, "Limiter: Limits must be consistent. However, uMax (=" + String(uMax) + ") < uMin (=" + String(uMin) + ")"); if strict then y = smooth(0, noEvent(if u > uMax then uMax else if u < uMin then uMin else u)); else y = smooth(0,if u > uMax then uMax else if u < uMin then uMin else u); end if; end Limiter;