home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21fb.zip / octave / SCRIPTS.ZIP / scripts / control / buildssic.m < prev    next >
Encoding:
Text File  |  1999-12-15  |  9.0 KB  |  302 lines

  1. ## Copyright (C) 1998 Kai P. Mueller
  2. ##
  3. ## This file is part of Octave. 
  4. ##
  5. ## Octave is free software; you can redistribute it and/or modify it 
  6. ## under the terms of the GNU General Public License as published by the 
  7. ## Free Software Foundation; either version 2, or (at your option) any 
  8. ## later version. 
  9. ## 
  10. ## Octave is distributed in the hope that it will be useful, but WITHOUT 
  11. ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  12. ## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
  13. ## for more details.
  14. ## 
  15. ## You should have received a copy of the GNU General Public License 
  16. ## along with Octave; see the file COPYING.  If not, write to the Free 
  17. ## Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. 
  18.  
  19. ## -*- texinfo -*-
  20. ## @deftypefn {Function File } {@var{sys} =} buildssic(@var{Clst}, @var{Ulst}, @var{Olst}, @var{Ilst}, @var{s1}, @var{s2}, @var{s3}, @var{s4}, @var{s5}, @var{s6}, @var{s7}, @var{s8})
  21. ## 
  22. ## Contributed by Kai Mueller.
  23. ## 
  24. ##  Form an arbitrary complex (open or closed loop) system in
  25. ##  state-space form from several systems. "@code{buildssic}" can
  26. ##  easily (despite it's cryptic syntax) integrate transfer functions
  27. ##  from a complex block diagram into a single system with one call.
  28. ##  This function is especially useful for building open loop
  29. ##  interconnections for H_infinity and H2 designs or for closing
  30. ##  loops with these controllers.
  31. ## 
  32. ##  Although this function is general purpose, the use of "@code{sysgroup}"
  33. ##  "@code{sysmult}", "@code{sysconnect}" and the like is recommended for standard
  34. ##  operations since they can handle mixed discrete and continuous
  35. ##  systems and also the names of inputs, outputs, and states.
  36. ##  
  37. ##  The parameters consist of 4 lists that describe the connections
  38. ##  outputs and inputs and up to 8 systems s1-s8.
  39. ##  Format of the lists:
  40. ## @table @var
  41. ## @item      Clst
  42. ## connection list, describes the input signal of
  43. ## each system. The maximum number of rows of Clst is
  44. ## equal to the sum of all inputs of s1-s8.
  45. ## 
  46. ## Example:
  47. ## @code{[1 2 -1; 2 1 0]} ==> new input 1 is old inpout 1
  48. ## + output 2 - output 1, new input 2 is old input 2
  49. ## + output 1. The order of rows is arbitrary.
  50. ## 
  51. ## @item     Ulst
  52. ##  if not empty the old inputs in vector Ulst will
  53. ##            be appended to the outputs. You need this if you
  54. ##            want to "pull out" the input of a system. Elements
  55. ##            are input numbers of s1-s8.
  56. ## 
  57. ## @item     Olst
  58. ##  output list, specifiy the outputs of the resulting
  59. ##            systems. Elements are output numbers of s1-s8.
  60. ##            The numbers are alowed to be negative and may
  61. ##            appear in any order. An empty matrix means
  62. ##            all outputs.
  63. ## 
  64. ## @item     Ilst
  65. ##  input list, specifiy the inputs of the resulting
  66. ##            systems. Elements are input numbers of s1-s8.
  67. ##            The numbers are alowed to be negative and may
  68. ##            appear in any order. An empty matrix means
  69. ##            all inputs.
  70. ## @end table
  71. ## 
  72. ##  Example:  Very simple closed loop system.
  73. ## @example
  74. ## @group
  75. ## w        e  +-----+   u  +-----+
  76. ##  --->o--*-->|  K  |--*-->|  G  |--*---> y
  77. ##      ^  |   +-----+  |   +-----+  |
  78. ##    - |  |            |            |
  79. ##      |  |            +----------------> u
  80. ##      |  |                         |
  81. ##      |  +-------------------------|---> e
  82. ##      |                            |
  83. ##      +----------------------------+
  84. ## @end group
  85. ## @end example
  86. ## 
  87. ## The closed loop system GW can be optained by
  88. ## @example
  89. ## GW = buildssic([1 2; 2 -1], 2, [1 2 3], 2, G, K);
  90. ## @end example
  91. ## @table @var
  92. ## @item Clst
  93. ## (1. row) connect input 1 (G) with output 2 (K).
  94. ## (2. row) connect input 2 (K) with neg. output 1 (G).
  95. ## @item Ulst
  96. ## append input of (2) K to the number of outputs.
  97. ## @item Olst
  98. ## Outputs are output of 1 (G), 2 (K) and appended output 3 (from Ulst).
  99. ## @item Ilst
  100. ## the only input is 2 (K).
  101. ## @end table
  102. ## 
  103. ## Here is a real example:
  104. ## @example
  105. ## @group
  106. ##                          +----+
  107. ##     -------------------->| W1 |---> v1
  108. ## z   |                    +----+
  109. ## ----|-------------+                   || GW   ||     => min.
  110. ##     |             |                        vz   infty
  111. ##     |    +---+    v      +----+
  112. ##     *--->| G |--->O--*-->| W2 |---> v2
  113. ##     |    +---+       |   +----+
  114. ##     |                |
  115. ##     |                v
  116. ##    u                  y
  117. ## @end group
  118. ## @end example
  119. ## 
  120. ## The closed loop system GW from [z; u]' to [v1; v2; y]' can be
  121. ## obtained by (all SISO systems):
  122. ## @example
  123. ## GW = buildssic([1, 4; 2, 4; 3, 1], 3, [2, 3, 5],
  124. ##                [3, 4], G, W1, W2, One);
  125. ## @end example
  126. ## where "One" is a unity gain (auxillary) function with order 0.
  127. ## (e.g. @code{One = ugain(1);})
  128. ## @end deftypefn
  129.  
  130. function sys = buildssic (Clst, Ulst, Olst, Ilst, s1, s2, s3, s4, s5, s6, s7, s8)
  131.  
  132.   ## Written by Kai Mueller April 1998
  133.  
  134.   if((nargin < 5) || (nargin > 12))
  135.     usage("sys = buildssic(Clst,Ulst,Olst,Ilst,s1,s2,s3,s4,s5,s6,s7,s8)");
  136.   endif
  137.   if (nargin >= 5)
  138.     if (!is_struct(s1))
  139.       error("---> s1 must be a structed system.");
  140.     endif
  141.     s1 = sysupdate(s1, "ss");
  142.     [n, nz, m, p] = sysdimensions(s1);
  143.     if (!n && !nz)
  144.       error("---> pure static system must not be the first in list.");
  145.     endif
  146.     if (n && nz)
  147.       error("---> cannot handle mixed continuous and discrete systems.");
  148.     endif
  149.     D_SYS = (nz > 0);
  150.     [A,B,C,D,tsam] = sys2ss(s1);
  151.     nt = n + nz;
  152.   endif
  153.   for ii = 6:nargin
  154.     eval(["ss = s", num2str(ii-4), ";"]);
  155.     if (!is_struct(ss))
  156.       error("---> Parameter must be a structed system.");
  157.     endif
  158.     ss = sysupdate(ss, "ss");
  159.     [n1, nz1, m1, p1] = sysdimensions(ss);
  160.     if (n1 && nz1)
  161.       error("---> cannot handle mixed continuous and discrete systems.");
  162.     endif
  163.     if (D_SYS)
  164.       if (n1)
  165.           error("---> cannot handle mixed cont. and discr. systems.");
  166.       endif
  167.       if (tsam != sysgettsam(ss))
  168.     error("---> sampling time of all systems must match.");
  169.       endif
  170.     endif
  171.     [as,bs,cs,ds] = sys2ss(ss);
  172.     nt1 = n1 + nz1;
  173.     if (!nt1)
  174.       ## pure gain (pad B, C with zeros)
  175.       B = [B, zeros(nt,m1)];
  176.       C = [C; zeros(p1,nt)];
  177.     else
  178.       A = [A, zeros(nt,nt1); zeros(nt1,nt), as];
  179.       B = [B, zeros(nt,m1);  zeros(nt1,m),  bs];
  180.       C = [C, zeros(p,nt1);  zeros(p1,nt),  cs];
  181.     endif
  182.     D = [D, zeros(p,m1); zeros(p1,m), ds];
  183.     n = n + n1;
  184.     nz = nz + nz1;
  185.     nt = nt + nt1;
  186.     m = m + m1;
  187.     p = p + p1;
  188.   endfor
  189.  
  190.   ## check maximum dimensions
  191.   [nx, mx] = size(Clst);
  192.   if (nx > m)
  193.     error("---> more rows in Clst than total number of inputs.");
  194.   endif
  195.   if (mx > p+1)
  196.     error("---> more cols in Clst than total number of outputs.");
  197.   endif
  198.   ## empty vector Ulst is OK
  199.   lul = length(Ulst);
  200.   if (lul)
  201.     if (!is_vector(Ulst))
  202.       error("---> Input u list Ulst must be a vector.");
  203.     endif
  204.     if (lul > m)
  205.       error("---> more values in Ulst than number of inputs.");
  206.     endif
  207.   endif
  208.   if (!length(Olst))  Olst = [1:(p+lul)];  endif
  209.   if (!length(Ilst))  Ilst = [1:m];        endif
  210.   if (!is_vector(Olst))
  211.     error("---> Output list Olst must be a vector.");
  212.   endif
  213.   if (!is_vector(Ilst))
  214.     error("---> Input list Ilst must be a vector.");
  215.   endif
  216.  
  217.   ## build the feedback "K" from the interconnection data Clst
  218.   K = zeros(m, p);
  219.   inp_used = zeros(m,1);
  220.   for ii = 1:nx
  221.     xx = Clst(ii,:);
  222.     iu = xx(1);
  223.     if ((iu < 1) || (iu > m))
  224.       error("---> Illegal value in first col of Clst.");
  225.     endif
  226.     if (inp_used(iu))
  227.       error("---> Input specified more than once.");
  228.     endif
  229.     inp_used(iu) = 1;
  230.     for kk = 2:mx
  231.       it = xx(kk);
  232.       if (abs(it) > p)
  233.           error("---> Illegal row value in Clst.");
  234.       elseif (it)
  235.     K(iu,abs(it)) = sign(it);
  236.       endif
  237.     endfor
  238.   endfor
  239.  
  240.   ## form the "closed loop", i.e replace u in
  241.   ## .
  242.   ## x = Ax + Bu
  243.   ##                            ~
  244.   ## y = Cx + Du   by   u = K*y+u
  245.   ##
  246.   ##            -1
  247.   ## R = (I-D*K)   must exist.
  248.  
  249.   R = eye(p) - D*K;
  250.   if (rank(R) < p)
  251.     error("---> singularity in algebraic loop.");
  252.   else
  253.     R = inv(R);
  254.   endif
  255.   A = A + B*K*R*C;
  256.   B = B + B*K*R*D;
  257.   C = R*C;
  258.   D = R*D;
  259.  
  260.   ## append old inputs u to the outputs (if lul > 0)
  261.   kc = K*C;
  262.   kdi = eye(m) + K*D;
  263.   for ii = 1:lul
  264.     it = Ulst(ii);
  265.     if ((it < 1) || (it > m))
  266.       error("---> Illegal value in Ulst.");
  267.     endif
  268.     C = [C; kc(it,:)];
  269.     D = [D; kdi(it,:)];
  270.   endfor
  271.  
  272.   ## select and rearrange outputs
  273.   nn = length(A);
  274.   lol = length(Olst);
  275.   Cnew = zeros(lol,nn);
  276.   Dnew = zeros(lol,m);
  277.   for ii = 1:lol
  278.     iu = Olst(ii);
  279.     if (!iu || (abs(iu) > p+lul))
  280.       error("---> Illegal value in Olst.");
  281.     endif
  282.     Cnew(ii,:) = sign(iu)*C(abs(iu),:);
  283.     Dnew(ii,:) = sign(iu)*D(abs(iu),:);
  284.   endfor
  285.   C = Cnew;
  286.   D = Dnew;
  287.   lil = length(Ilst);
  288.   Bnew = zeros(nn,lil);
  289.   Dnew = zeros(lol,lil);
  290.   for ii = 1:lil
  291.     iu = Ilst(ii);
  292.     if (!iu || (abs(iu) > m))
  293.       error("---> Illegal value in Ilst.");
  294.     endif
  295.     Bnew(:,ii) = sign(iu)*B(:,abs(iu));
  296.     Dnew(:,ii) = sign(iu)*D(:,abs(iu));
  297.   endfor
  298.  
  299.   sys = ss2sys(A, Bnew, C, Dnew, tsam, n, nz);
  300.  
  301. endfunction
  302.