2

I need to perform a ZOH discretization of a continuous LTI state-space model in OpenModelica (OMEdit). I tried two ways of doing this:

  1. using matrix exponential (Matrices.exp function) for calculating discretized A matrix (Ad) and subsequent calculation of discretized B matrix (Bd) following equation: Bd = A-1 (Ad - I) B, where I is identity matrix; This algebraic equation can be solved either by direct calculation of matrix inversion (Matrices.inv function) or, more efficiently, by solving for Bd matrix using Matrices.solve2 function: Bd = Matrices.solve2(A,(Ad-identity(2))), thus avoiding calculation of matrix inversion. However, in both cases A matrix must be invertible, what generally (and very often) doesn't hold.
  2. using Matrices.integralExp function which should return both discretized matrices (Ad, Bd) and should work for general matrix A, whether invertible or singular; However, this function does not work for me - it returns error message: "No viable alternative near token: (".

I attach code for both methods for demonstration purpose. The state space model represents a very simple second-order system of linearized pendulum with length 1 m, mass 1 kg and gravitational acceleration 9.81 m/s2. Sampling time for discretization is 0.1 s. The first code works fine (A is invertible in this particular case) but the second code doesn't. Does anybody know what am I doing wrong? I'd be grateful for any advice.

method #1:

model ssDiscretization
  import Modelica.Math.Matrices;
  // Continuous LTI state-space model of pendulum: L=1, m=1, g=9.81
  Real A[2,2] = [0, 1; -9.81, 0] "system matrix";
  Real B[2,1] = [0; 1] "input matrix";
  // Discretization with sampling time 0.1 s
  Real Ad[2,2] = Matrices.exp(A,0.1) "T = 0.1 s";
  Real Bd[2,1] = Matrices.inv(A)*(Ad - identity(2))*B;
end ssDiscretization;

method #2:

model ssDiscretization
  import Modelica.Math.Matrices;
  // Continuous LTI state-space model of pendulum: L=1, m=1, g=9.81
  Real A[2,2] = [0, 1; -9.81, 0] "system matrix";
  Real B[2,1] = [0; 1] "input matrix";
  // Discretization with sampling time 0.1 s
  Real Ad[2,2];
  Real Bd[2,1];
  (Ad,Bd) = Matrices.integralExp(A,B,0.1) "T = 0.1 s";
end ssDiscretization;

Oliver

Olivetti
  • 23
  • 4
  • Not of real help, but `(Ad,Bd) = Matrices.integralExp(A,B,0.1) "T = 0.1 s";` gives the same result as the first code snippet when run from Dymola's "Commands" line. So it seems to be an issue related to the tool, not the usage... I can't give any advice on OpenModelica though... – Markus A. Apr 12 '21 at 06:41
  • Good to know that the code works in Dymola. Maybe somebody will give suggestion why it doesn't work when I run it in OMEdit. Thank you, Markus. – Olivetti Apr 13 '21 at 07:29

1 Answers1

1

You forgot the equation keyword in example 2. It still won't work in OpenModelica since it seems to have a problem with the alias na=size(A,1) in that function but you could easily fix the source code to make that work.

model ssDiscretization
  import Modelica.Math.Matrices;
  // Continuous LTI state-space model of pendulum: L=1, m=1, g=9.81
  Real A[2,2] = [0, 1; -9.81, 0] "system matrix";
  Real B[2,1] = [0; 1] "input matrix";
  // Discretization with sampling time 0.1 s
  Real Ad[2,2];
  Real Bd[2,1];
equation // This was missing
  (Ad,Bd) = Matrices.integralExp(A,B,0.1) "T = 0.1 s";
end ssDiscretization;
sjoelund.se
  • 3,468
  • 12
  • 15
  • The problem is solved, thank you. Actually I didn't forget to put the `equation` keyword in the 2nd example, I did it deliberatly since I thought it should work without the equation/algorithm section the same way as the 1st example. Now I know I was wrong. But as you suggested, putting the last equation in the equation section did not solve the problem. I also had to fix the code of the integralExp function. The fix comprised rewriting the line `input Real A[:, size(A, 1)];` to `input Real A[:,:];` and similarly, rewriting the line `input Real B[size(A, 1), :];` to `input Real B[:,:];`. – Olivetti May 06 '21 at 05:55
  • It should now also work in the OpenModelica nightly builds without changing the standard library: https://github.com/OpenModelica/OpenModelica/commit/9b527bc6bf – sjoelund.se May 06 '21 at 06:38