• PID控制器开发笔记之四:梯形积分PID控制器的实现


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

    1、梯形积分基本思路

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

     

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

     

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

     

    2、算法实现

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

    1)位置型PID算法实现

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

     1 /*定义结构体和公用体*/
     2 
     3 typedef struct
     4 
     5 {
     6 
     7   float setpoint;       //设定值
     8 
     9   float proportiongain;     //比例系数
    10 
    11   float integralgain;      //积分系数
    12 
    13   float derivativegain;    //微分系数
    14 
    15   float lasterror;     //前一拍偏差
    16 
    17   float result; //输出值
    18 
    19   float integral;//积分值
    20 
    21 }PID;

    接下来实现PID控制器:

     1 void PIDRegulation(PID *vPID, float processValue)
     2 
     3 {
     4 
     5   float thisError;
     6 
     7  
     8 
     9   thisError=vPID->setpoint-processValue;
    10 
    11   vPID->integral+=(thisError+ vPID-> lasterror)/2;
    12 
    13   vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);
    14 
    15   vPID->lasterror=thisError;
    16 
    17 }

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

    2)增量型PID算法实现

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

     1 /*定义结构体和公用体*/
     2 
     3 typedef struct
     4 
     5 {
     6 
     7   float setpoint;       //设定值
     8 
     9   float proportiongain;     //比例系数
    10 
    11   float integralgain;      //积分系数
    12 
    13   float derivativegain;    //微分系数
    14 
    15   float lasterror;     //前一拍偏差
    16 
    17   float preerror;     //前两拍偏差
    18 
    19   float deadband;     //死区
    20 
    21   float result; //输出值
    22 
    23 }PID;

    接下来实现PID控制器:

     1 void PIDRegulation(PID *vPID, float processValue)
     2 
     3 {
     4 
     5   float thisError;
     6 
     7   float increment;
     8 
     9   float pError,dError,iError;
    10 
    11  
    12 
    13   thisError=vPID->setpoint-processValue; //得到偏差值
    14 
    15   pError=thisError-vPID->lasterror;
    16 
    17   iError=(thisError+ vPID-> lasterror)/2;
    18 
    19   dError=thisError-2*(vPID->lasterror)+vPID->preerror;
    20 
    21   increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量计算
    22 
    23  
    24 
    25   vPID->preerror=vPID->lasterror;  //存放偏差用于下次运算
    26 
    27   vPID->lasterror=thisError;
    28 
    29   vPID->result+=increment;
    30 
    31 }

    3、总结

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

    欢迎关注:

  • 相关阅读:
    洛谷 P1383 高级打字机==codevs 3333 高级打字机
    洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]
    洛谷P2668 斗地主==codevs 4610 斗地主[NOIP 2015 day1 T3]
    poj1426
    3049 舞蹈家怀特先生
    1444 “破锣摇滚”乐队
    cocos2d-x开发的《派对小游戏》-github源代码分享
    【c语言】字符串替换空格:请实现一个函数,把字符串中的每一个空格替换成“%20”
    CAP理论与HBase
    也谈以人为本—— 服务型企业的管理随想
  • 原文地址:https://www.cnblogs.com/foxclever/p/9031556.html
Copyright © 2020-2023  润新知