使用Matlab的app designer(GUI)展示PID参数对输出影响 (一)

2 篇文章 0 订阅
2 篇文章 0 订阅

作者:金广林

通过 Matlab 的 app designer 可以展示PID三个参数对输出的影响,在这里我并没有使用Simulink仿真的原因是因为不能实时、动态地观察到输出曲线变化,也就是说,如果我们使用Simulink,我们在搭建好仿真结构图后,需要一次又一次地手动设定KP/KI/KD,点击仿真运行后才能观察到曲线。我希望通过调整参数的同时观察到输出曲线的变化,因此采用了界面编程GUI(老版本matlab),也就是高版本的 Matlab 中的 app designer。

设计目标:在鼠标拖动滑块的同时,观察到输出曲线的变化

一、首先需要搭建一个界面图

我所设计的界面如下:

 左上角是输入信号选择栏,可以选择阶跃信号或脉冲信号作为输入的信号。

左侧有三个滑块,分别对应KP、KI、KD。

左下角,一个是Generate生成图像,一个是Reset将所有参数恢复默认并清空图像。

右上角,Tab栏是被控系统传递函数的特征方程,我只设到了二次,当然大家也可以设更多次项,Tab2可以以另一种方式表示被控系统,即输入零极点(本人偷懒,若输入正数则视为未输入,毕竟右半平面的零极点不稳定,输出曲线发散,若输入了非正数,则视为填入了零极点后续将会参与运算)

 右下角则是输出图像的区域。

二、代码

首先我们需要定义几个函数以便后续调用

第一个是输入特征方程系数的,第二个是输入零极点方式的。

#由于本人不希望输出曲线的纵坐标带小数点因此将输入的阶跃信号扩大了十倍,即R(s)=10/s。

function OUTPUT=PIDtest(KP,KI,KD,a,b,c,in)
syms s
%TF means Transfer_Function
GTF=(KP+KI/s+KD*s)/(c*s^2+b*s+a);
Output_TF=10*GTF/((1+GTF)*s^in);
OUTPUT=ilaplace(Output_TF);
end
function OUTPUT = PIDtest2(KP,KI,KD,p,z,in)
syms s
%TF means Transfer_Function
CTF=1;
for ii=1:length(p)
    if imag(p(ii))==0
       CTF=(1/(s-p(ii)))*CTF;
    else
       CTF=(1/(s-conj(p(ii))))*CTF;
    end
end
for jj=1:length(z)
    if imag(z(jj))==0
       CTF=(1/(s-z(jj)))*CTF;
    else
       CTF=(1/(s-conj(z(jj))))*CTF;
    end    
end
GTF=(KP+KI/s+KD*s)*CTF;
Output_TF=10*GTF/((1+GTF)*s^in);
OUTPUT=ilaplace(Output_TF);
end

有了这两个函数时候,在app designer 中就可以轻松调用了。

KP、KI、KD三个滑块的代码几乎相同,因此只展示其中KP滑块的代码。

% Value changing function: KPSlider
        function KPSliderValueChanging(app, event)
            changingValue = event.Value;
            KP=changingValue;
            KI=app.KISlider.Value;
            KD=app.KDSlider.Value;
            in=app.StepButton.Value;
            if app.Lamp.Color==[0 1 0]
            A=app.S0Spinner.Value;
            B=app.S1Spinner.Value;
            C=app.S2Spinner.Value;
            OUTPUT=PIDtest(KP,KI,KD,A,B,C,in);
            else
                p=[];
                P1=app.EditField.Value;
                P2=app.EditField_2.Value;
                P3=app.EditField_3.Value;
                P4=app.EditField_4.Value;
                Z1=app.EditField_5.Value;
                Z2=app.EditField_6.Value;
                if P1<0||P1==0
                    p=[p P1];
                end
                if P2<0||P2==0
                    p=[p P2];
                end
                if P3<0||P3==0
                    p=[p P3];
                end
                if P4<0||P4==0
                    p=[p P4];
                end               
                z=[];
                if real(Z1)<0||real(Z1)==0
                    z=[z Z1];
                end
                if real(Z2)<0||real(Z2)==0
                    z=[z Z2];
                end
                OUTPUT=PIDtest2(KP,KI,KD,p,z,in);
            end
            fplot(app.UIAxes,OUTPUT,[0 50])
            grid(app.UIAxes,"on")  
        end

Reset 按键代码:

 % Button pushed function: ResetButton
        function ResetButtonPushed(app, event)
          app.KPSlider.Limits=[1,15];
          app.KISlider.Limits=[0,3];
          app.KDSlider.Limits=[0,20];
          app.KPSlider.Value=1;
          app.KISlider.Value=0;
          app.KDSlider.Value=0;
          app.StepButton.Value=1;
          app.ImpulseButton.Value=0;
          app.Spinner_4.Value=15;
          app.Spinner_5.Value=3;
          app.Spinner_6.Value=20;
          app.XlabelSpinner.Value=20;
          app.YlabelSpinner.Value=20;
          app.UIAxes.XLim=[0 20];
          app.UIAxes.YLim=[-10 20];
          app.EditField.Value=1;
          app.EditField_2.Value=1;
          app.EditField_3.Value=1;
          app.EditField_4.Value=1;
          app.EditField_5.Value=1;
          app.EditField_6.Value=1;
          app.S0Spinner.Value=1;
          app.S1Spinner.Value=1;
          app.S2Spinner.Value=1;
          GenerateButtonPushed(app, event)
        end

Generate 按键代码:

 % Button pushed function: GenerateButton
        function GenerateButtonPushed(app, event)
                KP=app.KPSlider.Value;
                KI=app.KISlider.Value;
                KD=app.KDSlider.Value;
                in=app.StepButton.Value;

            if app.Lamp.Color==[0 1 0]
                A=app.S0Spinner.Value;
                B=app.S1Spinner.Value;
                C=app.S2Spinner.Value;
                OUTPUT=PIDtest(KP,KI,KD,A,B,C,in); 
            else
                p=[];
                P1=app.EditField.Value;
                P2=app.EditField_2.Value;
                P3=app.EditField_3.Value;
                P4=app.EditField_4.Value;
                Z1=app.EditField_5.Value;
                Z2=app.EditField_6.Value;
                if P1<0||P1==0
                    p=[p P1];
                end
                if P2<0||P2==0
                    p=[p P2];
                end
                if P3<0||P3==0
                    p=[p P3];
                end
                if P4<0||P4==0
                    p=[p P4];
                end               
                z=[];
                if real(Z1)<0||real(Z1)==0
                    z=[z Z1];
                end
                if real(Z2)<0||real(Z2)==0
                    z=[z Z2];
                end
                OUTPUT=PIDtest2(KP,KI,KD,p,z,in);
            end
            fplot(app.UIAxes,OUTPUT,[0 50])
        end

其他关于设置坐标刻度、字体大小、颜色、刻度上限等代码省略

后续文章将展示PID三个参数作用的结论。

代码已开源:

https://github.com/JihnGlyn/PID-Visualizer-crafted-by-Matlab-GUI.git

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值