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

15 vues (au cours des 30 derniers jours)
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)

Réponse acceptée

Fangjun Jiang
Fangjun Jiang le 10 Juin 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

Plus de réponses (5)

Carla
Carla le 10 Juin 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 le 10 Juin 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.
  2 commentaires
sadel
sadel le 10 Juin 2011
this means that sample time and delay should be dependent.I don't want this.

Connectez-vous pour commenter.


Arnaud Miege
Arnaud Miege le 10 Juin 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 le 9 Mar 2017

Rais Akhmetsafin
Rais Akhmetsafin le 10 Avr 2018
Modifié(e) : Rais Akhmetsafin le 10 Avr 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

Catégories

En savoir plus sur Data Types dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by