Discretize State Space feedback controller using c2d()

31 views (last 30 days)
I'm looking to discretize a State Space feedback controller using c2d(), to find loop rate limits with which this feedback system remains stable.
I tried what I thought was correct (below), but the discrete sys step response to approach 0 as the Ts decreases (rate increase). Also, is there a way in Matlab to create a discretized feedback controller around a continuous plant?
Background:
If I just do c2d() on the continuous CL (closed-loop) sys, as expected the discrete sys's step()/etc plots are always stable: just a sampled version of the continous CL response output. But I'm looking for controller stability, and just c2d(closed-loop sys) seems like it wouldn't show stability in presence of disturbances, say.
Is the discretization process below correct, as far as Matlab command usage?
a) Find continuous-domain plant A, B, C, D, and feedback gains K, eg:
sys = ss(A, B, C, D)
K = lqr(sys, Q, R)
sysCL = ss(sys.A - sys.B * K, sys.B * K * [1;0], sys.C, sys.D)
And to check response to disturbance inputs:
F = [0; 1/m] % since this is a 2nd-O spring/mass/damper system
sysCL = ss(sys.A - sys.B * K, [ sys.B * K * [1;0], F], sys.C, sys.D)
Use the cts version as inputs to discretization process, and as comparison
b) To find the equivalent discrete version, find discrete gains K_disc, eg:
sys_d = c2d(sys, Ts)
K_d = lqrd(sys_d.A, sys_d.B, Q, R, Ts)
sysCL_d = ss(sys_d.A - sys_d.B * K_d, sys_d.B * K_d * [1;0], sys_d.C, sys_d.D, Ts)
% Ref gain is small when loop rate is low...why do I need to scale sysCL_d by 1/dcgain(sysCL_d)?
dcgain(sysCL_d)
And to check response to disturbance inputs:
% Is F the same for a discretized system? sysCL_d.B has elements for both states, unlike sysCL.B
F = [0; 1/m] %since this is a 2nd-O spring/mass/damper system
sysCL_d = ss(sys_d.A - sys_d.B * K_d, [ sys_d.B * K_d * [1;0], F ], sys_d.C, sys_d.D, Ts)
% Ref gain is small when loop rate is low...why do I need to scale sysCL_d by 1/dcgain(sysCL_d)?
dcgain(sysCL_d)
Questions:
Then I check step(sysCL, sysCL_d)
1) The above causes the discrete sys step response to approach 0 as the Ts decreases (rate increase). The cts version steps to 1 as expected.
What am I missing?
2) Is there a way in Matlab to create a discretized feedback controller around a continuous plant?
The disturbance outputs for the discrete version approach 0 as the rate goes down (Ts increase) -- but I would have expected a lower rate to cause the full dist to be at the output y until the next controller tick. Is this because only a sampled y is being displayed. I'm looking for a way to display the cts system states.

Accepted Answer

Paul
Paul on 8 Apr 2023
Hi John,
lqrd returns the gains for a discrete time controller. The Control System Toolbox cannot model hybrid systems, as far as I know (you can do that in Simulink if you want). With a continuous plant and discrete time controller the typical approach is to discretize the plant and then apply the feedback to approximate the hybrid, closed loop system. In other words, we can't close the loop using the continuous plant and the dicrete controller as done in the code in the Question
Here's an example.
Continuous plant
zeta = 0.3;
wn_rPs = 250;
ampl = 1;
m = 1e-5;
b = zeta * 2 * wn_rPs * m;
k = wn_rPs^2 * m;
A = [0 1; -k/m -b/m];
B = [0; 1/m];
C = [1 0];
D = 0;
plant = ss(A,B,C,D);
Desing LQR feedback gains
Q = [1000 0 ; 0 0.001];
R = 0.01;
K = lqr(plant, Q, R);
Continuous, closed loop system
syscl = ss(plant.A - plant.B*K,plant.B*K*[1;0],plant.C,plant.D);
Find the eigenvalues of the closed loop system to define an appropriate sampling period
format short e
e = eig(syscl)
e = 2×1
1.0e+00 * -1.0006e+03 -3.1605e+04
Ts = -1/e(2)/10;
Design discrete time gains
Kd = lqrd(plant.A,plant.B,Q,R,Ts);
Discretize the plant
plantd = c2d(plant,Ts);
Discrete time, closed loop system
syscld = ss(plantd.A - plantd.B*Kd,plantd.B*Kd*[1;0],plantd.C,plantd.D,Ts);
Compare step responses, they are nearly identical.
step(syscl,syscld)
  15 Comments
John
John on 12 Apr 2023
Edited: John on 12 Apr 2023
100% agreed; that's my process as well.
I'll clarify: the step after doing what you described (connecting blocks of varying rates, diagnostics, etc) is to eventually implement this on a physical system. Given what that system is, this process will be manually recreating the simulink / matlab system, so understanding what ML / SL does is a needed step... Using ML/SL to create a working system at a high level, is certainly part of that process.
Hence being a bit unclear on what Matlab simulating, if increasing loop rates lead to performance better than a continuous sytems (which shouldn't be possible).
Paul
Paul on 12 Apr 2023
Edited: Paul on 12 Apr 2023
I'm seeing basically the same response to a step disturbance for all three models as long as Ts is small enough. Same code as above, just added a plot for the repsonse to the disturbance and cycled through three values of Ts
overShootPec = 5;
zeta = abs(log(overShootPec/100)) / sqrt(pi^2 * log(overShootPec/100)^2);
wn_rPs = 2 * pi * 40;
%% OL system
ampl = 1;
J_kgm2 = 1e-5;
b = zeta * 2 * wn_rPs * J_kgm2;
k = wn_rPs^2 * J_kgm2;
A = [0 1; -k/J_kgm2 -b/J_kgm2];
B = [0; 1/J_kgm2];
C = [1 0];
D = [0];
massSys = ss(A, B, C, D, ...
'StateName', {'theta', 'theta_dot'}, ...
'InputName', {'u'}, ...
'OutputName', {'theta'});
%Plant with disturbance
% define F so that disturbance is a torque
F = [0; 1/J_kgm2];
sysOlWithDist = ss(massSys.A, [massSys.B F] , eye(2),0);
sysOlWithDist.StateName = {'theta', 'theta_dot'};
sysOlWithDist.InputName = {'u', 'd'};
sysOlWithDist.OutputName = {'theta','theta_dot'};
H = [2*0.7*1000 1 -1000^2];
Q = H.'*H;
R = 100;
Kc = lqi(sysOlWithDist(1,1), Q, R);
sysintcont = tf(1,[1 0],'OutputName','xi','InputName','e');
Kcc = ss(-Kc,'InputName',{'theta','theta_dot','xi'},'OutputName','u');
S = sumblk('e = r - theta');
sysc = connect(sysOlWithDist,Kcc,S,sysintcont,{'r','d'},'theta');
for Ts = [1e-4 1e-5 1e-6]
sysintdisc = c2d(sysintcont,Ts,'Tustin');
sysd1 = connect(c2d(sysOlWithDist,Ts,'zoh'),Kcc,S,sysintdisc,{'r','d'},'theta');
sysintdisc = ss(-tf(Ts,[1 -1],Ts));
sysintdisc.B = sysintdisc.B*sysintdisc.C;
sysintdisc.C = 1;
set(sysintdisc,'InputName','theta','OutputName','xi','StateName','xi');
augplant = connect(c2d(sysOlWithDist(1,1),Ts,'zoh'),sysintdisc,'u','xi');
Kd = lqr(augplant,Q,R);
sysintdisc = ss(tf(Ts,[1 -1],Ts));
set(sysintdisc,'InputName','e','OutputName','xi','StateName','xi');
Kcd = ss(-Kd,'InputName',{'theta','theta_dot','xi'},'OutputName','u');
sysd2 = connect(c2d(sysOlWithDist,Ts,'zoh'),Kcd,S,sysintdisc,{'r','d'},'theta');
figure
step(sysc(1,1),sysd1(1,1),sysd2(1,1));
text(0,1,"Ts = " + string(Ts))
figure
step(sysc(1,2),sysd1(1,2),sysd2(1,2));
text(0,0,"Ts = " + string(Ts))
end

Sign in to comment.

More Answers (0)

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!