home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l455 / 10.ddi / CONTROL.DI$ / C2DM.M < prev    next >
Encoding:
Text File  |  1993-03-11  |  5.0 KB  |  176 lines

  1. function [adout,bd,cd,dd] = c2dm(a,b,c,d,Ts,method,w)
  2. %C2DM    Conversion of continuous LTI systems to discrete-time.
  3. %    [Ad,Bd,Cd,Dd] = C2DM(A,B,C,D,Ts,'method') converts the continuous-
  4. %    time state-space system (A,B,C,D) to discrete time using 'method':
  5. %      'zoh'            Convert to discrete time assuming a zero order
  6. %            hold on the inputs.
  7. %      'foh'            Convert to discrete time assuming a first order 
  8. %            hold on the inputs.
  9. %      'tustin'      Convert to discrete time using the bilinear 
  10. %            (Tustin) approximation to the derivative.
  11. %      'prewarp'     Convert to discrete time using the bilinear 
  12. %            (Tustin) approximation with frequency prewarping.
  13. %            Specify the critical frequency with an additional
  14. %            argument, i.e. C2DM(A,B,C,D,Ts,'prewarp',Wc)
  15. %      'matched'     Convert the SISO system to discrete time using the
  16. %            matched pole-zero method.
  17. %
  18. %    [NUMd,DENd] = C2DM(NUM,DEN,Ts,'method') converts the continuous-
  19. %    time polynomial transfer function G(s) = NUM(s)/DEN(s) to discrete
  20. %    time, G(z) = NUMd(z)/DENd(z), using 'method'.
  21. %
  22. %    See also: C2D, and D2CM.
  23.  
  24. %    Clay M. Thompson  7-19-90
  25. %    Copyright (c) 1986-93 by the MathWorks, Inc.
  26.  
  27. error(nargchk(3,7,nargin));
  28.  
  29. tf = 0;
  30. % --- Determine which syntax is being used ---
  31. if (nargin==3),        % Transfer function without method, assume 'zoh'
  32.   [num,den] = tfchk(a,b);
  33.   Ts = c;
  34.   method = 'zoh';
  35.   [a,b,c,d] = tf2ss(num,den);
  36.   tf = 1;
  37.  
  38. elseif (nargin==4),    % Transfer function with method.
  39.   [num,den] = tfchk(a,b);
  40.   Ts = c;
  41.   method = d;
  42.   [a,b,c,d] = tf2ss(num,den);
  43.   tf = 1;
  44.  
  45. elseif (nargin==5),
  46.   if isstr(d),        % Transfer function with method and prewarp const.
  47.     [num,den] = tfchk(a,b);
  48.     w = Ts;
  49.     Ts = c;
  50.     method = d;
  51.     [a,b,c,d] = tf2ss(num,den);
  52.     tf = 1;
  53.   else            % State space system without method, assume 'zoh'
  54.     error(abcdchk(a,b,c,d));
  55.     method = 'zoh';
  56.   end
  57.  
  58. else            % State space system with method.
  59.   error(abcdchk(a,b,c,d));
  60.  
  61. end
  62. [nx,na] = size(a);
  63. [nb,nu] = size(b);
  64.  
  65. % --- Determine conversion method ---
  66. if method(1)=='z',    % Zero order hold approximation.
  67.   [ad,bd] = c2d(a,b,Ts);
  68.   cd = c; dd = d;
  69.  
  70. elseif method(1)=='f',    % First order hold (triangle) approximation.
  71.   [n,n] = size(a);
  72.   [ny,nx] = size(c); cc = zeros(ny,nx);
  73.   [nx,nu] = size(b); bb = zeros(nx,nu);
  74.   aa = [a            b            zeros(nx,nu)
  75.         zeros(nu,nx) zeros(nu,nu) eye(nu,nu)/Ts
  76.         zeros(nu,nx) zeros(nu,nu) zeros(nu,nu)];
  77.   pp = expm(aa*Ts);
  78.   ad = pp(1:n,1:n);
  79.   g1 = pp(1:n,n+[1:nu]);
  80.   g2 = pp(1:n,n+nu+[1:nu]);
  81.   bd = g1 + ad*g2 - g2;
  82.   cd = c;
  83.   dd = d + c*g2;
  84.  
  85. elseif method(1)=='t',    % Tustin approximation.
  86.   I = eye(nx);
  87.   P = inv(I - a.*Ts/2);
  88.   ad = (I + a.*Ts/2)*P;
  89.   bd = P*b;
  90.   cd = Ts*c*P;
  91.   dd = cd*b/2 + d;
  92.  
  93. elseif method(1)=='p',    % Tustin approximation with frequency prewarping.
  94.   if ~((nargin==5)|(nargin==7)),
  95.     error('The critical frequency must be specified when using ''prewarp''.');
  96.   end
  97.   T = 2*tan(w*Ts/2)/w;        % Prewarp
  98.   I = eye(nx);
  99.   P = inv(I - a.*T/2);
  100.   ad = (I + a.*T/2)*P;
  101.   bd = P*b;
  102.   cd = T*c*P;
  103.   dd = cd*b/2 + d;
  104.   
  105. elseif method(1)=='m',    % Matched pole-zero approximation.
  106.   [ny,nu] = size(d);
  107.   if (ny>1)|(nu>1),
  108.     error('System must be SISO for matched pole-zero method.');
  109.   end
  110.   if tf & ny & nu,
  111.     z = roots(num); p = roots(den);
  112.   else
  113.     [z,p] = ss2zp(a,b,c,d);
  114.   end
  115.   z = [z;inf*ones(length(p)-length(z),1)]; % Pad zeros with inf's
  116.   pd = exp(p*Ts);
  117.   zd = zeros(length(z),1);
  118.   if ~isempty(z),
  119.     zd(z~=inf) = exp(z(z~=inf)*Ts);
  120.     zd(z==inf) = -1*ones(length(z(z==inf)),1);
  121.   end
  122.   ndx = find(z==inf);
  123.   if ~isempty(ndx), zd(ndx(1))=inf; end      % Put one infinite zero at infinity.
  124.   [ad,bd,cd,dd] = zp2ss(zd,pd,1);
  125.  
  126.   % Match D.C. gain or gain at s=1 for singular systems.
  127.   if any(abs(p)<sqrt(eps)), % Match gain at s = 1.
  128.     if tf & nu & ny
  129.       kc = abs(polyval(num,sqrt(-1)))/abs(polyval(den,sqrt(-1)));
  130.     else
  131.       kc = c/(eye(nx)-a)*b + d;
  132.     end
  133.     kd = abs(cd/(exp(sqrt(-1)*Ts)*eye(nx)-ad)*bd + dd);
  134.   else
  135.     if tf & nu & ny,
  136.       kc = num(length(num))/den(length(den));
  137.     else
  138.       kc = -c/a*b + d;
  139.     end
  140.     kd = cd/(eye(nx)-ad)*bd + dd;
  141.   end
  142.   km = sqrt(abs(kc/kd));
  143.   sm = sign(kc/kd);
  144.   bd = bd.*km;
  145.   cd = cd.*km.*sm;
  146.   dd = dd.*km.*km.*sm;
  147.  
  148. else
  149.   error('Conversion method is unknown.');
  150.  
  151. end
  152.  
  153. if nargout==0,        % Compare Bode or Singular value plots
  154.   [ny,nc] = size(c);
  155.   if (ny==1)&(nu==1),    % Plot Bode plots
  156.     [magc,phasec,wc] = bode(a,b,c,d);
  157.     [magd,phased,wd] = dbode(ad,bd,cd,dd,Ts,1);
  158.     semilogx(wc,20*log10(magc),'-',wd,20*log10(magd),'--')
  159.     title('C2DM comparison plot')
  160.     xlabel('Frequency (rad/sec)'), ylabel('Gain dB')
  161.   else
  162.     [svc,wc] = sigma(a,b,c,d);
  163.     [svd,wd] = dsigma(ad,bd,cd,dd,Ts);
  164.     semilogx(wc,20*log10(svc),'-',wd,20*log10(svd),'--');
  165.     title('C2DM comparison plot')
  166.     xlabel('Frequency (rad/sec)'), ylabel('Singular Values dB')
  167.   end
  168.   return
  169. end
  170.  
  171. if tf,        % Convert to TF form for output
  172.   [ad,bd] = ss2tf(ad,bd,cd,dd,1);
  173. end
  174.  
  175. adout = ad;
  176.