home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21eb.zip / octave / SCRIPTS.ZIP / scripts / control / stepimp.m < prev    next >
Text File  |  1999-03-05  |  7KB  |  276 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 [y, t] = stepimp(sitype, sys, inp, tstop, n)
  18. # step: Impulse or step response for a linear system.
  19. #       The system can be discrete or multivariable (or both).
  20. #       This m-file contains the "common code" of step and impulse.
  21. #
  22. # [y, t] = stepimp(sitype, sys[, inp, tstop, n])
  23. # Produces a plot or the response data for system sys.
  24. #
  25. # Limited argument checking; "do not attempt to do this at home".
  26. # Use step or impulse instead.
  27. #
  28. # See also:  step, impulse
  29.  
  30. # Written by Kai P. Mueller October 2, 1997
  31. # based on lsim.m of Scottedward Hodel
  32.  
  33.   if (sitype == 1)         IMPULSE = 0;
  34.   elseif (sitype == 2)     IMPULSE = 1;
  35.   else                  error("stepimp: illegal sitype argument.")
  36.   endif
  37.   sys = sysupdate(sys,"ss");
  38.  
  39.   USE_DEF = 0;   # default tstop and n if we have to give up
  40.   N_MIN = 50;    # minimum number of points
  41.   N_MAX = 2000;  # maximum number of points
  42.   T_DEF = 10.0;  # default simulation time
  43.  
  44.   # collect useful information about the system
  45.   [ncstates,ndstates,NIN,NOUT] = sysdimensions(sys);
  46.   TSAMPLE = sysgettsam(sys);
  47.  
  48.   if (nargin < 3)                      inp = 1;
  49.   elseif (inp < 1 | inp > NIN)         error("Argument inp out of range")
  50.   endif
  51.  
  52.   DIGITAL = is_digital(sys);
  53.   if (DIGITAL)
  54.     NSTATES = ndstates;
  55.     if (TSAMPLE < eps)
  56.       error("stepimp: sampling time of discrete system too small.")
  57.     endif
  58.   else        NSTATES = ncstates;       endif
  59.   if (NSTATES < 1)
  60.     error("step: pure gain block (n_states < 1), step response is trivial");
  61.   endif
  62.   if (nargin < 5)
  63.     # we have to compute the time when the system reaches steady state
  64.     # and the step size
  65.     ev = eig(sys2ss(sys));
  66.     if (DIGITAL)
  67.       # perform bilinear transformation on poles in z
  68.       for i = 1:NSTATES
  69.         pole = ev(i);
  70.     if (abs(pole + 1) < 1.0e-10)
  71.       ev(i) = 0;
  72.     else
  73.       ev(i) = 2 / TSAMPLE * (pole - 1) / (pole + 1);
  74.     endif
  75.       endfor
  76.     endif
  77.     # remove poles near zero from eigenvalue array ev
  78.     nk = NSTATES;
  79.     for i = 1:NSTATES
  80.       if (abs(ev(i)) < 1.0e-10)
  81.         ev(i) = 0;
  82.         nk = nk - 1;
  83.       endif
  84.     endfor
  85.     if (nk == 0)
  86.       USE_DEF = 1;
  87.       #printf("##STEPIMP-DEBUG: using defaults.\n");
  88.     else
  89.       ev = ev(find(ev));
  90.       x = max(abs(ev));
  91.       t_step = 0.2 * pi / x;
  92.       x = min(abs(real(ev)));
  93.       t_sim = 5.0 / x;
  94.       # round up
  95.       yy = 10^(ceil(log10(t_sim)) - 1);
  96.       t_sim = yy * ceil(t_sim / yy);
  97.       #printf("##STEPIMP-DEBUG: nk=%d   t_step=%f  t_sim=%f\n",
  98.       #       nk, t_step, t_sim);  
  99.     endif
  100.   endif
  101.  
  102.   if (DIGITAL)
  103.     # ---- sampled system
  104.     if (nargin == 5)
  105.       n = round(n);
  106.       if (n < 2)
  107.         error("stepimp: n must not be less than 2.")
  108.       endif
  109.     else
  110.       if (nargin == 4)
  111.         # n is unknown
  112.       elseif (nargin >= 1)
  113.         # tstop and n are unknown
  114.         if (USE_DEF)
  115.           tstop = (N_MIN - 1) * TSAMPLE;
  116.         else
  117.           tstop = t_sim;
  118.         endif
  119.       endif
  120.       n = floor(tstop / TSAMPLE) + 1;
  121.       if (n < 2)  n = 2;  endif
  122.       if (n > N_MAX)
  123.     n = N_MAX;
  124.     printf("Hint: number of samples limited to %d by default.\n", \
  125.            N_MAX);
  126.     printf("  ==> increase \"n\" parameter for longer simulations.\n");
  127.       endif
  128.     endif
  129.     tstop = (n - 1) * TSAMPLE;
  130.     t_step = TSAMPLE;
  131.   else
  132.     # ---- continuous system
  133.     if (nargin == 5)
  134.       n = round(n);
  135.       if (n < 2)
  136.         error("step: n must not be less than 2.")
  137.       endif
  138.       t_step = tstop / (n - 1);
  139.     else
  140.       if (nargin == 4)
  141.         # only n in unknown
  142.         if (USE_DEF)
  143.           n = N_MIN;
  144.       t_step = tstop / (n - 1);
  145.         else
  146.           n = floor(tstop / t_step) + 1;
  147.         endif
  148.       else
  149.         # tstop and n are unknown
  150.         if (USE_DEF)
  151.           tstop = T_DEF;
  152.       n = N_MIN;
  153.       t_step = tstop / (n - 1);
  154.         else
  155.           tstop = t_sim;
  156.           n = floor(tstop / t_step) + 1;
  157.         endif
  158.       endif
  159.       if (n < N_MIN)
  160.     n = N_MIN;
  161.         t_step = tstop / (n - 1);
  162.       endif
  163.       if (n > N_MAX)
  164.         tstop = (n - 1) * t_step;
  165.     t_step = tstop / (N_MAX - 1);
  166.     n = N_MAX;
  167.       endif
  168.     endif
  169.     tstop = (n - 1) * t_step;
  170.     [jnk,B] = sys2ss(sys);
  171.     B = B(:,inp);
  172.     sys = c2d(sys, t_step);
  173.   endif
  174.   #printf("##STEPIMP-DEBUG: t_step=%f n=%d  tstop=%f\n", t_step, n, tstop);
  175.  
  176.   F = sys.a;
  177.   G = sys.b(:,inp);
  178.   C = sys.c;
  179.   D = sys.d(:,inp);
  180.   y = zeros(NOUT, n);
  181.   t = linspace(0, tstop, n);
  182.  
  183.   if (IMPULSE)
  184.     if (!DIGITAL && (D'*D > 0))
  185.       error("impulse: D matrix is nonzero, impulse response infinite.")
  186.     endif
  187.     if (DIGITAL)
  188.       y(:,1) = D;
  189.       x = G / t_step;
  190.     else
  191.       x = B;
  192.       y(:,1) = C * x;
  193.       x = F * x;
  194.     endif
  195.     for i = 2:n
  196.       y(:,i) = C * x;
  197.       x = F * x;
  198.     endfor
  199.   else
  200.     x = zeros(NSTATES, 1);
  201.     for i = 1:n
  202.       y(:,i) = C * x + D;
  203.       x = F * x + G;
  204.     endfor
  205.   endif
  206.  
  207.   if(nargout == 0)
  208.     # Plot the information
  209.     oneplot();
  210.     gset nogrid
  211.     gset nologscale
  212.     gset autoscale
  213.     gset nokey
  214.     clearplot();
  215.     if (gnuplot_has_multiplot)
  216.       if (IMPULSE)
  217.         gm = zeros(NOUT, 1);
  218.     tt = "impulse";
  219.       else
  220.         ssys = ss2sys(F, G, C, D, t_step);
  221.         gm = dcgain(ssys);
  222.     tt = "step";
  223.       endif
  224.       ncols = floor(sqrt(NOUT));
  225.       nrows = ceil(NOUT / ncols);
  226.       for i = 1:NOUT
  227.         subplot(nrows, ncols, i);
  228.     title(sprintf("%s: | %s -> %s", tt,sysgetsignals(sys,"in",inp,1), ...
  229.       sysgetsignals(sys,"out",i,1)));
  230.     if (DIGITAL)
  231.       [ts, ys] = stairs(t, y(i,:));
  232.       ts = ts(1:2*n-2)';  ys = ys(1:2*n-2)';
  233.       if (length(gm) > 0)
  234.         yy = [ys; gm(i)*ones(size(ts))];
  235.       else
  236.         yy = ys;
  237.       endif
  238.       grid("on");
  239.       xlabel("time [s]");
  240.       ylabel("y(t)");
  241.           plot(ts, yy);
  242.     else
  243.       if (length(gm) > 0)
  244.         yy = [y(i,:); gm(i)*ones(size(t))];
  245.       else
  246.         yy = y(i,:);
  247.       endif
  248.       grid("on");
  249.       xlabel("time [s]");
  250.       ylabel("y(t)");
  251.       plot(t, yy);
  252.     endif
  253.       endfor
  254.       # leave gnuplot in multiplot mode is bad style
  255.       oneplot();
  256.     else
  257.       # plot everything in one diagram
  258.       title([tt, " response | ", sysgetsignals(sys,"in",inp,1), ...
  259.     " -> all outputs"]);
  260.       if (DIGITAL)
  261.         stairs(t, y(i,:));
  262.       else
  263.     grid("on");
  264.     xlabel("time [s]");
  265.     ylabel("y(t)");
  266.     plot(t, y(i,:));
  267.       endif
  268.     endif
  269.     y=[];
  270.     t=[];
  271.   endif
  272.   #printf("##STEPIMP-DEBUG: gratulations, successfull completion.\n");
  273. endfunction
  274.