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

  1. //--------------------------------------------------------------------------------
  2. // lqrmsf
  3. //
  4. // Syntax: D=lqrmsf(A,B,Q,R,CT,Reps,iterm)
  5. //
  6. // This routine solves the Algebraic Riccati Equation using the matrix
  7. // Sign function. It also computes the optimal feedback gain matrix such that
  8. // the feedback law u = -Kx  minimizes the following cost function:
  9. //
  10. //           Inf
  11. //     J = Integral (x'Qx + u'Ru) dt
  12. //            0
  13. //
  14. // subject to the constraint
  15. //   .
  16. //   x = Ax + Bu
  17. //
  18. // The solution P solves the following equation:
  19. //
  20. //                 -1
  21. //   A'P + PA - PBR  B'P + Q = 0
  22. //
  23. // When the term CT is included, a Cross-Term is added that relates u to x
  24. // in the following cost function:
  25. //
  26. //           Inf
  27. //     J = Integral (x'Qx + u'Ru + 2*x'CTu) dt
  28. //            0
  29. //
  30. // The input Reps is the tolerance for the iteration procedure and the
  31. // variable iterm is the maximum number of iterations.
  32. //
  33. // Note: Three matrices are returned in a list.
  34. //
  35. //       D.G = Optimal Feedback Gain matrix
  36. //       D.P = Steady-State Solution to the Algebraic Riccatti Eqn.
  37. //
  38. //
  39. //  Ref.: (1) Chapter 5 of Junkins & Kim, Dyn. & Ctrl. of Structures.
  40. //        (2) Bierman, G.J.,
  41. //            "Computational Aspects of the Matrix Sign Function to the ARE"
  42. //            Proc. 23rd CDC, 1984, pp.514-519.
  43. //
  44. // Copyright (C), by Jeffrey B. Layton, 1994
  45. // Version JBL 940618
  46. //--------------------------------------------------------------------------------
  47.  
  48. rfile abcdchk
  49.  
  50. static (lqrmsf_compute)    // Hide this function
  51.  
  52. lqrmsf = function(a,b,q,r,ct,Reps,iterm)
  53. {
  54.    local(nargs,itermax,eps,msg,estr)
  55.  
  56. // Count number of input arguments
  57.    nargs=0;
  58.    if (exist(a)) {nargs=nargs+1;}
  59.    if (exist(b)) {nargs=nargs+1;}
  60.    if (exist(q)) {nargs=nargs+1;}
  61.    if (exist(r)) {nargs=nargs+1;}
  62.  
  63. // Error Traps
  64. // ===========
  65.  
  66. // Check if Q and R are consistent.
  67.    if ( a.nr != q.nr || a.nc != q.nc ) {
  68.        error("LQRMSF: A and Q must be the same size");
  69.    }
  70.    
  71.    if ( r.nr != r.nc || b.nc != r.nr ) {
  72.        error("LQRMSF: B and R must be consistent");
  73.    }
  74.    
  75. // Check if A and B are empty
  76.    if ( (!length(a)) || (!length(b)) ) {
  77.        error("LQRMSF: A and B matrices cannot be empty.");
  78.    }
  79.  
  80. // A has to be square
  81.    if (a.nr != a.nc) {
  82.        error("LQRMSF: A has to be square.");
  83.    }
  84.  
  85. // See if A and B are compatible.
  86.    msg="";
  87.    msg=abcdchk(a,b);
  88.    if (msg != "") {
  89.        estr="LQRMSF: "+msg;
  90.        error(estr);
  91.    }
  92.  
  93. // Check if Q is positive semi-definite and symmetric
  94.    if (!issymm(q)) {
  95.        printf("%s","LQRMSF: Warning: Q is not symmetric.\n");
  96.    else
  97.        if (any(eig(q).val < -epsilon()*norm(q,"1")) ) { 
  98.            printf("%s","LQRMSF: Warning: Q is not positive semi-definite.\n");
  99.        }
  100.    }
  101.  
  102. // Check if R is positive definite and symmetric
  103.    if (!issymm(r)) {
  104.        printf("%s","LQRMSF: Warning: R is not symmetric.\n");
  105.    else
  106.        if (any(eig(r).val < -epsilon()*norm(r,"1")) ) {
  107.            printf("%s","LQRMSF: Warning: R is not positive semi-definite.\n");
  108.        }
  109.    }
  110.  
  111. // Set defaults if variables are not input.
  112. // ========================================
  113.  
  114.    if (!exist(iterm)) {
  115.        itermax=1000;
  116.    else
  117.        itermax=iterm;
  118.    }
  119.  
  120.    if (!exist(Reps)) {
  121.        eps=1.0e-10;
  122.    else
  123.        eps=Reps
  124.    }
  125.  
  126. //
  127. // Call lqrmsf_compute with revised arguments. This prevents us from needlessly
  128. // making a copy if ct does not exist, and also prevents us from overwriting
  129. // A and Q if CT exists.
  130. //
  131.  
  132. // If Cross-Term exists, modify Q and A.
  133.    if (exist(ct)) {
  134.        if ( ct.nr != a.nr || ct.nc != r.nc) {
  135.             error("LQRMSF: CT must be consistent with Q and R");
  136.        }
  137.        return lqrmsf_compute (a-solve(r',b')'*ct', b, ...
  138.                               q-solve(r',ct')'*ct', r, ct, ...
  139.                               eps, itermax);
  140.    else
  141.        return lqrmsf_compute (a, b, q, r, zeros (a.nr, b.nc), ...
  142.                               eps, itermax);
  143.    }
  144. };
  145.  
  146. //----------------------------------------------------------------------------
  147. //
  148. // This is where the computation is performed. Note that lqrmsf_compute is a
  149. // static variable and is never seen from the global workspace.
  150. //
  151.  
  152. lqrmsf_compute = function (A, B, Q, R, CT, eps, itermax)
  153. {
  154.    local(n,Jhat,Hhat,Hhatnew,SignH,W,W12,W11,errstr)
  155.  
  156.    n=A.nr;
  157.  
  158. //  Iteration begins for computing matrix sign function of Hamiltonian
  159. //  (Use transformed Hamiltonian to get accurate inverse of Hamiltonian)
  160.  
  161.    Jhat=[zeros(n,n),-eye(n,n);eye(n,n),zeros(n,n)];
  162.    Hhat=[Q, A';A,-B*inv(R)*B'];
  163.  
  164.    for (i in 1:itermax) {
  165.         Hhatnew=0.5*(Hhat+Jhat*inv(Hhat)*Jhat);
  166.         if (norm(Hhatnew-Hhat,"f") < eps) {
  167.             break;
  168.         }
  169.         Hhat=Hhatnew;
  170.    }
  171.  
  172. // Check iteration counter
  173.    if (i == itermax) {
  174.        errstr="lqrmsf: failed to converge in "+int2str(itermax)+" iterations"
  175.        printf("%s",errstr);
  176.    }
  177.  
  178.    SignH=-Jhat*Hhatnew;
  179.  
  180. //  Compute the Riccati Solution
  181.  
  182.    W=0.5*(SignH+eye(2*n,2*n));
  183.    W12=W[1:n;n+1:2*n];
  184.    W11=W[1:n;1:n];
  185.    P=-inv(W12)*W11;
  186. // G=inv(R)*B'*P;
  187.    G=solve( R, CT'+B'*P );
  188.  
  189.    return << G=G; P=P >>
  190. };
  191.