PI

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;