第1页 共29页
利用MATLAB GUI设计控制系统分析与设计界面
1 引言
图形用户接口GUI是用户和计算机程序之间进行信息交流的方式。通过图形用户界面,用户不需要输入脚本或命令,不需要了解任务的内部运行方式,计算机在屏幕显示图形和文本,若有扬声器还可产生声音。用户通过输入设备,键盘,鼠标,麦克风等与计算机进行通信。图形用户界面GUI中包含多个图形对象,如图标,菜单,文本的用户界面。以某种方式选择或激活这些对象,引起相应的动作或变化,最常用的激活方式是用鼠标控制屏幕上的鼠标指针运动。
图形用户界面GUI具有操作方便,控制灵活的特点,已成为现代应用程序的主要方式。
用MATLAB GUI设计一个控制系统分析与设计界面,将系统的传递函数输入到GUI中,可以方便的绘制系统的各种常用曲线,如阶跃响应曲线,Nyquist曲线可以用于系统稳定性的分析,我们可以有意识的输入系统的开环传递函数或是闭环传递函数,分别对应Nyquist曲线和阶跃响应图。根轨迹对控制系统的分析和设计也很有价值。零极点图可以方便的查看系统的零极点分布,对于配置系统的极点进行系统校正具有重要意义。Bode图和幅频响应图对系统的频率响应分析是一种手段,而阶跃响应指标则可更细致的观察系统的性能。
用GUI设计控制系设计控制系统分析与设计界面不仅在工程上有参考意义,在我们的学习过程中也很有意义,可以帮助我们更深入更容易理解控制系统的分析与设计意义。传递函数是控制系统的核心,在这里设计了两种常用的传递函数输入形式,第一种可以称为直接形式,因为他的传递函数是已知的,我们可以将系统或以开环传递函数或闭环传递函数的形式输入GUI中,进行相应的分析设计;第二种是状态变量形式,这里开环或闭环取决于转换而来的状态空间方程,因为开环和闭环系统都可以转换为状态空间,因而在进行相应的计算和绘图时需注意。
2 问题分析
题目要求以MATLAB GUI设计图形用户界面,设计控制系统分析与设计界面,界面中包含控制系统中常见的功能,传递函数的输入和创建,性能指标计数显示,
第2页 共29页
绘制常用曲线等。传递函数是控制系统研究中的核心问题,常用的有
G(s)?num den和状态变量形式
X?AX?Bu y?CX?D u两种形式,第一种对于具体的某个传递函数而言是单输入但输出的(如果系统是多输入多输出的,则对于不同的输入而言,传递函数一般式不同的。),第二种形式可以设置y和u来实现多输入多输出。 本设计将这些功能具体化如下表格所示:
表1.1 传递函数 第一种形式 状态变量形式 分子矩阵num 矩阵A 矩阵B 矩阵C 分母矩阵den 矩阵D .阶跃响应性能指标(performance) 峰值mp 峰值时间Tp 常用曲线 Bode Nyquist 输入序号n 标志位k close按钮 RootLocus PoleZero impulse step nichols 幅频特性 稳态增益yss 超调量Del 上升时间Tr 调整时间Ts 指定多输入时是创建哪个输入量的传递函数 指定使用第一种形式还是状态变量形式下的传递函数 关闭GUI的运行 3 GUI设计
3.1 启动GUI
启动MATLAB后在命令窗口中键入guide,启动GUIDE,弹出“GUIDE Quick Start”对话框,或者通过file→new→GUI进入,在弹出的GUIDE模版中创建新的GUI或打开已经存在的GUI,也可以选择一些模版,这里新建一个GUI,选择Blank GUI (Default)模版。
3.2 GUI窗口大小设计
我们可以改变GUI输出编辑器的网格区域大小指定GUI的大小,操作方法是,
第3页 共29页
单击网格区域的右下角并进行拖拉。另外可以在“View”菜单下选择“Property Inspector”打开属性查看器,选择“Units”后面的按钮,然后选择弹出式菜单的“inches”,单击“Position”后面的“+”符号,输入x和y的坐标和GUI窗口的宽度和高度,再将“Units”属性设为character,这样可以进行精确地设置GUI的位置和大小。本设计采用默认地情况。
3.3 添加、对齐组件
GUI输出编辑器中包含了各种组件供用户设计界面,这里从工具箱中选择9个“Static Text”静态文本框,8个“Edit Text”可编辑文本框,一个“Pop-up Menu”下拉式列表框,一个“Push Button”按钮和一个“Axes”坐标系,将它们分别拉到设计区。具有相同父对象的组件,可以用对齐工具将他们对齐,例如对第一列的是四个可编辑文本,按住
”图标进入对
齐工具对话框,从中选择水平左对齐,当然去我们也可以设置他们之间的间隔,对齐工具和各组件布局如下:
图3.1 对齐工具
第4页 共29页
图 3.2 组件布局图
3.4 设置GUI组件属性
GUI中各组件的属性设置很重要,对回调函数的识别,数据的输入都很重要。从“View”菜单中选择“Porperty Inspector”选项,或点击工具条上的“
”
按钮,显示属性对话框,利用属性对话框设置个组件的属性。如果没有选择组件,属性查看器会显示GUI图形窗口的属性。在输出编辑器中选择各静态文本,将他们的“String”属性依次设置成“num” 、“den” 、“A” 、“B” 、“C” 、“D” 、“输入序号n” 、“标志位k” 、“types” ,他们分别指示他们图标位置之下的可编辑文本输入的信息类型,其中“num” 、“den” 、“A” 、“B” 、“C” 、“D”对应传递函数的矩阵,如表1.1所示。 “输入序号n”表示输入量的顺序号,在多输入创建传递函数时指定创建的是那个输入的传递函数,这里我们不能将输入序号n的值设置的比输入个数多,否则可能出错,其初始值为1,表示单输入的情况或多输入的第一个输入量。“标志位k”表示传递函数是“num” 、“den”所确定的还是“A” 、“B” 、“C” 、“D”所创建的,在绘制常用曲线图形以及计算显示性能指标的时候需要指定传递函数是来源于哪种情况,以免发生错误。标志位k的初始值为0,表示使用“num” 、“den”确定的传递函数,k值为1时使用“A” 、“B” 、“C” 、“D”所确定的传递函数。“types”表示在其图标位置之下的下拉式列表框中选择绘图类型和计算性能指标。下拉式列表框的
第5页 共29页
“String”属性设置方法为单击String属性后的“
”图标打开String属性
的编辑窗口,如图2.3所示输入。下拉式列表框共有九种类型,即其“String”属性中所列的“Bode” 、“Nyquist” 、“RootLocus” 、“PoleZero” 、“impulse” 、“step” 、“nichols” 、“幅频特性”、“performance”分别表示绘制波德图、奈奎斯特图、根轨迹、零极点图、脉冲响应曲线图、阶跃响应曲线图、nichols图、幅频特性图、计算阶跃响应的性能指标。依据上面得“String”属性顺序依次设置可编辑文本的“Tag”属性为“num_edit”“den_edit”“AA”“BB”“CC”“DD”“n_edit”“k_edit”将下拉式列表框的Tag属性设置为“popupmenu”。GUI根据组件的Tag属性值在保存时和第一次运行时自动设置回调函数的名称,如下拉式列表框的回调函数名为“popupmenu_Callback”。设置按钮的String的属性为“close”,Tag属性为“pushbutton”。功能为按下close按钮结束GUI的运行。组件的“String’属性见图3.2.
图3.3 下拉式列表框的String属性编辑窗口
3.5 对象浏览
利用对象浏览器,可查看当前所创建的图形对象,选择Tools→Object Browser命令或单击设计编辑器界面工具栏的“
”按钮,打开对象浏览器,
从中可以看出,对象在浏览器中是按创建的先后顺序显示的。见图 3.4.
第6页 共29页
图 3.4 对象浏览器
3.6 M文件编写
完成GUI输出编辑器的设计和属性设置之后,接下来就是进行M文件的编辑。第一次保存和运行GUI时,GUIDE会生成一个函数式M文件,它包含每个组件要用到的回调函数框架,以及一些初始化代码,一个初始函数回调和一个输出函数回调。生成M文件以后,它打开“Save GUI as”对话框,在“File name”文本框中键入文件名,本次设计文件名为“sheji”,GUIDE将相同的名称指定给FIG文件和M文件,单击“Save”按钮时,GUIDE会保存M文件并在M文件编辑器中打开它。创建了M文件以后,就可以通过单击输出编辑器中的工具条上的“按钮来打开M文件编辑器。在M文件编辑器中可以通过单击工具条上的“
””
按钮,然后在下拉菜单中选择目标回调来将光标移动到指定的回调函数。下面从功能的角度来分析个函数。 3.6.1 回调间和数据共享
通过将数据保存到MATLAB handles结构中,可以实现回调间的数据共享。GUI中的所有组件使用同一个handles结构,它会传递一个输入变量给GUIDE生成的所有回调函数。例如本设计中的一句语句handles.N=str2num(get(handles.n_edit,'String')),功能为先通过get函数命令获得对象属性,将n可编辑文本输入的字符转换为数字赋给名称为handles.N的handles结构的字段,用guidata(hObject, handles)函数保存handles结构,在其他的回调函数中就可以使用handles.N,或者赋给某个变量,
第7页 共29页
调用这些数据了。 3.6.2 初始化
为了增加美感,本次设计初始化函数中增加了一个绘制曲面的函数,绘制的是MathWorks公司的图标,因而选用了这个函数。使用surf命令,数据来源于membrane。在初始化中设置可编辑文本的初始值时使用set函数,例如set(handles.num_edit,'String','2 8 6'),功能为设置num矩阵的初始值为[2 8 6],但是需要注意的是这里是文本矩阵。 3.6.3 数据输入
本设计中需要输入的数据有矩阵和控制数据(n,k),输入的形式都是文本字符或字符串的形式,通过可编辑文本Edit Text输入的。对于矩阵先要将字符串转换为文本矩阵,再将文本矩阵转换为数字矩阵,例如handles.num0=str2mat(get(handles.num_edit,'String')); handles.num1=str2num(handles.num0);
将get获得num对象字符串通过str2mat命令转为文本矩阵handles.num0再将其通过str2num命令将其转换为数字矩阵handles.num1,这样便能在MATLAB中进行处理了。
3.6.4 创建传递函数和输入量的选择
这里所用的传递函数有两种两种形式,对于已知传递函数,以分子分母矩阵形式输入的情形比较简单,绘图时都是直接利用分子分母矩阵。对于状态变量形式的情况,需要先将A,B,C,D四个矩阵转换为分子分母矩阵形式,以利于以后的绘图和计算性能指标。例如
[handles.numx,handles.denx]=ss2tf(handles.AAA,handles.BBB,handles.CCC,handles.DDD,handles.N);
使用ss2tf命令将前面程序中获得handles.AAA,handles.BBB,handles.CCC,handles.DDD矩阵和handles.N数字转化为分子矩阵handles.numx和分母矩阵handles.denx,handles.N为指定ss2tf命令转换序号为handles.N(在GUI界面中看为输入序号n)的输入量的数据,这里我们要弄清楚输入量的个数不能将输入序号n的值设置的比输入个数还大,输入序号n的初始值设为1,表示单输入或多输入第一个输入量的情况。 3.6.5 选择传递函数
在后面的绘图和计算性能指标中需要选择使用哪种形式下的传递函数,因此
第8页 共29页
设计了一个标志位k,标志位k的可选值为0和1,值0时为选择分子分母形式输入的传递函数,值1为时选择状态变量形式创建的传递函数,若输入其他值,则不能正确绘图和计算性能指标,且在命令窗口中输出“标志位k=0or1”以及弹出消息对话框进行提醒,使用if…elseif…else…end语句结构实现这些功能。例如
if handles.K==0
bode(handles.num1,handles.den1); elseif handles.K==1
bode(handles.numx,handles.denx); else
disp('标志位k=0or1'); end
3.6.6 绘图类型的选择
绘图和计算性能指标类型是集中在下拉式列表框中的,因此需要对他们进行选择识别,每次用户选择其中的某项功能时,下拉式列表框的回调函数都会读取下拉式列表框的Value属性值,以便执行相应的功能,这里使用分支语句实现实现选择,例如:
val=get(hObject,'Value'); str=get(hObject,'String'); switch str{val} case 'Nyquist' hs=figure;
if handles.K==0
nyquist(handles.num1,handles.den1); elseif handles.K==1
nyquist(handles.numx,handles.denx); else
disp('标志位k=0or1'); end
title('Nyquist Fig');
图 3.5 k输入其他值时消息提醒 3.6.7 性能指标计算
性能指标是计算系统阶跃响应的相关指标,这里计算了六项,分别为,
第9页 共29页
% mp--峰值???????? % Tp--峰值时间??????? % Tr--上升时间??????? % Del--超调量???
% Ts--调整时间(2%准则)? % yss--稳态值
程序中将阶跃响应设置成幅值和时间两者返回数据来表现[Y,t]=step(sys);,这样就能方便的计算出mp,Tp,yss。上升时间是定义成幅值从0.1(t1)达到0.9(t2)的时间,计算式为 Tr?t2?t1
调整时间为最后一超出2%准则区域后再一次进入2%准则区域时的时间,这里需要用程序进行循环判断,以确定Ts,具体见附录程序。 超调量计算式为
Del?100(mp?yss)
yss在这里我们可以在绘制阶跃响应时在程序中加上两条语句 hs=figure;
step(handles.num1,handles.den1);(对应k=0,当然也可以针对k=1加对应的语句) 使之在axes中绘图的同时也绘制一张Figure图,在这张图中,可以点击右键,选择“characteristics”选择相应的性能指标,Peak Response ,Setting Time ,Rise Time ,Steady State ,在选择Peak Response时,将鼠标定位在相应的曲线点上还能显示Overshoot和At time两项指标,我们可以从这张图中得到的信息和命令窗口中输出的指标信息进行对比,发现计算还是比较准确的,初始设置数据生成的传递函数(k=0,n=1)的计算结果和Figure图对比信息如下; Transfer function: 2 s^2 + 8 s + 6
---------------------- Figure图 s^3 + 8 s^2 + 10 s + 6 yss=
0.9980 1 mp=
1.0948 1.09 Tp=
2.8166 2.82 Del=
9.7054 9.48
第
页
10页 共29
Tr=
1.2071 1.2 Ts=
5.2309 5.16 2.6.8 close功能
close按钮主要是在点击close按钮时关闭GUI的运行,它的回调函数如下: function pushbutton_Callback(hObject, eventdata, handles) close;
4 GUI测试
4.1 初始化界面
设计好GUI和编辑好程序后,保存后,接下来就是运行GUI,测试设计的正确性,查看程序是否能完成设定的功能。从“Tools”菜单中选择“Run”选项,或者单击GUIDE工具条中的“
”按钮,运行GUI。由于GUI界面的axes坐标
系不是复数坐标系,因而在绘制Nyquist,根轨迹等图时加入一条hs=figure语句,使得图形绘制在Figure中,如果使用h = axes语句指定axes,则会出现绘制的图形充满整个GUI界面的结果,并不令人满意,因而这里采用绘制在Figure中的方法。GUI运行的初始界面如下
图 4.1 GUI初始化运行界面
第
页
11页 共29
4.2 对num,den模型的测试
4.2.1 初始数据测试
使用初始数据,从下拉式列表框中,选择目标选项后,绘制的图形和计算的数据如下(n=1,k=0)num=[2 8 6],den=[1 8 10 6],从阶跃响应图和Nyquist图中可看出系统是稳定的(假设传递函数为开环的,则系统在右半平面无极点,Nyquist曲线不包括点(-1,0))
图 4.2 Bode图 图 4.3 Nyquist图
第
页
12页 共29
图 4.4 根轨迹图 图4.5 零极点图
图 4.6 nichols图 图 4.7 幅频响应图
第
页
13页 共29
图 4.8 脉冲响应图
图 4.9 阶跃响应图 Transfer function: 2 s^2 + 8 s + 6 ---------------------- s^3 + 8 s^2 + 10 s + 6 yss=
0.9980 mp=
1.0948 Tp=
2.8166 Del=
9.7054 Tr=
1.2071 Ts=
5.2309
4.2.2 改变num,den矩阵的测试
改变num=[1 3 5 6],den=[2 8 4 9]输入则会得到不同的结果,限于篇幅,这里仅给出一些图代表。
第
页
14页 共29
图4.10 阶跃响应图
图4.11 零极点图
图4.12 根轨迹图 图4.13 Nyquist图
第
页
15页 共29
Transfer function: s^3 + 3 s^2 + 5 s + 6 ----------------------- 2 s^3 + 8 s^2 + 4 s + 9 yss=
0.6674 mp=
1.0285 Tp=
2.2672 Del=
54.1151 Tr=
1.5458 Ts=
31.6380
图4.14 Bode图
4.3 对A,B, C, D模型的测试
4.3.1 初始数据的测试
对于A,B,C,D模型的测试,使用初始数据时为单输入单输出系统,A=[0 1 1;0 1 1;-6 -16 -8],B=[0;0;1],C=[6 8 2],D=[0](n=1,k=1)这里也给出一些图形和数据,从下面的的图形中也可以看出系统是稳定的,阶跃响应最终趋于稳定值。
图4.15 脉冲响应图
第
页
16页 共29
图4.16 阶跃响应图
图4.17 Nyquist图 图4.18 根轨迹图 Transfer function:
2 s^2 + 12 s - 3.331e-014 ------------------------------- s^3 + 7 s^2 + 14 s - 4.333e-015 yss=
0.8572 mp=
0.8575 Tp=
2.0000 Del=
0.0383 Tr=
0.6857 Ts=
1.0857
图4.19 Bode图
第
页
17页 共29
4.3.2 改变A,B,C,D矩阵的测试
A,B,C,D矩阵形式生成传递函数的优点是容易进行多输入多输出系统的生成,下面具体具体给出双输入单输出的第二个变量的测试结果。数据设置如下A=[1.13 -0.49 0.11;1 0 0;0 1 0],B=[-0.38 0.45;0.52 0.23;0.26 0.78], C=[1 0.12 0.24],D=[0.3 0.9],输入序号n=2,标志位k=1,这里也顺带测试了n和k。在我们输入矩阵时必须注意的是B的行数必须等于A的行数,C的列数必须等于A的列数,D的行数必须等于C的行数,D的列数必须等于B的列数。测试结果如下
图4.20 脉冲响应图
图4.21 阶跃响应图
第
页
18页 共29
图4.22 Bode图 图4.23 Nyquist图
图4.24根轨迹 图4.25 零极点图
第
页
19页 共29
图4.26 幅频响应图 图4.27 nichols图 Transfer function:
0.9 s^3 - 0.3522 s^2 + 0.2806 s + 0.07395 ----------------------------------------- s^3 - 1.13 s^2 + 0.49 s - 0.11 yss=
20.0223 mp=
20.0223 Tp=
3.9534 Del= 0 Tr=
2.8552 Ts=
3.8802
从上面的阶跃响应图,Nyquist图和计算数据来看系统式不稳定的,系统在右半平面有三个极点(假设为开环传递函数),但Nyquist曲线并没有以逆时针方向包围点(-1,0)三次。计算得出的数据是以软件停止计算时已得出的数据为基准计算的,因而有些指标不一定准确,如超调量Del,他是以阶跃响应的最大值减去终值得到结果乘以100(这里是指绘图停止时的值)再除以终值得来的,
第
页
20页 共29
因而这里的结果是0.但对于稳定的系统,在计算终止时已经稳定了的话,计数结果就就是准确的。
对于多输入多输出系统,由于绘制根轨迹的rlocus命令只能用于单输出的系统,pzmap命令对多输入多输出系统是绘制系统的特征向量和传递零点,因而这两个命令在本设计中对于多输入多输出系统不能使用。另外性能指标也是针对单输出的,也不能用,幅频响应也不能用,否则会出错。下面给出一个双输入双输出例子
A=[2.25 -5 -1.25 -0.5;2.25 -0.45 -1.25 -0.25;0.25 -0.5 -1.25 -1;1.25 -1.75 -0.25 -0.75],B=[4 6;2 4;2 2;0 2],C=[0 0 0 1;0 2 0 2],D=[0 0;0 0],对它的第一个输入进行测试,结果如下
图4.28 阶跃响应图
图4.29 脉冲响应图
第
页
21页 共29
图4.30Bode图 图4.31Nyquist图
图4.32 nichols图
4.4 对close按钮的测试
对close按钮的测试很简单,在所有的测试过程中都可以进行,在运行GUI时,点击close按钮就可以关闭GUI的运行,但Figure文件并不是在输出编辑器中创建的,因而需要另外单独关闭。
5 设计总结
本次综合课程设计要求设计一个控制系统的分析和设计MATLAB GUI界面,
第
页
22页 共29
界面包括控制系统的常用功能。MATLAB GUI拥有强大的图形用户界面设计功能,GUIDE提供了一系列创建图形用户界面的工具,fig文件的设计因而比较简单,大体可分为启动GUI,设定GUI窗口大小,添加组件对齐组件,设置组件的属性,对象浏览等几个步骤,这些工作比较简单,一看就会,关键是在于M文件的编写。
由于是第一次使用MATLAB GUI,因而不可避免的遇到许多问题,尤其是在程序的编写上。首先是在数据的输入上,GUI中的数据都是以字符的形式输入的,这和命令窗口中直接输入数字数据截然不同,虽然感慨时就注意到了这一点,设计中对单数字的输入页没有问题,但对矩阵的输入却有问题,后来查书发现str2mat命令只是将字符串输入转换为文本矩阵,还需要用到str2num命令将文本矩阵转换为数字矩阵,到此也一并解决了ss2tf命令需要A矩阵为方阵的问题。遇到的另一个主要问题是设计的过程中有时需要对fig文件进行修改,比如对某个组件的Tag属性进行修改,保存后,但是在M文件中查看函数列表时,发现相关组件的回调函数名称并没有改正过来,虽然运行GUI时调用可能没有问题,但却给人不统一的感觉,这时有可能就要重新设计。不过相对来说,MATLAB GUI使用起来还是比较方便的。
通过这次的综合课程设计使我们学到了很多东西,从我们拿到题目开始,我们就需要认真对其进行分析,查找相关资料,翻看某些辅导书籍学习MATLAB GUI的使用方法,经过这近三周的课程设计,虽然断断续续的,但也从这些工作中学到很多,第一,我们熟悉了MATLAB中很多的绘图命令,如Nyquist,pzmap等,也熟悉一些数据转换命令如ss2tf,str2mat,str2num以及设置对象属性命令set,获得对象属性命令get等等,这些知识的积累对我们今后用到的MATLAB GUI时是一次很好的先前练习,同时也进一步充实了MATLAB的知识;第二我们进一步认识到论文格式规范性的重要,为我们将来的毕业论文的书写打下基础。
总之,此次课程设计既是对我们综合运用各科知识能力的培养,也是对我们自学知识并加以运用和研究问题的能力得以提高。
最后,感谢谢蓉华老师的指导。
附录
%GUI设计程序
function varargout = sheji(varargin)
第
页
23页 共29
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @sheji_OpeningFcn, ... 'gui_OutputFcn', @sheji_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
function sheji_OpeningFcn(hObject, eventdata, handles, varargin) %初始化函数 handles.membrane=membrane; [x,y]=meshgrid(-8:.5:8); r=sqrt(x.^2+y.^2)+eps;
handles.current_data=handles.membrane; surf(handles.current_data);
set(handles.k_edit,'String','0'); %设置初始属性值
handles.K=str2num(get(handles.k_edit,'String')); %获得属性值 set(handles.num_edit,'String','2 8 6'); set(handles.den_edit,'String','1 8 10 6');
handles.num0=str2mat(get(handles.num_edit,'String')); handles.den0=str2mat(get(handles.den_edit,'String')); handles.num1=str2num(handles.num0); handles.den1=str2num(handles.den0);
set(handles.AA,'String','0 1 1;0 1 1;-6 -16 -8'); set(handles.BB,'String','0;0;1'); set(handles.CC,'String','6 8 2'); set(handles.DD,'String','0'); set(handles.n_edit,'String','1');
AAAA=str2mat(get(handles.AA,'String')); BBBB=str2mat(get(handles.BB,'String')); CCCC=str2mat(get(handles.CC,'String')); DDDD=str2mat(get(handles.DD,'String'));
handles.N=str2num(get(handles.n_edit,'String')); handles.AAA=str2num(AAAA); handles.BBB=str2num(BBBB); handles.CCC=str2num(CCCC); handles.DDD=str2num(DDDD);
第
页
24页 共29
handles.output = hObject; %设定默认输出 guidata(hObject, handles); %保存handles结构
function varargout = sheji_OutputFcn(hObject, eventdata, handles) varargout{1} = handles.output;
function num_edit_Callback(hObject, eventdata, handles) function num_edit_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function den_edit_Callback(hObject, eventdata, handles) function den_edit_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function AA_Callback(hObject, eventdata, handles) function AA_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function BB_Callback(hObject, eventdata, handles) function BB_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function CC_Callback(hObject, eventdata, handles) function CC_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function DD_Callback(hObject, eventdata, handles) function DD_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
第
页
25页 共29
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function n_edit_Callback(hObject, eventdata, handles) function n_edit_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function k_edit_Callback(hObject, eventdata, handles) function k_edit_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
function pushbutton_Callback(hObject, eventdata, handles) close;
function popupmenu_Callback(hObject, eventdata, handles)
handles.K=str2num(get(handles.k_edit,'String')); %获得标志位k handles.num0=str2mat(get(handles.num_edit,'String')); handles.den0=str2mat(get(handles.den_edit,'String')); handles.num1=str2num(handles.num0); handles.den1=str2num(handles.den0); AAAA=str2mat(get(handles.AA,'String')); BBBB=str2mat(get(handles.BB,'String')); CCCC=str2mat(get(handles.CC,'String')); DDDD=str2mat(get(handles.DD,'String'));
handles.N=str2num(get(handles.n_edit,'String')); %获得输入顺序号n handles.AAA=str2num(AAAA); handles.BBB=str2num(BBBB); handles.CCC=str2num(CCCC); handles.DDD=str2num(DDDD);
[handles.numx,handles.denx]=ss2tf(handles.AAA,handles.BBB,handles.CCC,handles.DDD,handles.N);
val=get(hObject,'Value'); str=get(hObject,'String');
switch str{val} %绘图和计算 case 'Bode' hs=figure;
if handles.K==0
bode(handles.num1,handles.den1); elseif handles.K==1
bode(handles.numx,handles.denx);
第
页
26页 共29
else
disp('标志位k=0or1'); %错误提示从命令窗口输出
hmb=msgbox('k=0 or 1','消息对话框','warn'); %弹出提示框 end
title('Bode Fig'); case 'Nyquist' hs=figure;
if handles.K==0
nyquist(handles.num1,handles.den1); elseif handles.K==1
nyquist(handles.numx,handles.denx); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end
title('Nyquist Fig'); case 'RootLocus' hs=figure;
if handles.K==0
rlocus(handles.num1,handles.den1); elseif handles.K==1
rlocus(handles.numx,handles.denx); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end
title('Root Locus Fig'); case 'PoleZero' hs=figure;
if handles.K==0
[z,p]=tf2zp(handles.num1,handles.den1); pzmap(p,z); elseif handles.K==1
[z,p]=tf2zp(handles.numx,handles.denx); pzmap(p,z); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end
title('PoleZero'); case '幅频特性' hs=figure;
if handles.K==0
freqs(handles.num1,handles.den1);
第
页
27页 共29
elseif handles.K==1
freqs(handles.numx,handles.denx); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end
title('幅频特性'); case 'nichols' hs=figure;
if handles.K==0
nichols(handles.num1,handles.den1); elseif handles.K==1
nichols(handles.numx,handles.denx); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end case 'step'
if handles.K==0
plot(step(handles.num1,handles.den1)); elseif handles.K==1
plot(step(handles.numx,handles.denx)); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end
title('Step Response'); case 'impulse'
if handles.K==0
plot(impulse(handles.num1,handles.den1)); elseif handles.K==1
plot(impulse(handles.numx,handles.denx)); else
disp('标志位k=0or1');
hmb=msgbox('k=0 or 1','消息对话框','warn'); end
title('Impulse Response'); case 'performance' if handles.K==0
sys=tf(handles.num1,handles.den1) elseif handles.K==1
sys=tf(handles.numx,handles.denx) else
disp('标志位k=0or1');
第
页
28页 共29
hmb=msgbox('k=0 or 1','消息对话框','warn'); end % mp--峰值????????
% Tp--峰值时间????????????? % Tr--上升时间???????????? % Del--超调量?????????
% Ts--调整时间(2%准则)?????????????? % yss--稳态值???????????? [Y,t]=step(sys); [mp,ind]=max(Y); dimt=length(t); yss=Y(dimt);
Del=100*(mp-yss)/yss; Tp=t(ind);
i=1;j=1;k=1;q=1; while Y(i)<0.1*yss i=i+1; end; t1=t(i);
while Y(j)<0.9*yss j=j+1; end; t2=t(j); Tr=t2-t1; i=dimt+1; n=0;
while n==0 i=i-1; if i==1 n=1;
elseif Y(i)>=1.02*yss, n=1; end; end; t1=t(i);
i=dimt+1;n=0; while n==0 i=i-1; if i==1, n==1;
elseif Y(i)<=0.98*yss, n=1; end; t2=t(i);
第
页
29页 共29
if t1>t2 Ts=t1; else Ts=t2; end end
disp('yss='); disp(yss); disp('mp='); disp(mp); disp('Tp='); disp(Tp); disp('Del='); disp(Del); disp('Tr='); disp(Tr); disp('Ts='); disp(Ts); end
handles.output=hObject; guidata(hObject,handles);
function popupmenu_CreateFcn(hObject, eventdata, handles) if ispc
set(hObject,'BackgroundColor','white'); else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end
参考文献
[1] 苏金明,王永利. MATLAB7.0实用指南(上册)[M].北京:电子工业出版社, 2004, 81-98.
[2] 刘慧颖. MATLAB R2006a基础教程[M].北京:清华大学出版社,2007,132-136 [3] 陈晓平,李长杰. MATLAB及其在电路与控制理论中的应用[M].合肥:中国科学技术大学出版社,2004,99,109-119,125-143
[4] 陈 光,毛涛涛,王正林,王玲.精通MATLAB GUI设计[M].北京:电子工业出版社,2008,292,341-345
[5] 瞿亮,凌民,傅 ,蔡立军.基于MATLAB的控制系统计算机仿真[M].北京:清华大学出版社,2006,155-164