www.pudn.com > Closid30.rar > CLMKFX.M, change:1997-06-05,size:4900b


function [F,nf,MM,nm]=clmkfx(Gx,C,nx,nc,option) 
 
% [F,nf,MM,nm]=clmkfx(Gx,C,nx,nc,option) 
% 
% Given a (multivariable) auxiliary plant model Gx and a controller C that 
% stabilizes Gx, a filter F is constructed according to  
%                             -1 
%              F = [Dx + C*Nx]  * [C  I],    
% where (Nx,Dx) is a right coprime factorization (RCF) of Gx, being 
% read from the input or constructed by the function itself. 
% 
% INPUTS: 
% Gx     : system representation of (auxiliary) model, either in 
%          system-format of Gx itself (default) or in system-format of 
%          a RCF col(Dx,Nx) (option = 'R'). 
% C      : system representation of controller that stabilizes Gx. 
% OPTIONAL INPUTS: 
% nx     : state-space dimension of representation of Gx. 
%          Default the SISO situation applies: nx=size(Gx)-1, provided 
%          that Gx is square; 
% nc     : state-space dimension of representation of C. 
%          Default the SISO situation applies: nc=size(C)-1, provided 
%          that C is square; 
% option : use option = 'R' to compute F using the RCF (Nx,Dx) of Gx which 
%          is specified in Gx using the DN-format. Default, a normalized 
%          RCF (Nx,Dx) is being computed. 
% OUTPUTS: 
% F      : system representation of filter F 
% nf     : state-space dimension of representation of F (= nx+nc); 
% MM     : RCF of Gx that is used in construction of F; (in DN-format) 
% nm     : state-space dimension of representation of MM (= nx); 
 
%************************************************************************** 
% 
% (c) P.M.J. Van den Hof, november 1996. 
% Mechanical Engineering Systems and Control Group 
% Delft University of Technology 
 
% file         : clmkfx.m 
% info         : This file is based on the routine makefx.m written by 
%              : R.A. de Callafon, june 1996. 
% functions    : clsplit, cldncf 
% last update  : 20 november 1996 
 
%**************************************************************************** 
 
%ERROR CHECKS 
if nargin==0, 
  error('No input arguments present; type help clmkfx for info!'); 
elseif ((nargin<2)|(nargin>5)), 
  error('Number of input arguments is not correct'); 
end 
 
[nx1,nx2]=size(Gx); 
[nc1,nc2]=size(C); 
if nargin==2, 
  if ((nx1~=nx2)|(nc1~=nc2)), 
   error('The dimensions of Gx and/or C have to be specified'); 
  end; 
  nx=nx1-1; 
  nc=nc1-1; 
elseif nargin==3, 
  if nc1~=nc2, 
   error('The dimension of C has to be specified'); 
  elseif ((nx>=min(nx1,nx2))|(nx<=0)), 
   error('The dimension of Gx is not correct'); 
  else 
   nc=nc1-1; 
  end; 
elseif nargin>=4, 
  if ((nx>=min(nx1,nx2))|(nx<=0)|(nc>=min(nc1,nc2))|(nc<=0)), 
    error('The dimension of Gx and/or C is not correct'); 
  end; 
end; 
 
if nargin<5, 
    option=' '; 
end; 
if length(option)==0, 
    option=' '; 
end; 
 
if ~isstr(option), 
    error('Incorrect option: should be the character ''R'''); 
end 
 
if ((option=='r')|(option=='R')), 
    pre_sp=1; 
else 
    if option~=' ', 
        error('Illegal option, should be ''R'''); 
    end 
    pre_sp=0; 
end; 
 
[Ac,Bc,Cc,Dc]=clsplit(C,nc); 
[a,b,c,d]=clsplit(Gx,nx); 
if pre_sp==1, 
    [n1,n2]=size(d); 
    nim=n2; 
    nom=n1-nim; 
    if nom<=0, 
        error('Incorrect dimensions, probably Gx is not a RCF'); 
    end 
else 
    [nom,nim]=size(d); 
end; 
[nok,nik]=size(Dc); 
 
if (nik~=nom)|(nok~=nim), 
    if pre_sp==0, 
        error('dimensions of controller C and model Gx do not match'); 
    else 
        error('dimensions of controller C and RCF of Gx do not match'); 
    end 
end 
 
if pre_sp==0, 
    disp([' Computing nrcf of auxiliary model.']); 
    [MM,nm]=cldncf(Gx,nx,'R'); 
%    [nm1,nm2]=size(MM); 
%    nm=nx-(nx2-nm2); 
else 
    disp([' Using specified RCF of auxiliary model.']) 
    MM=Gx; 
    nm=nx; 
end 
 
[a,b,c,d]=clsplit(MM,nm); 
[n1,n2]=size(d); 
ni=n2; 
no=n1-ni; 
if no<=0, 
    error('Incorrect dimensions: illegal RCF'); 
end 
 
Ad=a; 
Bd=b; 
Cd=c(1:ni,:); 
Dd=d(1:ni,:); 
An=a; 
Bn=b; 
Cn=c(ni+1:n1,:); 
Dn=d(ni+1:n1,:); 
 
% Construction of F: 
S=svd(Dd+Dc*Dn); 
if min(S)<=10*eps, 
 disp('Closed loop feedthrough matrix Dd+Dc*Dn cannot be inverted.'); 
 Dd,Dc,Dn 
 error('Cannot compute closed loop matrix for filter F.'); 
end 
Di=inv(Dd+Dc*Dn); 
Af=[Ad-Bd*Di*[Cd+Dc*Cn]         Bd*Di*Cc 
    -Bc*Cn+Bc*Dn*Di*[Cd+Dc*Cn]   Ac-Bc*Dn*Di*Cc]; 
n=size(Dn*Di*Dc); 
Bf=[Bd*Di*Dc                      Bd*Di 
    Bc*[eye(nik,nik)-Dn*Di*Dc] -Bc*Dn*Di]; 
Cf=[-Di*[Dc*Cn+Cd] Di*Cc]; 
Df=[Di*Dc Di]; 
F=[Af Bf;Cf Df];   %grp(Af,Bf,Cf,Df,'fx'); 
nf=nm+nc; 
% 
% Check on stability of F: 
index=[]; 
ew=eig(Af); 
index=find(abs(ew)>1); 
if length(index)>=1 
    disp([' WARNING: filter F INTERNALLY unstable!']); 
%    disp([' ' num2str(length(index)) ' eigenvalues found with absolute values larger than 1']); 
%    disp(ew(index)) 
else 
    disp([' OK, filter F is stable.']); 
end