TransferFunction

block TransferFunction "Discrete Transfer Function block"
    parameter Real b[:] = {1} "Numerator coefficients of transfer function.";
    parameter Real a[:] = {1} "Denominator coefficients of transfer function.";

    extends Interfaces.DiscreteSISO;

    output Real x[size(a, 1) - 1](each start = 0, each fixed = true) "State of transfer function from controller canonical form";
protected
    parameter Integer nb = size(b, 1) "Size of Numerator of transfer function";
    parameter Integer na = size(a, 1) "Size of Denominator of transfer function";
    Real x1(start = 0, fixed = true);
    Real xext[size(a, 1)](each start = 0, each fixed = true);
equation
    when sampleTrigger then 
        x1 = (u - a[2:size(a, 1)] * pre(x)) / a[1];
        xext = vector([x1; pre(x)]);
        x = xext[1:size(x, 1)];
        y = vector([zeros(na - nb, 1); b]) * xext;
    end when;

    annotation (
        Documentation(
            info = "<html>\n<p>The <strong>discrete transfer function</strong> block defines the\ntransfer function between the input signal u and the output\nsignal y. The numerator has the order nb-1, the denominator\nhas the order na-1.</p>\n<pre>\n          b(1)*z^(nb-1) + b(2)*z^(nb-2) + ... + b(nb)\n   y(z) = -------------------------------------------- * u(z)\n          a(1)*z^(na-1) + a(2)*z^(na-2) + ... + a(na)\n</pre>\n<p>State variables <strong>x</strong> are defined according to\n<strong>controller canonical</strong> form. Initial values of the\nstates can be set as start values of <strong>x</strong>.</p>\n<p>Example:</p>\n<pre>     Blocks.Discrete.TransferFunction g(b = {2,4}, a = {1,3});\n</pre>\n<p>results in the following transfer function:</p>\n<pre>        2*z + 4\n   y = --------- * u\n         z + 3\n</pre>\n\n</html>",
            revisions = "<html>\n<p><strong>Release Notes:</strong></p>\n<ul>\n<li><em>November 15, 2000</em>\n    by <a href=\"http://www.dynasim.se\">Hans Olsson</a>:<br>\n    Converted to when-semantics of Modelica 1.4 with special\n    care to avoid unnecessary algebraic loops.</li>\n<li><em>June 18, 2000</em>\n    by <a href=\"http://www.robotic.dlr.de/Martin.Otter/\">Martin Otter</a>:<br>\n    Realized based on a corresponding model of Dieter Moormann\n    and Hilding Elmqvist.</li>\n</ul>\n</html>"),
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(
                    points = {
                        {82, 0}, 
                        {-84, 0}},
                    color = {0, 0, 127}), 
                Text(
                    lineColor = {0, 0, 127},
                    extent = {
                        {-92, 12}, 
                        {86, 92}},
                    textString = "b(z)"), 
                Text(
                    lineColor = {0, 0, 127},
                    extent = {
                        {-90, -90}, 
                        {90, -12}},
                    textString = "a(z)")}),
        Diagram(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Rectangle(
                    extent = {
                        {-60, 60}, 
                        {60, -60}},
                    lineColor = {0, 0, 255}), 
                Line(
                    points = {
                        {40, 0}, 
                        {-44, 0}},
                    thickness = 0.5), 
                Text(
                    extent = {
                        {-54, 54}, 
                        {54, 4}},
                    textString = "b(z)"), 
                Text(
                    extent = {
                        {-54, -6}, 
                        {56, -56}},
                    textString = "a(z)"), 
                Line(
                    points = {
                        {-100, 0}, 
                        {-60, 0}},
                    color = {0, 0, 255}), 
                Line(
                    points = {
                        {60, 0}, 
                        {100, 0}},
                    color = {0, 0, 255})}));
end TransferFunction;