How can I convert a system with delay from continuous to discrete and from discrete to continuous and the result be the same?

15 visualizaciones (últimos 30 días)
How can I run this code and the first and the third results be the same?
sys=tf(1,[1 1],'InputDelay',0.4)
sysd=c2d(sys,0.3)
sysagain=d2c(sysd)

Respuesta aceptada

Fangjun Jiang
Fangjun Jiang el 10 de Jun. de 2011
When you convert your continuous transfer function to discrete with sample time as 0.3, every step happens at the times of 0.3, like 0.3, 0.6, 0.9... So when your continuous transfer function has 0.4 delay, your conversion loses accuracy or should I say your conversion is not done right. Look at the discrete transfer function, it is z^(-2) which means 0.6 second delay. You can also see it when you convert it back to continuous. So the problem is not that sample time and delay are dependent. The problem is that your sample time is not appropriate to for that specific delay time.
>> sys=tf(1,[1 1],'InputDelay',0.4)
Transfer function:
1
exp(-0.4*s) * -----
s + 1
>> sysd=c2d(sys,0.3)
Transfer function:
0.1813 z + 0.07791
z^(-2) * ------------------
z - 0.7408
Sampling time: 0.3
>> sysagain=d2c(sysd)
Transfer function:
0.1813 s + 1
exp(-0.6*s) * ------------
s + 1

Más respuestas (5)

Carla
Carla el 10 de Jun. de 2011
When discretizing a model with a sampling time not commensurate with your time delay, you can use c2dOptions to tell c2d to approximate the residual fractional delay by a discrete-time all-pass filter:
sys=tf(1,[1 1],'InputDelay',0.4);
opts = c2dOptions('Method','tustin','FractDelayApproxOrder',3);
sys_d = c2d(sys,0.3,opts);
You still will not be able to recover the original continuous time model by converting back to continuous time with d2c, because the all-pass filter approximates the fractional time delay by adding additional states to the model.
However, if you are worried about just throwing away that fractional portion of the time delay, using this option might help. (R2010a and later.)
For more information, see:
doc c2d
web([docroot '/toolbox/control/ug/f2-3161.html'])
On the latter, look for the example entitled "Tustin Approximation for Systems with Time Delays."

Ivan van der Kroon
Ivan van der Kroon el 10 de Jun. de 2011
In that case the sample time in tf should be an integer times the sample time in c2d. You can try it for arbitrary a and integer n
sys=tf(1,[1 1],'InputDelay',a)
d2c(c2d(sys,a/n))
Just don't go near poles near zero.

Arnaud Miege
Arnaud Miege el 10 de Jun. de 2011
I agree with Ivan and Fangjun. Try the following code and you'll see the warnings in the MATLAB command window:
sys=tf(1,[1 1],'InputDelay',0.4);
c2d_methods = {'zoh','foh','impulse','tustin','matched'};
d2c_methods = {'zoh','tustin','matched'};
for i = 1:length(c2d_methods)
for j=1:length(d2c_methods)
try
sysd(i,j) = c2d(sys,0.3,c2d_methods{i}); %#ok<*SAGROW>
catch %#ok<*CTCH>
disp(['Error with c2d method ' c2d_methods{i}]);
end
try
sysagain(i,j) = d2c(sysd(i,j),d2c_methods{j});
catch
disp(['Error with d2c method ' d2c_methods{j}]);
end
end
end
bode(sys)
hold on
for i = 1:length(c2d_methods)
for j=1:length(c2d_methods)
bode(sysagain(i,j));
end
end

Rais Akhmetsafin
Rais Akhmetsafin el 9 de Mzo. de 2017

Rais Akhmetsafin
Rais Akhmetsafin el 10 de Abr. de 2018
Editada: Rais Akhmetsafin el 10 de Abr. de 2018
clc
clear all
tau = 0.7;
ts = 0.5;
H = tf(1,[1 1.8 .9],'InputDelay',tau)
Hz = c2d(H,ts,'zoh')
H1 = d2c(Hz,'zoh')
disp('Problem!!!')
H2 = d2c_with_zoh(Hz)
disp('GOOD!!!')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function sysc = d2c_with_zoh(sysd)
%% Rais Akhmetsafin 2016
eps1 = eps*1e10;
BZ = sysd.num{1}; AZ = sysd.den{1}; ts = sysd.Ts;
d = sysd.InputDelay;
if BZ(1) ~= 0; d = d+1; end
AZ = fliplr(AZ); BZ = fliplr(BZ);
AS = conv(-AZ,[1 -1]);
[g z K] = residue(BZ,AS);
s = -log(z)/ts; st = s.*ts; stl1 = g;
deriv = 0; z_1 = z.^(-1.0-eps1);
while real(sum(stl1)*(stl1.'*z_1)) > 0
deriv = deriv + 1;
stl=stl1; stl1=stl.*st;
end
X0 = 0.5; MaxIter = 50; Iter = 0; Done = 0;
stl=stl1; stl1=stl.*st;
while (~Done) & (Iter < MaxIter)
Iter=Iter+1;
X = X0 - (stl.'*(z.^(-X0))) / (stl1.'*(z.^(-X0)));
Done = abs(X - X0) <= eps1;
X0 = X;
end;
X = real(X); c=-g.*z.^(-X);
[BS AS] = residue(c, s, K);
AS = real(AS); BS = real(BS);
AS = AS(1:end-1); BS = BS(2+deriv:end);
tau = (d+X-1)*ts;
sysc = sysd;
sysc.Ts = 0; sysc.Variable = 's';
sysc.InputDelay = tau;
sysc.ioDelay = 0;
sysc.num{1} = BS; sysc.den{1} = AS;
end

Categorías

Más información sobre Data Types en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by