home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / r / rlab / CTB / c2dm < prev    next >
Encoding:
Text File  |  1995-11-15  |  5.9 KB  |  208 lines

  1. //-------------------------------------------------------------------------------
  2. // c2dm
  3. //
  4. // Syntax: G=c2dm(A,B,C,D,T,method,om1)
  5. //
  6. // This routine converts a continuous linear time invariant (LTI)
  7. // system to a discrete time system. This routine allows the user
  8. // to choose from several conversions methods.
  9. //
  10. //  "zoh"     Convert to discrete time assuming a zero order hold
  11. //            on the inputs.
  12. //  "foh"     Convert to discrete time assuming a first order hold
  13. //            on the inputs.
  14. //  "tustin"  Convert to discrete time using a bilinear (Tustin)
  15. //            approximation to the derivative.
  16. //  "prewarp" Convert to discrete time using a bilinear (Tustin)
  17. //            approximation, but with frequency pre-warping.
  18. //            The desired frequency is om1.
  19. //
  20. // The routine may be called as,
  21. //
  22. //      G=c2dm(A,B,C,D,T,"method",om1)
  23. //
  24. // where the state-space model is given by (A,B,C,D), the sample time
  25. // is given by T, the desired conversion is given by "method," and the
  26. // desired frequency for prewarping is given by om1.
  27. //
  28. // The results are passed back in a list:
  29. //
  30. //   G.ad = discrete A matrix
  31. //   G.bd = discrete B matrix
  32. //   G.cd = discrete C matrix
  33. //   G.dd = discrete D matrix
  34. //
  35. // The routine can also be used to convert systems given in the Transfer
  36. // Function form:
  37. //
  38. //     G=c2dm(num,den,T,"method")
  39. //
  40. // which converts a continuous polynomial G(s)=num(s)/den(s) to a discrete
  41. // time polynomial G(z)=num(z)/den(z).
  42. //
  43. // Ths results are passed back in a list:
  44. //
  45. //   G.ad = discrete numerator
  46. //   G.bd = discrete denominator
  47. //
  48. // Ref:  Frankin, G. F., Powell, J. D., Workman, M. L., "Digital Control of
  49. //       Dynamic Systems," Addison-Wesley, Reading Mass., 1990.
  50. //
  51. // Copyright (C), by Jeffrey B. Layton, 1994
  52. // Version JBL 940108
  53. //-------------------------------------------------------------------------------
  54.  
  55. rfile tfchk
  56. rfile tf2ss
  57. rfile abcdchk
  58. rfile c2d
  59. rfile ss2tf
  60. rfile isstr
  61.  
  62. static (c2dm_compute)    // Hide this function
  63.  
  64. c2dm = function(A,B,C,D,T,method,om1)
  65. {
  66.    local(nargs,P,msg,estr,tf)
  67.  
  68. // count number of input arguments
  69.    nargs=0;
  70.    if (exist(A)) {nargs=nargs+1;}
  71.    if (exist(B)) {nargs=nargs+1;}
  72.    if (exist(C)) {nargs=nargs+1;}
  73.    if (exist(D)) {nargs=nargs+1;}
  74.    if (exist(T)) {nargs=nargs+1;}
  75.    if (exist(method)) {nargs=nargs+1;}
  76.    if (exist(om1)) {nargs=nargs+1;}
  77.  
  78. // switch on which type of system is being input
  79.    if (nargs == 2) {
  80. // Transfer Function with no method specified
  81.        P=tfchk(A,B);
  82.        P=tf2ss(P.numc,P.denc,2);
  83.        tf=1;
  84.        return c2dm_compute (P.a, P.b, P.c, P.d, C, "zoh", om1, tf)
  85.    else if (nargs == 4) {
  86. // Transfer Function with method specified
  87.        P=tfchk(A,B);
  88.        P=tf2ss(P.numc,P.denc,2);
  89.        tf=1;
  90.        return c2dm_compute (P.a, P.b, P.c, P.d, C, D, om1, tf)
  91.    else if (nargs == 5) {
  92.        if (isstr(D)) {
  93. // Transfer function with method specified and prewarp freq.
  94.            P=tfchk(A,B);
  95.            P=tf2ss(P.numc,P.denc,2);
  96.            tf=1;
  97.            return c2dm_compute (P.a, P.b, P.c, P.d, C, D, T, tf)
  98.        else
  99. // State-Space model without method specified
  100.            msg="";
  101.            msg=abcdchk(A,B,C,D);
  102.            if (msg != "") {
  103.                estr="C2DM: "+msg;
  104.                error(estr);
  105.            }
  106.            return c2dm_compute (A, B, C, D, T, "zoh", om1, tf)
  107.        }
  108.    else
  109. // State Space system with specified method
  110.        msg="";
  111.        msg=abcdchk(A,B,C,D);
  112.        if (msg != "") {
  113.            estr="C2DM: "+msg;
  114.            error(estr);
  115.        }
  116.        return c2dm_compute (A, B, C, D, T, method, om1, tf)
  117.    }}}
  118.  
  119. };
  120.  
  121. //-------------------------------------------------------------------------------
  122. //
  123. // This is where the computation is performed. Note that c2dm_compute is a
  124. // static variable and is never seen from the global workspace.
  125. //
  126.  
  127. c2dm_compute = function(A, B, C, D, T, method, om1, tf)
  128. {
  129.    local(P,estr,Adum,FT,E,gam1,gam2,I,Tw,...
  130.          ad,bd,cd,dd)
  131.  
  132. // Switch on Method
  133.  
  134. // Zero Order Hold
  135. // ---------------
  136.    if (strsplt(method)[1] == "z") {
  137.  
  138. // Just call c2d which already performs the zero order hold conversion
  139.        P=c2d(A,B,T);
  140.        ad=P.phi;
  141.        bd=P.gamma;
  142.        cd=C;
  143.        dd=D;
  144.  
  145. // First Order Hold Using Triangle Approximation
  146. // ---------------------------------------------
  147.    else if (strsplt(method)[1] == "f") {
  148.  
  149. // Form FT matrix
  150.        FT = [      A,                B,        zeros(A.nr,B.nc);
  151.              zeros(B.nc,A.nr),zeros(B.nc,B.nc),eye(B.nc,B.nc)/T;
  152.              zeros(B.nc,A.nr),zeros(B.nc,B.nc),zeros(B.nc,B.nc)];
  153. // Take Matrix exponential
  154.        E=expm(FT*T);
  155. // Find Phi, Gamma1, Gamma2 partitions
  156.        ad=E[1:A.nr;1:A.nr];
  157.        gam1=E[1:A.nr;(A.nr+1):(A.nr+B.nc)];
  158.        gam2=E[1:A.nr;(A.nr+B.nc+1):(A.nr+(2*B.nc))];
  159. // Form B,C,D discrete matrices
  160.        bd=gam1+ad*gam2-gam2;
  161.        cd=C;
  162.        dd=D+C*gam2;
  163.  
  164. // Bilinear (Tustin)
  165. // -----------------
  166.    else if (strsplt(method)[1] == "t") {
  167.        I=eye(A.nr,A.nr);
  168.        E=inv(I-A.*T/2);
  169.        ad=(I+A.*T/2)*E;
  170.        bd=E*B;
  171.        cd=T*C*E;
  172.        dd=cd*B/2+D;
  173.  
  174. // Bilinear (Tustin) with frequency prewarping
  175. // -------------------------------------------
  176.    else if (strsplt(method)[1] == "p") {
  177.  
  178.        if ( nargs != 5) {
  179.            if ( nargs != 7) {
  180.                Tw=2*tan(om1*T/2)/om1;
  181.                I=eye(A.nr,A.nr);
  182.                E=inv(I-A.*Tw/2);
  183.                ad=(I+A.*Tw/2)*E;
  184.                bd=E*B;
  185.                cd=Tw*C*E;
  186.                dd=cd*B/2+D;
  187.            else
  188.                estr="c2dm: The critical frequency must be specified ";
  189.                estr=estr+"when using the prewarp method.";
  190.                error(estr);
  191.            }
  192.        }
  193.    else
  194.        estr="c2dm: The critical frequency must be specified ";
  195.        estr=estr+"when using the prewarp method.";
  196.        error(estr);
  197.    }}}}
  198.  
  199.    if (tf) {
  200.        Adum=ss2tf(ad,bd,cd,dd,1);
  201.        ad=Adum.num;
  202.        bd=Adum.den;
  203.        return << ad=ad; bd=bd >>
  204.    }
  205.  
  206.    return << ad=ad; bd=bd; cd=cd; dd=dd >>
  207. };
  208.