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

  1. %
  2. %     << 4-block L-inf optimal Controller (all solution formulae) >>
  3. %           (derived by Limebeer and Kasenally, Dec. 1987)
  4. %
  5. %   HINFLIM is a script file which computes the H-inf optimal controller 
  6. %   using L-K's all-solution "two-Riccati" formulae.
  7. %   A particular controller F(s) is returned by default, however the
  8. %   other solution can be generated by prespecifing the transfer function
  9. %   in the workspace
  10. %                       U(s):= (AU,BU,CU,DU)
  11. %   where U(s) is a free stable contraction which parameterizes all the 
  12. %   stabilizing controllers.
  13. %
  14. %   Input data (must be in Upper Case !!!): 
  15. %              augmented plant (A,B1,B2,C1,C2,D11,D12,D21,D22) 
  16. %              stable contraction U(s):= (AU,BU,CU,DU) (optional)
  17. %   Output data: H-inf controller F(s):= (acp,bcp,ccp,dcp),
  18. %                CLTF Ty1u1:= (acl,bcl,ccl,dcl).
  19. %
  20.  
  21. % R. Y. Chiang & M. G. Safonov 2/10/88
  22. % Copyright (c) 1988 by the MathWorks, Inc.
  23. % All Rights Reserved.
  24. % ------------------------------------------------------------------------
  25. disp('   ')
  26. disp('                << H-inf Optimal Control Synthesis >>')
  27. disp(' ')
  28. disp(' - - - Computing 4-block L-inf optimal controller ')
  29. disp('       (using the all-solution formulae of Limebeer and Kasenally) - - -')
  30. %
  31. flagcase1 = exist('b1');
  32. flagcase2 = exist('B1');
  33. if (flagcase1 > 0) & (flagcase2 < 1)
  34.  error('   THIS SCRIPT FILE REQUIRES THE INPUT VARIABLE NAMES IN UPPER CASE !!!')
  35. end
  36. %
  37. FLAG = exist('AU');
  38. if FLAG < 1
  39.    disp('  ')
  40.    disp(' - - - Solving a particular solution F(s) (U(s) = 0 case) - - -');
  41. end
  42. if FLAG > 0
  43.    disp('  ')
  44.    disp(' - - - Solving the all-solution F(s) (U(s):=(AU,BU,CU,DU)) - - -');
  45. end
  46. AREFLAG = exist('aretype');
  47. %
  48. % ------------------------------------------- Pre-process the augmented plant:
  49. %
  50. % ------------------------------------------- 1) Zero out the D22 term:
  51. %
  52. [mD22,nD22] = size(D22);
  53. d22 = zeros(mD22,nD22);
  54. %
  55. % ------------------------------------------- 2) Find scaling factors:
  56. %
  57. [p1,m2] = size(D12);
  58. [uu,sig12,vv] = svd(D12);
  59. u1 = uu(:,1:m2);
  60. u2 = uu(:,m2+1:p1);
  61. su = vv*inv(sig12(1:m2,1:m2));
  62. sz = [u2';u1'];
  63. %
  64. [p2,m1] = size(D21);
  65. [uuu,sig21,vvv] = svd(D21);
  66. v1 = vvv(:,1:p2);
  67. v2 = vvv(:,p2+1:m1);
  68. sy = inv(sig21(1:p2,1:p2))*uuu';
  69. sw = [v2 v1];
  70. %
  71. b1 = B1*sw;
  72. c1 = sz*C1;
  73. b2 = B2*su;
  74. c2 = sy*C2;  
  75. d11 = sz*D11*sw;
  76. d12 = sz*D12*su;
  77. d21 = sy*D21*sw;
  78. %
  79. % ----------------------------------- 3) Checking the frequency @ inf:
  80. %
  81. d1111 = d11(1:p1-m2,1:m1-p2);
  82. d1121 = d11(p1-m2+1:p1,1:m1-p2);
  83. d1112 = d11(1:p1-m2,m1-p2+1:m1);
  84. d1122 = d11(p1-m2+1:p1,m1-p2+1:m1);
  85. mxsvd11r = max(svd([d1111 d1112]));
  86. mxsvd11c = max(svd([d1111;d1121]));
  87. if mxsvd11r >= 1 | mxsvd11c >= 1
  88.      disp('  ')
  89.      disp('    ------------------------------------------------------------');
  90.      disp('       NO CONTROLLER MEETS THE SPEC. EVEN AT FREQ. INF ALONE !!')
  91.      disp('       ADJUST "Gam" AND TRY AGAIN ...')
  92.      disp('    ------------------------------------------------------------');
  93.      break
  94. end
  95. %
  96. % ----------------------------------- 4) Orthogonal complements of D12 & D21:
  97. %
  98. d12p = ortc(d12);
  99. d21p = ortr(d21);
  100. % ----------------------------------------------------------------------------
  101. % ---------------------------------------- Start to compute the controller:
  102. siz = [1 0]';
  103. n = size(A)*siz;
  104. gam = 1;                    % for small-gain problem
  105. gam2 = gam*gam;
  106. RI = gam2*eye(n);
  107. %
  108. % ---------------------------------------- Fix D11 term:
  109. %
  110. if m1 == p2 | p1 == m2
  111.    fopt = -d1122;
  112. else
  113.    fopt  = -(d1122+d1121*inv(eye(m1-p2)-d1111'*d1111)*d1111'*d1112);
  114. end
  115. %
  116. a   = A  + b2*fopt*c2;
  117. b1  = b1 + b2*fopt*d21;
  118. c1  = c1 + d12*fopt*c2;
  119. d11 = d11+ d12*fopt*d21;
  120. %                                                  ~
  121. % ---------------------------------------- Solving P Riccati:
  122. %
  123. ar1 = a+(b1*d11'*d12p*d12p' - b2*d12'*gam2)*...
  124.       inv(gam2*eye(size(d11)*siz)-d11*d11'*d12p*d12p')*c1;
  125. q1 = c1'*d12p*inv(gam2*eye(size(d12p')*siz)-...
  126.      d12p'*d11*d11'*d12p)*d12p'*c1;
  127. r1 = RI*b2*b2'-(b1-b2*d12'*d11)*gam2*inv(gam2*eye(size(d11')*siz)-...
  128.      d11'*d12p*d12p'*d11)*(b1'-d11'*d12*b2');
  129. disp(' ');
  130. disp(' - - - Solving the 1st Riccati - - -');
  131. if AREFLAG > 0
  132.    [P1,P2,lamPc,Perr,wellposed,P] = aresolv(ar1,q1,r1,aretype);
  133. else
  134.    [P1,P2,lamPc,Perr,wellposed,P] = aresolv(ar1,q1,r1);
  135. end
  136. %                                                  ~
  137. % ---------------------------------------- Solving S Riccati:
  138. %
  139. ar2 = a+b1*inv(gam2*eye(size(d21p')*siz)-d21p'*d21p*d11'*d11)*...
  140.       (d21p'*d21p*d11'*c1-gam2*d21'*c2);
  141. q2 = b1*d21p'*inv(gam2*eye(size(d21p)*siz)-...
  142.      d21p*d11'*d11*d21p')*d21p*b1';
  143. r2 = RI*c2'*c2-(c1'-c2'*d21*d11')*gam2*inv(gam2*eye(size(d11)*siz)-...
  144.      d11*d21p'*d21p*d11')*(c1-d11*d21'*c2);
  145. disp('   ');
  146. disp(' - - - Solving the 2nd Riccati - - -');
  147. if AREFLAG > 0
  148.    [S1,S2,lamSc,Serr,wellposed,S] = aresolv(ar2',q2,r2,aretype);
  149. else
  150.    [S1,S2,lamSc,Serr,wellposed,S] = aresolv(ar2',q2,r2);
  151. end
  152. lamP  = min(real(eig(P)));
  153. lamS  = min(real(eig(S)));
  154. format long
  155. lamPS = max(real(eig(P*S)))
  156. if (lamP<0 & abs(lamP)>1e-10) | (lamS<0 & abs(lamS)>1e-10) | lamPS > 1
  157.          disp('  ')
  158.          disp('    ----------------------------------------------------');
  159.          disp('       NO STABILIZING CONTROLLER MEETS THE SPEC. !!')
  160.          disp('       ADJUST "Gam" AND TRY AGAIN ...')
  161.          disp('    ----------------------------------------------------');
  162.          break
  163. end
  164. %
  165. % ---------------------------- Controller in descriptor form:
  166. %
  167. ek = eye(n)-S*P*RI;
  168. bk1 = -gam2*(b1+S*c1'*d11 -S*c2'*d21*...
  169.       (d11'*d11-gam2*eye(size(d11')*siz)))...
  170.       *inv(gam2*eye(size(d21p')*siz)-...
  171.       d21p'*d21p*d11'*d11)*d21';
  172. ck1 = -gam2*d12'*inv(gam2*eye(size(d11)*siz)...
  173.       -d11*d11'*d12p*d12p')...
  174.       *(c1+d11*b1'*P-(d11*d11'-...
  175.       gam2*eye(size(d11)*siz))*d12*b2'*P);
  176. dk11 = zeros(size(ck1)*siz,size(bk1)*[0 1]');
  177. %
  178. bk2 = b1*d21'*d22-b2+(gam2*S*c1'+b1*d21p'*d21p*d11'-...
  179.          gam2*S*c2'*d21*d11')*...
  180.          inv(gam2*eye(size(d11)*siz)-...
  181.          d11*d21p'*d21p*d11')*(d11*d21'*d22-d12)+...
  182.          gam2*S*c2'*d22;
  183. rbk2 = chol(d12'*(gam2*eye(size(d11)*siz)-d11*d11')...
  184.          *gam2*inv(gam2*eye(size(d12p)*siz)-...
  185.          d12p*d12p'*d11*d11')*d12);
  186. rbk2 = rbk2';
  187. bk2 = bk2*rbk2;
  188. ck2 = (d22*d12'*c1-c2)+d22*b2'*P*gam2+(d22*d12'*d11-d21)...
  189.          *inv(gam2*eye(size(d11')*siz)-d11'*d12p*d12p'*d11)*...
  190.          (d11'*d12p*d12p'*c1-d11'*d12*b2'*P*gam2+b1'*P*gam2);
  191. rck2 = chol(gam2*d21*inv(gam2*eye(size(d11')*siz)-...
  192.          d11'*d11*d21p'*d21p)*...
  193.          (gam2*eye(size(d11')*siz)-d11'*d11)*d21');
  194. ck2 = rck2*ck2;
  195. dk12 = chol(d12'*(gam2*eye(size(d11)*siz)-d11*d11')*...
  196.            gam2*inv(gam2*eye(size(d12p)*siz)...
  197.           -d12p*d12p'*d11*d11')*d12);
  198. dk12 = -dk12';
  199. dk21 = chol(gam2*d21*inv(gam2*eye(size(d11')*siz)-...
  200.             d11'*d11*d21p'*d21p)*...
  201.            (gam2*eye(size(d11')*siz)-d11'*d11)*d21');
  202. dk21 = -dk21;
  203. dk22 = dk21*d22*dk12+inv(dk21')*d21*d11'*...
  204.           inv(gam2*eye(size(d11)*siz)-...
  205.           d11*d21p'*d21p*d11')*d12*dk12*gam2;
  206. %
  207. ak = -(S*c1'*d11+b1)*inv(gam2*eye(size(d21p')*siz)-...
  208.       d21p'*d21p*d11'*d11)...
  209.      *d21'*d21*inv(gam2*eye(size(d11')*siz)-...
  210.      d11'*d12p*d12p'*d11);
  211. ak = ak*(d11'*d12p*d12p'*c1*gam2+gam2*gam2*b1'*P-...
  212.      gam2*gam2*d11'*d12*b2'*P...
  213.      +gam2*(gam2*eye(size(d11')*siz)-...
  214.      d11'*d12p*d12p'*d11)*d21'*c2);
  215. ak0 = -S*c2'*d21*inv(gam2*eye(size(d11')*siz)-...
  216.       d11'*d11*d21p'*d21p)*...
  217.       (gam2*eye(size(d11')*siz)-d11'*d11)*...
  218.       inv(gam2*eye(size(d11')*siz)-d11'*d12p*d12p'*d11);
  219. ak0 = ak0*(d11'*d12p*d12p'*c1*gam2+gam2*gam2*b1'*P-...
  220.        gam2*gam2*d11'*d12*b2'*P +...
  221.        gam2*(gam2*eye(size(d11')*siz)-...
  222.        d11'*d12p*d12p'*d11)*d21'*c2);
  223. ak = ak+ak0;
  224. ak = ak+ek*(a+(b1*d11'*d12p*d12p'-b2*d12'*gam2)*...
  225.      inv(gam2*eye(size(d11)*siz)-...
  226.      d11*d11'*d12p*d12p')*c1-(gam2*b2*b2'-...
  227.      (b1-b2*d12'*d11)*gam2*inv(gam2*eye(size(d11')*siz)-...
  228.      d11'*d12p*d12p'*d11)*(b1'-d11'*d12*b2'))*P);
  229. ak = ak+bk1*d22*ck1;
  230. %
  231. % --------------- Flip the sign of controller:
  232. %
  233. bk1 = -bk1; bk2 = -bk2;
  234. dk11 = -dk11; dk12 = -dk12; dk21 = -dk21; dk22 = -dk22;
  235. %
  236. % ------------------------------------ Post-process the controller:
  237. %
  238. % ------------------------------------ 1) Reverse the "fopt" term:
  239. %
  240. dk11 = dk11 + fopt;
  241. %
  242. % ------------------------------------ 2) Reverse the controller scaling:
  243. %
  244. bk1  = bk1*sy;
  245. ck1  = su*ck1;
  246. dk11 = su*dk11*sy;
  247. dk12 = su*dk12;
  248. dk21 = dk21*sy;
  249. %
  250. % ------------------------------------ 3) Shifting D22 term:
  251. %
  252. temp = inv(eye(size(dk11)*[1;0]) + dk11*D22);
  253. ak   = ak-bk1*D22*temp*ck1;
  254. bk2  = bk2-bk1*D22*temp*dk12;
  255. ck2  = ck2-dk21*D22*temp*ck1;
  256. ck1  = temp*ck1;
  257. dk22 = dk22-dk21*D22*temp*dk12;
  258. dk12 = temp*dk12;
  259. dk11 = temp*dk11;
  260. temp = eye(size(D22)*[1;0])-D22*dk11;
  261. bk1  = bk1*temp;
  262. dk21 = dk21*temp;
  263. %
  264. % ----------------  Putting descriptor controller K(s) in state space form:
  265. %
  266. se = svd(ek);
  267. nullE = size(find(se<1.e-7))*[1;0];
  268. [ak,bk,ck,dk] = des2ss(ak,[bk1,bk2],[ck1;ck2],...
  269.                          [dk11,dk12;dk21,dk22],ek,nullE);
  270. [rbk1,cbk1] = size(bk1);
  271. [rbk2,cbk2] = size(bk2);
  272. [rck1,cck1] = size(ck1);
  273. [rck2,cck2] = size(ck2);
  274. bk1=bk(:,1:cbk1);
  275. bk2=bk(:,cbk1+1:cbk1+cbk2);
  276. ck1=ck(1:rck1,:);
  277. ck2=ck(rck1+1:rck1+rck2,:);
  278. dk11=dk(1:rck1,1:cbk1);
  279. dk12=dk(1:rck1,cbk1+1:cbk1+cbk2);
  280. dk21=dk(rck1+1:rck1+rck2,1:cbk1);
  281. dk22=dk(rck1+1:rck1+rck2,cbk1+1:cbk1+cbk2);
  282. %
  283. % --------------------- computing controller F(s) = (acp,bcp,ccp,dcp):
  284. %
  285. sysk = [ak,bk1,bk2;ck1,dk11,dk12;ck2,dk21,dk22];
  286. dimk = [size(ak)*[1 0]',size(bk1)*[0 1]',size(bk2)*[0 1]',...
  287.             size(ck1)*[1 0]',size(ck2)*[1 0]'];
  288. if ~( exist('AU') & exist('BU') & exist('CU') & exist('DU'))
  289.    acp = ak; bcp = bk1; ccp = ck1; dcp = dk11;
  290. else
  291.    [acp,bcp,ccp,dcp] = lftf(sysk,dimk,AU,BU,CU,DU);
  292. end
  293. %
  294. % ----------------------------------------------------------------------------
  295. %
  296. % ------------------------------------ Closed-loop TF (Ty1u1):
  297. %
  298. sysp = [A B1 B2;C1 D11 D12;C2 D21 D22];
  299. dimp = [n,size(B1)*[0 1]',size(B2)*[0 1]',...
  300.        size(C1)*[1 0]',size(C2)*[1 0]'];
  301. [acl,bcl,ccl,dcl] = lftf(sysp,dimp,acp,bcp,ccp,dcp);
  302. %
  303. clear sysp, clear dimp, clear a, clear b1, clear b2, clear c1, clear c2
  304. clear d11, clear d12, clear d21, clear d22, clear syscp, clear dimcp
  305. clear temp
  306. %
  307. % ---------- End of HINFLIM.M --- RYC/MGS -- %
  308.