zoukankan      html  css  js  c++  java
  • 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、总结

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

    欢迎关注:

  • 相关阅读:
    搞懂分布式技术30:高并发解决方案——提升高并发量服务器性能解决思路
    海量数据处理
    海量数据处理
    Linux虚拟机的三种网络连接方式
    一篇文章,读懂Netty的高性能架构之道
    MYCAT学习笔记
    Java网络编程和NIO详解开篇:Java网络编程基础
    Java网络编程和NIO详解8:浅析mmap和Direct Buffer
    apache 2.4.23 只能本地访问,其他用户不能访问,提示You don't have permission to access
    python数据分析及展示(三)
  • 原文地址:https://www.cnblogs.com/foxclever/p/9031556.html
Copyright © 2011-2022 走看看