I need to perform a ZOH discretization of a continuous LTI state-space model in OpenModelica (OMEdit). I tried two ways of doing this:
- 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. - 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