Mercurial > hg > octave-lyh
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 |