⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_reduction.m

📁 很优良的PID控制器设计仿真程序与模型,经过严格检验
💻 M
📖 第 1 页 / 共 2 页
字号:
%mod_reduction is used to administrate the reduction of the plant model.
%
%   mod_reduction(nTask,arg1)
%
%If there is no input argument supplied, then reduced model comparison dialog box 
%will appear which allows the user to compare the behaviours of different reduced 
%models.
%
%If there is only one input argument supplied, then the parameters of the reduction 
%process should be entered, and it will chose properiate algorithm to do reduction.
%
%If there are two input arguments supplied, then 
%    
%   arg1=0 --- setting reduction parameters
%   arg1=1,2 --- perform reduction
%   arg1=3 --- compare reduction
%
%Available lists of functions under this module
%
%  do_reduction -- manipulate the model reduction procedures
%  pade_red -- implements the Pade approximation technique
%  routh_red -- implements the Routh approximation technique
%  dom_mod_red -- implements the dominent mode technique
%  ffpade_red -- implements the FF Pade approximation technique
%  bal_real_red -- implements the balanced rr\ealization technique
%  robust_red -- implements the robust reduction technique
%  opt_reduction -- implements the optimal reduction technique
%  tf_monic -- performs monic transformation to transfer functions
%  tf_revs -- write the TF polynomials in reversed order
%  cmp_reduction -- compare different reduced order models.
%  modcmp_win -- creates a dialog box for model comparison
%  modred_win -- creates a dialog box for reduction parameters
%  opt_func -- defines the optimal criterion for model reduction
%  r_intgl -- evaluate the H_2 norm using recursive algorithm
%  tf_derv -- obtain the first derivative of a TF
%  vec_plus -- adds two polynomials of different lengths
%

%Designed by Professor Dingyu Xue
%School of Information Science and Engineering, Northeastern University
%Shenyang 110006, P R China
%Email: xue_dy@hotmail.com
%
%This module is for CtrllAB 3.0, (c) 1996-1999
%Last modified 5 October, 1999
%-------------------------------------------------------------------------

function G_out=mod_reduction(nTask,arg1,arg2,arg3,arg4,arg5,arg6,arg7)

switch nargin
case 0, modcmp_win;
case 1, 
   g_main=findobj('Tag','CtrlLABMain');
   uu0=get(g_main,'UserData'); g1=get(uu0{1}(1),'UserData');
   if length(g1)>0, modred_win(nTask);
   else, 
      warndlg('Plant model dose not exist, please enter it first!','Model reduction failed'); 
   end   
case 2   
   switch arg1
   case 0, do_reduction;
   case 1
      uu=get(gcf,'UserData'); nTask=get(uu{1}(1),'Value');
      switch nTask
      case {1,3,4}, extra_funs(4,2,'Visible',1:4,5:10);
      case 6, extra_funs(4,2,'Visible',[1:4,7:10],5:6);
      otherwise, extra_funs(4,2,'Visible',5:6,[1:4,7:10]);   
      end
   case 2
      uu=get(gcf,'UserData'); nTask=get(uu{1}(1),'Value');
      switch get(uu{2}(10),'Value')
      case 1, avec(4:5)=[0,0];
      case 2, avec(4:5)=[0,1];
      case 3, avec(4:5)=[1,0]; 
      end; 
      set(uu{2}(8),'String',mat2str(avec));  
   case 3, cmp_reduction;
   case 4
      uu0=get(findobj('Tag','CtrlLABMain'),'UserData');
      g4=get(uu0{1}(4),'UserData'); ModPars=g4{3}; 
      m_list=findobj(gcf,'Tag','MList'); m_list=m_list(end:-1:1);
      keyMod=extra_funs(5,m_list,'Value');
      if length(keyMod)==0, keyMod=n_max; end
      nn=ModPars(keyMod,1); nd=ModPars(keyMod,2); 
      num=ModPars(keyMod,7:7+nd); den=ModPars(keyMod,8+nd:8+2*nd);
      Tau=ModPars(keyMod,9+2*nd); g4{4}=tf(num,den,'Td',Tau);
      set(uu0{1}(4),'UserData',g4);
      proc_model(1,5);   
   end
case {3,4,5,6,7}   
   G_Sys=nTask; 
   nn=arg1(1); nd=arg1(2); avec=arg2; id=arg3(1); ic=arg3(2);
   nPade=arg4(1); Pdly=arg4(2);
   G_out=opt_reduction(G_Sys,nn,nd,avec,id,ic,[nPade,Pdly]);
case 8, G_out=opt_func(nTask,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
end

%------------------------------------------------------------------------------
%do_reduction is the function which calls the corresponding routines to perform
%model reduction.
%------------------------------------------------------------------------------
function do_reduction()
uu=get(gcf,'UserData'); nTask=get(uu{1}(1),'Value'); Pdly=get(uu{1}(2),'Value');
if any([1,3,4,6]==nTask),
   nn=eval(get(uu{2}(2),'String')); nd=eval(get(uu{2}(4),'String'));
   if nTask==6,
      avec=eval(get(uu{2}(8),'String')); ic=get(uu{2}(10),'Value');
   else, ic=0; id=0; end;
else, 
   ic=0; id=0; nd=eval(get(uu{2}(6),'String')); nn=nd-1; 
   if nTask==5, nn=nd; end
end

uu0=get(findobj('Tag','CtrlLABMain'),'UserData');
g1=get(uu0{1}(1),'UserData'); G1=tf(g1{2}); g4=get(uu0{1}(4),'UserData');
Td=g4{1}; nPade=g4{2}; G1.Td=Td; 

if nTask==6
   if abs(avec(2))<1e-5, id=2;
   elseif abs(avec(1))<1e-5, if abs(avec(3))<1e-5, id=1; else, id=3; end
   else, if abs(avec(3))<1e-5, id=4; else, id=5; end
   end
end

%check whether such a reduced order model exists
ModPars=g4{3}; [n,m]=size(ModPars); key1=0;
for i=1:n,
   ii=(ModPars(i,1:6)==[nn,nd,nTask,Pdly id ic]);
   if sum(ii)==6, key1=1; break; end
end

key=1; 
if key1==1
   %if it exists, then load and display it directly
   nn=ModPars(i,1); nd=ModPars(i,2);
   num=ModPars(i,7:7+nd); den=ModPars(i,8+nd:8+2*nd);
   Td=ModPars(i,9+2*nd); G_red=tf(num,den,'Td',Td); 
else
   %if not exist, then perform reduction
   switch nTask
   case 1, G_red=pade_red(G1,nn,nd,[nPade,Pdly]);
   case 2, G_red=routh_red(G1,nd,[nPade,Pdly]);
   case 3, [G_red,key]=dom_mod_red(G1,nn,nd,[nPade,Pdly]);
   case 4, G_red=ffpade_red(G1,nn,nd,[nPade,Pdly]);
   case 5, G_red=bal_real_red(G1,nd,[nPade,Pdly]);
   case 6, 
      g_wait=extra_funs(12,'Performing optimal reduction');
      pause(0.01)
      G_red=opt_reduction(G1,nn,nd,avec,id,ic,[nPade,Pdly]);
      close(g_wait);
   case {9,10}
      if exist('balmr')~=2,
         key=0;
         errordlg('Robust Control Toolbox is not available!','Warning: Reduction failed!');
      else,
         G_red=robust_red(G1,nd,nTask,[nPade,Pdly]);
      end
   otherwise,
      key=0;
      errordlg('Algorithm not available yet!','Warning: Reduction failed!');
   end
   if key==1, 
      %if reduction is success, then write the results back to the system
      g4=get(uu0{1}(4),'UserData'); ModPars=g4{3}; [n1,n2]=size(ModPars);
      [num,den,Td]=tfdata(G_red,'v'); PVec=[nn,nd,nTask,Pdly,id,ic,num,den,Td];
      n3=length(PVec); 
      ModPars=[ModPars,zeros(n1,n3-n2); PVec, zeros(1,n2-n3)];
      % reserve only the last 7 models
      if n1==7, ModPars=ModPars(2:8,:); end
      g4{3}=ModPars; 
   end
end
if key==1
   g4{4}=G_red; set(uu0{1}(4),'UserData',g4); close(gcf); proc_model(1,5); 
   uu=get(gcf,'UserData'); set(uu(6),'Visible','on');
end

%-----------------------------------------------------------------------------
%pade_red implements the Pade approximation technique
%
%   G_red=pade_red(G_Sys,nn,nd,arg1)
%where G_Sys is the original plant model transfer function which possibily have 
%delay terms.  (nn,nd) is the expected order of num and den, respectively. arg1 
%contains delay parameters -- [nPade, Pdly], where nPade is the order of Pade 
%approximation, and Pdly is where delay terms are used in the reduced model.
%G_red is the reduced model which can contain delays.
%------------------------------------------------------------------------------
function G_red=pade_red(G_Sys,nn,nd,arg1)
nPade=arg1(1); Pdly=arg1(2); [num,den,Td]=tfdata(G_Sys,'v');
if abs(Td)>0 & Pdly==0, [nP,dP]=pade(Td,nPade); num=conv(num,nP); den=conv(den,dP); end
n=length(den)-1; k=length(num)-1; d0=den(n+1); L=nn+nd;
num0=[zeros(1,L+n-k-1) num]/d0; den0=[zeros(1,L) den]/d0;
c=zeros(1,nn+nd); c(1)=num0(n+L);
for i=2:nn+nd+1, c(i)=num0(n+1+L-i)-sum(den0(n-i+2+L:n+L).*c(1:i-1)); end

w=-c(nn+2:nn+nd+1)'; vv=[c(nn+1:-1:1)'; zeros(nd-1-nn,1)];
W=rot90(hankel(c(nn+nd:-1:nn+1),vv)); V=rot90(hankel(c(nn:-1:1)));
x=[1 (W\w)']; dred=x(nd+1:-1:1)/x(nd+1); y=[c(1) x(2:nn+1)*V'+c(2:nn+1)]; nred=y(nn+1:-1:1)/x(nd+1);

if Pdly==0, Td=0; end
G_red=tf(nred,dred,'Td',Td);

%----------------------------------------------------------
%routh_red implements the Routh approximation technique
%
%   G_red=routh_red(G_Sys,nd,arg1)
%descriptions to the I/O arguments can be found in pade_red
%----------------------------------------------------------
function G_red = routh_red(G_Sys,nr,arg1)
nPade=arg1(1); Pdly=arg1(2); [num,den,Td]=tfdata(G_Sys,'v');
if abs(Td)>0 & Pdly==0, [nP,dP]=pade(Td,nPade); num=conv(num,nP); den=conv(den,dP); end
n0=length(den); n1=length(num); a1=den(n0:-1:1); b1=[num(n1:-1:1) zeros(1,n0-n1-1)];
for k=1:n0-1, 
   k1=k+2; alpha(k)=a1(k)/a1(k+1); beta(k)=b1(k)/a1(k+1);
   for i=k1:2:n0-1, a1(i)=a1(i)-alpha(k)*a1(i+1); b1(i)=b1(i)-beta(k)*a1(i+1); end, 
end
nn=[]; dd=[1]; nn1=beta(1); dd1=[alpha(1), 1]; nred=nn1; dred=dd1;
for i=2:nr,
   nred=[alpha(i)*nn1, beta(i)]; dred=[alpha(i)*dd1, 0]; n0=length(dd); n1=length(dred);
   nred=nred+[zeros(1,n1-n0),nn]; dred=dred+[zeros(1,n1-n0),dd];
   nn=nn1; dd=dd1; nn1=nred; dd1=dred;
end
nred=nred(1:nr); [nred,dred]=tf_revs(nred,dred); [nred,dred]=tf_monic(nred,dred,1);

if Pdly==0, Td=0; end
G_red=tf(nred,dred,'Td',Td);

%----------------------------------------------------------
%dom_mod_red implements the dominent mode technique
%
%   G_red=dom_mod_red(G_Sys,nn,nd,arg1)
%descriptions to the I/O arguments can be found in pade_red
%----------------------------------------------------------
function [G_red,key]=dom_mod_red(G_Sys,nn,nd,arg1)
nPade=arg1(1); Pdly=arg1(2); key=1; [num,den,Td]=tfdata(G_Sys,'v');
if abs(Td)>0 & Pdly==0, [nP,dP]=pade(Td,nPade); num=conv(num,nP); den=conv(den,dP); end
n0=length(den); n1=length(num); j=sqrt(-1); r=roots(den); rr=abs(real(r)); ri=imag(r);
[rr,i]=sort(rr); dmode(1:nd)=-rr(1:nd)+ri(i(1:nd))*j; dred=[1 -dmode(1)];
for i=2:nd, dred=conv(dred,[1 -dmode(i)]); end
d0=dred(nd+1); dred=dred(nd+1:-1:1)/d0; num1=[zeros(1,n0-n1) num]; c(1)=num(n1)/den(n0);
for i=2:nd, c0=0;
   for j=1:i-1, 
      i0=n0-j; if i0>0, c0=c0+den(i0)*c(i-j); end
   end
   i0=n0+1-i; if i0>0, c(i)=(num1(i0)-c0)/den(n0);
   else, c(i)=-c0/den(n0);
end, end
v0=dred(2:nn+1); 
for i=1:nn, for j=1:nn, if i+1-j>0, v(i,j)=c(i+1-j); end, end, end
nred=[c(1) v0*v'];
for i=2:nn+1, nred(i)=nred(i)+c(i); end
[nred,dred]=tf_revs(nred,dred); [nred,dred]=tf_monic(nred,dred,1);
if (abs(sum(imag(nred)))+abs(sum(imag(dred)))<10000*eps), 
   key=0; 
   errordlg('Cannot find the specified dominent modes!','Warning: Reduction failed!');
else,
   if Pdly==0, Td=0; end
   G_red=tf(nred,dred,'Td',Td);
end

%------------------------------------------------------------------------
%ffpade_red implements the frequency fitting Pade approximation technique
%
%   G_red=ffpade_red(G_Sys,nn,nd,arg1)
%descriptions to the I/O arguments can be found in pade_red
%------------------------------------------------------------------------
function G_red=ffpade_red(G_Sys,nn,nd,arg1)
nPade=arg1(1); Pdly=arg1(2); [num,den,Td]=tfdata(G_Sys,'v');
if abs(Td)>0 & Pdly==0, [nP,dP]=pade(Td,nPade); num=conv(num,nP); den=conv(den,dP); end
w=logspace(-1,3); [m,p]=bode(num,den,w); graf_tool(1);
semilogx(w,20*log10(m)); [xx,yy]=ginput(nd-1);
np=nd-1;xx=[1;4]; wp=xx'; [mp,pp]=bode(num,den,wp); pp=pp*pi/180;

n0=length(den); n1=length(num); num1=[zeros(1,n0-n1) num]; c(1)=num(n1)/den(n0);
aa=den(n0:-1:1); bb=num1(n0:-1:1); [bb,aa]=tf_monic(bb,aa);
for i=2:nn+nd+1,
   for j=1:n0-1, cc(j)=bb(1)*aa(j+1)-bb(j+1); end
   bb=[cc zeros(1,n0-length(cc))]; cc=[]; c(i)=(-1)^(i-1)*bb(1);  
end
w11=eye(nn+1); w21=zeros(nd,nn+1); w12=zeros(1,nd); temp=w12;
for i=1:nn, temp=[-c(i), temp(1:nd-1)]; w12=[w12; temp]; end
w22=[c(nn+1), -temp(1:nd-1)]; temp=w22;
for i=1:nd-1, temp=[c(nn+1+i), temp(1:nd-1)]; w22=[w22; temp]; end
W=[w11,w12; w21,w22]; V=[c(1:nn+1)'; -c(nn+2:nn+nd+1)'];
%  ** replacing 2*np equation by Frequency Fit
for i=1:np,
   i1=nd+nn+2-2*i; i2=i1+1; W(i1,1)=-sin(pp(i)); W(i2,1)=cos(pp(i)); xp=wp(i)*wp(i);
   if nn~=0, W(i1,2)=wp(i)*cos(pp(i)); W(i2,2)=wp(i)*sin(pp(i)); end
   for j=3:nn+1, W(i1,j)=-xp*W(i1,j-2); W(i2,j)=-xp*W(i2,j-2); end
   W(i1,nn+2)=-wp(i)*mp(i); W(i1,nn+3)=0; W(i2,nn+2)=0; W(i2,nn+3)=xp*mp(i);
   for j=nn+4:nn+nd+1, W(i1,j)=-xp*W(i1,j-2); W(i2,j)=xp*W(i2,j-2); end
   V(i1)=0; V(i2)=mp(i);
end
theta=inv(W)*V; nred=theta(nn+1:-1:1)'/theta(nd+nn+1); dred=[theta(nd+nn+1:-1:nn+2)' 1]/theta(nd+nn+1);

if Pdly==0, Td=0; end
G_red=tf(nred,dred,'Td',Td);

%----------------------------------------------------------
%bal_real_red implements the balanced realization technique
%
%   G_red=bal_real_red(G_Sys,nr,arg1)
%descriptions to the I/O arguments can be found in pade_red
%----------------------------------------------------------
function G_red=bal_real_red(G_Sys,nr,arg1)
nPade=arg1(1); Pdly=arg1(2); [num,den,Td]=tfdata(G_Sys,'v');
if abs(Td)>0 & Pdly==0, [nP,dP]=pade(Td,nPade); num=conv(num,nP); den=conv(den,dP); end
G_Sys=ss(tf(num,den)); G_red=minreal(G_Sys); [G_red,g]=balreal(G_red);
nn=length(g); aa=nn:-1:1; [g,ii]=sort(g); aa=aa(ii); elim=aa(nr+1:nn);
G_red=modred(G_red,elim); 
if Pdly==0, Td=0; end
G_red=tf(G_red); G_red.Td=Td; 

%--------------------------------------------------------------------------------
%robust_red implements the robust reduction technique
%
%   robust_red(G_Sys,nd,nTask,arg1)
%where nTask=1 for optimal Hankel approximation, while 2 for Schur approximation. 
%Other descriptions to the I/O arguments can be found in pade_red
%--------------------------------------------------------------------------------
function G_red=robust_red(G_Sys,nd,nTask,arg1);
nPade=arg1(1); Pdly=arg1(2); [num,den,Td]=tfdata(G_Sys,'v');
if abs(Td)>0 & Pdly==0, [nP,dP]=pade(Td,nPade); G_Sys=G_Sys*tf(nP,dP); end
ss_G=ss(G_Sys); ii=find(real(eig(ss_G))>=0);
if nTask==9, [am,bm,cm,dm,totbnd,hsv]=balmr(ss_G.a,ss_G.b,ss_G.c,ss_G.d,1,nd);
else, [am,bm,cm,dm,totbnd,hsv]=schmr(ss_G.a,ss_G.b,ss_G.c,ss_G.d,1,nd); end
G_red=tf(ss(am,bm,cm,dm)); 
num=G_red.num{1}; ii=find(abs(num)>eps); G_red.num{1}=num(ii(1):end);
if Pdly==0, Td=0; end
G_red.Td=Td;

%----------------------------------------------------------------
%opt_reduction implements the optimal reduction technique
%
%   G_red=opt_reduction(G_Sys,nn,nd,avec,id,ic,arg1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -