File: buildssic.m

package info (click to toggle)
octave-control 1.0.11-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,628 kB
  • ctags: 160
  • sloc: makefile: 64; sh: 4
file content (332 lines) | stat: -rw-r--r-- 9,583 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
## Copyright (C) 1998, 2000, 2002, 2004, 2005, 2006, 2007 Kai P. Mueller
##
##
## This program is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or (at
## your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {} 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})
##
## Form an arbitrary complex (open or closed loop) system in
## state-space form from several systems. @command{buildssic} can
## easily (despite its cryptic syntax) integrate transfer functions
## from a complex block diagram into a single system with one call.
## This function is especially useful for building open loop
## interconnections for 
## @iftex
## @tex
## $ { \cal H }_\infty $ and $ { \cal H }_2 $
## @end tex
## @end iftex
## @ifinfo
## H-infinity and H-2
## @end ifinfo
## designs or for closing loops with these controllers.
##
## Although this function is general purpose, the use of @command{sysgroup}
## @command{sysmult}, @command{sysconnect} and the like is recommended for
## standard operations since they can handle mixed discrete and continuous
## systems and also the names of inputs, outputs, and states.
##
## The parameters consist of 4 lists that describe the connections
## outputs and inputs and up to 8 systems @var{s1}--@var{s8}.
## Format of the lists:
## @table @var
## @item      clst
## connection list, describes the input signal of
## each system. The maximum number of rows of Clst is
## equal to the sum of all inputs of s1-s8.
##
## Example:
## @code{[1 2 -1; 2 1 0]} means that:  new input 1 is old input 1
## + output 2 - output 1, and new input 2 is old input 2
## + output 1. The order of rows is arbitrary.
##
## @item ulst
## if not empty the old inputs in vector @var{ulst} will
## be appended to the outputs. You need this if you
## want to ``pull out'' the input of a system. Elements
## are input numbers of @var{s1}--@var{s8}.
##
## @item olst
## output list, specifies the outputs of the resulting
## systems. Elements are output numbers of @var{s1}--@var{s8}.
## The numbers are allowed to be negative and may
## appear in any order. An empty matrix means
## all outputs.
##
## @item ilst
## input list, specifies the inputs of the resulting
## systems. Elements are input numbers of @var{s1}--@var{s8}.
## The numbers are allowed to be negative and may
## appear in any order. An empty matrix means
## all inputs.
## @end table
##
## Example:  Very simple closed loop system.
## @example
## @group
## w        e  +-----+   u  +-----+
##  --->o--*-->|  K  |--*-->|  G  |--*---> y
##      ^  |   +-----+  |   +-----+  |
##    - |  |            |            |
##      |  |            +----------------> u
##      |  |                         |
##      |  +-------------------------|---> e
##      |                            |
##      +----------------------------+
## @end group
## @end example
##
## The closed loop system @var{GW} can be obtained by
## @example
## GW = buildssic([1 2; 2 -1], 2, [1 2 3], 2, G, K);
## @end example
## @table @var
## @item clst
## 1st row: connect input 1 (@var{G}) with output 2 (@var{K}).
##
## 2nd row: connect input 2 (@var{K}) with negative output 1 (@var{G}).
## @item ulst
## Append input of 2 (@var{K}) to the number of outputs.
## @item olst
## Outputs are output of 1 (@var{G}), 2 (@var{K}) and 
## appended output 3 (from @var{ulst}).
## @item ilst
## The only input is 2 (@var{K}).
## @end table
##
## Here is a real example:
## @example
## @group
##                          +----+
##     -------------------->| W1 |---> v1
## z   |                    +----+
## ----|-------------+
##     |             |
##     |    +---+    v      +----+
##     *--->| G |--->O--*-->| W2 |---> v2
##     |    +---+       |   +----+
##     |                |
##     |                v
##    u                  y
## @end group
## @end example
## @iftex
## @tex
## $$ { \rm min } \Vert GW_{vz} \Vert _\infty $$  
## @end tex
## @end iftex
## @ifinfo
## @example
## min || GW   ||
##          vz   infty
## @end example
## @end ifinfo
##
## The closed loop system @var{GW} 
## @iftex
## @tex
## from $ [z, u]^T $ to $ [v_1, v_2, y]^T $
## @end tex
## @end iftex
## @ifinfo
## from [z, u]' to [v1, v2, y]' 
## @end ifinfo
## can be obtained by (all @acronym{SISO} systems):
## @example
## GW = buildssic([1, 4; 2, 4; 3, 1], 3, [2, 3, 5],
##                [3, 4], G, W1, W2, One);
## @end example
## where ``One'' is a unity gain (auxiliary) function with order 0.
## (e.g. @code{One = ugain(1);})
## @end deftypefn

## Author: Kai P. Mueller <mueller@ifr.ing.tu-bs.de>
## Created: April 1998

function sys = buildssic (Clst, Ulst, Olst, Ilst, s1, s2, s3, s4, s5, s6, s7, s8)

  if (nargin < 5 || nargin > 12)
    print_usage ();
  endif
  if (nargin >= 5)
    if (! isstruct (s1))
      error ("---> s1 must be a structed system.");
    endif
    s1 = sysupdate (s1, "ss");
    [n, nz, m, p] = sysdimensions (s1);
    if (! n && ! nz)
      error ("---> pure static system must not be the first in list.");
    endif
    if (n && nz)
      error ("---> cannot handle mixed continuous and discrete systems.");
    endif
    D_SYS = (nz > 0);
    [A, B, C, D, tsam] = sys2ss (s1);
    nt = n + nz;
  endif
  for ii = 6:nargin
    eval (["mysys = s", num2str(ii-4), ";"]);
    if (! isstruct (mysys))
      error ("---> Parameter must be a structed system.");
    endif
    mysys = sysupdate (mysys, "ss");
    [n1, nz1, m1, p1] = sysdimensions (mysys);
    if (n1 && nz1)
      error ("---> cannot handle mixed continuous and discrete systems.");
    endif
    if (D_SYS)
      if (n1)
        error ("---> cannot handle mixed cont. and discr. systems.");
      endif
      if (tsam != sysgettsam (mysys))
        error ("---> sampling time of all systems must match.");
      endif
    endif
    [as, bs, cs, ds] = sys2ss (mysys);
    nt1 = n1 + nz1;
    if (! nt1)
      ## pure gain (pad B, C with zeros)
      B = [B, zeros(nt,m1)];
      C = [C; zeros(p1,nt)];
    else
      A = [A, zeros(nt,nt1); zeros(nt1,nt), as];
      B = [B, zeros(nt,m1); zeros(nt1,m), bs];
      C = [C, zeros(p,nt1); zeros(p1,nt), cs];
    endif
    D = [D, zeros(p,m1); zeros(p1,m), ds];
    n = n + n1;
    nz = nz + nz1;
    nt = nt + nt1;
    m = m + m1;
    p = p + p1;
  endfor

  ## check maximum dimensions
  [nx, mx] = size (Clst);
  if (nx > m)
    error ("---> more rows in Clst than total number of inputs.");
  endif
  if (mx > p+1)
    error ("---> more cols in Clst than total number of outputs.");
  endif
  ## empty vector Ulst is OK
  lul = length (Ulst);
  if (lul)
    if (! isvector (Ulst))
      error ("---> Input u list Ulst must be a vector.");
    endif
    if (lul > m)
      error ("---> more values in Ulst than number of inputs.");
    endif
  endif
  if (! length (Olst))
    Olst = 1:(p+lul);
  endif
  if (! length (Ilst))
    Ilst = 1:m;
  endif
  if (! isvector(Olst))
    error ("---> Output list Olst must be a vector.");
  endif
  if (! isvector (Ilst))
    error ("---> Input list Ilst must be a vector.");
  endif

  ## build the feedback "K" from the interconnection data Clst
  K = zeros (m, p);
  inp_used = zeros (m, 1);
  for ii = 1:nx
    xx = Clst(ii,:);
    iu = xx(1);
    if (iu < 1 || iu > m)
      error ("---> invalid value in first col of Clst.");
    endif
    if (inp_used(iu))
      error ("---> Input specified more than once.");
    endif
    inp_used(iu) = 1;
    for kk = 2:mx
      it = xx(kk);
      if (abs (it) > p)
        error ("---> invalid row value in Clst.");
      elseif (it)
        K(iu,abs(it)) = sign (it);
      endif
    endfor
  endfor

  ## form the "closed loop", i.e replace u in
  ## .
  ## x = Ax + Bu
  ##                            ~
  ## y = Cx + Du   by   u = K*y+u
  ##
  ##            -1
  ## R = (I-D*K)   must exist.

  R = eye (p) - D*K;
  if (rank (R) < p)
    error ("---> singularity in algebraic loop.");
  else
    R = inv (R);
  endif
  A = A + B*K*R*C;
  B = B + B*K*R*D;
  C = R*C;
  D = R*D;

  ## append old inputs u to the outputs (if lul > 0)
  kc = K*C;
  kdi = eye (m) + K*D;
  for ii = 1:lul
    it = Ulst(ii);
    if (it < 1 || it > m)
      error ("---> invalid value in Ulst.");
    endif
    C = [C; kc(it,:)];
    D = [D; kdi(it,:)];
  endfor

  ## select and rearrange outputs
  nn = length (A);
  lol = length (Olst);
  Cnew = zeros (lol, nn);
  Dnew = zeros (lol, m);
  for ii = 1:lol
    iu = Olst(ii);
    if (! iu || abs(iu) > p+lul)
      error ("---> invalid value in Olst.");
    endif
    Cnew(ii,:) = sign(iu)*C(abs(iu),:);
    Dnew(ii,:) = sign(iu)*D(abs(iu),:);
  endfor
  C = Cnew;
  D = Dnew;
  lil = length (Ilst);
  Bnew = zeros (nn, lil);
  Dnew = zeros (lol, lil);
  for ii = 1:lil
    iu = Ilst(ii);
    if (! iu || abs(iu) > m)
      error ("---> invalid value in Ilst.");
    endif
    Bnew(:,ii) = sign (iu) * B(:,abs(iu));
    Dnew(:,ii) = sign (iu) * D(:,abs(iu));
  endfor

  sys = ss (A, Bnew, C, Dnew, tsam, n, nz);

endfunction