LQI with time-delay system

19 visualizaciones (últimos 30 días)
John
John el 12 de En. de 2024
Comentada: Paul el 16 de Feb. de 2024
Matlab's documentation mentions that state-space systems with dead-time (eg. plant or measurement delays) can be defined with ss(), using 'inputDelay' and 'outputDelay'.
But, documentation (and Matlab error messages) also say that time-delay Pade approximations must be used for lqr() or lqi(), ie those functions cannot take ss() with time delays as defined above with 'inputDelay' or 'outputDelay'.
If I have a feedback loop period (the delay in the measurement I'm looking to take into account), I can use lqi() with a discretized model input, which should yield the correct gains for the corresponding loop delay.
But for a continuous system modeled in Simulink with a transport delay, there is no discretization step, and I'd need to find lqi() gains using the continuous system as approximated by the model and pade.
But in this case, what is the Q used? I'm unclear on what Matlab would like as Q matrix input to lqi() for a continuous system.
As a guess, I tried the following, which yielded error messages. Say the loop period is ts, and I have some basic 2nd-order plant model (attached).
load("lqiWithDelay")
plant
ts = 1 / 100e3;
[num, den] = pade(ts, 3); % Nth-order
loopDelayPadeApproxTf = tf(num, den);
plantWithDelay = plant * loopDelayPadeApproxTf;
% Find non-delayed CL gains
wnTarget_rPs = 10 * 2 * pi;
H_lqi = [2 * 0.7 * wnTarget_rPs, 0.5, -wnTarget_rPs^2];
Q_lqi = H_lqi.'* H_lqi;
R_lqi = 1;
K_lqi = lqi(model, Q_lqi, R_lqi)
% Find delayed CL gains
neededDelayedQsize = size(plantWithDelay.A, 1) + 1; % +1 needed for LQI
neededQlqiSize = size(modelWithDelay.A, 1) + 1
bigDelayedQ = zeros(neededDelayedQsize);
bigDelayedQ(1:3, 1:3) = Q_lqi
K_lqi_delayed = lqi(modelWithDelay, bigDelayedQ, R_lqi)
This uses zeros(), and i also tried eye() -- but im only guessing, since i don't know what lqi() does under the hood for those additional pade states that lead to a bigger needed Q matrix.

Respuestas (1)

Paul
Paul el 14 de En. de 2024
Editada: Paul el 15 de En. de 2024
Yes, if using a Pade apporoximant for the time delay, then the Q matrix will have to be expanded to include the additional state(s). In principle, you could buld the new Q matrix using the symmetric root locus technique, as I think is being done here, to drive the closed-loop poles to desirable locations. Maybe not penalizing that state(s) might be reasonable as well.
In addition, the Pade state(s) isn't available for feedback in the actual system, so they'd have to be reconstructed somehow, perhaps with a reduced order state estimator.
In the question you mentioned that the time delay is on the plant measurements, but the code has the time delay on the plant input. I'm going to assume it's on the input for what follows.
For this particular problem, the time delay at the input to the plant seems to be small enough that it is easily accomodated by the very large stability margins at the plant input that are guaranteed by LQ state feedback.
load("lqiWithDelay")
plant;
ts = 1 / 100e3;
%[num, den] = pade(ts, 3); % Nth-order
%loopDelayPadeApproxTf = tf(num, den);
%plantWithDelay = plant * loopDelayPadeApproxTf; % delay is at the plant input
% Find non-delayed CL gains
wnTarget_rPs = 10 * 2 * pi;
H_lqi = [2 * 0.7 * wnTarget_rPs, 0.5, -wnTarget_rPs^2];
Q_lqi = H_lqi.'* H_lqi;
R_lqi = 1;
%K_lqi = lqi(model, Q_lqi, R_lqi) % what was model? not defined ... assume it's supposed to be plant
K_lqi = lqi(plant, Q_lqi, R_lqi);
sysp = ss(plant.A,plant.B,[eye(2);plant.C],[zeros(2,1);plant.D],'InputName','u','OutputName',{'x1' 'x2' 'y'});
int = tf(K_lqi(3),[1 0],'InputName','e','OutputName','ui');
Kfb = ss(K_lqi(1:2),'InputName',{'x1' 'x2'},'OutputName','ufb');
esum = sumblk('e = r - y');
usum = sumblk('u = -ui - ufb');
sysc = connect(sysp,int,Kfb,esum,usum,'r','y','u');
Bode plot of the open-loop transfer function (w/o delay) at the plant input and of the delay.
L = getLoopTransfer(sysc,'u',-1);
figure
bode(L,exp(-tf('s')*ts))
As expected from an LQ design, the gain margin is infinite and the phase margin is quite large, about 90 deg in this case. The phase lag that would be introduced by the time delay at the input to the plant is quite small at the open-loop gain crossover frequency (~5000 rads/sec) and the phase margin will hardly be changed. The additional phase lag will cause an open-loop phase cross-over at very high frequency, but there the gain will be quite low and the gain margin quite large.
The effect of the delay on the closed-loop step response is negligible.
sysp = ss(plant.A,plant.B,[eye(2);plant.C],[zeros(2,1);plant.D],'InputName','u','OutputName',{'x1' 'x2' 'y'},'InputDelay',ts);
int = tf(K_lqi(3),[1 0],'InputName','e','OutputName','ui');
Kfb = ss(K_lqi(1:2),'InputName',{'x1' 'x2'},'OutputName','ufb');
esum = sumblk('e = r - y');
usum = sumblk('u = -ui - ufb');
syscdelay = connect(sysp,int,Kfb,esum,usum,'r','y','u');
figure
step(sysc,syscdelay)
  28 comentarios
John
John el 15 de Feb. de 2024
Thanks @Paul. I think there are two issues at play that are causing this difference:
  • Per the discrete-time block diagram i posted, I was using Transport Delay after the rate transition -- but this doesn't work (i had assumed it would account for discrete-time, but it doesn't). It needs to be before the rate transition, or i need to use z^-n delay. Using Transport Delay in this manner my system unstable. Fixing this made the SL simulations at least somewhat match at low loop rates.
  • There seems to be some difference between connect() and SL that i've been unable to understand so far, perhaps related to the discretization method you 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."
I'll pause on this post and start another specific thread on discrete time sims, that I'm unable to make even closely match the connect() versions, as that seems to be the limiting question at the moment...
Paul
Paul el 16 de Feb. de 2024
In the Simulink model in this comment it looked like the Transport Delay blocks were Commented Through. Yes, the transport delay should go before the Rate Transition blocks.
I don't see any difference at all between the results from connect/getLoopTransfer and from linearizing the Simulink model using linearize (which I'm sure is the same as what you'd get using any other method to linearize the model).
Load the system parameters and set the sample time.
load newPlantAndGains
plant.C = [eye(2);plant.C];
plant.Ts
ans = 0
Ts = 1e-6;
Buld the Simulink model with the continuous-time plant, discrete-time integrator, and feedback signals sampled at Ts.
bdclose('all');
hsys = new_system('lqitest');
hstep = add_block('simulink/Sources/Constant','lqitest/Step');
herror = add_block('simulink/Math Operations/Subtract','lqitest/error');
%hint = add_block('simulink/Continuous/Integrator','lqitest/int');
hint = add_block('simulink/Discrete/Discrete-Time Integrator','lqitest/int');
set_param(hint,'SampleTime','Ts');
hintgain = add_block('simulink/Math Operations/Gain','lqitest/intgain');
set_param(hintgain,'Gain','K_lqi(3)')
hcontrol = add_block('simulink/Math Operations/Subtract','lqitest/control');
set_param(hcontrol,'Inputs','--');
hplant = add_block('cstblocks/LTI System','lqitest/plant');
set_param(hplant,'MaskValues',{'plant';'[]';'0'});
hdemux = add_block('simulink/Signal Routing/Demux','lqitest/demux');
set_param(hdemux,'Outputs','[2 1]');
hstategain = add_block('simulink/Math Operations/Gain','lqitest/stategain');
set_param(hstategain,'Gain','K_lqi(1:2)');
set_param(hstategain,'Multiplication','Matrix(K*u)');
% hdelay1 = add_block('simulink/Continuous/Transport Delay','lqitest/delay1');
% set_param(hdelay1,'DelayTime','0');
%
% hdelay2 = add_block('simulink/Continuous/Transport Delay','lqitest/delay2');
% set_param(hdelay2,'DelayTime','0');
hzoh1 = add_block('simulink/Discrete/Zero-Order Hold','lqitest/zoh1');
set_param(hzoh1,'SampleTime','Ts');
hzoh2 = add_block('simulink/Discrete/Zero-Order Hold','lqitest/zoh2');
set_param(hzoh2,'SampleTime','Ts');
hout = add_block('simulink/Sinks/To Workspace','lqitest/output');
set_param(hout,'VariableName','y');
PH = 'PortHandles';
add_line(hsys, ...
get_param(hstep,PH).Outport,...
get_param(herror,PH).Inport(1));
add_line(hsys,...
get_param(herror,PH).Outport,...
get_param(hint,PH).Inport);
add_line(hsys,...
get_param(hint,PH).Outport,...
get_param(hintgain,PH).Inport);
add_line(hsys,...
get_param(hintgain,PH).Outport,...
get_param(hcontrol,PH).Inport(2));
add_line(hsys,...
get_param(hstategain,PH).Outport,...
get_param(hcontrol,PH).Inport(1));
add_line(hsys,...
get_param(hcontrol,PH).Outport,...
get_param(hplant,PH).Inport);
add_line(hsys,...
get_param(hplant,PH).Outport,...
get_param(hdemux,PH).Inport);
add_line(hsys,...
get_param(hdemux,PH).Outport(2),...
get_param(hout,PH).Inport);
add_line(hsys,...
get_param(hdemux,PH).Outport(2),...
get_param(hzoh2,PH).Inport);
add_line(hsys,...
get_param(hdemux,PH).Outport(1),...
get_param(hzoh1,PH).Inport);
add_line(hsys,...
get_param(hzoh1,PH).Outport,...
get_param(hstategain,PH).Inport);
add_line(hsys,...
get_param(hzoh2,PH).Outport,...
get_param(herror,PH).Inport(2));
Uncomment this line to open the model on the Simulink canvas for by-hand editing, execution, etc.
% open_system(hsys);
Simulate the model in the time domain with a fixed step solver with a simulation solver step size of 1e-8
cset = getActiveConfigSet(hsys);
set_param(cset,'StopTime','0.015');
set_param(cset,'Solver','FixedStepAuto');
set_param(cset,'FixedStep','1e-8');
out = sim('lqitest',cset);
figure
plot(out.y),grid
Get the open loop system at the input to the plant. linearize automagically deals with the hybrid model
sysolsimulink = -1*linearize('lqitest',linio('lqitest/control',1,'looptransfer'));
Build the system using connect after explicitly discretizing the plant using the ZOH assumption.
sysp = ss(plant.A,plant.B,plant.C,plant.D,'InputName','u','OutputName',{'x1' 'x2' 'y'});
%int = tf(K_lqi(3),[1 0],'InputName','e','OutputName','ui');
Kfb = ss(K_lqi(1:2),'InputName',{'x1' 'x2'},'OutputName','ufb');
esum = sumblk('e = r - y');
usum = sumblk('u = -ui - ufb');
syspdiscrete = c2d(sysp,Ts,'zoh');
intdiscrete = tf(Ts*K_lqi(3),[1 -1],Ts,'InputName','e','OutputName','ui');
syscdiscrete = connect(syspdiscrete,intdiscrete,Kfb,esum,usum,'r','y','u');
Compare the Bode plots of the open loop system derived by linearize() and derived by connect() followed by getLoopTransfer
figure
bode(sysolsimulink,getLoopTransfer(syscdiscrete,'u',-1),{10 1e7});
The results match.

Iniciar sesión para comentar.

Categorías

Más información sobre Time and Frequency Domain Analysis en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by