Integrator

block Integrator "Output the integral of the input signal with optional reset"
    import Modelica.Blocks.Types.Init;

    parameter Real k(unit = "1") = 1 "Integrator gain";
    parameter Boolean use_reset = false "=true, if reset port enabled"
        annotation (
            Evaluate = true,
            HideResult = true,
            choices(checkBox = true));
    parameter Boolean use_set = false "=true, if set port enabled and used as reinitialization value when reset"
        annotation (
            Dialog(enable = use_reset),
            Evaluate = true,
            HideResult = true,
            choices(checkBox = true));
    parameter Modelica.Blocks.Types.Init initType = Modelica.Blocks.Types.Init.InitialState "Type of initialization (1: no init, 2: steady state, 3,4: initial output)"
        annotation (
            Evaluate = true,
            Dialog(group = "Initialization"));
    parameter Real y_start = 0 "Initial or guess value of output (= state)"
        annotation (Dialog(group = "Initialization"));

    extends Interfaces.SISO(y(start = y_start));

    Modelica.Blocks.Interfaces.BooleanInput reset if use_reset "Optional connector of reset signal"
        annotation (Placement(transformation(
            extent = {
                {-20, -20}, 
                {20, 20}},
            rotation = 90,
            origin = {60, -120})));
    Modelica.Blocks.Interfaces.RealInput set if use_reset and use_set "Optional connector of set signal"
        annotation (Placement(transformation(
            extent = {
                {-20, -20}, 
                {20, 20}},
            rotation = 270,
            origin = {60, 120})));
protected
    Modelica.Blocks.Interfaces.BooleanOutput local_reset annotation (HideResult = true);
    Modelica.Blocks.Interfaces.RealOutput local_set annotation (HideResult = true);
initial equation
    if initType == Init.SteadyState then 
        der(y) = 0;
    elseif initType == Init.InitialState or initType == Init.InitialOutput then 
        y = y_start;
    end if;
equation
    if use_reset then 
        connect(reset,local_reset);
        if use_set then 
            connect(set,local_set);
        else 
            local_set = y_start;
        end if;
        when local_reset then 
            reinit(y, local_set);
        end when;
    else 
        local_reset = false;
        local_set = 0;
    end if;
    der(y) = k * u;

    annotation (
        Documentation(info = "<html>\n<p>\nThis blocks computes output <strong>y</strong> as\n<em>integral</em> of the input <strong>u</strong> multiplied with\nthe gain <em>k</em>:\n</p>\n<pre>\n         k\n     y = - u\n         s\n</pre>\n\n<p>\nIt might be difficult to initialize the integrator in steady state.\nThis is discussed in the description of package\n<a href=\"modelica://Modelica.Blocks.Continuous#info\">Continuous</a>.\n</p>\n\n<p>\nIf the <em>reset</em> port is enabled, then the output <strong>y</strong> is reset to <em>set</em>\nor to <em>y_start</em> (if the <em>set</em> port is not enabled), whenever the <em>reset</em>\nport has a rising edge.\n</p>\n</html>"),
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(
                    points = {
                        {-80, 78}, 
                        {-80, -90}},
                    color = {192, 192, 192}), 
                Polygon(
                    lineColor = {192, 192, 192},
                    fillColor = {192, 192, 192},
                    fillPattern = FillPattern.Solid,
                    points = {
                        {-80, 90}, 
                        {-88, 68}, 
                        {-72, 68}, 
                        {-80, 90}}), 
                Line(
                    points = {
                        {-90, -80}, 
                        {82, -80}},
                    color = {192, 192, 192}), 
                Polygon(
                    lineColor = {192, 192, 192},
                    fillColor = {192, 192, 192},
                    fillPattern = FillPattern.Solid,
                    points = {
                        {90, -80}, 
                        {68, -72}, 
                        {68, -88}, 
                        {90, -80}}), 
                Text(
                    lineColor = {192, 192, 192},
                    extent = {
                        {0, -70}, 
                        {60, -10}},
                    textString = "I"), 
                Text(
                    extent = {
                        {-150, -150}, 
                        {150, -110}},
                    textString = "k=%k"), 
                Line(
                    points = DynamicSelect({
                        {-80, -80}, 
                        {80, 80}}, if use_reset then {{-80, -80}, {60, 60}, {60, -80}, {80, -60}} else {{-80, -80}, {80, 80}}),
                    color = {0, 0, 127}), 
                Line(
                    visible = use_reset,
                    points = {
                        {60, -100}, 
                        {60, -80}},
                    color = {255, 0, 255},
                    pattern = LinePattern.Dot), 
                Text(
                    visible = use_reset,
                    extent = {
                        {-28, -62}, 
                        {94, -86}},
                    textString = "reset")}),
        Diagram(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Rectangle(
                    extent = {
                        {-60, 60}, 
                        {60, -60}},
                    lineColor = {0, 0, 255}), 
                Line(
                    points = {
                        {-100, 0}, 
                        {-60, 0}},
                    color = {0, 0, 255}), 
                Line(
                    points = {
                        {60, 0}, 
                        {100, 0}},
                    color = {0, 0, 255}), 
                Text(
                    extent = {
                        {-36, 60}, 
                        {32, 2}},
                    textString = "k"), 
                Text(
                    extent = {
                        {-32, 0}, 
                        {36, -58}},
                    textString = "s"), 
                Line(points = {
                    {-46, 0}, 
                    {46, 0}})}));
end Integrator;