Chinaunix首页 | 论坛 | 博客
  • 博客访问: 646910
  • 博文数量: 194
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 884
  • 用 户 组: 普通用户
  • 注册时间: 2015-09-21 16:48
文章分类

全部博文(194)

文章存档

2023年(1)

2022年(3)

2021年(16)

2020年(4)

2019年(5)

2018年(10)

2017年(72)

2016年(36)

2015年(47)

我的朋友

分类: 嵌入式

2021-09-24 14:26:56

转:https://www.cnblogs.com/foxclever/p/9031556.html

从微积分的基本原理看,积分的实现是在无限细分的情况下进行的矩形加和计算。但是在离散状态下,时间间隔已经足够大,矩形积分在某些时候显得精度要低了一些,于是梯形积分被提出来以提升积分精度。

1、梯形积分基本思路

在PID控制其中,积分项的作用是消除余差,为了尽量减小余差,应提高积分项的运算精度。在积分项中,默认是按矩形方式来计算积分,将矩形积分改为梯形积分可以提高运算精度。其计算公式为:

于是如果在位置型PID算法中引入梯形积分则可以修改计算公式如下:

 

同样要在增量型PID算法中引入梯形积分则可以修改计算公式如下:

 

2、算法实现

从微积分的角度来说,当微分分到无限小时,矩形积分与梯形积分是没有区别的。但事实上我们的采样时间不可能无限小,而且也不可能是连续的,那么采样周期越大,那么矩形近似于实际曲线间的偏差就越大,而梯形积分则可以更加接近实际曲线,所以采用梯形积分代替矩形积分就可以得到更高的精度。

1)位置型PID算法实现

位置型PID的实现在前面就已经完成,所不同的是前面使用的是矩形积分,在这一节我们将举行积分部分改为梯形积分,同样首先定义PID对象的结构体:

点击(此处)折叠或打开

  1. /*定义结构体和公用体*/
  2. typedef struct
  3. {
  4.   float setpoint; //设定值
  5.   float proportiongain; //比例系数
  6.   float integralgain; //积分系数
  7.   float derivativegain; //微分系数
  8.   float lasterror; //前一拍偏差
  9.   float result; //输出值
  10.   float integral;//积分值
  11. }PID;
接下来实现PID控制器:

点击(此处)折叠或打开

  1. void PIDRegulation(PID *vPID, float processValue)
  2. {
  3.   float thisError;

  4.   thisError=vPID->setpoint-processValue;
  5.   vPID->integral+=(thisError+ vPID-> lasterror)/2;
  6.   vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);

  7.   vPID->lasterror=thisError;
  8. }


从上述实现我们不难看出,变化仅仅只是在做积分累计vPID->integral时,将累计量按梯形方式累计。

2)增量型PID算法实现

同样的增量型PID的梯形积分实现也就是即将积分部分有矩形积分部分换成梯形积分即可。首先定义PID对象的结构体:

点击(此处)折叠或打开

  1. /*定义结构体和公用体*/
  2. typedef struct
  3. {
  4.   float setpoint; //设定值
  5.   float proportiongain; //比例系数
  6.   float integralgain; //积分系数
  7.   float derivativegain; //微分系数
  8.   float lasterror; //前一拍偏差
  9.   float preerror; //前两拍偏差
  10.   float deadband; //死区
  11.   float result; //输出值
  12. }PID;
接下来实现PID控制器:

点击(此处)折叠或打开

  1. void PIDRegulation(PID *vPID, float processValue)
  2. {
  3.   float thisError;
  4.   float increment;
  5.   float pError,dError,iError;

  6.   thisError=vPID->setpoint-processValue; //得到偏差值
  7.   pError=thisError-vPID->lasterror;
  8.   iError=(thisError+ vPID-> lasterror)/2;
  9.   dError=thisError-2*(vPID->lasterror)+vPID->preerror;
  10.   increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError; //增量计算

  11.   vPID->preerror=vPID->lasterror; //存放偏差用于下次运算
  12.   vPID->lasterror=thisError;
  13.   vPID->result+=increment;
  14. }

3、总结

积分项的引入目的就是为了消除系统的余差,那么积分项的计算精度越高,对消除系统的余差就越有利。梯形积分相较于矩形积分其精度有比较大的提高,所以对消除余差也就越有效。



阅读(610) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~