home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l455 / 10.ddi / CONTROL.DI$ / RLOCUS.M < prev    next >
Encoding:
Text File  |  1993-03-11  |  8.9 KB  |  294 lines

  1. function [rout,k] = rlocus(a,b,c,d,e,f)
  2. %RLOCUS    Evans root locus.
  3. %    RLOCUS(NUM,DEN) calculates and plots the locus of the roots of:
  4. %                              NUM(s)
  5. %               H(s) = 1 + k ----------  =  0
  6. %                              DEN(s)
  7. %    for a set of gains K which are adaptively calculated to produce a 
  8. %    smooth plot. Alternatively the vector K can be specified with an 
  9. %    optional right-hand argument RLOCUS(NUM,DEN,K). Vectors NUM and 
  10. %    DEN must contain the numerator and denominator coefficients in 
  11. %    descending powers of s or z. When invoked with left hand arguments
  12. %        R = RLOCUS(NUM,DEN,K)  or  [R,K] = RLOCUS(NUM,DEN)
  13. %    returns the matrix R with LENGTH(K) rows and (LENGTH(DEN(-1) 
  14. %    columns containing the complex root locations.  Each row of the 
  15. %    matrix corresponds to a gain from vector K.  If a second left hand
  16. %    argument is included, the gains are returned in K.
  17. %    RLOCUS(A,B,C,D), R = RLOCUS(A,B,C,D,K), or [R,K] = RLOCUS(A,B,C,D)
  18. %    finds the root-locus from the equivalent SISO state-space system
  19. %    (A,B,C,D).
  20. %                    dx/dt = Ax + Bu    u = -k*y
  21. %                        y = Cx + Du
  22. %
  23. %    See also: PZMAP and RLOCFIND.
  24.  
  25. %     J.N. Little 10-11-85
  26. %    Revised A.C.W.Grace 7-8-89, 6-21-92 
  27. %    Copyright (c) 1986-93 by the MathWorks, Inc.
  28.  
  29. if nargin==0, eval('exresp(''rlocus'');'), return, end
  30.  
  31. error(nargchk(2,6,nargin));
  32.  
  33. % The next variable controls how many points are plotted on the graph.
  34. precision = 1; %Set to a higher number (e.g. 2 for more points on the graph).
  35. k=[];
  36.  
  37. if (nargin==3 | nargin==2 )     % Convert to state space
  38.     if nargin==3, k = c; end
  39.     [num,den] = tfchk(a,b);
  40.     [a,b,c,d] = tf2ss(a,b);
  41. end
  42.  
  43. [ny,nu] = size(d);
  44. if (ny*nu==0)|isempty(a), k=[]; if nargout~=0, rout=[]; end, return, end
  45.  
  46. %  Multivariable systems
  47. error(abcdchk(a,b,c,d));
  48. if nargin==5,
  49.   k=e; 
  50. elseif nargin==6,
  51.   b=b(:,e); d=d(:,e); k = f;
  52. end
  53.  
  54. % Trap MIMO case
  55. [ny,nu] = size(d);
  56. if ny*nu~=1,
  57.   if nargout~=0,
  58.     disp('Warning: Root locus with outputs must be SISO.'), 
  59.     return,
  60.   end
  61.   [e,nargin,r]=mulresp('rlocus',a,b,c,d,k,0,0);
  62.   if ~e, if nargout, rout = r; end, return, end
  63. end
  64.  
  65. sp=sum([1:length(a)].^2);
  66.  
  67. % Set up graphics and other parameters.
  68.  
  69. if isempty(k) | nargout==0
  70. % Work out scales and ranges
  71.     kgiven = 0;
  72.     ep=eig(a);
  73.     p=length(ep);
  74.     if nargin>=4
  75.         tz=tzero(a,b,c,d);
  76.         z=length(tz);
  77.         sp2=[1:z].^2;
  78.         den=poly(ep);
  79.         num=poly(tz);
  80.     else
  81.         tz=roots(num);
  82.         z=length(tz);
  83.     end
  84.     den2 = den + 1e-20*(den==0); 
  85.     dcgain=num(length(num))/den2(length(den));
  86. % Normalize for better numerical properties
  87.     if abs(den(1)) > eps & den(1) ~= 1
  88.         den=den/den(1);
  89.         num=num/den(1);
  90.     end
  91.     mep=max([eps;abs([real(ep);real(tz);imag(ep);imag(tz)])]);
  92.     if z==p
  93. % Round up axis to units to the nearest 5
  94.         ax=1.2*mep;        
  95.     else
  96.         % Round graph axis    
  97.         exponent=5*10^(floor(log10(mep))-1);
  98.         ax=2*round(mep/exponent)*exponent;    
  99.     end
  100.     if nargout==0 
  101. % Real and imaginary axis - uncomment these if you don't want them
  102.         axstate = axis('state');
  103.         holdon = ishold;
  104.         newplot;
  105.         if ~holdon
  106.             plot([-ax,ax],[0,0],'w:',[0,0],[-ax,ax],'w:');
  107.             axis([-ax,ax,-ax,ax])
  108.         else
  109.             ax4 = axis;
  110.             ax = sum(abs(ax4))/4;
  111.             plot([ax4(1:2)],[0,0],'w:',[0,0],[ax4(3:4)],'w:');
  112.             axis(ax4)
  113.         end
  114. % If plotting is required then set up axis and titles
  115.         hold on
  116.         plot(real(ep),imag(ep),'x');
  117.         if ~isempty(tz)
  118.             plot(real(tz),imag(tz),'o');
  119.         end
  120.         xlabel('Real Axis')
  121.         ylabel('Imag Axis')
  122.         % Use none as Erasemode for fast plotting
  123.         erasemode = 'none';
  124.         drawnow
  125.     end
  126. end
  127.  
  128. % Adaptively search for values of gain  if K is not specified
  129.  
  130. if isempty(k)
  131. % Set up initial gain based on D.C.Gain of open loop and 
  132. % positions of zeros and poles.
  133. % Since closed loop den = num + k*den, sensitivity is related
  134. % to difference between num and denominator coefficients.
  135.     diff=abs(num)./abs(den2(1:length(num)));
  136.     kinit=0.01/(abs(dcgain) + polyval(diff,4))+1e-12;
  137.     bc=b*c;
  138.     k=[0,1e-4*kinit,kinit]; dist=kinit;
  139.     r(:,1)=ep;
  140.     r(:,2)=vsort(ep, eig(a-bc*(k(2)./(1+k(2)*d))), sp);
  141.     if nargout==0, plot( real([ep,r(:,2)])', imag([ep,r(:,2)])','-' ,'Erasemode', erasemode), end
  142.     i=2; ij=sqrt(-1); perr=1;
  143.     terminate=0;     
  144.     while  ~terminate
  145.         i=i+1;
  146.         ki=k(i)./(1+k(i)*d);
  147.         r1=eig(a-bc*ki);
  148.         mx=max(abs([real(r1).';imag(r1).']));
  149.         % If any line outside box then set erasemode back to normal
  150.         % for clipping
  151.         if any(mx > ax), erasemode = 'normal'; end
  152. % Sort out eigenvalues so that plotting appears continuous. 
  153.         [r(:,i),pind]=vsort(r(:,i-1),r1,sp);
  154. % Adjust values of k based on linearity of the roots:
  155.         % First two points in line
  156.         y1=imag(r(:,i-2)); y2=imag(r(:,i-1));
  157.         x1=real(r(:,i-2)); x2=real(r(:,i-1));
  158.         % Current  points
  159.         y=imag(r(:,i)); x=real(r(:,i));
  160.         % Nearest x-y co-ordinates of new point to line
  161.         [newx,newy]=perpxy(x1,y1,x2,y2,x,y);
  162.         % Error estimation
  163.         err=sqrt((newy-y).^2+(newx-x).^2);
  164.         distm=norm((y-y2)+ij*(x-x2));
  165.         fferr=find(~finite(err));
  166.         err(fferr)=zeros(length(fferr),1);
  167.         perr=precision*max(err(find(finite(err))))/(distm+ax/(1e3*(distm+eps))); 
  168.  
  169. % If percentage error greater than threshold then go back and 
  170. % re-evaluate more roots:
  171.         pind = any((y==0)~=(y2==0));
  172.         if perr>0.2 | pind
  173.             % Decrement distance between gains
  174.             npts=3+5*round(min([5,perr*3]))+17*pind;
  175.             kval=logspace(log10(k(i-1)),log10(k(i)),npts);
  176.             dist=(k(i)-k(i-1))/(npts-7*pind);
  177.             i=i-1;
  178.             for kcnt=kval(2:npts)
  179.                 i=i+1;
  180.                 k(i)=kcnt;
  181.                 ki=kcnt./(1+kcnt*d);
  182.                 r1=eig(a-bc*ki);
  183.                 r(:,i) = vsort(r(:,i-1),r1,sp);
  184.                 y=imag(r(:,i)); y2=imag(r(:,i-1));
  185.                 x=real(r(:,i)); x2=real(r(:,i-1));
  186.                 ind = 0; 
  187.                 if nargout==0  
  188. % Intersection of rlocus on the  real axis.
  189.                     if pind   
  190. % The inequality abs(y+y2)<ax makes sure that its not one that 
  191. % goes off to inf and then 
  192. % comes back on the real axis. 
  193.                         ind = find((y==0)~=(y2==0) & abs(y+y2)<ax);
  194.                         if ~isempty(ind)
  195.                             if (imag(r(ind(1),i))==0), cix = 1; else, cix = 0; end
  196.                             realr = r(:,i-cix);
  197.                             realr(ind)=real(r(ind,i-cix));
  198.                             plot( real([realr,r(:,i-1)])', imag([realr,r(:,i-1)])','-','Erasemode',erasemode)
  199.                             plot( real([r(:,i),realr])', imag([r(:,i),realr])','-' ,'Erasemode',erasemode)
  200.                         else
  201.                             ind=0;
  202.                         end
  203.                     end
  204.                     if ~ind
  205. % Fix for plot when rlocus goes from -inf to inf or -inf to inf
  206.                         infind = find(abs(x)>ax & sign(x2)~=sign(x));
  207.                         if length(infind)>0
  208.                             x(infind) = sign(x2(infind))*ax;
  209.                         end 
  210.                         plot([x,x2]',[y,y2]','-','Erasemode',erasemode)
  211.                     end
  212.  
  213.                 end
  214.             end
  215.         else
  216. % Fix for plot when rlocus goes comes from -inf to inf or -inf to inf
  217.             infind = find(abs(x)>ax & sign(x2)~=sign(x) );
  218.             if length(infind)>0
  219.                 x(infind) = sign(x2(infind))*ax;
  220.             end 
  221.             % Use none as Erasemode for fast plotting
  222.             if nargout==0, plot([x,x2]',[y,y2]','-','Erasemode',erasemode), end
  223.             % Increase/decrease distance to next k based on linearity estimate:
  224.             dist=dist*(0.3/precision+exp(1-15*perr));
  225.         end
  226.         % Next gain value
  227.         k(i+1)=k(i)+dist;
  228. % Termination criterion
  229.         terminate=1;
  230.         if z==p
  231.             tz = vsort(r1, tz);
  232.             terminate=max(abs(tz-r1))<ax/100;
  233.         else 
  234.             % Make sure all loci tending to infinity are out of graph before terminating
  235.             % Terminate when all poles have approached their corresponding  zeros
  236.             % Note: this may not work well if zeros are close together
  237.             if z > 0
  238.                 terminate=max(min(abs(r1*ones(1,z)-ones(p,1)*tz.')))<ax/100;
  239.             end
  240.             mx=max(abs([real(r1).';imag(r1).']));
  241.             terminate = ( sum(mx>1.2*ax)>=p-z & terminate );
  242.         end
  243.         terminate = terminate | abs(k(i)) > 1e30;
  244.         if nargout == 0
  245.             if rem(i,10) == 0 % Draw graph every ten iterations
  246.                 drawnow
  247.             end
  248.         end
  249.     end
  250.  
  251. else
  252. % When K is given:
  253.     kgiven = 1;
  254.     [ns,nu] = size(b);
  255.     nk = length(k); i=1;
  256.     r  = sqrt(-1) * ones(ns,nk);
  257.     bc = b*c; 
  258. % Find eigenvalues of:  A - B*inv(I+k*D)*k*C:
  259.     k2 = k./(1+k.*d);
  260.     r(:,1)=eig(a-bc*k2(1)); k2(1)=[];
  261.     if nk == 1 & nargout == 0
  262.         % Special case when only one point
  263.         plot(real(r(:,1))', imag(r(:,1)), '+');
  264.     end
  265.     for ki=k2
  266.         i = i + 1;
  267.         r1 = eig(a-bc*ki);
  268. % Sort eigenvalues
  269.         r(:,i)=vsort(r(:,i-1),r1,sp);
  270.         if nargout==0
  271.             % Plot in pairs to get colored crosses
  272.             plot( real([r(:,i),r(:,i-1)])', imag([r(:,i),r(:,i-1)])','+','Erasemode','none')
  273.         end
  274.     end
  275. end
  276. r = r.';
  277.  
  278. if nargout==0, 
  279. % Uncomment the next line to obtain grid on plot
  280.     %grid
  281.     % Return graphics to original state
  282.     if ~holdon, hold off, end
  283.     % axis(axstate);
  284.     return % Suppress output
  285. end
  286.  
  287. rout = r;
  288. % Last element of k is never used
  289. if ~kgiven 
  290.     k(length(k))=[];
  291.     k = k.';
  292. end
  293.