home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21eb.zip / octave / SCRIPTS.ZIP / scripts / control / nyquist.m < prev    next >
Text File  |  1999-03-05  |  7KB  |  187 lines

  1. # Copyright (C) 1996,1998 A. Scottedward Hodel 
  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. # Octave is distributed in the hope that it will be useful, but WITHOUT 
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  11. # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
  12. # for more details.
  13. # You should have received a copy of the GNU General Public License 
  14. # along with Octave; see the file COPYING.  If not, write to the Free 
  15. # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  16.  
  17. function [realp,imagp,w] = nyquist(sys,w,outputs,inputs,atol)
  18. # [realp,imagp,w] = nyquist(sys[,w,outputs,inputs,atol])
  19. # Produce Nyquist plots of a system
  20. #
  21. # Compute the frequency response of a system.
  22. # inputs: (pass as empty to get default values
  23. #   sys: system data structure (must be either purely continuous or discrete;
  24. #        see is_digital)
  25. #   w: frequency values for evaluation.
  26. #      if sys is continuous, then bode evaluates G(jw)
  27. #      if sys is discrete, then bode evaluates G(exp(jwT)), where 
  28. #         T=sysgettsam(sys) (the system sampling time)
  29. #      default: the default frequency range is selected as follows: (These
  30. #        steps are NOT performed if w is specified)
  31. #          (1) via routine bodquist, isolate all poles and zeros away from 
  32. #              w=0 (jw=0 or exp(jwT)=1) and select the frequency
  33. #             range based on the breakpoint locations of the frequencies.
  34. #          (2) if sys is discrete time, the frequency range is limited
  35. #              to jwT in [0,2p*pi]
  36. #          (3) A "smoothing" routine is used to ensure that the plot phase does
  37. #              not change excessively from point to point and that singular
  38. #              points (e.g., crossovers from +/- 180) are accurately shown.
  39. #   outputs, inputs: the indices of the output(s) and input(s) to be used in
  40. #     the frequency response; see sysprune.
  41. #   atol: for interactive nyquist plots: atol is a change-in-angle tolerance 
  42. #     (in degrees) for the of asymptotes (default = 0; 1e-2 is a good choice).
  43. #     Consecutive points along the asymptotes whose angle is within atol of
  44. #     the angle between the largest two points are omitted for "zooming in"
  45. #
  46. # outputs:
  47. #    realp, imagp: the real and imaginary parts of the frequency response
  48. #       G(jw) or G(exp(jwT)) at the selected frequency values.
  49. #    w: the vector of frequency values used
  50. #
  51. # If no output arguments are given, nyquist plots the results to the screen.
  52. # If atol != 0 and asymptotes are detected then the user is asked 
  53. #    interactively if they wish to zoom in (remove asymptotes)
  54. # Descriptive labels are automatically placed.  See xlabel, ylable, title,
  55. # and replot.
  56. #
  57. # Note: if the requested plot is for an MIMO system, a warning message is
  58. # presented; the returned information is of the magnitude 
  59. # ||G(jw)|| or ||G(exp(jwT))|| only; phase information is not computed.
  60.    
  61.   # By R. Bruce Tenison, July 13, 1994
  62.   # A. S. Hodel July 1995 (adaptive frequency spacing, 
  63.   #     remove acura parameter, etc.)
  64.   # Revised by John Ingram July 1996 for system format
  65.   #
  66.  
  67.   # Both bode and nyquist share the same introduction, so the common parts are 
  68.   # in a file called bodquist.m.  It contains the part that finds the 
  69.   # number of arguments, determines whether or not the system is SISO, and 
  70.   # computes the frequency response.  Only the way the response is plotted is
  71.   # different between the two functions.
  72.  
  73.   save_val = implicit_str_to_num_ok;    # save for later
  74.   implicit_str_to_num_ok = 1;
  75.  
  76.   # check number of input arguments given
  77.   if (nargin < 1 | nargin > 5)
  78.     usage("[realp,imagp,w] = nyquist(sys[,w,outputs,inputs,atol])");
  79.   endif
  80.   if(nargin < 2)
  81.     w = [];
  82.   endif
  83.   if(nargin < 3)
  84.     outputs = [];
  85.   endif
  86.   if(nargin < 4)
  87.     inputs = [];
  88.   endif
  89.   if(nargin < 5)
  90.     atol = 0;
  91.   elseif(!(is_sample(atol) | atol == 0))
  92.     error("atol must be a nonnegative scalar.")
  93.   endif
  94.  
  95.   # signal to bodquist who's calling
  96.    
  97.   [f,w] = bodquist(sys,w,outputs,inputs,"nyquist");
  98.  
  99.   # Get the real and imaginary part of f.
  100.   realp = real(f);
  101.   imagp = imag(f);
  102.  
  103.   # No output arguments, then display plot, otherwise return data.
  104.   if (nargout == 0)
  105.     dnplot = 0;
  106.     while(!dnplot)
  107.       if(gnuplot_has_multiplot)
  108.         oneplot();
  109.         gset key;
  110.       endif
  111.       clearplot();
  112.       grid ("on");
  113.       gset data style lines;
  114.   
  115.       if(is_digital(sys))
  116.         tstr = " G(e^{jw}) ";
  117.       else
  118.         tstr = " G(jw) ";
  119.       endif
  120.       xlabel(["Re(",tstr,")"]);
  121.       ylabel(["Im(",tstr,")"]);
  122.   
  123.       [stn, inn, outn] = sysgetsignals(sys);
  124.       if(is_siso(sys))
  125.         title(sprintf("Nyquist plot from %s to %s, w (rad/s) in [%e, %e]", ...
  126.       nth(inn,1), nth(outn,1), w(1), w(length(w))) )
  127.       endif
  128.   
  129.       gset nologscale xy;
  130.  
  131.       axis(axis2dlim([[vec(realp),vec(imagp)];[vec(realp),-vec(imagp)]]));
  132.       plot(realp,imagp,"- ;+w;",realp,-imagp,"-@ ;-w;");
  133.  
  134.       # check for interactive plots
  135.       dnplot = 1; # assume done; will change later if atol is satisfied
  136.       if(atol > 0 & length(f) > 2)
  137.  
  138.         # check for asymptotes
  139.         fmax = max(abs(f));
  140.         fi = max(find(abs(f) == fmax));
  141.         
  142.         # compute angles from point to point
  143.         df = diff(f);
  144.         th = atan2(real(df),imag(df))*180/pi;
  145.  
  146.         # get angle at fmax
  147.         if(fi == length(f)) fi = fi-1; endif
  148.         thm = th(fi);
  149.     
  150.         # now locate consecutive angles within atol of thm
  151.         ith_same = find(abs(th - thm) < atol);
  152.         ichk = union(fi,find(diff(ith_same) == 1));
  153.  
  154.         #locate max, min consecutive indices in ichk
  155.         loval = max(complement(ichk,1:fi));
  156.         if(isempty(loval)) loval = fi;
  157.         else               loval = loval + 1;   endif
  158.  
  159.         hival = min(complement(ichk,fi:length(th)));
  160.         if(isempty(hival))  hival = fi+1;      endif
  161.  
  162.         keep_idx = complement(loval:hival,1:length(w));
  163.  
  164.         if(length(keep_idx))
  165.           resp = input("Remove asymptotes and zoom in (y or n): ",1);
  166.           if(resp(1) == "y")
  167.             dnplot = 0;                 # plot again
  168.             w = w(keep_idx);
  169.             f = f(keep_idx);
  170.             realp = real(f);
  171.             imagp = imag(f);
  172.           endif
  173.         endif
  174.  
  175.      endif
  176.     endwhile
  177.     w = [];
  178.     realp=[];
  179.     imagp=[];
  180.   endif
  181.  
  182.   implicit_str_to_num_ok = save_val;    # restore value
  183.  
  184. endfunction
  185.