comparison scripts/control/bodquist.m @ 3425:8625164a0a39

[project @ 2000-01-13 08:31:37 by jwe]
author jwe
date Thu, 13 Jan 2000 08:32:16 +0000
parents 1a8e2c0d627a
children
comparison
equal deleted inserted replaced
3424:61e40232a4e8 3425:8625164a0a39
1 ## Copyright (C) 1996, 1998 Auburn University. All rights reserved. 1 ## Copyright (C) 1996, 1998 Auburn University. All rights reserved.
2 ## 2 ##
3 ## This file is part of Octave. 3 ## This file is part of Octave.
4 ## 4 ##
5 ## Octave is free software; you can redistribute it and/or modify it 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 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 7 ## Free Software Foundation; either version 2, or (at your option) any
8 ## later version. 8 ## later version.
9 ## 9 ##
10 ## Octave is distributed in the hope that it will be useful, but WITHOUT 10 ## Octave is distributed in the hope that it will be useful, but WITHOUT
11 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 ## for more details. 13 ## for more details.
14 ## 14 ##
15 ## You should have received a copy of the GNU General Public License 15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, write to the Free 16 ## along with Octave; see the file COPYING. If not, write to the Free
17 ## Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. 17 ## Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
18 18
19 ## -*- texinfo -*- 19 ## -*- texinfo -*-
20 ## @deftypefn {Function File } { [@var{f}, @var{w}] =} bodquist (@var{sys}, @var{w}, @var{out_idx}, @var{in_idx}) 20 ## @deftypefn {Function File} {[@var{f}, @var{w}] =} bodquist (@var{sys}, @var{w}, @var{out_idx}, @var{in_idx})
21 ## used internally by bode, nyquist; compute system frequency response. 21 ## used internally by bode, nyquist; compute system frequency response.
22 ## 22 ##
23 ## @strong{Inputs} 23 ## @strong{Inputs}
24 ## @table @var 24 ## @table @var
25 ## @item sys 25 ## @item sys
26 ## input system structure 26 ## input system structure
27 ## @item w 27 ## @item w
34 ## name of routine that called bodquist ("bode" or "nyquist") 34 ## name of routine that called bodquist ("bode" or "nyquist")
35 ## @end table 35 ## @end table
36 ## @strong{Outputs} 36 ## @strong{Outputs}
37 ## @table @var 37 ## @table @var
38 ## @item w 38 ## @item w
39 ## list of frequencies 39 ## list of frequencies
40 ## @item f 40 ## @item f
41 ## frequency response of sys; @math{f(ii) = f(omega(ii))} 41 ## frequency response of sys; @math{f(ii) = f(omega(ii))}
42 ## @end table 42 ## @end table
43 ## @strong{Note} bodquist could easily be incorporated into a Nichols 43 ## @strong{Note} bodquist could easily be incorporated into a Nichols
44 ## plot function; this is in a "to do" list. 44 ## plot function; this is in a "to do" list.
45 ## 45 ##
46 ## Both bode and nyquist share the same introduction, so the common parts are 46 ## Both bode and nyquist share the same introduction, so the common parts are
47 ## in bodquist. It contains the part that finds the number of arguments, 47 ## in bodquist. It contains the part that finds the number of arguments,
48 ## determines whether or not the system is SISO, and computes the frequency 48 ## determines whether or not the system is SISO, and computes the frequency
49 ## response. Only the way the response is plotted is different between the 49 ## response. Only the way the response is plotted is different between the
50 ## two functions. 50 ## two functions.
51 ## @end deftypefn 51 ## @end deftypefn
52 52
53 function [f, w] = bodquist (sys, w, outputs, inputs, rname) 53 function [f, w] = bodquist (sys, w, outputs, inputs, rname)
54 54
55 ## check number of input arguments given 55 ## check number of input arguments given
56 if (nargin != 5) 56 if (nargin != 5)
57 usage("[f,w] = bodquist(sys,w,outputs,inputs,rname)"); 57 usage("[f,w] = bodquist(sys,w,outputs,inputs,rname)");
59 59
60 ## check each argument to see if it's in the correct form 60 ## check each argument to see if it's in the correct form
61 if (!is_struct(sys)) 61 if (!is_struct(sys))
62 error("sys must be a system data structure"); 62 error("sys must be a system data structure");
63 endif 63 endif
64 64
65 ## let freqresp determine w if it's not already given 65 ## let freqresp determine w if it's not already given
66 USEW = freqchkw(w); 66 USEW = freqchkw(w);
67 67
68 ## get initial dimensions (revised below if sysprune is called) 68 ## get initial dimensions (revised below if sysprune is called)
69 [nn,nz,mm,pp ] = sysdimensions(sys); 69 [nn,nz,mm,pp ] = sysdimensions(sys);
70 70
71 ## check for an output vector and to see whether it`s correct 71 ## check for an output vector and to see whether it`s correct
72 if (!isempty(outputs)) 72 if (!isempty(outputs))
73 if (isempty(inputs)) 73 if (isempty(inputs))
74 inputs = 1:mm; # use all inputs 74 inputs = 1:mm; # use all inputs
75 warning([rname,": outputs specified but not inputs"]); 75 warning([rname,": outputs specified but not inputs"]);
76 endif 76 endif
77 sys = sysprune(sys,outputs,inputs); 77 sys = sysprune(sys,outputs,inputs);
78 [nn,nz,mm,pp ] = sysdimensions(sys); 78 [nn,nz,mm,pp ] = sysdimensions(sys);
79 endif 79 endif
80 80
81 ## for speed in computation, convert local copy of 81 ## for speed in computation, convert local copy of
82 ## SISO state space systems to zero-pole form 82 ## SISO state space systems to zero-pole form
83 if( is_siso(sys) & strcmp( sysgettype(sys), "ss") ) 83 if( is_siso(sys) & strcmp( sysgettype(sys), "ss") )
84 [zer,pol,k,tsam,inname,outname] = sys2zp(sys); 84 [zer,pol,k,tsam,inname,outname] = sys2zp(sys);
85 sys = zp2sys(zer,pol,k,tsam,inname,outname); 85 sys = zp2sys(zer,pol,k,tsam,inname,outname);
86 endif 86 endif
87 87
88 ## get system frequency response 88 ## get system frequency response
89 [f,w] = freqresp(sys,USEW,w); 89 [f,w] = freqresp(sys,USEW,w);
90 90
91 phase = arg(f)*180.0/pi; 91 phase = arg(f)*180.0/pi;
92 92
93 if(!USEW) 93 if(!USEW)
94 ## smooth plots 94 ## smooth plots
95 pcnt = 5; # max number of refinement steps 95 pcnt = 5; # max number of refinement steps
96 dphase = 5; # desired max change in phase 96 dphase = 5; # desired max change in phase
97 dmag = 0.2; # desired max change in magnitude 97 dmag = 0.2; # desired max change in magnitude
98 while(pcnt) 98 while(pcnt)
99 pd = abs(diff(phase)); # phase variation 99 pd = abs(diff(phase)); # phase variation
100 pdbig = vec(find(pd > dphase)); 100 pdbig = vec(find(pd > dphase));
101 101
102 lp = length(f); lp1 = lp-1; # relative variation 102 lp = length(f); lp1 = lp-1; # relative variation
103 fd = abs(diff(f)); 103 fd = abs(diff(f));
104 fm = max(abs([f(1:lp1); f(2:lp)])); 104 fm = max(abs([f(1:lp1); f(2:lp)]));
105 fdbig = vec(find(fd > fm/10)); 105 fdbig = vec(find(fd > fm/10));
106 106
107 bigpts = union(fdbig, pdbig); 107 bigpts = union(fdbig, pdbig);
111 else 111 else
112 pcnt = pcnt - 1; 112 pcnt = pcnt - 1;
113 wnew = []; 113 wnew = [];
114 crossover_points = find ( phase(1:lp1).*phase(2:lp) < 0); 114 crossover_points = find ( phase(1:lp1).*phase(2:lp) < 0);
115 pd(crossover_points) = abs(359.99+dphase - pd(crossover_points)); 115 pd(crossover_points) = abs(359.99+dphase - pd(crossover_points));
116 np_pts = max(3,ceil(pd/dphase)+2); # phase points 116 np_pts = max(3,ceil(pd/dphase)+2); # phase points
117 nm_pts = max(3,ceil(log(fd./fm)/log(dmag))+2); # magnitude points 117 nm_pts = max(3,ceil(log(fd./fm)/log(dmag))+2); # magnitude points
118 npts = min(5,max(np_pts, nm_pts)); 118 npts = min(5,max(np_pts, nm_pts));
119 119
120 w1 = log10(w(1:lp1)); 120 w1 = log10(w(1:lp1));
121 w2 = log10(w(2:lp)); 121 w2 = log10(w(2:lp));
122 for ii=bigpts 122 for ii=bigpts
131 wnew = create_set(wnew); 131 wnew = create_set(wnew);
132 if(isempty(wnew)) # all small crossovers 132 if(isempty(wnew)) # all small crossovers
133 pcnt = 0; 133 pcnt = 0;
134 else 134 else
135 [fnew,wnew] = freqresp(sys,1,wnew); # get new freq resp points 135 [fnew,wnew] = freqresp(sys,1,wnew); # get new freq resp points
136 w = [w,wnew]; # combine with old freq resp 136 w = [w,wnew]; # combine with old freq resp
137 f = [f,fnew]; 137 f = [f,fnew];
138 [w,idx] = sort(w); # sort into order 138 [w,idx] = sort(w); # sort into order
139 f = f(idx); 139 f = f(idx);
140 phase = arg(f)*180.0/pi; 140 phase = arg(f)*180.0/pi;
141 endif 141 endif
142 endif 142 endif
143 endwhile 143 endwhile
150 w_diff = diff(w); 150 w_diff = diff(w);
151 w_dup = find(w_diff == 0); 151 w_dup = find(w_diff == 0);
152 w_idx = complement(w_dup,1:length(w)); 152 w_idx = complement(w_dup,1:length(w));
153 w = w(w_idx); 153 w = w(w_idx);
154 f = f(w_idx); 154 f = f(w_idx);
155 155
156 endfunction 156 endfunction