📄 rlocusgui.m
字号:
rlPzMax=max(max(real(p)),max(real(z)))*scale;
imPzMax=max(max(imag(p)),max(imag(z)))*scale;
else %special case if there are no zeros.
rlPzMin=min(real(p))*scale;
rlPzMax=max(real(p))*scale;
imPzMax=max(imag(p))*scale;
end
if q~=0, %if the locus goes to infinity, make plot "scale" times bigger.
xmax=ceil(scale*rlPzMax); xmin=floor(scale*rlPzMin);
else % just a little bigger.
xmax=ceil(rlPzMax+0.1); xmin=floor(rlPzMin-0.1);
end
handles.Xmax=max(xmax,1); %Max is at least 1.
handles.Xmin=min(-1,xmin); %Min is less than -1.
handles.Ymax=max([ceil(1.5*imPzMax) 0.75*abs([xmax xmin]) 1]);
% find all complex poles and zeros (for angles of departure...)
handles.cmplxZero=[]; handles.cmplxPole=[];
for i=1:length(z),
if imag(z(i))>0, handles.cmplxZero(end+1)=z(i); end
end
for i=1:length(p),
if imag(p(i))>0, handles.cmplxPole(end+1)=p(i); end
end
guidata(hObject, handles); %save changes to handles.
%-------------------------------------------------------------------------
%------Draw locus on left-hand set of axes (unchanged thereafter)----------
function InitRlocus(handles)
axes(handles.axStatic); cla;
drawRLocus(handles,handles.axStatic,1.5,length(handles.K),...
'Complete Root Locus');
%--------------------------------------------------------------------------
%% Utility functions and GUI control
% --- Executes on button press in pbExit. Closes Gui ---------------------
function pbExit_Callback(hObject, eventdata, handles)
disp(' '); disp('Root Locus GUI tool closed.'); disp(' '); disp(' ');
close(handles.RLocusGuiFig);
%--------------------------------------------------------------------------
% --- Executes on button press in pbWebPage. Goes to my web page.----------
function pbWebPage_Callback(hObject, eventdata, handles)
web('http://www.swarthmore.edu/NatSci/echeeve1/Ref/LPSA/Root_Locus/DeriveRootLocusRules.html');
%--------------------------------------------------------------------------
% --- Draw grid on left set of axes if check box is checked ---------------
function cbRLocGrid_Callback(hObject, eventdata, handles)
if get(handles.cbRLocGrid,'Value'),
axes(handles.axStatic);
sgrid(0.1:0.2:0.9,1:1:2*sqrt((handles.Ymax)^2));
else
InitRlocus(handles);
end
get(handles.cbRLocGrid,'Value');
%--------------------------------------------------------------------------
% --Called when radio button is pushed, dispatches the correct function.---
function panelChooseRule_SelectionChangeFcn(hObject, eventdata, handles)
s=''; %Start "s" as an empty string.
set(handles.axRules,'Visible','on'); %Second axes visible.
set(handles.txtKval,'Visible','off'); %Text invisible.
set(handles.sldKIndex,'visible','off');%Slider invisible.
set(handles.txtKeq0,'visible','off');
set(handles.txtKeqInf,'visible','off');
set(handles.lbRuleDescr,'Value',1); %Display starting at line 1.
set(handles.cbInteract,'visible','off');%Interaction option not visible.
set(handles.cbInteract,'Value',0); %Interaction option is off.
handles.interactive=0; %Save interaction info.
guidata(handles.RLocusGuiFig, handles); %save changes to handles.
%Choose proper function based upon rule chosen. The variable "s" stores the
%string describing the application of the specified rule. Note the last
%two rules are handled differently because they allow interaction with
%user.
switch get(handles.panelChooseRule,'SelectedObject'),
case handles.rbInfo, s=RuleInfo(handles);
case handles.rbSym, s=RuleSymmetry(handles);
case handles.rbNumBranch, s=RuleNumBranch(handles);
case handles.rbStartEnd, s=RuleStartEnd(handles);
case handles.rbRealAxis, s=RuleRealAxis(handles);
case handles.rbAsymptotes, s=RuleAsymptotes(handles);
case handles.rbBreakOutIn, s=RuleBreakOutIn(handles);
case handles.rbDepart, s=RuleDepart(handles);
case handles.rbArrive, s=RuleArrive(handles);
case handles.rbCrossImag, s=RuleCrossImag(handles);
case handles.rbFindGain,
s=RuleFindGain(handles);
set(handles.cbInteract,'visible','on');
set(handles.cbInteract,'string','Specify another pole location?');
case handles.rbLocPos,
s=RuleLocPos(handles);
set(handles.cbInteract,'visible','on');
set(handles.cbInteract,'string','Change K and find roots?');
otherwise
beep
end
set(handles.lbRuleDescr,'String',s); %Display string in window.
guidata(hObject, handles); %save changes to handles.
%--------------------------------------------------------------------------
% --- Executes on button press in pbRuleDetail. ---------------------------
% Depending on which rule is selected, go to appropriate section of web
% page that describes rule.
function pbRuleDetail_Callback(hObject, eventdata, handles)
rt='http://www.swarthmore.edu/NatSci/echeeve1/Ref/LPSA/Root_Locus/DeriveRootLocusRules.html';
switch get(handles.panelChooseRule,'SelectedObject'),
case handles.rbInfo, rt=[rt '#Background'];
case handles.rbSym, rt=[rt '#RuleSym'];
case handles.rbNumBranch, rt=[rt '#RuleNum'];
case handles.rbStartEnd, rt=[rt '#RuleStart'];
case handles.rbRealAxis, rt=[rt '#RuleReal'];
case handles.rbAsymptotes, rt=[rt '#RuleInf'];
case handles.rbBreakOutIn, rt=[rt '#RuleBrk'];
case handles.rbDepart, rt=[rt '#RuleDep'];
case handles.rbArrive, rt=[rt '#RuleArv'];
case handles.rbCrossImag, rt=[rt '#RuleImag'];
case handles.rbFindGain, rt=[rt '#RuleFindPole'];
case handles.rbLocPos, rt=[rt '#RuleFindK'];
otherwise
beep
end
web(rt);
%-------------------------------------------------------------------------
% --- Executes on slider movement.----------------------------------------
function sldKIndex_Callback(hObject, eventdata, handles)
kInd=round(get(hObject,'Value')); %Get index of "K".
set(hObject,'Value',kInd);
%Get necessary values, and select right set of axes.
k=handles.K; r=handles.R; ColOrd=handles.ColorOrder;
axes(handles.axRules); cla;
if handles.interactive, %If GUI is in interactive mode,
handles.kInd=kInd; %Get value;
guidata(hObject, handles); % Update handles structure
s=RuleLocPos(handles); %Get explantory string,
set(handles.lbRuleDescr,'String',s); %...and display it.
end
%Show "K" value on plot.
set(handles.txtKval,'string',sprintf('K = %5.3g ',k(kInd)));
%Draw the locus.
drawRLocus(handles,handles.axRules,1.5,length(handles.K),...
get(handles.txtKval,'string'));
for c=1:size(r,1)
plot(real(r(c,kInd)),imag(r(c,kInd)),'o','MarkerSize',4,...
'MarkerEdgeColor',ColOrd(c,:),'MarkerFaceColor',ColOrd(c,:));
end
%-------------------------------------------------------------------------
% --- Executes on button press in cbInteract------------------------------
% This function is inelegant. It handles the special case when the GUI is
% interactive (i.e., for the last two rules).
function cbInteract_Callback(hObject, eventdata, handles)
if get(handles.cbInteract,'Value'), %If the GUI is interactive.
handles.interactive=1;
guidata(hObject, handles); %...update handles structure to save info.
switch get(handles.panelChooseRule,'SelectedObject'), %Find which rule.
case handles.rbFindGain, %If "Find gain"
s=RuleFindGain(handles); %... get string and display.
set(handles.lbRuleDescr,'String',s);
set(handles.cbInteract,'Value',0); %Clear check box.
case handles.rbLocPos, %If "Find Locus Location"
s=RuleLocPos(handles); %... get string and display.
set(handles.lbRuleDescr,'String',s);
otherwise
beep;
end
else
handles.interactive=0;
guidata(hObject, handles); % Update handles structure
switch get(handles.panelChooseRule,'SelectedObject'),
case handles.rbFindGain
s=RuleFindGain(handles);
set(handles.lbRuleDescr,'String',s);
case handles.rbLocPos
s=RuleLocPos(handles);
set(handles.lbRuleDescr,'String',s);
otherwise
beep;
end
end
guidata(hObject, handles); % Update handles structure
%-------------------------------------------------------------------------
%-------------------------------------------------------------------------
% Take a string "q", and a quantity "x" and generate correct syntax.
% i.e. Plurstr(3,'dog') yields "3 dogs", Plurstr(1,'dog') yields "1 dog"
function s=PlurStr(x,q)
switch(x),
case 0
s=['0 ' q 's'];
case 1
s=['1 ' q];
otherwise
s=sprintf('%g %ss',x,q);
end
%-------------------------------------------------------------------------
%-------------------------------------------------------------------------
% More advanced version of Plurstr that also enumerates elements in a list.
% It takes two strings, s1 and s2, andan array x (and a final puntuation
% mark) and forms a phrase. "x" can be complex.
% e.g. ListString('There exist',[-3 -2 -1],'pole','.')
% yields "There exist 3 poles at s=-3, -2, -1."
function s=ListString(s1,x,s2,punct)
if isempty(x),
s=[s1 '0 ' s2 's' punct];
else
s=[s1 PlurStr(length(x),s2) ' at s =' CmplxString(x)];
s(end)=punct;
end
%--------------------------------------------------------------------------
%--------------------------------------------------------------------------
% Generates a list of properly formatted, and comma separated, complex and
% real numbers from an array z. It assumes complex conjugate pairs are
% consecutive in the list and displays both with a "+/-"
function s=CmplxString(z)
s='';
if isempty(z),
s='(None exist)';
else
i=1;
while i<=length(z),
if isreal(z(i)),
s=sprintf('%s %5.2g, ',s,z(i));
else
s=sprintf('%s %5.2g
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -