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

21 views (last 30 days)
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)

Accepted Answer

Fangjun Jiang
Fangjun Jiang on 10 Jun 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

More Answers (5)

Carla
Carla on 10 Jun 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 on 10 Jun 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 on 10 Jun 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 on 9 Mar 2017

Rais Akhmetsafin
Rais Akhmetsafin on 10 Apr 2018
Edited: Rais Akhmetsafin on 10 Apr 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

Categories

Find more on Dynamic System Models in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!