前面已经实现了各种的PID算法,然而在某些给定值频繁且大幅变化的场合,微分项常常会引起系统的振荡。为了适应这种给定值频繁变化的场合,人们设计了微分先行算法。

1、微分先行算法的思想

微分先行PID控制是只对输出量进行微分,而对给定指令不起微分作用,因此它适合于给定指令频繁升降的场合,可以避免指令的改变导致超调过大。微分先行的基本结构图:

根据上面的结构图,我们可以推出PID控制器的输出公式,比例和积分是不变的只是微分部分变为只对对象输出积分,记为y,我们对微分部分引入一阶惯性滤波:,可记微分部分的传递函数如下:

于是微分部分可以推导出如下的公式:

前面我们在推导PID的公式时曾规定:Kd=Kp*Td/T,于是我们将其带入公式可得:

于是我们就可以得到微分先行的离散化公式:

这即是位置型PID的计算公式了,我们也可以使用前面的方法推导增量型的计算公式如下:

从上面的公式我们发现,微分部分只与测量值有关,而且与连续的几个测量值都有关。而与设定值没有关系,设定值的阶跃变化不会造成高频的干扰。

2、算法实现

前面我们已经简单的介绍了微分现行的基本结构,也推导了位置型以及增量型公式,接下来我们根据前面对其基本思想的描述,来实现基于微分先行的PID算法实现,同样是包括位置型和增量型两种实现方式。

2.1、位置型PID算法实现

关于微分先行PID算法的公式我们已经推导出来了,编码实现就是在公式的基础上将其计算机语言化。同样的,首先定义PID对象的结构体:

/*定义结构体和公用体*/
typedef struct
{float setpoint;       //设定值float proportiongain;     //比例系数float integralgain;      //积分系数float derivativegain;    //微分系数float lasterror;     //前一拍偏差float result;     //输出值float integral;   //积分值float derivative;      //微分项float lastPv;     //前一拍的测量值float gama;      //微分先行滤波系数
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{float thisError;float c1,c2,c3,temp;thisError=vPID->setpoint-processValue;vPID->integral+=thisError;temp=vPID-> gama * vPID-> derivativegain + vPID-> proportiongain;c3=vPID-> derivativegain/temp;c2=(vPID-> derivativegain+ vPID-> proportiongain)/temp;c1=vPID-> gama*c3;vPID-> derivative=c1* vPID-> derivative+c2*processValue+c3* vPID-> lastPv;vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivative;vPID->lasterror=thisError;vPID-> lastPv= processValue;
}

对于微分先行的位置型PID控制器来说,本次的微分项不仅与上一拍的微分结果有关,而且与上一拍的测量值有关。

2.2、增量型PID算法实现

微分先行增量型PID控制算法的实现就是以前面的增量型公式为基础。微分先行的比例与积分部分并没有什么变化,当然积分部分也可以采用各种优化算法。而微分部分以增量型公式实现即可,首先定义PID对象的结构体:

/*定义结构体和公用体*/
typedef struct
{float setpoint;       //设定值float proportiongain;     //比例系数float integralgain;      //积分系数float derivativegain;    //微分系数float lasterror;     //前一拍偏差float preerror;     //前两拍偏差float deadband;     //死区float result;      //输出值float deltadiff;              /*微分增量*/float integralValue;          /*积分累计量*/float gama;                   /*微分先行滤波系数*/float lastPv;                 /*上一拍的过程测量值*/float lastDeltaPv;            /*上一拍的过程测量值增量*/
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{float thisError;float increment;float pError,iError;float c1,c2,c3,temp;float deltaPv;temp=vPID-> gama * vPID-> derivativegain + vPID-> proportiongain;c3=vPID-> derivativegain/temp;c2=(vPID-> derivativegain+ vPID-> proportiongain)/temp;c1=vPID-> gama*c3;deltaPv=processValue- vPID-> lastDeltaPvvPID-> deltadiff =c1* vPID-> deltadiff +c2*deltaPv +c3* vPID-> lastDeltaPv;thisError=vPID->setpoint-processValue; //得到偏差值pError=thisError-vPID->lasterror;iError=thisError;increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID-> deltadiff;   //增量计算vPID->preerror=vPID->lasterror; //存放偏差用于下次运算vPID->lastDeltaPv=deltaPv;vPID->lastPv= processValue;vPID->lasterror=thisError;vPID->result+=increment;
}

这就实现了一个最简单的微分先行的增量型PID控制器,与一般的PID控制器相比,还需要知道前一拍的测量值、前一拍的测量值增值以及前一拍的微分增量,其余的只需要按公式完成即可。

3、总结

微分先行由于微分部分只对测量值起作用所以可以消除设定值突变的影响,还可以引入低通滤波,甚至在必要时将比例作用也可进行相应的改进。其实用于设定值会频繁改变的过程对象,防止设定值的频繁波动造成系统的不稳定。该控制对于改善系统的动态特性是有好处的,但势必影响响应的速度,需全面考虑。

欢迎关注:

PID控制器开发笔记之七:微分先行PID控制器的实现相关推荐

  1. PID控制器改进笔记之七:改进PID控制器之防超调设定

      我们已经设计了PID控制器,并根据实际使用的情况对器进行了诸多的改进.在这一篇中我们将讨论如何改进PID控制器超调的问题. 1.问题提出   在前面的文章中,我们曾推导过增量式PID控制器的公式, ...

  2. 微分先行PID控制器的实现

    理论部分参考:https://blog.csdn.net/foxclever/article/details/80633275 这里附上写的matlab程序: clear all; close all ...

  3. PID控制器开发笔记(转)

    源: PID控制器开发笔记 转载于:https://www.cnblogs.com/LittleTiger/p/10499701.html

  4. 微分先行PID控制算法用C语言实现!

    1.微分先行PID控制算法框图 2.微分先行PID控制算法公式 3.微分先行PID控制公式用C语言实现 微分先行的PID算法实现,包括位置型和增量型两种实现方式. (1)位置型 void PIDReg ...

  5. 微分先行PID控制算法

    微分先行PID控制算法 微分先行PID控制算法: 注:本文内容摘自<先进PID控制MATLAB仿真(第4版)>刘金琨 编著,研读此书受益匪浅,感谢作者! 微分先行PID控制算法: 微分先行 ...

  6. 用matlab微分先行设计,基于MATLAB的微分先行PID控制的设计与仿真

    第 34卷 第 1期 2014 年 1月 高 师 理 科 学 刊 Journal of Science of Teachers College and University Vo1.34 No.1 J ...

  7. Is620伺服驱动电机 伺服控制器开发设计方案成熟量产伺服控制器方案

    伺服控制器开发设计方案成熟量产伺服控制器方案 Is620伺服驱动电机,提供DSP程序和原理图,代码完整,学习工业代码的范例,采用ES232,RS485及CAN通讯接口处提供刚性表设置,惯性识别及振动抑 ...

  8. PID控制器开发笔记之十三:单神经元PID控制器的实现

    神经网络是模拟人脑思维方式的数学模型.神经网络是智能控制的一个重要分支,人们针对控制过程提供了各种实现方式,在本节我们主要讨论一下采用单神经元实现PID控制器的方式. 1.单神经元的基本原理 单神经元 ...

  9. PID控制器开发笔记之八:带死区的PID控制器的实现

    在计算机控制系统中,由于系统特性和计算精度等问题,致使系统偏差总是存在,系统总是频繁动作不能稳定.为了解决这种情况,我们可以引入带死区的PID算法. 1.带死区PID的基本思想 带死区的PID控制算法 ...

最新文章

  1. BZOJ 1036 [ZJOI2008]树的统计Count
  2. python numba jit加速使用方法
  3. 查看redhat版本信息
  4. 你是个失败者,有什么资格说话?
  5. HTML语义化的理解
  6. mysql的搜索效率_Mysql模糊查询like效率,以及更高效的写法
  7. Bailian4108 羚羊数量-Number Of Antelope【递推+打表】
  8. CSS进阶(15)—— CSS世界的层叠规则(上)
  9. 计算机windows错误恢复,为什么windows错误恢复?
  10. 微信亲戚备注分组名称_【微信分组备注名称大全】qq分组备注名称大全
  11. linux怎么进入系统安装界面,Linux图形化界面安装全过程
  12. java去除中文括号小括号,或者英文括号
  13. 计算机快捷键m是什么,电脑常用快捷键有哪些
  14. python图像纹理提取_提取图像的颜色、纹理特征(传统算法)
  15. 第六章、FOR、IF和while
  16. ORA-01122 ORA-01110 ORA-01200
  17. basler 虚拟相机的使用
  18. Linner和WebStorm前端开发环境搭建
  19. 使用微信开放标签<wx-open-launch-weapp>的踩坑日记
  20. 牛客-taotao要吃鸡

热门文章

  1. 【Java】函数式编程
  2. 【LeetCode】3月28日打卡-Day13
  3. 斯坦福大学CS520知识图谱系列课程学习笔记:第二讲如何构建知识图谱
  4. Web高效管理多个项目的SVN仓库
  5. K8s遇到问题解决思路
  6. Gradle 下载不了
  7. php类中双冒号和-的区别
  8. 防止表单按钮多次提交
  9. spring基础整理
  10. Log4Net 全方位跟踪程序运行