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

1、微分先行算法的思想

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

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

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

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

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

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

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

2、算法实现

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

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)增量型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-> lastDeltaPv

 vPID-> 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控制器开发笔记

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

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

  3. PID控制器开发笔记之十二:模糊PID控制器的实现

    在现实控制中,被控系统并非是线性时不变的,往往需要动态调整PID的参数,而模糊控制正好能够满足这一需求,所以在接下来的这一节我们将讨论模糊PID控制器的相关问题.模糊PID控制器是将模糊算法与PID控 ...

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

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

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

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

  6. PID控制器开发笔记之十一:专家PID控制器的实现

    前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...

  7. PID控制器开发笔记之十:步进式PID控制器的实现

    对于一般的PID控制系统来说,当设定值发生较大的突变时,很容易产生超调而使系统不稳定.为了解决这种阶跃变化造成的不利影响,人们发明了步进式PID控制算法. 1.步进式PID的基本思想 所谓步进式PID ...

  8. PID控制器开发笔记之九:基于前馈补偿的PID控制器的实现

    对于一般的时滞系统来说,设定值的变动会产生较大的滞后才能反映在被控变量上,从而产生合理的调节.而前馈控制系统是根据扰动或给定值的变化按补偿原理来工作的控制系统,其特点是当扰动产生后,被控变量还未变化以 ...

  9. PID控制器开发笔记之六:不完全微分PID控制器的实现

    从PID控制的基本原理我们知道,微分信号的引入可改善系统的动态特性,但也存在一个问题,那就是容易引进高频干扰,在偏差扰动突变时尤其显出微分项的不足.为了解决这个问题人们引入低通滤波方式来解决这一问题. ...

随机推荐

  1. 2016-2017-2 20155324实验二《Java面向对象程序设计》实验报告

    2016-2017-2 20155324实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...

  2. ARM核心板_迅为4418核心板_高稳定超轻薄_研发超灵感

    ARM核心板_迅为4418核心板_三星四核S5P4418处理器 4418核心板正面: 4418核心板反面:4418核心板尺寸图:详情了解:https://item.taobao.com/item.ht ...

  3. Kafka架构简介

    一.kafka的架构 1.Broker kafka集群包含一个或者多个服务器,这种服务器就叫做Broker 2.Topic 每条发布到kafka集群的消息都有一个类别,这个类别就叫做Topic(逻辑上 ...

  4. Python简介(2017-07-16)

    2017-07-15,这是我学习python的第一天. 首先,python是一门当下很火热的开发语言,它的创始人是Guido Van Rossum.就目前情况而言,python语言的热度持续上升,已经 ...

  5. 同步&异步+阻塞&非阻塞(理解)

    0 - 同步&异步 同步和异步关注的是消息通信机制. 0.1 - 同步 由“调用者”主动等待这个“调用”结果.即是,发出一个“调用”时,在没有得到结果之前,该“调用”不返回,一旦调用返回,则得 ...

  6. CentOS7开启防火墙及特定端口

    开启防火墙服务 以前为了方便,把防火墙都关闭了,因为现在项目都比较重要,害怕受到攻击,所以为了安全性,现在需要将防火墙开启,接下来介绍一下步骤. 1, 首先查看防火墙状态: firewall-cmd ...

  7. 【ARTS】01_14_左耳听风-20190211~20190217

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  8. 【转】python之配置日志的几种方式

    [转]python之配置日志的几种方式 作为开发者,我们可以通过以下3种方式来配置logging: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用 ...

  9. Python3-线程

    线程 什么是线程 线程的创建开销小 线程与进程的区别 为何要用多线程 多线程的应用举例 开启线程的两种方式 在一个进程下开启多个线程与在一个进程下开启多个子进程的区别 多线程并发的socket服务器 ...

  10. 【转】Linux查看系统是32位还是64位方法总结

    这篇博客是总结.归纳查看Linux系统是32位还是64位的一些方法,很多内容来自网上网友的博客.本篇只是整理.梳理这方面的知识,方便自己忘记的时候随时查看. 方法1:getconf LONG_BIT ...