📄 bodeplotgui.m
字号:
function varargout = BodePlotGui(varargin) % BODEPLOTGUI Application M-file for BodePlotGui.fig % FIG = BODEPLOTGUI launch BodePlotGui GUI. % BODEPLOTGUI('callback_name', ...) invoke the named callback. % Last Modified by GUIDE v2.5 09-Jun-2006 13:40:05 %Written by Erik Cheever (Copyright 2002) %Contact: erik_cheever@swarthmore.edu % Erik Cheever % Dept. of Engineering % Swarthmore College % 500 College Avenue % Swarthmore, PA 19081 USA %This function acts as a switchyard for several callbacks. It also intializes %the variables used by the GUI. Note that all variables are initialized here to %default values. A brief description of each variable is included. if nargin == 0 %If no arguments disp(' '); disp('Asymptotic Bode Plotter - proper usage is ''BodePlotGui(Sys)'',') disp(' where ''Sys'' is a transfer function object.'); disp(' '); disp(' '); %Check if first argument is a 'tf'. The GUI only works with transfer function objects. elseif isa(varargin{1},'tf') % LAUNCH GUI disp(' '); disp(' '); fig = openfig(mfilename,'new'); % Generate a structure of handles to pass to callbacks, and store it. handles = guihandles(fig); %Get handles structure. Sys=minreal(varargin{1}); %Get minimum realization. % Get numerator and denominator of two realizations. If their % lengths are unequal, it means that there were poles and zeros that % cancelled. [n1,d1]=tfdata(Sys,'v'); [n2,d2]=tfdata(varargin{1},'v'); if (length(n1)~=length(n2)), disp(' '); disp(' '); disp(' '); disp('************Warning******************'); disp('Original transfer function was:'); varargin{1} disp('Some poles and zeros were equal. After cancellation:'); Sys disp('The simplified transfer function is the one that will be used.'); disp('*************************************'); disp(' '); beep; waitfor(warndlg('System has poles and zeros that cancel. See Command Window for caveats.')); end handles.Sys=Sys; %The variable Sys is the transfer function. handles.sysInc=Sys; %The variable sysInc is that part of the transfer % function that will be plotted (with no poles or zeros excluded). Start with % it equal to Sys. This variable is modified in BodePlotSys handles.Terms=[]; %The structure "Term" has three elements. % type: this can be any of the 7 types listed below. % 1) The multiplicative constant. % 2) Real poles % 3) Real zeros % 4) Complex poles % 5) Complex zeros % 6) Poles at the origin % 7) Zeros at the origin % value: this is the location of the pole or zero (or in the case % of the multiplicative constant, its value). % multiplicity: this gives the multiplicity of the pole or zero. It has % no meaning in the case of the multiplicative constant. %The variable "Acc" is a relative accuracy used to determine whether or not %two poles (or zeros) are the same. Because Matlab uses an approximate %technique to find roots of an equation, it is likely to give slightly %different locations to identical roots. handles.Acc=1E-3; guidata(fig, handles); %Save handles. %The function BodePlotTerms separates the transfer function into its consituent parts. % The variable DoQuit will come back as non-zero if there was a problem. DoQuit=BodePlotTerms(handles); handles=guidata(fig); %Load handles (w/ changes from BodePlotTerms). %if DoQuit is zero, there were no problems and we may continue. if ~DoQuit, handles.IncludeString=[]; %An array of strings representing terms to include in the plot. handles.ExcludeString=[]; %An array of strings representing terms to exclude from plot. handles.IncElem=[]; %An array of indices of terms corresponding to their % location in the IncludeString array. handles.ExcElem=[]; %An array of indices of terms corresponding to their % location in the ExcludeString array. handles.FirstPlot=1; %This term is 1 the first time a plot is made. This lets % Matlab do the original autoscaling. The scales are then % saved and reused. handles.MagLims=[]; %The limits on the magnitude plot determined by MatLab autoscaling. handles.PhaseLims=[]; %The limits on the phase plot determined by MatLab autoscaling. handles.LnWdth=2; set(handles.LineWidth,'String',num2str(handles.LnWdth)); %Set the color of lines used in gray scale. The plotting functions %cycle through these colors (and then cycle through the linestyles). handles.Gray=[0.75 0.75 0.75; 0.5 0.5 0.5; 0.25 0.25 0.25]; handles.GrayZero=[0.9 0.9 0.9]; %This is the color used for the zero reference. %Set the color of lines used in color plots. The plotting functions %cycle through these colors (and then cycle through the linestyles). handles.Color=[0 1 1; 0 0 1; 0 1 0; 1 0 0; 1 0 1;1 0.52 0.40]; handles.ColorZero=[1 1 0]; %Yellow, this is the color used for the zero reference. %Sets order of linestyles used. handles.linestyle={':','--','-.'}; %This sets the default scheme to color (GUI can set them to gray scale). handles.colors=handles.Color; handles.zrefColor=handles.ColorZero; handles.exactColor=[0 0 0]; %Black guidata(fig, handles); %Save changes to handles. if nargout > 0 %If output argument is used, set it to figure. varargout{1} = fig; end BodePlotter(handles); %Make plot handles=guidata(fig); %Reload handles after function call. %DoQuit was non-zero, so there was a problem. Quit program. else CloseButton_Callback(fig,'',handles,''); end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard catch disp(lasterr); end endend% ------------------End of function BodePlotGui ----------------------%| ABOUT CALLBACKS:%| GUIDE automatically appends subfunction prototypes to this file, and%| sets objects' callback properties to call them through the FEVAL%| switchyard above. This comment describes that mechanism.%|%| Each callback subfunction declaration has the following form:%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)%|%| The subfunction name is composed using the object's Tag and the%| callback type separated by '_', e.g. 'slider2_Callback',%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.%|%| H is the callback object's handle (obtained using GCBO).%|%| EVENTDATA is empty, but reserved for future use.%|%| HANDLES is a structure containing handles of components in GUI using%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This%| structure is created at GUI startup using GUIHANDLES and stored in%| the figure's application data using GUIDATA. A copy of the structure%| is passed to each callback. You can store additional information in%| this structure at GUI startup, and you can change the structure%| during callbacks. Call guidata(h, handles) after changing your%| copy to replace the stored original so that subsequent callbacks see%| the updates. Type "help guihandles" and "help guidata" for more%| information.%|%| VARARGIN contains any extra arguments you have passed to the%| callback. Specify the extra arguments by editing the callback%| property in the inspector. By default, GUIDE sets the property to:%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))%| Add any extra arguments after the last argument, before the final%| closing parenthesis.% --------------------------------------------------------------------function varargout = IncludedElements_Callback(h, eventdata, handles, varargin) % Stub for Callback of the uicontrol handles.IncludedElements. % If a term in the "Included Elements" box is clicked, this callback is invoked. %Get index of element in box that is chosen.%If the index corresponds to one of the terms of the transfer function, deal with it. i=get(handles.IncludedElements,'Value'); % The alternative is that it corresponds to another string in the box (there is a blank % line, a line with dashes "----" and a line instructing the user to click on an element % to include it). if i<=length(handles.IncElem) TermsInd=handles.IncElem(i); %Get the index of the included element. handles.Terms(TermsInd).display=0; %Set display to 0 (to exclude it) guidata(handles.AsymBodePlot, handles); %save changes to handles. BodePlotter(handles); %Plot the Transfer function. handles=guidata(handles.AsymBodePlot); %Reload handles after function call. endend% ------------------End of function IncludedElements_Callback --------% --------------------------------------------------------------------function varargout = ExcludedElements_Callback(h, eventdata, handles, varargin) % Callback of the uicontrol handles.ExcludedElements. % If a term in the "Excluded Elements" box is clicked, this callback is invoked. i=get(handles.ExcludedElements,'Value'); %Get index of element in box that is chosen. %If the index corresponds to one of the terms of the transfer function, deal with it. % The alternative is that it corresponds to another string in the box (there is a blank % line, a line with dashes "----" and a line instructing the user to click on an element % to exclude it). if i<=length(handles.ExcElem) TermsInd=handles.ExcElem(i); %Get the index of the excluded element. handles.Terms(TermsInd).display=1; %Set display to 1 (to include it) guidata(handles.AsymBodePlot, handles); %save changes to handles. BodePlotter(handles); %Plot the Transfer function. handles=guidata(handles.AsymBodePlot); %Reload handles after function call. endend% ------------------End of function ExcludedElements_Callback --------% --------------------------------------------------------------------function varargout = CloseButton_Callback(h, eventdata, handles, varargin) % Callback for the uicontrol handles.CloseButton. %This function closes the window, and displays a message. disp(' '); disp('Asymptotic Bode Plotter closed.'); disp(' '); disp(' '); delete(handles.AsymBodePlot);end% ------------------End of function CloseButton_Callback -------------% --------------------------------------------------------------------function DoQuit=BodePlotTerms(handles) %This function takes a system and splits it up into terms that are plotted %individually when making a Bode plot by hand (it finds %1) The multiplicative constant. %2) All real poles %3) All real zeros %4) All complex poles %5) All complex zeros %6) All poles at the origin %7) All zeros at the origin % %In addition to finding the poles and zeros, it determines their multiplicity. %If two poles or zeros are very close they are determined to be the same pole %or zero. sys=handles.Sys; Acc=handles.Acc; %Relative accuracy. [z,p,k]=zpkdata(sys,'v'); %Get pole and zero data. %Find gain term. [n,d]=tfdata(sys,'v'); k=n(max(find(n~=0)))/d(max(find(d~=0))); term(1).type='Constant'; term(1).value=k; term(1).multiplicity=1; %Get all poles. j=length(term); for i=1:length(p), term(j+i).value=p(i); term(j+i).multiplicity=1; term(j+i).type='Pole'; end %Get all zeros. j=length(term); for i=1:length(z), term(j+i).value=z(i); term(j+i).multiplicity=1; term(j+i).type='Zero'; end %Check for multiplicity for i=2:length(term), for k=(i+1):length(term), %Handle pole or zero at origin as special case. if (term(i).value==0), %Multiple pole or zero at origin. if (term(k).value==0), term(i).multiplicity=term(i).multiplicity+term(k).multiplicity; %Set multiplicity of kth term to 0 to signify that it has been % subsumed by term(i) (by increasing the ith term's multiplicity). term(k).multiplicity=0; end %We know term is not at origin, so check for (approximate) equality % Since we know this term is not at origin, we can divide by value. elseif (abs((term(i).value-term(k).value)/term(i).value) < Acc), term(i).multiplicity=term(i).multiplicity+term(k).multiplicity; %Set multiplicity of kth term to 0 to signify that it has been % subsumed by term(i) (by increasing the ith term's multiplicity). term(k).multiplicity=0; end end end %Check for location of poles and zeros (and remove complex conjugates).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -