StateSpace

block StateSpace "Linear state space system"
    import Modelica.Blocks.Types.Init;

    parameter Real A[:,size(A, 1)] = [1,0; 0,1] "Matrix A of state space model (e.g., A=[1, 0; 0, 1])";
    parameter Real B[size(A, 1),:] = [1; 1] "Matrix B of state space model (e.g., B=[1; 1])";
    parameter Real C[:,size(A, 1)] = [1,1] "Matrix C of state space model (e.g., C=[1, 1])";
    parameter Real D[size(C, 1),size(B, 2)] = zeros(size(C, 1), size(B, 2)) "Matrix D of state space model";
    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[nx] = zeros(nx) "Initial or guess values of states"
        annotation (Dialog(group = "Initialization"));
    parameter Real y_start[ny] = zeros(ny) "Initial values of outputs (remaining states are in steady state if possible)"
        annotation (Dialog(
            enable = initType == Init.InitialOutput,
            group = "Initialization"));

    extends Interfaces.MIMO(final nin = size(B, 2), final nout = size(C, 1));

    output Real x[size(A, 1)](start = x_start) "State vector";
protected
    parameter Integer nx = size(A, 1) "number of states";
    parameter Integer ny = size(C, 1) "number of outputs";
initial equation
    if initType == Init.SteadyState then 
        der(x) = zeros(nx);
    elseif initType == Init.InitialState then 
        x = x_start;
    elseif initType == Init.InitialOutput then 
        x = Modelica.Math.Matrices.equalityLeastSquares(A, -B * u, C, y_start - D * u);
    end if;
equation
    y = C * x + D * u;
    der(x) = A * x + B * u;

    annotation (
        Documentation(info = "<html>\n<p>\nThe State Space block defines the relation\nbetween the input u and the output\ny in state space form:\n</p>\n<pre>\n\n    der(x) = A * x + B * u\n        y  = C * x + D * u\n</pre>\n<p>\nThe input is a vector of length nu, the output is a vector\nof length ny and nx is the number of states. Accordingly\n</p>\n<pre>\n        A has the dimension: A(nx,nx),\n        B has the dimension: B(nx,nu),\n        C has the dimension: C(ny,nx),\n        D has the dimension: D(ny,nu)\n</pre>\n<p>\nExample:\n</p>\n<pre>\n     parameter: A = [0.12, 2;3, 1.5]\n     parameter: B = [2, 7;3, 1]\n     parameter: C = [0.1, 2]\n     parameter: D = zeros(ny,nu)\nresults in the following equations:\n  [der(x[1])]   [0.12  2.00] [x[1]]   [2.0  7.0] [u[1]]\n  [         ] = [          ]*[    ] + [        ]*[    ]\n  [der(x[2])]   [3.00  1.50] [x[2]]   [0.1  2.0] [u[2]]\n                             [x[1]]            [u[1]]\n       y[1]   = [0.1  2.0] * [    ] + [0  0] * [    ]\n                             [x[2]]            [u[2]]\n</pre>\n</html>"),
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Text(
                    extent = {
                        {-90, 10}, 
                        {-10, 90}},
                    textString = "A",
                    lineColor = {0, 0, 127}), 
                Text(
                    extent = {
                        {10, 10}, 
                        {90, 90}},
                    textString = "B",
                    lineColor = {0, 0, 127}), 
                Text(
                    extent = {
                        {-90, -10}, 
                        {-10, -90}},
                    textString = "C",
                    lineColor = {0, 0, 127}), 
                Text(
                    extent = {
                        {10, -10}, 
                        {90, -90}},
                    textString = "D",
                    lineColor = {0, 0, 127}), 
                Line(
                    points = {
                        {0, -90}, 
                        {0, 90}},
                    color = {192, 192, 192}), 
                Line(
                    points = {
                        {-90, 0}, 
                        {90, 0}},
                    color = {192, 192, 192})}),
        Diagram(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Rectangle(
                    extent = {
                        {-60, 60}, 
                        {60, -60}},
                    lineColor = {0, 0, 255}), 
                Text(
                    extent = {
                        {-60, 40}, 
                        {60, 0}},
                    textString = "sx=Ax+Bu"), 
                Text(
                    extent = {
                        {-60, 0}, 
                        {60, -40}},
                    textString = " y=Cx+Du"), 
                Line(
                    points = {
                        {-100, 0}, 
                        {-60, 0}},
                    color = {0, 0, 255}), 
                Line(
                    points = {
                        {60, 0}, 
                        {100, 0}},
                    color = {0, 0, 255})}));
end StateSpace;