You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
7.1 KiB
135 lines
7.1 KiB
6 years ago
|
within AIDAModelica;
|
||
|
block PID_discrete "PID-controller in additive description form"
|
||
|
import Modelica.Blocks.Types.InitPID;
|
||
|
import Modelica.Blocks.Types.Init;
|
||
|
extends Modelica.Blocks.Interfaces.SISO;
|
||
|
parameter Real k(unit = "1") = 1 "Gain";
|
||
|
parameter SIunits.Time Ti(min = Modelica.Constants.small, start = 0.5) "Time Constant of Integrator";
|
||
|
parameter SIunits.Time Td(min = 0, start = 0.1) "Time Constant of Derivative block";
|
||
|
parameter Real Nd(min = Modelica.Constants.small) = 10 "The higher Nd, the more ideal the derivative block";
|
||
|
parameter Modelica.Blocks.Types.InitPID initType = Modelica.Blocks.Types.InitPID.DoNotUse_InitialIntegratorState "Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)" annotation(
|
||
|
Evaluate = true,
|
||
|
Dialog(group = "Initialization"));
|
||
|
parameter Real xi_start = 0 "Initial or guess value value for integrator output (= integrator state)" annotation(
|
||
|
Dialog(group = "Initialization"));
|
||
|
parameter Real xd_start = 0 "Initial or guess value for state of derivative block" annotation(
|
||
|
Dialog(group = "Initialization"));
|
||
|
parameter Real y_start = 0 "Initial value of output" annotation(
|
||
|
Dialog(enable = initType == InitPID.InitialOutput, group = "Initialization"));
|
||
|
constant SI.Time unitTime = 1 annotation(
|
||
|
HideResult = true);
|
||
|
Blocks.Math.Gain P(k = 1) "Proportional part of PID controller" annotation(
|
||
|
Placement(transformation(extent = {{-60, 60}, {-20, 100}})));
|
||
|
Blocks.Continuous.Integrator I(k = unitTime / Ti, y_start = xi_start, initType = if initType == InitPID.SteadyState then Init.SteadyState else if initType == InitPID.InitialState or initType == InitPID.DoNotUse_InitialIntegratorState then Init.InitialState else Init.NoInit) "Integral part of PID controller" annotation(
|
||
|
Placement(transformation(extent = {{-60, -20}, {-20, 20}})));
|
||
|
Blocks.Continuous.Derivative D(k = Td / unitTime, T = max([Td / Nd, 100 * Modelica.Constants.eps]), x_start = xd_start, initType = if initType == InitPID.SteadyState or initType == InitPID.InitialOutput then Init.SteadyState else if initType == InitPID.InitialState then Init.InitialState else Init.NoInit) "Derivative part of PID controller" annotation(
|
||
|
Placement(transformation(extent = {{-60, -100}, {-20, -60}})));
|
||
|
Blocks.Math.Gain Gain(k = k) "Gain of PID controller" annotation(
|
||
|
Placement(transformation(extent = {{60, -10}, {80, 10}})));
|
||
|
Blocks.Math.Add3 Add annotation(
|
||
|
Placement(transformation(extent = {{20, -10}, {40, 10}})));
|
||
|
initial equation
|
||
|
if initType == InitPID.InitialOutput then
|
||
|
y = y_start;
|
||
|
end if;
|
||
|
equation
|
||
|
connect(u, P.u) annotation(
|
||
|
Line(points = {{-120, 0}, {-80, 0}, {-80, 80}, {-64, 80}}, color = {0, 0, 127}));
|
||
|
connect(u, I.u) annotation(
|
||
|
Line(points = {{-120, 0}, {-64, 0}}, color = {0, 0, 127}));
|
||
|
connect(u, D.u) annotation(
|
||
|
Line(points = {{-120, 0}, {-80, 0}, {-80, -80}, {-64, -80}}, color = {0, 0, 127}));
|
||
|
connect(P.y, Add.u1) annotation(
|
||
|
Line(points = {{-18, 80}, {0, 80}, {0, 8}, {18, 8}}, color = {0, 0, 127}));
|
||
|
connect(I.y, Add.u2) annotation(
|
||
|
Line(points = {{-18, 0}, {18, 0}}, color = {0, 0, 127}));
|
||
|
connect(D.y, Add.u3) annotation(
|
||
|
Line(points = {{-18, -80}, {0, -80}, {0, -8}, {18, -8}}, color = {0, 0, 127}));
|
||
|
connect(Add.y, Gain.u) annotation(
|
||
|
Line(points = {{41, 0}, {58, 0}}, color = {0, 0, 127}));
|
||
|
connect(Gain.y, y) annotation(
|
||
|
Line(points = {{81, 0}, {110, 0}}, color = {0, 0, 127}));
|
||
|
annotation(
|
||
|
defaultComponentName = "PID",
|
||
|
Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100.0, -100.0}, {100.0, 100.0}}), graphics = {Line(points = {{-80.0, 78.0}, {-80.0, -90.0}}, color = {192, 192, 192}), Polygon(lineColor = {192, 192, 192}, fillColor = {192, 192, 192}, fillPattern = FillPattern.Solid, points = {{-80.0, 90.0}, {-88.0, 68.0}, {-72.0, 68.0}, {-80.0, 90.0}}), Line(points = {{-90.0, -80.0}, {82.0, -80.0}}, color = {192, 192, 192}), Polygon(lineColor = {192, 192, 192}, fillColor = {192, 192, 192}, fillPattern = FillPattern.Solid, points = {{90.0, -80.0}, {68.0, -72.0}, {68.0, -88.0}, {90.0, -80.0}}), Line(points = {{-80, -80}, {-80, -20}, {60, 80}}, color = {0, 0, 127}), Text(lineColor = {192, 192, 192}, extent = {{-20.0, -60.0}, {80.0, -20.0}}, textString = "PID"), Text(extent = {{-150.0, -150.0}, {150.0, -110.0}}, textString = "Ti=%Ti")}),
|
||
|
Documentation(info = "<html>
|
||
|
<p>
|
||
|
This is the text-book version of a PID-controller.
|
||
|
For a more practically useful PID-controller, use
|
||
|
block LimPID.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The PID block can be initialized in different
|
||
|
ways controlled by parameter <b>initType</b>. The possible
|
||
|
values of initType are defined in
|
||
|
<a href=\"modelica://Modelica.Blocks.Types.InitPID\">Modelica.Blocks.Types.InitPID</a>.
|
||
|
This type is identical to
|
||
|
<a href=\"modelica://Modelica.Blocks.Types.Init\">Types.Init</a>,
|
||
|
with the only exception that the additional option
|
||
|
<b>DoNotUse_InitialIntegratorState</b> is added for
|
||
|
backward compatibility reasons (= integrator is initialized with
|
||
|
InitialState whereas differential part is initialized with
|
||
|
NoInit which was the initialization in version 2.2 of the Modelica
|
||
|
standard library).
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Based on the setting of initType, the integrator (I) and derivative (D)
|
||
|
blocks inside the PID controller are initialized according to the following table:
|
||
|
</p>
|
||
|
|
||
|
<table border=1 cellspacing=0 cellpadding=2>
|
||
|
<tr><td valign=\"top\"><b>initType</b></td>
|
||
|
<td valign=\"top\"><b>I.initType</b></td>
|
||
|
<td valign=\"top\"><b>D.initType</b></td></tr>
|
||
|
|
||
|
<tr><td valign=\"top\"><b>NoInit</b></td>
|
||
|
<td valign=\"top\">NoInit</td>
|
||
|
<td valign=\"top\">NoInit</td></tr>
|
||
|
|
||
|
<tr><td valign=\"top\"><b>SteadyState</b></td>
|
||
|
<td valign=\"top\">SteadyState</td>
|
||
|
<td valign=\"top\">SteadyState</td></tr>
|
||
|
|
||
|
<tr><td valign=\"top\"><b>InitialState</b></td>
|
||
|
<td valign=\"top\">InitialState</td>
|
||
|
<td valign=\"top\">InitialState</td></tr>
|
||
|
|
||
|
<tr><td valign=\"top\"><b>InitialOutput</b><br>
|
||
|
and initial equation: y = y_start</td>
|
||
|
<td valign=\"top\">NoInit</td>
|
||
|
<td valign=\"top\">SteadyState</td></tr>
|
||
|
|
||
|
<tr><td valign=\"top\"><b>DoNotUse_InitialIntegratorState</b></td>
|
||
|
<td valign=\"top\">InitialState</td>
|
||
|
<td valign=\"top\">NoInit</td></tr>
|
||
|
</table>
|
||
|
|
||
|
<p>
|
||
|
In many cases, the most useful initial condition is
|
||
|
<b>SteadyState</b> because initial transients are then no longer
|
||
|
present. If initType = InitPID.SteadyState, then in some
|
||
|
cases difficulties might occur. The reason is the
|
||
|
equation of the integrator:
|
||
|
</p>
|
||
|
|
||
|
<pre>
|
||
|
<b>der</b>(y) = k*u;
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
The steady state equation \"der(x)=0\" leads to the condition that the input u to the
|
||
|
integrator is zero. If the input u is already (directly or indirectly) defined
|
||
|
by another initial condition, then the initialization problem is <b>singular</b>
|
||
|
(has none or infinitely many solutions). This situation occurs often
|
||
|
for mechanical systems, where, e.g., u = desiredSpeed - measuredSpeed and
|
||
|
since speed is both a state and a derivative, it is natural to
|
||
|
initialize it with zero. As sketched this is, however, not possible.
|
||
|
The solution is to not initialize u or the variable that is used
|
||
|
to compute u by an algebraic equation.
|
||
|
</p>
|
||
|
|
||
|
</html>"));
|
||
|
end PID_discrete;
|