Discrete-time Simulink not matching Matlab Connect()

5 views (last 30 days)
I'm trying to understand why my discrete-time Simulink feedback loops are seemingly far from Matlab's Connect() results.
Per help from @Paul, I'm comparing matlab Connect() of fully discrete-time LQI (since Matlab doesn't do mixed-signal), to a Simulink sim of a discrete-time LQI but with continuous-time plant. The transport delays are set to 0 for the block diagram below, ie same as commenting them through (they have no effect currently).
The reason I'm looking to compare ML and SL, is I'm looking for an analytical way to determine loop delay margin in the disc-time case, ie how much delay can a discrete-time loop tolerate in the x and y feedback, and still maintain a set overall loop Phase Margin (eg "what sensor delay can be accommodated, to maintain N deg PM in the open loop transfer function for the input 'u'?")
When i compare ML and SL, a step() response of discrete-time Matlab feedback system seem to indicate instability (quickly blows up), and Simulink seems to run stably and with high stability margins. In contrast, the continuous-time system results match between ML and SL, but I'm interested in discrete-time delay margins, so the cts-time results aren't relevant.
How can I set up Matlab to more accurately simulate a discrete-time system?
Here is the Simulink version:
As can be seen, this seems to runs stably. Adding in nonzero delays to the loop also seem to work (not shown). The solver is set to fixed-step of 1e-8 s.
Here's the Matlab code to finds gains for the above system, and also find the Matlab-based feedback system using connect() :
clear all
load discTime
% Param setup
Ts = 1 / 100e3; % loop rate
sysBw_rPs = 450 * 2 * pi;
zeta = 1;
Pd = c2d(P, Ts, 'tustin'); % Could be ZOH; doesn't matter
H = [2 * zeta * sysBw_rPs, 0.5, -sysBw_rPs^2];
Q = H.'* H;
R = 1e-3;
[K, Sn, en] = lqi(P, Q, R);
[K_d, Sd, ed] = lqi(Pd, Q, R);
% Define loop junctions
esum = sumblk('e = r - y');
usum = sumblk('u = -ui - ufb');
APs = 'u';
% (1) Make cts-time FB sys
P_aug = ss(P.A,P.B,[eye(2);P.C],[zeros(2,1);P.D],'InputName','u','OutputName',{'x1' 'x2' 'y'});
% Paths for integrator Ki and state gains Kx
intPath = tf(K(3),[1 0],'InputName','e','OutputName','ui');
kPath = ss(K(1:2),'InputName',{'x1' 'x2'},'OutputName','ufb');
sys_c = connect(P_aug, intPath, kPath, esum, usum, 'r', 'y', APs);
% (2) Make disc-time FB sys, version 1: use cts Kx, and discretize Ki
P_aug_d = c2d(P_aug, Ts, 'zoh');
intPath_d = tf(Ts * K(3),[1 -1], Ts, 'InputName','e','OutputName','ui');
sys_d_v1 = connect(P_aug_d, intPath_d, kPath, esum,usum,'r','y','u');
% (3) Make disc-time FB sys, version 2: discretize paths for both Kx, Ki
intPath_d_2 = tf(K_d(3),[1 -1], Ts, 'InputName','e','OutputName','ui');
kPath_d = ss(K_d(1:2),'InputName',{'x1' 'x2'},'OutputName','ufb', 'Ts', Ts);
sys_d_v2 = connect(P_aug_d ,intPath_d_2, kPath_d, esum, usum,'r','y','u');
% Results
figure;
loopTransferFunc_c = getLoopTransfer(sys_c,'u',-1);
loopTransferFunc_d_v1 = getLoopTransfer(sys_d_v1,'u',-1);
loopTransferFunc_d_v2 = getLoopTransfer(sys_d_v2,'u',-1);
bode(loopTransferFunc_c, loopTransferFunc_d_v1, loopTransferFunc_d_v2);
legend('Cts', 'Disc 1', 'Disc 2'); title('OLTFs at u'); grid;
figure;
subplot(3,1,1); step(sys_c); grid on; title('Cts');
subplot(3,1,2); step(sys_d_v1); grid on; title('Disc v1');
subplot(3,1,3); step(sys_d_v2); grid on; title('Disc v2');
sgtitle('step()');
Both Disc v1 and Disc v2 versions blow up (but Disc V2 less so). Also adding my step() plot here since the Mathworks autorun plot seems to have obfuscated the step() plot titles:
What could cause this large difference, in the Matlab version step() not being stable? Perhaps the differences between ML and SL relates to the discretization method @Paul pointed out:
"In Simulink the plant is integrated forward using the continuous-time solver, whereas in Matlab with the connect the plant is discretized. They can be close, but they're not the same. ... As previously discussed, the way Simulink linearizes a hybrid system is by linearizing the nonlinear blocks and then discretizing the continuous-time blocks and then connecting it all together, which is exactly what I did with connect. I expect using linearize on the model will return the same result as I got with connect. Maybe I'll try this."
If this is the case, how can Matlab be set up to more accurately simulate a discrete-time system, so that i can find the delay margin? Right now, even ballpark is fine -- but the ML system blows up for some reason.

Answers (1)

Paul
Paul on 16 Feb 2024
Hi John,
Check this comment for an example that shows the same open loop system obtained from the combination of connect and getLoopTransfer as compared to the result obtained from a Simulink model using linearize.
  1 Comment
John
John on 16 Feb 2024
I checked out the post on the other thread -- thanks :) -- and will respond to it too.
I started this post here since it seemed a new topic: specifically trying to understand the step response differences (vs open loop transfer function results), ie stability vs unstable. In the example above with the step response, I also see some discrete-time results matching between ML and SL with certain parameter value, and others that don't (eg ML and SL don't match with the params above).
Maybe i'm misundertsanding though, what you were mentioning in your linearization post, about why connect() and discrete-time SL didn't seem to match ...

Sign in to comment.

Categories

Find more on Linearization in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!