How can I convert a system with delay from continuous to discrete and from discrete to continuous and the result be the same?
조회 수: 16 (최근 30일)
이전 댓글 표시
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)
댓글 수: 0
채택된 답변
Fangjun Jiang
2011년 6월 10일
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
댓글 수: 0
추가 답변 (5개)
Carla
2011년 6월 10일
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."
댓글 수: 0
Ivan van der Kroon
2011년 6월 10일
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
2011년 6월 10일
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
댓글 수: 0
Rais Akhmetsafin
2018년 4월 10일
편집: Rais Akhmetsafin
2018년 4월 10일
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
댓글 수: 0
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!