关于一阶系统的PID 算法控制的仿真设计
一、设计内容
对一阶系统实现PID 算法控制并进行仿真,具体功能如下:基本要求:实现PID 算法和一阶系统差分方程仿真,PID 算法中的四个参数和一阶系统的参数都可以通过菜单进行设定,系统对阶越函数的响应以图形方式实时显示在窗口中。
二、涉及算法的基本原理
在模拟系统中,PID 算法的表达式为: ])()(1)([)(?++
=dt
t de T dt t e T t e K t P D I P (1) 式中 P(t):调节器的输出信号
e(t):调节器的偏差信号,等于测量值与给定值之差 P K :调节器的比例系数
I T :调节器的积分时间 D T :调节器的微分时间
欲控制系统的微分方程为: )()()(1
t x t y t y dt
d
T =+ (2)
x(t)为系统输入,y(t)为系统输出。对于闭环的单位负反馈,我们有PID 控制器的输入是测试信号r(t)与系统输出y(t)之差,因此有:
T 1dy(t)dt +y (t )=K P [(r (t )?y (t ))+1T I ∫(r (τ)?y(τ))dτt 0+T D d(r (t )?y (t ))dt
] (3)
又因为r(t)为阶跃函数,故有:
d 2y (t )dt 2+1+K P T 1+K P T D dy (t )dt +K P
T I (T 1+K P T D )
y (t )=K P T 1+K P T D [δ(t )+T D dδ(t )dt ]+r(t)T I (T 1+K P T D )
(4) 令:
2ab =?1+K P
T 1+K P T D
,b =√K
P
T I
(T 1
+K
P T D
) ,c =K P T 1
+K P T D
,d =K P T D
T 1
+K P T
D
e =1
T I
(T 1
+K P T D )
(5)
则有:
d 2y (t )dt 2?2ab dy (t )dt +b 2y (t )= cδ(t )+d dδ(t )dt
+er(t) (6)
由Laplace 变换,且设y(0)=y ′(0)=0 ,有:Type equation here.
Y (s )=cs +ds 2+e s ?2abs +b 1
s
(7)
令:A =b(a +2,B =b(a ?2 解得:
{
y (t )=(c +dA )A +e (A ?B)A e At ?(c +dB )B +e (A ?B)B e Bt +e AB (A ≠B)
y (t )=((c +dA )t +d)e At +e A te At ?e
AB
(e At ?1) (A =B)
(8)
当T 很小时:
y (0)=d ,y (T )≈d +(c +2abd)T (9)
对于极小的时间间隔,及采样周期T ,我们有:
{
d 2y (kT )dt ≈
y (kT )?2y((k ?1)T)+y((k ?2)T)T dy (kT )dt ≈y (kT )?y((k ?1)T)T
(10)
代入(6),且考虑k>2,有:
y (k )=2(1?abT )1?2abT +(bT )y (k ?1)?1
1?2abT +(bT )
y (k ?2)+T 2e (11)
我们只需要求得y(0),y(1) 即可求得系统的输出。
三、利用Matlab GUI 设计PID 的一阶系统的仿真
1、实验仪器
装有Matlab2013a 的PC 机一台 2、实验步骤
A 、学习有关Matlab GUI 界面编程的相关知识
B 、打开Matlab GUI 页面,设计PID 控制器的界面,如下图:
其中如图所示的功能键的功能如下:
Start—stop模块:
单击start开始绘制默认参数下的PID响应图;
单击close关闭窗口
Player and Precision adjustment输入模块(时间单位为秒):
Display :动态显示绘图时间,即前进一个设定的步长所需的时间
Tf :绘图的最大的时间的设定
T :采样周期
PID_Controller Parameter Setting 输入模块:
Kp :比例环节系数
Ti :积分环节系数
Td :微分环节系数
System Parameter Setting输入模块:
T1:一阶惯性系统的时间常数
其中的默认参数如上图所示。
C 、编写相关的回调函数
(1)、打开Matlab自动生成的M文件,找到以下函数段,即初始化的函数。在下面加入初始化的模块程序:
function PID_Controller_OpeningFcn(hObject, eventdata, handles, varargin)
set(handles.Kp,'String',1);
set(handles.Ti,'String',1);
set(handles.Tf,'String',10);
set(handles.Td,'String',1);
set(handles.T,'String',0.01);
set(handles.T1,'String',1);
set(handles.Time,'String',0.1);
(2) 找的下面的函数,加入主程序,即我们得到的算法(5)、(9)、(10)、(11)式,可以得到如下程序:
function start_Callback(hObject, eventdata, handles)
Tf=str2num(get(handles.Tf,'String')); %%
Td=str2num(get(handles.Td,'String')); %% 规定变量类型为数值性
Ti=str2num(get(handles.Ti,'String')); %%
T=str2num(get(handles.T,'String')); %%
Kp=str2num(get(handles.Kp,'String')); %%
T1=str2num(get(handles.T1,'String')); %%
Time=str2num(get(handles.Time,'String')); %%
N=fix(Tf/T); %%把绘图结束时间取下整
b=sqrt(Kp/(Ti*(T1+Kp*Td))); %%
a=-0.5*(1+Kp)/(T1+Kp*Td)/b; %%
c=Kp/(T1+Kp*Td); %%
d=Kp*Td/(T1+Kp*Td); %%由算法的到的计算值
e=1/(T1+Kp*Td)/Ti; %%
System_output(1)=d; %% 初始值
System_output(2)=d+(c+2*a*b*d)*T; %%
for k=3:N
System_output(k)=2*(1-a*b*T)/(1-2*a*b*T+(b*T)^2 )* System_output(k-1)-1/(1-2*a*b*T+(b*T)^2 )*System_output(k-2)+e*T^2;
end %%系统输出
n=1:N;
x=T*n;
hold on
grid on;
axis([0,max(x)+1,min(System_output)-1,max(System_output)+1]) %%规范围定显示坐标
comet(x,System_output(n),Time); %% 动态显示
function Time_Callback(hObject, eventdata, handles)
四、运行结果及调试分析
(1)、算法正确性的检验
默认参数时,我们有图(1),为检验算法的正确性,当参数取上述数值是,可得系统传递函数为:
Y(s) R(s)=
1+s+s2 1+2s+2s2
利用Matlab,在命令窗口输入:num=[1 1 1];
>> den=[2 2 1];
>> step(num,den)
得到系统的单位阶跃响应曲线如图(2)。
图(1)本设计算法PID闭环控制一阶惯性系统
默认参数响应
图(2)Matlab自带工具箱PID闭环控制一阶惯性系统
默认参数响应
由此,比较此二曲线,我们可以肯定我们的算法是正确的。
(2)、其他参数下的响应
Tf=50,其他参数不变(左)
Ti=10、Td=1,Kp=3 ,Tf=12,Display=0.1,T=0.01
Kp=3,Ti=0.5,Td=100,T1=1,如下图所示:
当点击close键时,系统关闭。
经多次调试,该系统能运行正常。
五、心得体会
首先,我是第一次用Matlab设计界面,有好多东西多不会。因此试了很多次,到最后是做出来了。感悟是:会者不难。其次我没有用老师所给的算法,而是自己设计的,在做这算法的过程中深感到数学的重要性。好在这些数学知识都会。其次就是在编程的过程中发现自己不太细心,这需要更多的练习。最后就是由于时间仓促,有一些可以做的更好地方没有做。
六、参考文献
信号与线性系统.上册/管致中,夏恭恪等编著.4版。—北京:高等教育出版社,2004.1
精通MATLAB CUI设计/陈垚光等编著,—3版.—北京:电子工业出版社,2013.8
计算机控制系统/何克忠,李伟编著。—北京清华大学出版社,1998,4
Matlab代码(已去掉Matlab自动生成的注释):
function varargout = PID_Controller(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn',
@PID_Controller_OpeningFcn, ...
'gui_OutputFcn',
@PID_Controller_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 PID_Controller_OpeningFcn(hObject, eventdata, handles, varargin)
set(handles.Kp,'String',1);
set(handles.Ti,'String',1);
set(handles.Tf,'String',10);
set(handles.Td,'String',1);
set(handles.T,'String',0.01);
set(handles.T1,'String',1);
set(handles.Time,'String',0.1);
handles.output = hObject;
guidata(hObject, handles);
function varargout = PID_Controller_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function System_output_ButtonDownFcn(hObject, eventdata, handles)
function stop_Callback(hObject, eventdata, handles)
close
function reset_Callback(hObject, eventdata, handles)
function T1_Callback(hObject, eventdata, handles)
function T1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Kp_Callback(hObject, eventdata, handles) function Kp_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Ti_Callback(hObject, eventdata, handles) function Ti_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Td_Callback(hObject, eventdata, handles) function Td_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function T_Callback(hObject, eventdata, handles) function T_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Tf_Callback(hObject, eventdata, handles) function Tf_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function start_Callback(hObject, eventdata, handles) Tf=str2num(get(handles.Tf,'String'));
Td=str2num(get(handles.Td,'String'));
Ti=str2num(get(handles.Ti,'String'));
T=str2num(get(handles.T,'String'));
Kp=str2num(get(handles.Kp,'String'));
T1=str2num(get(handles.T1,'String'));
Time=str2num(get(handles.Time,'String'));
N=fix(Tf/T);
b=sqrt(Kp/(Ti*(T1+Kp*Td)));
a=-0.5*(1+Kp)/(T1+Kp*Td)/b;
c=Kp/(T1+Kp*Td);
d=Kp*Td/(T1+Kp*Td);
e=1/(T1+Kp*Td)/Ti;
System_output(1)=d;
System_output(2)=d+(c+2*a*b*d)*T;
for k=3:N
System_output(k)=2*(1-a*b*T)/(1-2*a*b*T+(b*T)^2 )*
System_output(k-1)-1/(1-2*a*b*T+(b*T)^2 )*System_output(k-
2)+e*T^2;
end
n=1:N;
x=T*n;
hold on
grid on;
axis([0,max(x)+1,min(System_output)-1,max(System_output)+1]) comet(x,System_output(n),Time);
function Time_Callback(hObject, eventdata, handles)
function Time_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end