Mercurial > hg > octave-lyh
diff scripts/control/base/frdemo.m @ 3431:99ab64f4a09d
[project @ 2000-01-14 03:53:03 by jwe]
author | jwe |
---|---|
date | Fri, 14 Jan 2000 04:12:41 +0000 |
parents | |
children | 2e06c3941943 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/scripts/control/base/frdemo.m @@ -0,0 +1,601 @@ +## Copyright (C) 1996, 1998 Auburn University. All rights reserved. +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation; either version 2, or (at your option) any +## later version. +## +## Octave is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, write to the Free +## Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. + +## -*- texinfo -*- +## @deftypefn {Function File} {} frdemo () +## Octave Controls toolbox demo: Frequency Response demo +## @end deftypefn + +## Author: David Clem +## Created: August 15, 1994 +## a s hodel: updated to match new order of ss2zp outputs +## J Ingram: updated for system data structure format August 1996 + +function frdemo () + + disp("") + clc + j = 0; + while (j != 4) + disp(""); + j = menu("Octave Controls Systems Toolbox Frequency Response Demo", + "Bode analysis (bode)", + "Nyquist analysis (nyquist)", + "Nichols analysis (nichols)", + "Return to main demo menu"); + + if (j == 1) + k1 = 0; + while (k1 != 4) + disp("\n"); + clc + + k1 = menu("Bode analysis (bode)", + "Continuous system bode analysis", + "Discrete system bode analysis", + "Bode command description", + "Return to frdemo menu"); + + if( k1 == 1 ) + disp(" ") + clc + disp("\nContinuous system bode analysis\n"); + disp("Example #1:") + disp("\nConsider the system sys1="); + sys1=tf2sys([1, 1], [1, 0, -1]); + sysout(sys1); + disp("\nPole-zero form can be obtained as follows:") + cmd = "sysout(sys1,""zp"");"; + run_cmd; + disp("The systems bode plot is obtained as follows:"); + cmd = "bode(sys1);"; + run_cmd; + disp("\nNotice that bode automatically labels the plots according to") + disp("the selected input/output combinations.") + disp(" ") + disp("If the frequency range is not specified, bode automatically") + disp("selects a frequency range based on the natural frequencies of") + disp("of all poles away from s=0 (or z=1 in discrete time). Bode") + disp("then checks to make sure that the phase plot is sufficiently") + disp("smooth that relevant plot behavior is captured.") + disp("") + disp("Bode exits with an error if the system is mixed (both continuous") + disp("and discrete; see is_digital for conditions)") + prompt + disp("\nIf the plot magnitude, phase and frequency data is desired, the"); + disp("user can enter the following command:"); + disp("\n[Mag,Phase,w] = bode(sys);"); + disp("\nThis will return three vectors containing the magnitude,"); + disp("phase and frequency.\n"); + prompt; + + disp("") + clc + disp("Example #2, sys2=") + cmd = "sys2=zp2sys(1, [-1, -5], 10);"; + eval(cmd); + cmd = "sysout(sys2);"; + eval(cmd); + disp("\nThe bode plot command is identical to the tf form:") + cmd = "bode(sys2);"; + run_cmd; + disp("\nThe internal representation of the system is not important;") + disp("bode automatically sorts it out internally.") + prompt; + + disp("") + clc + disp("Example #3, Consider the following state space system sys3=:\n"); + cmd = "sys3=ss2sys([0, 1; -1000, -1001], [0; 1], [0, -891], 1);"; + eval(cmd); + cmd = "sysout(sys3);"; + eval(cmd); + disp("\nOnce again, the bode plot command is the same:"); + cmd = "bode(sys3);"; + run_cmd; + disp("\nSuppose the user is interested in the response of the system"); + disp("defined over the input frequency range of 1 - 1000 rad/s.\n"); + disp("First, a frequency vector is required. It can be created"); + disp("with the command:\n"); + cmd = "wrange = logspace(log10(1),log10(1000),100);"; + disp(cmd); + eval(cmd); + disp("\nThis creates a logarithmically scaled frequency vector with"); + disp("100 values between 1 and 1000 rad/s\n"); + disp("Then, the bode command includes wrange in the input arguments"); + disp("like this:"); + cmd = "bode(sys3,wrange);"; + run_cmd; + prompt; + + disp("") + clc + disp("\nExample #4, The state-space system from example 3 will be"); + disp("grouped with the system from example 2 to form a MIMO system"); + disp("The commands to do this grouping are as follows (changing signal"); + disp("names for clarity):"); + cmd = "sys2 = syssetsignals(sys2,\"out\",\"y_sys2\");"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"in\",\"u_sys2\");"; + disp(cmd); eval(cmd); + cmd = "nn = sysdimensions(sys2);"; + disp(cmd); eval(cmd); + cmd = "[nn,nz] = sysdimensions(sys2);"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"st\",sysdefioname(nn+nz,\"x_sys2\"));"; + disp(cmd); eval(cmd); + cmd = "sys_mimo = sysgroup(sys2,sys3);"; + disp(cmd); eval(cmd); + disp("The resulting state-space system (after changing signal names"); + disp("in sys2) is"); + cmd = "sysout(sys_mimo)"; + eval(cmd); + disp("\nNotice that there are now 2 inputs and 2 outputs, and that it did"); + disp("not matter what form the two systems were in when they were grouped."); + disp(["\nTo view the system's bode plots, execute the", + " following command:\n"]) + cmd = "bode(sys_mimo);"; + run_cmd; + prompt + disp("\nTo view the bode plots for selected channels, the command form changes:") + cmd = "wrange = [];"; + disp(cmd) + eval(cmd); + cmd = "out = 1;"; + disp(cmd) + eval(cmd); + cmd = "in = 1;"; + disp(cmd) + eval(cmd); + cmd = "bode(sys_mimo,wrange,out,in);"; + run_cmd; + disp("\nNotice that this bode plot is the same as the plot from example 2."); + prompt + closeplot + + elseif( k1 == 2 ) + disp("") + clc + disp("\nDiscrete system bode analysis\n"); + disp("Display bode plots of a discrete SISO system (dbode)\n") + disp("Example #1, Consider the following discrete transfer"); + disp(" function:\n"); + cmd = "sys1 = tf2sys([0.00100502, -0.00099502], [1, -2, 1], 0.001);"; + disp(cmd); + eval(cmd); + cmd = "sysout(sys1)"; + disp(cmd); + eval(cmd); + disp("\nTo examine open loop zeros and poles of the system,"); + disp("use the command:\n") + cmd = "sysout(sys1,""zp"");"; + run_cmd; + disp("\nTo view the system's bode plots, execute the following"); + disp("command:\n") + cmd = "bode(sys1);"; + run_cmd; + disp("\nNotice (1) the plot label uses exp(jwT) for its title axis. This") + disp(" allows the user to determine what kind of system was") + disp(" used to generate the bode plot"); + disp(" (2) the system poles are both at z=1, (break frequency at") + disp(" jwT = 0); pure integrator poles like this are discarded") + disp(" by Octave when computing the plot frequency range.") + + disp("\nIf magnitude, phase, and frequency data are also desired,"); + disp(" perform the following command instead:\n"); + disp("[M,P,w]=dbode(num,den,T,wrange).\n Where:"); + disp("M => Bode magnitude response data"); + disp("P => Bode phase response data"); + disp("w => frequencies that M and P were evaluated at"); + disp("sys1 => system data structure") + disp("T => sample period") + disp("wrange => optional vector of frequencies") + disp(" if wrange is entered in the argument list, the"); + disp(" system will be evaluated at these specific"); + disp(" frequencies\n"); + + prompt + disp("") + clc + disp("Example #2, Consider the following set of discrete poles and"); + disp("zeros:\n") + cmd = "sys2 = zp2sys([0.99258;0.99745],[0.99961;0.99242],1,0.001);"; + disp(cmd); + eval(cmd); + cmd = "sysout(sys2)"; + disp(cmd); + eval(cmd); + disp("\nTo view the system's bode plots, execute the following"); + disp("command:\n") + cmd = "bode(sys2);"; + run_cmd; + disp("Notice that the bode command is the same in both of the previous"); + disp("examples. The bode command is also the same for the continuous case."); + disp("The function, dbode, is no longer used."); + + prompt + disp("") + clc + disp("\nExample #3, Now consider the following state space system:\n"); + cmd = "sys3 = ss2sys([.857, .0011; 0, .99930],[1;1],[-.6318, .0057096],5.2, .001);"; + disp(cmd); + eval(cmd); + cmd = "sysout(sys3);"; + disp(cmd); + eval(cmd); + disp("\nTo view the system's bode plots, execute the following command:\n") + cmd = "bode(sys3);"; + run_cmd; + disp("\nAgain, notice that the bode command is the same regardless of the form"); + disp("of the system."); + disp("\nSuppose the user is interested in the response of the system"); + disp("defined over the input frequency range of 1 - 1000 rad/s.\n"); + disp("First, a frequency vector is required. It can be created"); + disp("with the command:\n"); + cmd = "wrange = logspace(log10(1),log10(1000),100);"; + disp(cmd); + eval(cmd); + disp("\nThis creates a logrithmetically scaled frequency vector with"); + disp("100 values between 1 and 1000 rad/s\n"); + disp("Then, the bode command includes wrange in the input arguments"); + disp("like this:"); + cmd = "bode(sys3,wrange);"; + run_cmd; + prompt; + + disp("") + clc + disp("\nExample #4, We will now examine a MIMO state-space system. Systems"); + disp("two and three will be grouped."); + cmd = "[nn,nz] = sysdimensions(sys2);"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"out\",\"y_sys2\");"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"in\",\"u_sys2\");"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"st\",sysdefioname(nn+nz,\"x_sys2\"));"; + disp(cmd); eval(cmd); + cmd = "sys_mimo = sysgroup(sys2,sys3);"; + disp(cmd); eval(cmd); + cmd = "sysout(sys_mimo);"; + disp(cmd); + eval(cmd); + disp("\nTo view the system's bode plots, execute the following command:\n") + cmd = "bode(sys_mimo);"; + run_cmd; + prompt + + disp("\nThe bode plot of a single channel is viewed as follows:") + cmd = "wrange = [];"; + disp(cmd) + eval(cmd); + cmd = "out = 1;"; + disp(cmd) + eval(cmd); + cmd = "in = 1;"; + disp(cmd) + eval(cmd); + cmd = "bode(sys_mimo,wrange,out,in);"; + run_cmd; + disp("\nNotice that this bode plot is the same as the plot from example 2."); + prompt + closeplot + + elseif( k1 == 3 ) + help bode + prompt + endif + endwhile + elseif (j == 2) + k2 = 0; + disp(""); + while (k2 != 4) + disp("\n"); + help nyquist + prompt; + disp("") + clc; + + k2 = menu("Nyquist analysis (Nyquist)", + "Continuous system nyquist analysis", + "Discrete system nyquist analysis", + "Mixed system nyquist analysis", + "Return to frdemo menu"); + + if( k2 == 1 ) + disp("") + clc + disp("\nContinuous system nyquist analysis\n"); + disp("Display Nyquist plots of a SISO system (nyquist)\n") + disp("Example #1, Consider the following transfer function:\n") + cmd = "sys1 = tf2sys(1, [1, 0.8, 1]);"; + disp(cmd); + eval(cmd); + disp("To examine the transfer function, use the command:"); + cmd = "sysout(sys1);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the open loop zeros and poles, use the command:"); + cmd = "sysout(sys1,""zp"");"; + run_cmd; + disp("\nTo view the system""s nyquist plot, execute the following"); + disp("command:\n") + cmd = "nyquist(sys1);"; + run_cmd; + disp("\nIf the real and imaginary parts of the response are desired,"); + disp("use the following command:"); + disp("command: [R,I,w]=nyquist(sys1);\n"); + disp("If the user desires to evaluate the response in a certain"); + disp("frequency range, he may do so by entering the following:"); + disp("command: [M,P,w]=nyquist(num,den,wrange).\n") + disp("wrange is a vector of frequencies that spans the desired"); + disp("viewing range.\n"); + disp("This will be illustrated in the third nyquist example.\n") + disp("Variable Description:\n") + disp("R => real part of response") + disp("I => imaginary part of response") + disp("w => frequencies that the transfer function was evaluated at") + disp("sys1 => system data structure") + disp("wrange => optional vector of frequencies") + disp(" if wrange is entered in the argument list, the"); + disp(" system will be evaluated at these specific"); + disp(" frequencies\n") + prompt + + disp("") + clc + disp("Example #2, Consider the following set of poles and zeros:\n") + cmd = "sys2 = zp2sys([-1;-4],[-2+1.4142i;-2-1.4142i],1);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the poles and zeros, use the command:"); + cmd = "sysout(sys2)"; + disp(cmd); + eval(cmd); + disp("\nTo view the system""s nyquist plot, execute the following"); + disp("command:\n") + cmd = "nyquist(sys2);"; + run_cmd; + prompt + + disp("") + clc + disp("\nExample #3, Consider the following state space system:\n") + cmd = "sys3 = ss2sys([0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1; 0, 0, -20, -12],[0;0;0;1],[50, 100, 0, 0],0);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the state-space system, use the command:"); + cmd = "sysout(sys3)"; + disp(cmd); + eval(cmd); + disp("\nTo examine the poles and zeros, use the command:"); + cmd = "sysout(sys3,""zp"")"; + run_cmd; + disp("\nTo view the system""s nyquist plot, execute the following"); + disp("commands:\n") + cmd = "nyquist(sys3);"; + run_cmd; + prompt + + disp("Example #3 (continued), If the user wishes to evaluate the"); + disp("system response over a desired frequency range, he must first"); + disp("create a frequency vector.\n") + disp("For example, suppose the user is interested in the response"); + disp("of the system defined above over input frequency range of"); + disp("3 - 100 rad/s.\n") + disp("A frequency vector can be created using the command:\n"); + cmd = "wrange = logspace(log10(3),log10(100),100);"; + disp(cmd); + eval(cmd); + disp("\nNyquist can be run again using the frequency vector as"); + disp("follows:\n") + cmd = "nyquist(sys3,wrange);"; + run_cmd; + prompt + + disp("") + clc + disp("Example #4, Nyquist can be used for MIMO systems if the system has"); + disp("an equal number of inputs and outputs. Otherwise, nyquist returns"); + disp("an error. To examine a MIMO system, systems 2 and 3 will be grouped"); + cmd = "[nn,nz] = sysdimensions(sys2);"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"out\",\"y_sys2\");"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"in\",\"u_sys2\");"; + disp(cmd); eval(cmd); + cmd = "sys2 = syssetsignals(sys2,\"st\",sysdefioname(nn+nz,\"x_sys2\"));"; + disp(cmd); eval(cmd); + cmd = "sys_mimo = sysgroup(sys2,sys3);"; + disp(cmd); eval(cmd); + cmd = "sysout(sys_mimo);"; + disp(cmd); + eval(cmd); + disp("\nTo view the system's nyquist plot, execute the following command:\n") + cmd = "nyquist(sys_mimo);"; + run_cmd; + prompt + disp("\nTo view the nyquist plots for selected channels, the command form changes:") + cmd = "nyquist(sys_mimo,[],1,1);"; + run_cmd; + disp("\nNotice that this bode plot is the same as the plot from example 2."); + prompt + closeplot + + + + elseif( k2 == 2 ) + disp("") + clc + disp("\nDiscrete system nyquist analysis\n"); + disp("Display Nyquist plots of a discrete SISO system (nyquist)\n") + disp("We will first define a sampling time, T"); + cmd = "T = 0.01;"; + disp(cmd); + eval(cmd); + disp("\nExample #1, Consider the following transfer function:\n") + cmd = "sys1 = tf2sys([2, -3.4, 1.5],[1, -1.6, 0.8],T);"; + disp(cmd); + eval(cmd); + disp("To examine the transfer function, use the command:"); + cmd = "sysout(sys1);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the open loop zeros and poles, use the command:"); + cmd = "sysout(sys1,""zp"")"; + disp(cmd); + eval(cmd); + disp("\nTo view the system""s nyquist plot, execute the following"); + disp("command:") + cmd = "nyquist(sys1);"; + run_cmd; + disp("To change the range used for the frequency, a frequency"); + disp("is needed. Suppose the user would like to examine the"); + disp("nyquist plot in the frequency range of 0.01 - 31.6 rad/s."); + disp("\nThe frequency vector needed to do this is created with the"); + disp("command:"); + cmd = "wrange = logspace(-2,1.5,200);"; + disp(cmd); + eval(cmd); + disp("\nNyquist can be run again with this frequency vector"); + cmd = "nyquist(sys1,wrange);"; + run_cmd; + disp("\nIf the real and imaginary parts of the response are desired,"); + disp("perform the following command:\n"); + disp("[R,I,w]=nyquist(sys,wrange)\n") + disp("Variable Description:\n") + disp("R => real part of response") + disp("I => imaginary part of response") + disp("w => frequencies that the transfer function was evaluated at") + disp("sys => The system data structure"); + disp("wrange => optional vector of frequencies") + disp(" if wrange is entered in the argument list, the"); + disp(" system will be evaluated at these specific"); + prompt + + disp("") + clc + disp("\nExample #2, Consider the following set of poles and zeros:\n") + cmd = "sys2 = zp2sys([0.98025 + 0.01397i; 0.98025 - 0.01397i],[0.96079;0.99005],1,T);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the open loop zeros and poles, use the command:"); + cmd = "sysout(sys2)"; + disp(cmd); + eval(cmd); + disp("\nTo view the system's nyquist plot between the frequencies"); + disp("0.01 - 100 rad/s, execute the following commands:\n") + cmd = "wrange = logspace(-2,2,100);"; + disp(cmd); + eval(cmd); + cmd = "nyquist(sys2,wrange);"; + run_cmd; + prompt; + + disp("") + clc + disp("\nExample #3, Consider the following discrete state space"); + disp("system:\n"); + disp("This example will use the same system used in the third"); + disp("example in the continuous nyquist demo. First, that system"); + disp("will have to be re-entered useing the following commands:\n"); + cmd = "sys3 = ss2sys([0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1; 0, 0, -20, -12],[0;0;0;1],[50, 100, 0, 0],0);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the state-space system, use the command:"); + cmd = "sysout(sys3)"; + disp(cmd); + eval(cmd); + disp("\nTo examine the poles and zeros, use the command:"); + cmd = "sysout(sys3,""zp"")"; + disp(cmd); + eval(cmd); + disp("\nTo convert the system to discrete time, we need a sampling"); + disp("time which can be entered like this:"); + cmd = "T = 0.01"; + disp(cmd); + eval(cmd); + disp("\nNow the command, c2d, is used to convert the system from"); + disp("continuous to discrete time, with the following command"); + cmd = "dsys3 = c2d(sys3,T);"; + run_cmd; + disp("\nTo examine the new discrete state-space system, use the"); + disp("command"); + cmd = "sysout(dsys3);"; + disp(cmd); + eval(cmd); + disp("\nTo examine the new discrete poles and zeros, use the command:"); + cmd = "sysout(dsys3,""zp"")"; + disp(cmd); + eval(cmd); + disp("\nTo view the system's nyquist plot, execute the following"); + disp("commands:\n"); + cmd = "gset xrange [-4:2];"; + disp(cmd); eval(cmd); + cmd = "gset yrange [-2.5:2.5];"; + disp(cmd); eval(cmd); + cmd = "nyquist(dsys3);"; + run_cmd; + disp("Notice that the asymptotes swamp out the behavior of the plot") + disp("near the origin. You may use interactive nyquist plots") + disp("to \"zoom in\" on a plot as follows:") + + cmd = "atol = 1;"; + disp(cmd) + eval(cmd) + cmd = "nyquist(dsys3,[],[],[],atol);"; + run_cmd + prompt + + + disp("") + clc + disp("MIMO SYSTEM: Nyquist cannot be used for discrete MIMO systems"); + disp("at this time."); + ## cmd = "dsys_mimo = sysgroup(sys2,dsys3);"; + ## disp(cmd); + ## eval(cmd); + ## cmd = "sysout(dsys_mimo);"; + ## disp(cmd); + ## eval(cmd); + ## disp("\nTo view the system's nyquist plot, execute the following command:\n") + ## cmd = "nyquist(dsys_mimo);"; + ## run_cmd; + ## prompt + ## disp("\nTo view the nyquist plots for selected channels, the command form changes:") + ## cmd = "nyquist(dsys_mimo,[],1,1);"; + ## run_cmd; + ## disp("\nNotice that this bode plot is the same as the plot from example 2."); + prompt + closeplot + + + elseif( k2 == 3 ) + disp("\nMixed system nyquist analysis\n"); + disp("Nyquist exits with an error if it is passed a ""mixed"" system (one") + disp("with both continuous and discrete states). Use c2d or d2c to") + disp("convert the system to either pure digital or pure continuous form"); + endif + endwhile + elseif (j == 3) + help nichols + prompt + endif + endwhile + +endfunction