目录
前言
PID控制是最早发展起来的控制策略之一,其算法简单、鲁棒性好且可靠性高,在运动控制和过程控制中被广泛使用。为了进一步学习了解PID,笔者正在学习北京航空航天大学的刘金琨老师的先进PID控制MATLAB仿真一书,并在此记录分享,希望和大家一起进步。
一、PID控制原理
模拟控制系统由模拟PID控制器和被控对象组成。PID控制器是一种线性控制器,它根据给定目标值和实际输出值构成控制偏差:
PID控制规律为:
这也是经典PID控制方程,其中kp为比例系数,T1为积分时间常数,TD为微分时间常数。
PID本质是校正,也可以理解成三种校正环节的结合,各校正环节的作用如下:
- 比例环节:成比例地反映控制系统的偏差信号error(t),比例系数为kp
- 积分环节:主要用于消除静差,提高系统的无差度。积分作用的强弱与积分时间常数密切相关
- 微分环节:反映偏差信号的变化趋势(变化速率),也就是起到一个预测作用,可以引入早期修正信号,从而可以加快系统的动作速度,减少调节时间。
二、连续系统的PID控制Simulink仿真
Simulink是MATLAB中的一种可视化仿真工具,本书也采用Simulink进行仿真。本节主要采用Simulink里的PID控制器和采用S函数以及采用简化S函数实现PID控制正弦响应(代码来源于书)
以二阶线性传递函数(传递函数是指零初始条件下线性系统响应(即输出)量的拉普拉斯变换(或z变换)与激励(即输入)量的拉普拉斯变换之比)为被控对象,进行模拟PID控制。在信号发生器中选择正弦波,信号发生器设置A为1,F=0.2HZ,仿真时选择kp=60,ki=1,kd=3。采用OED45迭代方法(重要),仿真时间为10s。
1.利用自带的PID控制器仿真
(1)本仿真是采用了传递函数的另外一种表达方式,也就是状态方程,仿真程序如下:
(2)作图程序代码如下:
close all;
plot(out.t,out.yd(:,1),'r',out.t,out.y(:,1),'k:','linewidth',2);
xlabel('time(s)');
ylabel('yd,y');
legend('Ideal position signal','Position tracking');
(3)运行结果:
可以看出,位置跟踪效果十分完美,下面采用S函数来进行仿真 。
2.采用S函数进行仿真
S函数是Simulink的一项重要功能,采用S函数可以实现在Simulink下复杂控制器和复杂被控对象的编程。在上述仿真的基础上,采用S函数实现上述对象的表达、控制器的设计以及仿真结果的输出。在S函数中,采用三个函数,分别是mdlInitializeSizes函数(完成初始化功能)、mdlDerivatives函数(完成微分功能)和mdlOutputs函数(输出)。在初始化采用S函数的基本sizes结构,选择两个输出,三个输入(输入P、I、D三项),即设置sizes.NumOutputs=1,
sizes.NumInputs=3。在对对象的表达中,采用一输入一输出的形式。
(1)仿真程序如下:
(2)S函数代码:
s.m
function [sys,x0,str,ts]=s_function(t,x,u,flag)
switch flag,
case 0,
[sys,x0,str,ts]=mdlInitializeSizes;
case 3,
sys=mdlOutputs(t,x,u);
case {2,4,9}
sys=[];
otherwise
error(['Unhandled flag=',num2str(flag)]);
end
function [sys,x0,str,ts]=mdlInitializeSizes
sizes=simsizes;
sizes.NumContStates=0;
sizes.NumDiscStates=0;
sizes.NumOutputs=1;
sizes.NumInputs=3;
sizes.DirFeedthrough=1; %表示直接馈通,即输入信号是否在输出端出现的标识
sizes.NumSampleTimes=0;
sys=simsizes(sizes);
x0=[];
str=[];
ts=[];
function sys=mdlOutputs(t,x,u)
error=u(1);
derror=u(2);
errori=u(3);
kp=60;
ki=1;
kd=3;
ut=kp*error+kd*derror+ki*errori;
sys(1)=ut;
plant.m
function [sys,x0,str,ts]=s_function(t,x,u,flag)
switch flag,
case 0,
[sys,x0,str,ts]=mdlInitializeSizes;
case 1,
sys=mdlDerivatives(t,x,u);
case 3,
sys=mdlOutputs(t,x,u);
case {2,4,9}
sys=[];
otherwise
error(['Unhandled flag=',num2str(flag)]);
end
function [sys,x0,str,ts]=mdlInitializeSizes
sizes=simsizes;
sizes.NumContStates=2;
sizes.NumDiscStates=0;
sizes.NumOutputs=1;
sizes.NumInputs=1;
sizes.DirFeedthrough=0;
sizes.NumSampleTimes=0;
sys=simsizes(sizes);
x0=[0,0];
str=[];
ts=[];
function sys=mdlDerivatives(t,x,u)
sys(1)=x(2);
sys(2)=-(25+10*rands(1))*x(2)+(133+30*rands(1))*u;
function sys=mdlOutputs(t,x,u)
sys(1)=x(1);
(3)仿真结果:
简化的S函数方法这里就不介绍了,暴力赋值即可,实现起来比较容易。
总结
以上就是今天学习分享的内容,简单实现了连续系统的基本PID控制,第一次分享,希望大家多多支持,有建议可以直接提出来,我们互相交流进步,期待下一次记录。