How do I simulate a linearized state space model with MATLAB's lsim command?
Consider that you got these equations:
$$2.5 \dot{x_1} = 0.0050 - u_1*0.01*\sqrt{x_1}$$ $$2.5 \dot{x_2} = u_1*0.01*\sqrt{x_1} - u_2*0.01*\sqrt{x_2}$$
That will result a nonlinear state space model, due to $\sqrt{}$. Linearize that model in $$x_1 = 1.5, x_2 = 0.5 , u_1 = 0.40825, u_2 = 0.70711$$
And you will get this state space model: $$ \begin{bmatrix} \dot{x_1} - 0\\ \dot{x_2} - 0 \end{bmatrix} = \begin{bmatrix} -0.00167 & 0 \\ 0.00167 & -0.005 \end{bmatrix} \begin{bmatrix} x_1 - 1.5\\ x_2 - 0.5 \end{bmatrix} + \begin{bmatrix} -0.0122 & 0 \\ 0.0122 & -0.00707 \end{bmatrix} \begin{bmatrix} u_1 - 0.40825\\ u_2 - 0.70711 \end{bmatrix}\ $$
Question:$$ $$ How do I simulate this linearized state space equation by using MATLAb's / Octave's command lsim ?
$\endgroup$1 Answer
$\begingroup$Well, you're asking specifically how to use the lsim command and not about the linearization of your model, so I'm working from the assumption that your model is correctly linearized. SO, starting there, you would use the lsim command as follows:
lsim(sys,u,t,x0)From the documentation:
The vector t specifies the time samples for the simulation ... and consists of regularly spaced time samples:
t = 0:dt:Tfinal;
Then,
The input
uis an array having as many rows as time samples (length(t)) and as many columns as system inputs. For instance, ifsysis a SISO system, thenuis at-by-1 vector. Ifsyshas three inputs, thenuis at-by-3 array. Each rowu(i,:)specifies the input value(s) at the time samplet(i).
And finally,
x0is an initial condition for the system states. This syntax applies only whensysis a state-space model.
So, first define your system. Your question isn't formatted in a state space form that Matlab can accept because your state and input vectors $\bf{x}$ and $\bf{u}$ have constants in them. I'm going to make this a little easier on me by just masking everything behind constants. Multiply everything out and you get:
$$ \left[\begin{array}{cc} a & b \\ c & d \\ \end{array}\right]\left[\begin{array}{c} x_1 + e \\ x_2 + f \\ \end{array}\right] = \left[\begin{array}{cc} a(x_1 + e) + b(x_2 + f) \\ c(x_1 + e) + d(x_2 + f) \\ \end{array}\right] $$
$$ \left[\begin{array}{cc} a(x_1 + e) + b(x_2 + f) \\ c(x_1 + e) + d(x_2 + f) \\ \end{array}\right] = \left[\begin{array}{cc} a x_1 + ae + b x_2 + bf \\ c x_1 + ce + d x_2 + df \\ \end{array}\right] = \left[\begin{array}{cc} a x_1 + b x_2 + ae + bf \\ c x_1 + d x_2 + ce + df \\ \end{array}\right] $$
So, the tricky bit here might be to recognize that those last terms, ae+bf and ce+df are multiplied by one, so really you wind up with something like:
$$ \left[\begin{array}{cc} (a)x_1 + (b)x_2 + (ae + bf)1 \\ (c)x_1 + (d)x_2 + (ce + df)1 \\ \end{array}\right] $$
Now, if you were to have a variable that didn't change over time, you could set its initial value to one and then use that. You do this by adding a state to your state matrix $\bf{A}$ and leaving the corresponding row for that state equal to zeros. Now the new state ($x_3$) doesn't change over time, and as long as you set its initial value to one, you are left with the form you need in proper state space form:
$$ \left[\begin{array}{cc} (a)x_1 + (b)x_2 + (ae + bf)x_3 \\ (c)x_1 + (d)x_2 + (ce + df)x_3 \\ \end{array}\right] $$
You can easily separate that out: $$ \left[\begin{array}{ccc} a & b & ae + bf \\ c & d & ce + df \\ 0 & 0 & 0 \\ \end{array}\right]\left[\begin{array}{c} x_1 \\ x_2 \\ x_3 \\ \end{array}\right] $$
Now you need to be careful to include the constants you also have in your input vector:
$$ \left[\begin{array}{cc} g & h \\ j & k \\ \end{array}\right]\left[\begin{array}{c} u_1 + m \\ u_2 + n \\ \end{array}\right] = \left[\begin{array}{cc} g(u_1 + m) + h(u_2 + n) \\ j(u_1 + m) + k(u_2 + n) \\ \end{array}\right] $$
Same steps as before:
$$ \left[\begin{array}{cc} g(u_1 + m) + h(u_2 + n) \\ j(u_1 + m) + k(u_2 + n) \\ \end{array}\right] = \left[\begin{array}{cc} g(u_1) + gm + h(u_2) + hn \\ j(u_1) + jm + k(u_2) + kn \\ \end{array}\right] $$ $$ = \left[\begin{array}{cc} g(u_1) + h(u_2) + (gm + hn)x_3 \\ j(u_1) + k(u_2) + (jm + kn)x_3 \\ \end{array}\right] $$
Put it all together:
$$ \left[\begin{array}{c} \dot{x_1} \\ \dot{x_2} \\ \dot{x_3} \\ \end{array}\right] = \left[\begin{array}{ccc} a & b & ae + bf + gm + hn \\ c & d & ce + df + jm + kn \\ 0 & 0 & 0 \\ \end{array}\right]\left[\begin{array}{c} x_1 \\ x_2 \\ x_3 \\ \end{array}\right] + \left[\begin{array}{cc} g & h \\ j & k \\ 0 & 0 \\ \end{array}\right]\left[\begin{array}{c} u_1 \\ u_2 \\ \end{array}\right] $$
This was probably the tricky part in getting your equations to the point of being able to use lsim. From here, everything else is self-explanatory.
- Determine your sample interval
dtor your sample ratefsand calculate the sample interval asdt = 1/fs;. - Define your time vector
t = 0:dt:tFinal;. - Define your initial conditions. If you want to start with $x_1$ and $x_2$ at zero, then you would use
x0 = [0;0;1];because again, $x_3$ must be one. - Define your inputs. If you want to step only $u_1$, then you would use
u = [ones(length(t),1),zeros(length(t),1)];. Swap those to step $u_2$, or whatever other combination you want. - Define your matrices and then your system;
A = [...]; B = [...];etc., thensys = ss(A,B,C,D);, where the matrices are as I've defined above. - Invoke lsim -
lsim(sys,u,t,x0);.
Done!
$\endgroup$ 5