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

  1. # Copyright (C) 1993, 1994, 1995 John W. Eaton
  2. # This file is part of Octave.
  3. # Octave is free software; you can redistribute it and/or modify it
  4. # under the terms of the GNU General Public License as published by the
  5. # Free Software Foundation; either version 2, or (at your option) any
  6. # later version.
  7. # Octave is distributed in the hope that it will be useful, but WITHOUT
  8. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  9. # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  10. # for more details.
  11. # You should have received a copy of the GNU General Public License
  12. # along with Octave; see the file COPYING.  If not, write to the Free
  13. # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  14.  
  15. function dsys = c2d (sys, opt, T)
  16.  
  17. # Usage: dsys = c2d (sys[, T])
  18. # Usage: dsys = c2d (sys[, opt[, T]])
  19. # inputs:
  20. #   sys: system data structure (may be mixed discrete/continiuous time)
  21. #   optional arguments:
  22. #     opt: conversion option: 
  23. #          "ex" - use the matrix exponential (default)
  24. #          "bi" - use the bilinear transformation
  25. #                   2(z-1)
  26. #               s = -----
  27. #                   T(z+1)
  28. #               FIXME: This option exits with an error if sys is not purely 
  29. #               continuous. (The ex can handle mixed systems.)
  30. #
  31. #     T: sampling time; required if sys is purely continuous.
  32. # outputs: 
  33. #   dsys: discrete time equivalent via zero-order hold, sample each T sec.
  34. #
  35. # converts the system described by:
  36. #   .
  37. #   x = Ac x + Bc u
  38. #
  39. # into a discrete time equivalent model via the matrix exponential
  40. #
  41. #   x[n+1] = Ad x[n] + Bd u[n]
  42. #
  43. # Note: This function adds _d to the names of the new discrete states.   
  44.  
  45. # Written by R.B. Tenison (btenison@eng.auburn.edu)
  46. # October 1993
  47. # Updated by John Ingram for system data structure August 1996
  48.  
  49.   save_val = implicit_str_to_num_ok;    # save for later
  50.   implicit_str_to_num_ok = 1;
  51.  
  52. # parse input arguments
  53.   if(nargin < 1 | nargin > 3)
  54.     usage("dsys=c2d(sys[,T])");
  55.   elseif (!is_struct(sys))
  56.     error("sys must be a system data structure");
  57.   elseif (nargin == 1)
  58.     opt = "ex";
  59.   elseif (nargin == 2 & !isstr(opt) )
  60.     T = opt;
  61.     opt = "ex";
  62.   endif
  63.  
  64.   # check if sampling period T was passed.
  65.   Ts = sysgettsam(sys);
  66.   if(!exist("T"))
  67.     T = Ts;
  68.     if(T == 0)
  69.       error("sys is purely continuous; no sampling period T provided");
  70.     endif
  71.   elseif (T != Ts & Ts > 0)
  72.     warning(["c2d: T=",num2str(T),", system tsam==",num2str(Ts), ...
  73.       ": using T=", num2str(min(T,Ts))]);
  74.     T = min(T,Ts);
  75.   endif
  76.  
  77.   if (!is_sample(T))
  78.     error("sampling period T must be a postive, real scalar");
  79.   elseif( ! (strcmp(opt,"ex") | strcmp(opt,"bi") ) )
  80.     error(["illegal option passed: ",opt])
  81.   endif
  82.  
  83.   sys = sysupdate(sys,"ss");
  84.   [n,nz,m,p] = sysdimensions(sys);
  85.  
  86.   if (n == 0)
  87.     warning("c2d: sys has no continuous states; setting outputs to discrete");
  88.     dsys = syssetsignals(sys,"yd",ones(1:p));
  89.   elseif(strcmp(opt,"ex"))
  90.     # construct new state-space (a,b,c,d) for continuous subsystem
  91.     [csys,Acd] = syscont(sys);       # extract continuous subsystem
  92.     [csys_a, csys_b, csys_c, csys_d] = sys2ss(csys);
  93.     [ sys_a,  sys_b,  sys_c,  sys_d] = sys2ss( sys);
  94.     if(isempty(Acd))                Bmat = sys_b;
  95.     elseif(isempty(csys_b))         Bmat = Acd;
  96.     else                            Bmat = [Acd, csys_b];     endif
  97.     
  98.     row_zer = columns(Bmat);
  99.     csysn = sysdimensions(csys);
  100.     col_zer = csysn + row_zer;
  101.  
  102.     [csysa,csysb,csysc,csysd] = sys2ss(csys);
  103.     if(isempty(Bmat) )
  104.       warning("c2d: no inputs to continuous subsystem.");
  105.       mat = csysa;
  106.     else
  107.       mat = [csysa, Bmat ; zeros( row_zer,col_zer) ];
  108.     endif
  109.  
  110.     matexp = expm(mat * T);
  111.   
  112.     Abar = matexp( 1:csysn , 1:(csysn + columns(Acd)) );  
  113.     Bbar = matexp( 1:csysn , (columns(Abar) + 1):columns(matexp) );
  114.  
  115.     newnz = rows(Abar);
  116.     outlist = ones(1,rows(csysc));
  117.     [stnames,innames,outnames] = sysgetsignals(csys);
  118.     dsys = ss2sys(Abar,Bbar,csysc,csysd,T,0,newnz,stnames,innames, ...
  119.     outnames,outlist);
  120.     # rename states
  121.     for ii=1:newnz
  122.       strval = sprintf("%s_d",sysgetsignals(dsys,"st",ii,1));
  123.       dsys = syssetsignals(dsys,"st",strval,ii);
  124.     endfor
  125.  
  126.   elseif(strcmp(opt,"bi"))
  127.     if(is_digital(sys))
  128.       error("c2d: system is already digital")
  129.     else
  130.       # convert with bilinear transform
  131.       [a,b,c,d,tsam,n,nz,stname,inname,outname,yd] = sys2ss(sys);
  132.       IT = (2/T)*eye(size(a));
  133.       A = (IT+a)/(IT-a);
  134.       iab = (IT-a)\b;
  135.       tk=2/sqrt(T);
  136.       B = tk*iab;
  137.       C = tk*(c/(IT-a));
  138.       D = d + (c*iab);
  139.       stnamed = strappend(stname,"_d");
  140.       dsys = ss2sys(A,B,C,D,T,0,rows(A),stnamed,inname,outname);
  141.     endif
  142.   else
  143.     error(["Bad option=",opt])
  144.   endif
  145.   
  146.   implicit_str_to_num_ok = save_val;    # restore value
  147.  
  148. endfunction
  149.