home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
octa21fb.zip
/
octave
/
SCRIPTS.ZIP
/
scripts.fat
/
control
/
syscnct.m
< prev
next >
Wrap
Text File
|
1999-12-24
|
8KB
|
275 lines
## Copyright (C) 1996,1998 Auburn University. All Rights Reserved.
##
## This file is part of Octave.
##
## Octave 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 2, or (at your option) any
## later version.
##
## Octave 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 Octave; see the file COPYING. If not, write to the Free
## Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
## -*- texinfo -*-
## @deftypefn {Function File } {@var{retsys} =} syscnct (@var{sys}, @var{out_idx},@var{in_idx}@{,@var{order}, @var{tol}@})
## Close the loop from specified outputs to respective specified inputs
##
## @strong{Inputs}
## @table @var
## @item sys
## system data structure
## @item out_idx, in_idx
## list of connections indices; @math{y(out_idx(ii))}
## is connected to @math{u(in_idx(ii))}.
## @item order
## logical flag (default = 0)
## @table @code
## @item 0
## leave inputs and outputs in their original order
## @item 1
## permute inputs and outputs to the order shown in the diagram below
## @end table
## @item tol
## tolerance for singularities in algebraic loops default: 200@var{eps}
## @end table
##
## @strong{Outputs}
## @var{sys}: resulting closed loop system.
##
## @strong{Method}
## @code{syscnct} internally permutes selected inputs, outputs as shown
## below, closes the loop, and then permutes inputs and outputs back to their
## original order
## @example
## @group
## ____________________
## u_1 ----->| |----> y_1
## | sys |
## old u_2 | |
## u_2* ---->(+)--->| |----->y_2
## (in_idx) ^ -------------------| | (out_idx)
## | |
## -------------------------------
## @end group
## @end example
## The input that has the summing junction added to it has an * added to the end
## of the input name.
##
## @end deftypefn
function sys = syscnct (sys, output_list, input_list, order, tol)
## A. S. Hodel August 1995
## modified by John Ingram July 1996
if( (nargin < 3) | (nargin > 5) )
usage("retsys = syscnct(sys,output_list,input_list[,order,tol])");
endif
## check order
if(nargin <= 3)
order = 0;
elseif( (order != 0) & (order != 1) )
error("syscnct: order must be either 0 or 1")
endif
if (nargin <= 4)
tol = 200*eps;
elseif( !is_sampl(tol) )
error("syscnct: tol must be a positive scalar");
elseif(tol > 1e2*sqrt(eps))
warning(["syscnct: tol set to large value=",num2str(tol), ...
", eps=",num2str(eps)])
endif
## verify sizes,format of input, output lists
if( min(size(output_list))*min(size(input_list)) != 1)
error("output_list and input_list must be vectors");
else
lo = length(output_list);
li = length(input_list);
if(lo != li)
error("output_list and input_list must be of the same length")
endif
if(is_dupl(output_list) | is_dupl(input_list) )
error("duplicate entry in input_list and/or output_list");
endif
endif
[nc,nz,mm,pp] = sysdimen(sys);
nn = nc+nz;
if( !is_struct(sys))
error("sys must be in structured system form")
elseif(pp < li)
error(["length(output_list)=",num2str(li),", sys has only ", ...
num2str(pp),"system outputs"])
elseif(mm < li)
error(["length(input_list)=",num2str(li),", sys has only ", ...
num2str(mm),"system inputs"])
endif
## check that there are enough inputs/outputs in the system for the lists
if(max(input_list) > mm)
error("max(input_list) exceeds the number of inputs");
elseif(max(output_list) > pp)
error("max(output_list) exceeds the number of outputs");
endif
output_list = reshape(output_list,1,length(output_list));
## make sure we're in state space form
sys = sysupdat(sys,'ss');
## permute rows and columns of B,C,D matrices into pseudo-dgkf form...
all_inputs = sysreord(mm,input_list);
all_outputs = sysreord(pp,output_list);
[aa,bb,cc,dd] = sys2ss(sys);
bb = bb(:,all_inputs);
cc = cc(all_outputs,:);
dd = dd(all_outputs,all_inputs);
yd = sysgetsg(sys,"yd");
yd = yd(all_outputs);
## m1, p1 = number of inputs, outputs that are not being connected
m1 = mm-li;
p1 = pp-li;
## m2, p2: 1st column, row of B, C that is being connected
m2 = m1+1;
p2 = p1+1;
## partition system into a DGKF-like form; the loop is closed around
## B2, C2
if(m1 > 0)
B1 = bb(:,1:m1);
D21= dd(p2:pp,1:m1);
endif
B2 = bb(:,m2:mm);
if(p1 > 0)
C1 = cc(1:p1,:);
D12= dd(1:p1,m2:mm);
endif
C2 = cc(p2:pp,:);
if(m1*p1 > 0)
D11= dd(1:p1,1:m1);
endif
D22= dd(p2:pp,m2:mm);
if(norm(D22))
warning("syscnct: possible algebraic loop, D22 non-zero");
D22i = (eye(size(D22))-D22);
C2h = D22i\C2;
if(m1 > 0)
D21h = D22i\D21;
endif
D22h = D22i\D22;
else
C2h = C2;
if(m1 > 0)
D21h = D21;
endif
D22h = D22;
endif
## check cont state -> disc output -> cont state
dyi = find(yd(p2:pp));
## disp("syscnct: dyi=")
## dyi
## nc
## disp("/syscnct");
if( (nc > 0) & find(dyi > 0) )
B2con = B2(1:nc,dyi); # connection to cont states
C2hd = C2h(dyi,1:nc); # cont states -> outputs
else
B2con = C2hd = [];
endif
if(max(size(B2con)) & max(size(C2hd)) )
if(norm(B2con*C2hd))
warning("syscnct: cont-state -> disc output -> cont state derivative");
warning(" connection made; resulting system may not be meaningful");
endif
endif
Ac = aa+B2*C2h;
if(m1 > 0)
B1c = B1 + B2*D21h;
endif
B2c = B2*(eye(size(D22h)) + D22h);
if(p1*m1 > 0)
D11c = D11 + D12*D21h;
endif
if(p1 > 0)
C1c = C1+D12*C2h;
D12c = D12*(eye(size(D22h))+D22h);
endif
## construct system data structure
if(m1 > 0)
Bc = [B1c, B2c];
else
Bc = B2c;
endif
if(p1 > 0)
Cc = [C1c;C2h];
else
Cc = C2h;
endif
if(m1*p1 > 0)
Dc = [D11c,D12c; D21h,D22h];
elseif(m1 > 0)
Dc = [D21h, D22h];
elseif(p1 > 0)
Dc = [D12c; D22h];
else
Dc = D22h;
endif
## permute rows and columns of Bc, Cc, Dc back into original order
Im = eye(mm,mm);
Pi = Im(:,all_inputs);
back_inputs = Pi*[1:mm]';
Ip = eye(pp,pp);
Po = Ip(:,all_outputs);
back_outputs = Po*[1:pp]';
Bc = Bc(:,back_inputs);
Cc = Cc(back_outputs,:);
Dc = Dc(back_outputs,back_inputs);
yd = yd(back_outputs);
## rebuild system
Ts = sysgetts(sys);
[stnam,innam,outnam] = sysgetsg(sys);
sys = ss2sys(Ac,Bc,Cc,Dc,Ts,nc,nz,stnam,innam,outnam,find(yd));
## update connected input names
for ii = 1:length(input_list)
idx = input_list(ii);
strval = sprintf("%s*",nth(sysgetsg(sys,"in",idx),1) );
sys = syssetsg(sys,"in",strval,idx);
endfor
## maintain original system type if it was SISO
if (strcmp(sysgetty(sys),"tf") ) sysupdat(sys,'tf');
elseif(strcmp(sysgetty(sys),"zp") ) sysupdat(sys,'zp');
endif
endfunction