Plotting control closed loop input

15 views (last 30 days)
Kristofer Bailey
Kristofer Bailey on 3 Dec 2020
Edited: Paul on 7 Dec 2020
How can I fix my code for plotting closed loop control input to see whether y(t) asymptotically tracks the reference signal. Thanks
u(t)=-K^T x(t)+Fr(t)
A = [-0.313 56.7 0; -0.0139 -0.426 0; 0 56.7 0];
B = [0.232; 0.0203; 0];
C = [0 0 1];
D = 0;
K=[-0.4317 -0.6297 0.77]
F=[0.0219]
%Matlab Code for Plotting closed loop system response (works)
t = 0:0.1:25;
Acl = (A - B.*K);
Bcl = (B .* F);
sys_cl = ss(Acl, Bcl, C, D);
x0 = [0 0 0]';
r = ones(size(t));
ycl = lsim(sys_cl, r, t, x0);
plot(t,ycl)
%Matlab Code for Plotting closed loop control input (doesnt work)
ci = eye(3);
sys_cl2 = ss(Acl, Bcl, ci, D);
ycl2 = lsim(sys_cl2, r, t, x0);
u = -K.*ycl2 + F.*r;
plot(u,t)
Error is "Matrix dimensions must agree."

Answers (1)

Paul
Paul on 3 Dec 2020
Edited: Paul on 7 Dec 2020
The direct answer to your question is this line:
>> u = -K.*ycl2 + F.*r;
Matrix dimensions must agree.
>> size( -K.*ycl2)
ans =
251 3
>> size(F.*r)
ans =
1 251
Where you can see that the two addends have incompatible dimensions. There are two problems here. First, the code is using
.*
which is element-by-element mutiplication. But it should be using
* % no dot!
which is matrix multiply. But K is 1 x 3 and ycl2 is 251 x 3. So to get as a column vector
u = (-K * ycl2.').' + F * r.';
You have to be very careful when using the element-by-element multiplication because of a feature called automatic implicit expansion (look up this term in the doc), which it turns out this code is inadvertently using. However, state space modeling is all about matrices, and so the code should be using matrix multiplication throughout
Acl = (A - B * K);
Bcl = (B * F);
It turns out the code gave the correct answer anyway in this case, but don't count on it in general. Use proper matrix multiplication for manipulating state space models.
Another thing to point out is that the closed loop system, in general, needs to account for a non-zero D matrix in the plant in computing the output.
y = C * x + D * u;
u = -K * x + F * r;
ycl = C * X + D * (-K * x + F * r) = (C - D * K) * x + D * F * r
Of course in this case case D = 0 so it didn't matter.
There are easier ways to getting the control input instead coming up with a whole new model. One option would be to get the state vector output from lsim and then compute u algebraiclly as you're trying to do
[ycl,t,xcl] = lsim(sys_cl, r, t, x0);
u = (-K * xcl.').' + F * r.';
Another option would be to include u as a second output from your plant, and then close the loop (while properly accounting for the non-zero D matrix)
A = [-0.313 56.7 0; -0.0139 -0.426 0; 0 56.7 0];
B = [0.232; 0.0203; 0];
C = [0 0 1;0 0 0];
D = [0;1]
sys_cl = ss(A-B*K,B*F,C-D*K,D*F);
ycl = lsim(sys_cl, r, t, x0);
u = ycl(:,2);

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!