工控课堂

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

工控课堂 首页 工控文库 智能控制 查看内容

PID控制算法一勺烩从模型到实现再到口诀

2018-12-16 16:51| 发布者: gk-auto| 查看: 44| 评论: 0|原作者: mini0427

摘要: 一、PID的数学模型 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的 ...

一、PID的数学模型

在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在很多控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的。PID算法的一般形式:
Zp98An4LwL4p4tJw.jpg



PID算法通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻):
1.
输入量为
hn7X1b441MO0Z0O4.jpg


2.输出量为VMmyrj6Uf0qjuJZ8.jpg


3.偏差量为 JdGUucbg9934Iu3p.jpg

fzHJpP22j2222009.jpg

二、PID算法的数字离散化
假设采样间隔为T,则在第K个T时刻:
偏差= il146G6ge16k66l6.jpg


积分环节用加和的形式表示,即 Q11BnN41Wb33Yx9O.jpg


微分环节用斜率的形式表示,即Odyk5J4qnyYjxn48.jpg


PID算法离散化后的式子:
lLEEpQG14Rh1IdCv.jpg


则可表示成为:
qwqf91z90LQLxl31.jpg


其中式中:


比例参数VmBQ1oMoW2BDnZ7f.jpg控制器的输出与输入偏差值成比例关系。系统一旦出现偏差,比例调节立即产生调节作用以减少偏差。特点:过程简单快速、比例作用大,可以加快调节,减小误差;但是使系统稳定性下降,造成不稳定,有余差。


积分参数tVS9DAXDe9E33v97.jpg积分环节主要是用来消除静差,所谓静差,就是系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原有系统上以抵消系统造成的静差。


微分参数gVR2xPA9rI4P4h0Z.jpg微分信号则反应了偏差信号的变化规律,或者说是变化趋势,根据偏差信号的变化趋势来进行超前调节,从而增加了系统的快速性。


PID的基本离散表示形式如上。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由上述表达式可以轻易得到:
X8oL1SdO580c13zz.jpg


那么:
F2qq5plfKqQHzQuK.jpg


上式就是离散化PID的增量式表示方式,由公式可以看出,增量式的表达结果和最近三次的偏差有关,这样就大大提高了系统的稳定性。需要注意的是最终的输出结果应该为:
输出量 = kFK22z283tMW2G22.jpg+ 增量调节值


三、PID的C语言实现
1.位置式PID的C语言实现
上边已经抽象出了位置性PID和增量型PID的数学表达式,这里重点讲解C语言代码的实现过程。


第一步:定义PID变量结构体,代码如下:
struct t_pid{
    float SetSpeed;         //定义设定值
    float ActualSpeed;       //定义实际值
    float err;            //定义偏差值
    float err_last;         //定义上一个偏差值
    float Kp,Ki,Kd;         //定义比例、积分、微分系数
    float voltage;         //定义电压值(控制执行器的变量)
    float integral;         //定义积分值
}pid;


第二部:初始化变量,代码如下:
void PID_init(){
    pid.SetSpeed=0.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.Ki=0.015;
    pid.Kd=0.2;
}
统一初始化变量,尤其是Kp,Ki,Kd三个参数,调试过程当中,对于要求的控制效果,可以通过调节这三个量直接进行调节。


第三步:编写控制算法,代码如下:
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;
}
注意:这里用了最基本的算法实现形式,没有考虑死区问题,没有设定上下限,只是对公式的一种直接的实现,后面的介绍当中还会逐渐的对此改进。
   
到此为止,PID的基本实现部分就初步完成了。下面是测试代码:
int main(){
    PID_init();
    int count=0;
    while(countumax,则只累加负偏差; 如果u(k-1)pid.umax)  //灰色底色表示抗积分饱和的实现
    {
       if(abs(pid.err)>200)      //蓝色标注为积分分离过程
        {
            index=0;
        }else{
            index=1;
            if(pid.err0)
            {
            pid.integral+=pid.err;
            }
        }
    }else{
        if(abs(pid.err)>200)                 //积分分离过程
        {
            index=0;
        }else{
            index=1;
            pid.integral+=pid.err;
        }
    }
    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;
}

5.梯形积分的PID控制算法
先看一下梯形算法的积分环节公式

MtTdQPjQD1TDmTgn.jpg
作为PID控制律的积分项,其作用是消除余差,为了尽量减小余差,应提高积分项运算精度,为此可以将矩形积分改为梯形积分,具体实现的语句为:
pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last);  //梯形积分


6.变积分的PID控制算法
变积分PID可以看成是积分分离的PID算法的更一般的形式。在普通的PID控制算法中,由于积分系数是常数,所以在整个控制过程中,积分增量是不变的。但是,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。因此,根据系统的偏差大小改变积分速度是有必要的。
   
变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。
   
这里给积分系数前加上一个比例值index:  

当abs(err)0时,说明误差在朝向误差绝对值增大的方向变化,此时,如果abs(e)>Mmid,说明误差也较大,可考虑由控制器实施较强的控制作用,以达到扭转误差绝对值向减小的方向变化,并迅速减小误差的绝对值。此时如果abs(e)

路过

雷人

握手

鲜花

鸡蛋

相关阅读

最新评论

QQ|免责声明|本站介绍|工控课堂 ( 沪ICP备14007696号-3 )|网站地图

GMT+8, 2019-3-21 23:26 , Processed in 0.030207 second(s), 29 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

返回顶部