block PI "Proportional-Integral controller"
import Modelica.Blocks.Types.Init;
parameter Real k(unit = "1") = 1 "Gain";
parameter SIunits.Time T(start = 1, min = Modelica.Constants.small) "Time Constant (T>0 required)";
parameter Modelica.Blocks.Types.Init initType = Modelica.Blocks.Types.Init.NoInit "Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)"
annotation (
Evaluate = true,
Dialog(group = "Initialization"));
parameter Real x_start = 0 "Initial or guess value of state"
annotation (Dialog(group = "Initialization"));
parameter Real y_start = 0 "Initial value of output"
annotation (Dialog(
enable = initType == Init.SteadyState or initType == Init.InitialOutput,
group = "Initialization"));
extends Interfaces.SISO;
output Real x(start = x_start) "State of block";
initial equation
if initType == Init.SteadyState then
der(x) = 0;
elseif initType == Init.InitialState then
x = x_start;
elseif initType == Init.InitialOutput then
y = y_start;
end if;
equation
y = k * (x + u);
der(x) = u / T;
annotation (
defaultComponentName = "PI",
Documentation(info = "<html>\n<p>\nThis blocks defines the transfer function between the input u and\nthe output y as <em>PI</em> system:\n</p>\n<pre>\n 1\n y = k * (1 + ---) * u\n T*s\n T*s + 1\n = k * ------- * u\n T*s\n</pre>\n<p>\nIf you would like to be able to change easily between different\ntransfer functions (FirstOrder, SecondOrder, ... ) by changing\nparameters, use the general model class <strong>TransferFunction</strong>\ninstead and model a PI SISO system with parameters<br>\nb = {k*T, k}, a = {T, 0}.\n</p>\n<pre>\nExample:\n\n parameter: k = 0.3, T = 0.4\n\n results in:\n 0.4 s + 1\n y = 0.3 ----------- * u\n 0.4 s\n</pre>\n\n<p>\nIt might be difficult to initialize the PI component in steady state\ndue to the integrator part.\nThis is discussed in the description of package\n<a href=\"modelica://Modelica.Blocks.Continuous#info\">Continuous</a>.\n</p>\n\n</html>"),
Icon(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(
points = {
{-80, 78},
{-80, -90}},
color = {192, 192, 192}),
Polygon(
points = {
{-80, 90},
{-88, 68},
{-72, 68},
{-80, 90}},
lineColor = {192, 192, 192},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Line(
points = {
{-90, -80},
{82, -80}},
color = {192, 192, 192}),
Polygon(
points = {
{90, -80},
{68, -72},
{68, -88},
{90, -80}},
lineColor = {192, 192, 192},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Line(
points = {
{-80, -80},
{-80, -20},
{60, 80}},
color = {0, 0, 127}),
Text(
extent = {
{0, 6},
{60, -56}},
lineColor = {192, 192, 192},
textString = "PI"),
Text(
extent = {
{-150, -150},
{150, -110}},
textString = "T=%T")}),
Diagram(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Rectangle(
extent = {
{-60, 60},
{60, -60}},
lineColor = {0, 0, 255}),
Text(
extent = {
{-68, 24},
{-24, -18}},
textString = "k"),
Text(
extent = {
{-32, 48},
{60, 0}},
textString = "T s + 1"),
Text(
extent = {
{-30, -8},
{52, -40}},
textString = "T s"),
Line(points = {
{-24, 0},
{54, 0}}),
Line(
points = {
{-100, 0},
{-60, 0}},
color = {0, 0, 255}),
Line(
points = {
{62, 0},
{100, 0}},
color = {0, 0, 255})}));
end PI;