2.1 pid算法数学推导过程2.1.1 连续系统的pid算法
2.1.2 pid算法的离散化
2.2 位置型pid算法2.2.1 matlab算法clcclear%pid初始化len = 500 ; %运算次数y = zeros(1,len); %期望值y_d = zeros(1,len); %过程值err = zeros(1,len); %误差值err_0 = 0 ; %k时刻误差err_1 = 0 ; %k-1时刻误差y_d_last = 0 ; %k-1时刻输出integral = 0; %积分值kp = 0.2; %比例系数kd = 0.2; %微分值ki = 0.015 ; %积分值%运算过程for k=1:1:leny(k) = 200 ; %期望输出err_0 = y(k)-y_d_last; %计算偏差 integral = integral+err_last; %误差累计y_d_last = kp* err_0 + ki*integral + kd*( err_1- err_0); %位置型pid运算公式err_1 = err_0 ; %更新参数 y_d(k) = y_d_last ; err(k) = err_1 ;end%输出图像绘制t = 1:1:len;subplot( 2, 1, 1 ) ;plot( t, y, 'r', t, y_d, 'b' );axis([0 len, 0 1.5*y(1)])title('输出曲线');xlabel('t')ylabel('y(t)')%误差图像绘制subplot( 2, 1, 2 ) ;plot( t, err );axis([0 len, 0 1.5*y(1)])title('误差曲线');xlabel('t')ylabel('e(t)')matlab运行结果如下图所示。
2.2.2 c算法#includestruct _pid{ float setspeed ; //设置速度 float actualspeed ; //实际速度 float err ; //误差 float err_last ; //最终误差 float kp , kd , ki ; //比例系数 float voltage ; //输出电压 float integral ; //积分值}pid;void pid_init(){ pid.setspeed = 0 ; pid.actualspeed = 0.0 ; pid.err = 0.0 ; pid.err_last = 0.0 ; pid.voltage = 0.0 ; pid.integral = 0.0 ; pid.kp = 0.2 ; pid.kd = 0.2 ; pid.ki = 0.015 ;}float pid_realize( float speed ){ pid.setspeed = speed ; pid.err = pid.setspeed-pid.actualspeed ; pid.integral += pid.err ; pid.voltage = pid.kp*pid.err+pid.ki*pid.integral+pid.kd*( pid.err-pid.err_last ) ; pid.err_last = pid.err ; pid.actualspeed = pid.voltage*1.0 ; return pid.actualspeed ;}void main(){ int count ; count = 0 ; pid_init() ; while( count<850 ) { float speed = pid_realize( 200.0 ) ; count ++ ; }}2.3 增量型pid算法2.3.1 matlab算法clcclear%pid初始化len = 400 ; %运算次数y = zeros(1,len); %期望值y_d = zeros(1,len); %过程值err = zeros(1,len); %误差值err_0 = 0 ; %k时刻误差err_1 = 0 ; %k-1时刻误差err_2 = 0 ; %k-2时刻误差y_d_last = 0 ; %k-1时刻输出increment = 0 ; %增量kp = 0.2; %比例系数kd = 0.2; %微分值ki = 0.015 ; %积分值%运算过程for k=1:1:leny(k) = 200 ; %期望输出err_0 = y(k)-y_d_last; %计算偏差 increment = kp*(err_0-err_1) + ki*err_0 + kd*(err_0-2*err_1+err_2);%增量型pid运算公式 err_2 = err_1; err_1 = err_0; y_d_last = y_d_last + increment ; %输出叠加 %更新参数 y_d(k) = y_d_last ; err(k) = err_2;end%输出图像绘制t = 1:1:len;subplot( 2, 1, 1 ) ;plot( t, y, 'r', t, y_d, 'b' );axis([0 len, 0 1.5*y(1)])title('输出曲线');xlabel('t')ylabel('y(t)')%误差图像绘制subplot( 2, 1, 2 ) ;plot( t, err );axis([0 len, 0 1.5*y(1)])title('误差曲线');xlabel('t')ylabel('e(t)')matlab运行结果如下图所示。
2.3.2 c算法#includestruct _pid{ float setspeed ; //设置速度 float actualspeed ; //实际速度 float err ; //误差 float err_next ; //上一次误差 float err_last ; //最终误差 float kp , kd , ki ; //比例系数}pid;void pid_init(){ pid.setspeed = 0 ; pid.actualspeed = 0.0 ; pid.err = 0.0 ; pid.err_last = 0.0 ; pid.err_next = 0.0 ; pid.kp = 0.2 ; pid.kd = 0.2 ; pid.ki = 0.015 ;}float pid_realize( float speed ){ float incrementspeed ; pid.setspeed = speed ; pid.err = pid.setspeed-pid.actualspeed ;incrementspeed=pid.kp*(pid.err-pid.err_next)+pid.ki*pid.err+pid.kd*( pid.err-2*pid.err_next+pid.err_last ) ; pid.err_last = pid.err_next ; pid.err_next = pid.err ; pid.actualspeed += incrementspeed ; return pid.actualspeed ;}void main(){ int count ; count = 0 ; pid_init() ; while( count<850 ) { float speed = pid_realize( 200.0 ) ; count ++ ; }}2.4 积分分离型pid算法2.4.1 实现原理为了消除系统的稳态误差,提高控制精度引入了积分环节,但是在启动,结束和大幅度增减设定时,短时间内系统输出有很大的偏差,会造成pid运算的积分积累,导致控制量超过执行机构可能允许的最大动作范囲所对应的极限控制量,从而引起较大的超调,甚至震荡,为了克服这一问题,引入了积分分离的概念,基本思路是“当给定值与反馈值偏差较大时,取消积分的作用,当被控量接近给定值时,引入积分控制”,用于消除稳态误差,提高系统的精度。
2.4.2 matlab算法clcclear%pid初始化len = 500 ; %运算次数y = zeros(1,len); %期望值y_d = zeros(1,len); %过程值err = zeros(1,len); %误差值err_0 = 0 ; %k时刻误差err_1 = 0 ; %k-1时刻误差y_d_last = 0 ; %k-1时刻输出integral = 0; %积分值kp = 0.2; %比例系数kd = 0.2; %微分值ki = 0.015 ; %积分值max = 400 ; %积分上限index = 0 ; %积分有效性%运算过程for k=1:1:leny(k) = 200 ; %期望输出err_0 = y(k)-y_d_last; %计算偏差 if abs(err_0) <= y(k) index = 1 ; integral = integral+err_0; %误差累计 else index = 0 ; end y_d_last = kp*err_0 + ki*index*integral + kd*(err_1-err_0); %位置型pid运算公式err_1 = err_0 ; %更新参数 y_d(k) = y_d_last ; err(k) = err_1 ;end%输出图像绘制t = 1:1:len;subplot( 2, 1, 1 ) ;plot( t, y, 'r', t, y_d, 'b' );axis([0 len, 0 1.5*y(1)])title('输出曲线');xlabel('t')ylabel('y(t)')%误差图像绘制subplot( 2, 1, 2 ) ;plot( t, err );axis([0 len, 0 1.5*y(1)])title('误差曲线');xlabel('t')ylabel('e(t)')matlab运行结果如下图所示。
2.4.3 c算法#include#includestruct _pid{ float setspeed ; //设置速度 float actualspeed ; //实际速度 float err ; //误差 float err_last ; //最终误差 float kp , kd , ki ; //比例系数 float voltage ; //输出电压 float integral ; //积分值 float umax ; //积分上限 float umin ; //积分下限}pid;void pid_init(){ pid.setspeed = 0 ; pid.actualspeed = 0.0 ; pid.err = 0.0 ; pid.err_last = 0.0 ; pid.voltage = 0.0 ; pid.integral = 0.0 ; pid.kp = 0.2 ; pid.kd = 0.2 ; pid.ki = 0.1 ; pid.umax = 400 ; pid.umin = -200 ;}float pid_realize( float speed ){ char index ; pid.setspeed = speed ; pid.err = pid.setspeed-pid.actualspeed ; if( abs(pid.err)<= pid.umax ) { index = 1 ; pid.integral += pid.err ; } else index = 0 ; pid.voltage = pid.kp*pid.err+index*pid.ki*pid.integral+pid.kd*( pid.err-pid.err_last ) ; pid.err_last = pid.err ; pid.actualspeed = pid.voltage*1.0 ; return pid.actualspeed ;}void main(){ int count ; count = 0 ; pid_init() ; while( countmax if abs(err_0) <= y(k) index = 1 ; if err_0 < 0 integral = integral+err_0; %误差累计 end else index = 0 ; end elseif y_d_last
但是,实际的系统大部分属于非线性系统,或者说是系统模型不确定的系统,如果控制精度要求较高的话,那么对于参数的整定过程也是有难度的,专家pid和模糊pid就是为了满足这方面的需求而设计的,专家算法和模糊算法都归属于智能算法的范畴,智能算法最大的优点就是在控制模型未知的情况下,可以对模型进行控制,这里需要注意的是,专家pid也好,模糊pid也好,绝对不是专家系统或模糊算大与pid控制算法的简单加和,它是专家系统或者模糊算法在pid控制器参数整定上的应用,也就是说,智能算法是辅助pid进行参数整定的手段。
关于专家pid的c语言实现,需要找到一些依据,还需要从pid系数本身考虑。
1、比例系数kp的作用是加快系统的响应速度,提高系统的调节精度,kp越大,系统的响应速度越快,调节的精度越高,但是容易产生超调,甚至会引起系统不稳定,kp取值过小,则会降低系统的调节精度,拖慢响应速度,从而延长调节时间,使系统的静态,动态特性变差。
2、积分系数ki的作用是消除系统的稳态误差,ki越大,系统的静态误差消除得越快,但是若ki过大,在响应过程的初期就会产生积分饱和的现象,从而引起相应过程的较大超调,若ki过小,将使系统静态误差难以消除,影像系统的调节精度。
3、微分系数kd的作用是改善系统的动态特性,其作用主要是在响应过程中抑制偏差向任何方向的变化,对偏差变化进行提前预报,但是若kd过大,会使响应过程提前制动,从而延长调节时间,而且会降低系统的抗干扰性。
2.9 pid算法应用——电机转速控制pid是一种广泛应用在控制理论中的算法,以直流电机为例,要想精确控制电机的转速就需要形成一种闭环控制思想。首先将一个默认的输入端的电压值发送给直流电机,通过转速传感器将当前电机的转速反馈到输入端,通过与输入端做运算,如果转速高于设定的值,则减小输入端电压,如果转速低于设定的值,则提高输入端电压,由此形成了一种闭环控制回路,即通过不停的对输出端进行反馈,以达到精确控制的目的。为了使控制系统的速度更快,精确性更高,稳定性更强,pid控制器被广泛应用在了这里面,现在我们通过matlab的simulink来实现直流电机的pid控制。
一个直流电机的模型如上图所示,为了简化讨论,假设转子和转轴都是刚体,且转子受到的磁场恒定,转子收到的摩擦力与速度成正比,该电机的物理参数为:
(1)转子的转动惯量j=0.01kg·m^2^
(2)电机摩擦系数b=0.01n···m·s
(3)电动势常数ke=0.01v/rad/sec
(4)电机扭矩常数kt=0.01n·m/amp
(5)电阻r=1ω
(6)电感l=0.5h
我们希望控制器输入1v电压的时候稳定状态下保持0.1rad/sec的转速,稳定时间2s,稳态误差低于1%,受到阶跃输入干扰的时候超调小于5%。matlab的仿真并不像之前学习51的时候用的protuse一样,可以看到直观效果,matlab的仿真实际是对数学的计算过程,即输入与输出必须都抽象成函数表达式进行,通过观察输出的函数表达式与波形来判断系统的工作状态与性能。我们将上面得到的复频域下的函数表达式代入参数,得到
通过simulink创建仿真图如下图所示。
双击pid控制器的图标,打开了以下对话框。
对话框内的这三个参数就是pid控制器的三个参数,其中proportional代表比例环节,integral代表积分环节,derivative代表微分环节,通过修改这三个参数达到实现控制系统的目的。
在pid控制中,这三个参数分别对系统控制有以下几个作用:
(1)比例环节p:控制输出响应的速度,减小稳态误差,但是会增大超调量
(2)积分环节i:消除系统的稳态误差,加快达到稳定所需的时间,但也会增大超调量
(3)微分环节d:加快动态过程,容易引起系统震荡,同样,微分环节也会增大超调量
为了满足:
(1)稳定时间2s
(2)稳态误差低于1%
(3)超调小于5%
这三个条件,我们首先修改比例环节,用来满足稳态误差低于1%这个参数。通过实验发现,当比例环节设定在100以上的时候,稳态误差低于1%,如下图所示。
但是我们发现
即系统的超调量较大,达到了20%,此时需要调节微分环节达到目的,我们通过实验发现,当微分环节超过10时,系统的超调如下图所示。
此时系统已经不存在超调,现在只需要解决稳定时间小于2s这个参数即可,我们通过设置积分环节达到这个目的,通过实验发现,当系统的积分环节大于200时,稳定时间小于2s。此时整个系统的波形如下图所示。
自动往返的小车控制系统的编程实验
存储器行业发掘下一个增长点 国产存储主控厂商向车规进阶
广合科技为华勤计算事业部唯一PCB获奖供应商
索尼或公布小屏手机XperiaCompact系列 屏幕纵横比为21:9
采用人工智能技术实现构建智慧法院
什么是PID算法
虹科免拆诊断 | 2012 款奇瑞 A3 车发动机无法起动
MAX1470电路调整以及与天线的匹配
华为手表watch3-2599起,华为手表watch3价格-3299起
三星S8昨晚纽约发布,八大亮点为你解读三星S8系列
中国的无人机地位在全球是怎样的位置
风力发电机对蓄电池的充电电路设计
realme是如何成为全球增长的最快手机品牌?
TB5128FTG驱动芯片在家用电器中的应用与效果研究
中国芯如何突围?
基于BERT算法搭建一个问答搜索引擎
食品重金属检测仪的使用步骤
教你如何利用傅里叶变换干漂亮的事
AMD下个目标或瞄准工作站市场 目前局面对AMD十分有利
华为云数据库GaussDB:给世界一个更优选择