最近想学一下matlab的GUI编写,就是简单的玩一玩,想来想去就做一个和我专业相关一点的东西吧,就突然想到输入一个闭环传函特征多项式,给出系统稳定与否的结果,也可以给出劳斯表,当然现在函数已经实现,GUI有时间就能编好,到时候也会传到GitHub上。
给出程序流程图
不多说,贴上代码,其实注释已经写的很详细了
myrouth.m
function [RA,result]=myrouth(poli)
%part1 calculate the routh array
%
% part1 will calculate the symbolic Routh array RA for
% polynomial poli(s). The following special cases are considered:
% 1) zero first elements and 2) rows of zeros. All zero first
% elements are replaced with the variable EPSILON
% which can be later substituted with positive small
% numbers[in this code,small number is 1/100 * min(poli)]. When a
% row of zeros is found, the auxiliary polynomial is used.
%
% Examples:
%
% 1) Routh array for s^3+2*s^2+3*s+1
%
% >>ra=routh([1 2 3 1])
%
% 2) Routh array for s^3+a*s^2+b*s+c
%
% >>syms a b c;
% >>ra=routh([1 a b c]);
%
%
%
flag = 0; %to help judging the result,if row of zeros happen,set flag equals to 1
epsilon = min(poli)/100; %select one percent of the minimum of poli as epsilon
% if(nargin<2),
% fprintf('\nError: Not enough input arguments given.');
% return
% end
if all(poli<0)
poli = -1 * poli; %transform poli to all positive
end
dim=size(poli); %get size of poli
coeff=dim(2); %get number of coefficients
RA=sym(zeros(coeff,ceil(coeff/2))); %initialize symbolic Routh array
for i=1:coeff,
RA(2-rem(i,2),ceil(i/2))=poli(i); %assemble 1st and 2nd rows
end
rows=coeff-2; %number of rows that need determinants
index=zeros(rows,1); %initialize columns-per-row index vector
for i=1:rows,
index(rows-i+1)=ceil(i/2); %form index vector from bottom to top
end
for i=3:coeff, %go from 3rd row to last
if(all(RA(i-1,:)==0)), %row of zeros
flag = 1; %to help judging result
fprintf('\nSpecial Case: Row of zeros detected.\n');
a=coeff-i+2; %order of auxiliary equation
b=ceil(a/2)-rem(a,2)+1; %number of auxiliary coefficients
temp1=RA(i-2,1:b); %get auxiliary polynomial
temp2=a:-2:0; %auxiliry polynomial powers
RA(i-1,1:b)=temp1.*temp2; %derivative of auxiliary
elseif(RA(i-1,1)==0), %first element in row is zero
fprintf('\nSpecial Case: First element is zero.\n');
RA(i-1,1)=epsilon; %replace by epsilon
end
%compute the Routh array elements
for j=1:index(i-2),
RA(i,j)=-det([RA(i-2,1) RA(i-2,j+1);RA(i-1,1) RA(i-1,j+1)])/RA(i-1,1);
end
end
%part2 According to the routh array,judge the stablity of system
first_colomn_RA = RA(:,1);
if min(first_colomn_RA)<0
result = 'The system is unstable';
elseif all(first_colomn_RA>0) %first_colomn_RA has no zero
if flag == 1
result = 'The stablity can not be judged simply by Routh Criterion';
elseif flag == 0
result = 'The system is stable';
end
end
在matlab的workspace里面输入
guide
会出现如下图,点击新建,然后拖拽各种控件实现自己想要的效果
这里我主要想实现的效果是:输入系统闭环传函特征多项式的系数向量,点击按钮,就可以得到稳定性判定结果,并且显示得到的劳斯表(注意要把那个可编辑文本的框的属性里面的max调大一点,否则只能显示一行文本)还设计了一个按钮,一点就可以跳转到一个网页。所以设计如下(后来我还优化了一些细节,比如运行以后怎么让控件和字体自动适应分辨率)
会生成两个文件:routhGUI.m和routhGUI.fig,我的routhGUI.m里面如下,大部分是matlab自动生成的
function varargout = routhGUI(varargin)
% ROUTHGUI MATLAB code for routhGUI.fig
% ROUTHGUI, by itself, creates a new ROUTHGUI or raises the existing
% singleton*.
%
% H = ROUTHGUI returns the handle to a new ROUTHGUI or the handle to
% the existing singleton*.
%
% ROUTHGUI('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in ROUTHGUI.M with the given input arguments.
%
% ROUTHGUI('Property','Value',...) creates a new ROUTHGUI or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before routhGUI_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to routhGUI_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help routhGUI
% Last Modified by GUIDE v2.5 21-May-2019 14:45:35
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @routhGUI_OpeningFcn, ...
'gui_OutputFcn', @routhGUI_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before routhGUI is made visible.
function routhGUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to routhGUI (see VARARGIN)
% Choose default command line output for routhGUI
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes routhGUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = routhGUI_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
function editC_Callback(hObject, eventdata, handles)
% hObject handle to editC (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of editC as text
% str2double(get(hObject,'String')) returns contents of editC as a double
% --- Executes during object creation, after setting all properties.
function editC_CreateFcn(hObject, eventdata, handles)
% hObject handle to editC (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in btnC.
function btnC_Callback(hObject, eventdata, handles)
% hObject handle to btnC (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
feature_polynomial = str2num(get(handles.editC,'String'));% 这里用系统提示的str2double不行
[RA,result] = myrouth(feature_polynomial);
Ra = num2str(eval(RA));
set(handles.editResult,'String',result);
set(handles.editTable,'String',Ra);
function editResult_Callback(hObject, eventdata, handles)
% hObject handle to editResult (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of editResult as text
% str2double(get(hObject,'String')) returns contents of editResult as a double
% --- Executes during object creation, after setting all properties.
function editResult_CreateFcn(hObject, eventdata, handles)
% hObject handle to editResult (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function editRouth_Callback(hObject, eventdata, handles)
% hObject handle to editRouth (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of editRouth as text
% str2double(get(hObject,'String')) returns contents of editRouth as a double
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
url = 'https://en.wikipedia.org/wiki/Edward_Routh';
web(url,'-browser');
function editTable_Callback(hObject, eventdata, handles)
% hObject handle to editTable (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of editTable as text
% str2double(get(hObject,'String')) returns contents of editTable as a double
% --- Executes during object creation, after setting all properties.
function editTable_CreateFcn(hObject, eventdata, handles)
% hObject handle to editTable (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
运行一下,检验一下:
其实在编写的时候,发现劳斯判据有小BUG,就是劳斯判据的初衷就是之前人们没有很强的计算能力,发明的代数稳定判据方法。但是会出现一种全零行的特例,那时还需要求一下上一行构成的辅助方程(auxiliary equation)的根的情况,才能判断整个系统的稳定性,而不只是看补全后的劳斯表,所以还是roots()函数来的暴力直接!!
但毕竟锻炼了一下matlab的GUI编程,也对之前的知识复习一遍,在自己动手编的时候才会更深入发现问题,也是有收获的!!