comparison scripts/control/system/sysconnect.m @ 3430:65b3519ac3a1

[project @ 2000-01-14 03:44:03 by jwe]
author jwe
date Fri, 14 Jan 2000 03:50:02 +0000
parents
children 04aef7306dca
comparison
equal deleted inserted replaced
3429:b9f5829ec843 3430:65b3519ac3a1
1 ## Copyright (C) 1996, 1998 Auburn University. All rights reserved.
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{retsys} =} sysconnect (@var{sys}, @var{out_idx},@var{in_idx}@{,@var{order}, @var{tol}@})
21 ## Close the loop from specified outputs to respective specified inputs
22 ##
23 ## @strong{Inputs}
24 ## @table @var
25 ## @item sys
26 ## system data structure
27 ## @item out_idx
28 ## @itemx in_idx
29 ## list of connections indices; @math{y(out_idx(ii))}
30 ## is connected to @math{u(in_idx(ii))}.
31 ## @item order
32 ## logical flag (default = 0)
33 ## @table @code
34 ## @item 0
35 ## leave inputs and outputs in their original order
36 ## @item 1
37 ## permute inputs and outputs to the order shown in the diagram below
38 ## @end table
39 ## @item tol
40 ## tolerance for singularities in algebraic loops default: 200@var{eps}
41 ## @end table
42 ##
43 ## @strong{Outputs}
44 ## @var{sys}: resulting closed loop system.
45 ##
46 ## @strong{Method}
47 ## @code{sysconnect} internally permutes selected inputs, outputs as shown
48 ## below, closes the loop, and then permutes inputs and outputs back to their
49 ## original order
50 ## @example
51 ## @group
52 ## ____________________
53 ## u_1 ----->| |----> y_1
54 ## | sys |
55 ## old u_2 | |
56 ## u_2* ---->(+)--->| |----->y_2
57 ## (in_idx) ^ -------------------| | (out_idx)
58 ## | |
59 ## -------------------------------
60 ## @end group
61 ## @end example
62 ## The input that has the summing junction added to it has an * added to
63 ## the end of the input name.
64 ## @end deftypefn
65
66 ## Author: A. S. Hodel <a.s.hodel@eng.auburn.edu>
67 ## Created: August 1995
68 ## modified by John Ingram July 1996
69
70 function sys = sysconnect (sys, output_list, input_list, order, tol)
71
72 if( (nargin < 3) | (nargin > 5) )
73 usage("retsys = sysconnect(sys,output_list,input_list[,order,tol])");
74 endif
75
76 ## check order
77 if(nargin <= 3)
78 order = 0;
79 elseif( (order != 0) & (order != 1) )
80 error("sysconnect: order must be either 0 or 1")
81 endif
82
83 if (nargin <= 4)
84 tol = 200*eps;
85 elseif( !is_sample(tol) )
86 error("sysconnect: tol must be a positive scalar");
87 elseif(tol > 1e2*sqrt(eps))
88 warning(["sysconnect: tol set to large value=",num2str(tol), ...
89 ", eps=",num2str(eps)])
90 endif
91
92 ## verify sizes,format of input, output lists
93 if( min(size(output_list))*min(size(input_list)) != 1)
94 error("output_list and input_list must be vectors");
95 else
96 lo = length(output_list);
97 li = length(input_list);
98 if(lo != li)
99 error("output_list and input_list must be of the same length")
100 endif
101
102 if(is_duplicate_entry(output_list) | is_duplicate_entry(input_list) )
103 error("duplicate entry in input_list and/or output_list");
104 endif
105 endif
106
107 [nc,nz,mm,pp] = sysdimensions(sys);
108 nn = nc+nz;
109
110 if( !is_struct(sys))
111 error("sys must be in structured system form")
112 elseif(pp < li)
113 error(["length(output_list)=",num2str(li),", sys has only ", ...
114 num2str(pp),"system outputs"])
115 elseif(mm < li)
116 error(["length(input_list)=",num2str(li),", sys has only ", ...
117 num2str(mm),"system inputs"])
118 endif
119
120 ## check that there are enough inputs/outputs in the system for the lists
121 if(max(input_list) > mm)
122 error("max(input_list) exceeds the number of inputs");
123 elseif(max(output_list) > pp)
124 error("max(output_list) exceeds the number of outputs");
125 endif
126
127 output_list = reshape(output_list,1,length(output_list));
128
129 ## make sure we're in state space form
130 sys = sysupdate (sys, "ss");
131
132 ## permute rows and columns of B,C,D matrices into pseudo-dgkf form...
133 all_inputs = sysreorder(mm,input_list);
134 all_outputs = sysreorder(pp,output_list);
135
136 [aa,bb,cc,dd] = sys2ss(sys);
137 bb = bb(:,all_inputs);
138 cc = cc(all_outputs,:);
139 dd = dd(all_outputs,all_inputs);
140
141 yd = sysgetsignals(sys,"yd");
142 yd = yd(all_outputs);
143
144 ## m1, p1 = number of inputs, outputs that are not being connected
145 m1 = mm-li;
146 p1 = pp-li;
147
148 ## m2, p2: 1st column, row of B, C that is being connected
149 m2 = m1+1;
150 p2 = p1+1;
151
152 ## partition system into a DGKF-like form; the loop is closed around
153 ## B2, C2
154 if(m1 > 0)
155 B1 = bb(:,1:m1);
156 D21= dd(p2:pp,1:m1);
157 endif
158 B2 = bb(:,m2:mm);
159 if(p1 > 0)
160 C1 = cc(1:p1,:);
161 D12= dd(1:p1,m2:mm);
162 endif
163 C2 = cc(p2:pp,:);
164 if(m1*p1 > 0)
165 D11= dd(1:p1,1:m1);
166 endif
167 D22= dd(p2:pp,m2:mm);
168
169 if(norm(D22))
170 warning("sysconnect: possible algebraic loop, D22 non-zero");
171 D22i = (eye(size(D22))-D22);
172 C2h = D22i\C2;
173 if(m1 > 0)
174 D21h = D22i\D21;
175 endif
176 D22h = D22i\D22;
177 else
178 C2h = C2;
179 if(m1 > 0)
180 D21h = D21;
181 endif
182 D22h = D22;
183
184 endif
185
186 ## check cont state -> disc output -> cont state
187 dyi = find(yd(p2:pp));
188
189 ## disp("sysconnect: dyi=")
190 ## dyi
191 ## nc
192 ## disp("/sysconnect");
193
194 if( (nc > 0) & find(dyi > 0) )
195 B2con = B2(1:nc,dyi); # connection to cont states
196 C2hd = C2h(dyi,1:nc); # cont states -> outputs
197 else
198 B2con = C2hd = [];
199 endif
200
201 if(max(size(B2con)) & max(size(C2hd)) )
202 if(norm(B2con*C2hd))
203 warning("sysconnect: cont-state -> disc output -> cont state derivative");
204 warning(" connection made; resulting system may not be meaningful");
205 endif
206 endif
207
208 Ac = aa+B2*C2h;
209 if(m1 > 0)
210 B1c = B1 + B2*D21h;
211 endif
212 B2c = B2*(eye(size(D22h)) + D22h);
213 if(p1*m1 > 0)
214 D11c = D11 + D12*D21h;
215 endif
216 if(p1 > 0)
217 C1c = C1+D12*C2h;
218 D12c = D12*(eye(size(D22h))+D22h);
219 endif
220
221 ## construct system data structure
222 if(m1 > 0)
223 Bc = [B1c, B2c];
224 else
225 Bc = B2c;
226 endif
227
228 if(p1 > 0)
229 Cc = [C1c;C2h];
230 else
231 Cc = C2h;
232 endif
233
234 if(m1*p1 > 0)
235 Dc = [D11c,D12c; D21h,D22h];
236 elseif(m1 > 0)
237 Dc = [D21h, D22h];
238 elseif(p1 > 0)
239 Dc = [D12c; D22h];
240 else
241 Dc = D22h;
242 endif
243
244 ## permute rows and columns of Bc, Cc, Dc back into original order
245 Im = eye(mm,mm);
246 Pi = Im(:,all_inputs);
247 back_inputs = Pi*[1:mm]';
248
249 Ip = eye(pp,pp);
250 Po = Ip(:,all_outputs);
251 back_outputs = Po*[1:pp]';
252
253 Bc = Bc(:,back_inputs);
254 Cc = Cc(back_outputs,:);
255 Dc = Dc(back_outputs,back_inputs);
256 yd = yd(back_outputs);
257
258 ## rebuild system
259 Ts = sysgettsam(sys);
260 [stnam,innam,outnam] = sysgetsignals(sys);
261 sys = ss2sys(Ac,Bc,Cc,Dc,Ts,nc,nz,stnam,innam,outnam,find(yd));
262
263 ## update connected input names
264 for ii = 1:length(input_list)
265 idx = input_list(ii);
266 strval = sprintf("%s*",nth(sysgetsignals(sys,"in",idx),1) );
267 sys = syssetsignals(sys,"in",strval,idx);
268 endfor
269
270 ## maintain original system type if it was SISO
271 if (strcmp (sysgettype (sys), "tf"))
272 sysupdate (sys, "tf");
273 elseif (strcmp (sysgettype (sys),"zp"))
274 sysupdate (sys, "zp");
275 endif
276
277 endfunction