ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

增量型pid

2021-01-21 13:05:03  阅读:227  来源: 互联网

标签:偏差 err pid float PID 增量


PID算法的离散化

论述了PID算法的基本形式,并对其控制过程的实现有了一个简要的说明,通过上一节的总结,基本已经可以明白PID控制的过程。这一节中先继续上一节内容补充说明一下。

   1.说明一下反馈控制的原理,通过上一节的框图不难看出,PID控制其实是对偏差的控制过程;

   2.如果偏差为0,则比例环节不起作用,只有存在偏差时,比例环节才起作用。

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

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

   好了,关于PID的基本说明就补充到这里,下面将对PID连续系统离散化,从而方便在处理器上实现。下面把连续状态的公式再贴一下:

 

假设采样间隔为T,则在第K个 T时刻:

偏差err(K)=rin(K)-rout(K);

积分环节用加和的形式表示,即err(K)+err(K+1)+……;

微分环节用斜率的形式表示,即[err(K)-err(K-1)]/T;

从而形成如下PID离散表示形式:

 

 

 其中T为采样时间,Kp为比例带,TI为积分时间,TD为微分时间。PID控制的基本原理就是如此。

则u(K)可表示成为:位置型PID

 

可以这么理解:比例环节将误差线性放大,积分环节将误差值的积分放大,微分环节将两次的误差值放大,所有的值相加得到最终输出值

在不断变化中,err(k)(设定值与实际输出值差值)会降低或者升高,不断降低时比例和微分环节对最终的输出贡献变少而积分环节因为误差值的不断累加贡献最大。

至于说Kp、Ki、Kd三个参数的具体表达式,我想可以轻松的推出了,这里节省时间,不再详细表示了。

其实到这里为止,PID的基本离散表示形式已经出来了。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由上述表达式可以轻易得到:增量式PID

 

那么:

 

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

       u(K)+增量调节值;

PID的离散化过程基本思路就是这样,下面是将离散化的公式转换成为C语言,从而实现微控制器的控制作用。

当然,增量型PID必须记得一点,就是在记住U(k)=U(k-1)+∆U(k)。

 

 PID 控制算法可以分为位置式 PID 和增量式 PID 控制算法。

两者的区别:

(1)位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大;

(2)增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。

(3)由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。

 

增量型PID的C语言实现

   上一节中介绍了最简单的位置型PID的实现手段,这一节主要讲解增量式PID的实现方法,位置型和增量型PID的数学公式请参见我的系列文《PID控制算法的C语言实现二》中的讲解。实现过程仍然是分为定义变量、初始化变量、实现控制算法函数、算法测试四个部分,详细分类请参加《PID控制算法的C语言实现三》中的讲解,这里直接给出代码了。

1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 struct _pid{
 5     float SetSpeed;            //定义设定值
 6     float ActualSpeed;        //定义实际值
 7     float err;                //定义偏差值
 8     float err_next;            //定义上一个偏差值
 9     float err_last;            //定义最上前的偏差值
10     float Kp,Ki,Kd;            //定义比例、积分、微分系数
11 }pid;
12 
13 void PID_init(){
14     pid.SetSpeed=0.0;
15     pid.ActualSpeed=0.0;
16     pid.err=0.0;
17     pid.err_last=0.0;
18     pid.err_next=0.0;
19     pid.Kp=0.2;
20     pid.Ki=0.015;
21     pid.Kd=0.2;
22 }
23 
24 float PID_realize(float speed){
25     pid.SetSpeed=speed;
26     pid.err=pid.SetSpeed-pid.ActualSpeed;
27     float incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);
28     pid.ActualSpeed+=incrementSpeed;
29     pid.err_last=pid.err_next;
30     pid.err_next=pid.err;
31     return pid.ActualSpeed;
32 }
33 
34 int main(){
35     PID_init();
36     int count=0;
37     while(count<1000)
38     {
39         float speed=PID_realize(200.0);
40         printf("%f\n",speed);
41         count++;
42     }
43     return 0;
44 }

运行后的1000个数据为:(结果自行运行观看)

结论:从最终数据的结果显示来看,增量式PID数据的稳定性要好于位置型PID的;

 

标签:偏差,err,pid,float,PID,增量
来源: https://www.cnblogs.com/zhj88/p/14307385.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有