前面的文章中,我们已经讲述了PID控制器的实现,包括位置型PID控制器和增量型PID控制器。但这个实现只是最基本的实现,并没有考虑任何的干扰情况。在本节及后续的一些章节,我们就来讨论一下经典PID控制器的优化与改进。这一节我们首先来讨论针对积分项的积分分离优化算法。

1、基本思想

我们已经讲述了PID控制引入积分主要是为了消除静差,提高控制精度。但在过程的启动、结束或大幅度增减设定值时,短时间内系统输出有很大偏差,会造成PID运算的积分累积,引起超调或者振荡。为了解决这一干扰,人们引入了积分分离的思想。其思路是偏差值较大时,取消积分作用,以免于超调量增大;而偏差值较小时,引入积分作用,以便消除静差,提高控制精度。

具体的实现步骤是:根据实际情况,设定一个阈值;当偏差大于阈值时,消除积分仅用PD控制;当偏差小于等于阈值时,引入积分采用PID控制。则控制算法可表示为:

其中β称为积分开关系数,其取值范围为:

由上述表述及公式我们可以知道,积分分离算法的效果其实与ε值的选取有莫大关系,所以ε值的选取实际上是实现的难点,ε值过大则达不到积分分离的效果,而ε值过小则难以进入积分区,ε值的选取存在很大的主观因素。

对于经典的增量式PID算法,似乎没有办法由以上的公式推导而来,因为β随着err(k)的变化在不是修改着控制器的表达式。其实我们可以换一种角度考虑,每次系统调节未定后,偏差应该为零,然后只有当设定值改变时,系统才会响应而开始调节。设定值的改变实际上是一个阶跃变化,此时的控制输出记为U0,开始调节时,其调节增量其实与之前的一切没有关系。所以我们就可以以变化时刻开始为起点,而得到带积分分离的增量算法,以保证在启动、停止和快速变化时防止超调。公式如下:

其中β的取值与位置型PID算法一致。可能有人会担心偏差来回变化,造成积分作用的频繁分离和引入,进而使上述的增量表达式无法实现。其实我们分析一下就能发现,在开始时,由于设定值变化引起的偏差大而分离了积分作用,在接近设定值时,偏差变小就引入了积分,一边消除静差,而后处于稳态,直到下一次变化。

2、算法实现

这一部分,我们根据前面对其基本思想的描述,来实现基于积分分离的PID算法实现,同样是包括位置型和增量型两种实现方式。首先我们来看一下算法的实现过程,具体的流程图如下:

有上图我们知道,与普通的PID算法的区别,只是判断偏差的大小,偏差大时,为PD算法,偏差小时为PID算法。于是我们需要一个偏差检测与积分项分离系数β的函数。

static uint16_t BetaGeneration(float error,float epsilon)
{uint16_t beta=0;if(abs(error)<= epsilon)
{beta=1;
}return beta;}

2.1、位置型PID算法实现

根据前面的分析我们可以很轻松的编写程序,只需要在编写程序时判断偏差以确定是否引入积分项就可以了。同样先定义PID对象的结构体:

/*定义结构体和公用体*/
typedef struct
{floatsetpoint;       //设定值floatproportiongain;     //比例系数floatintegralgain;      //积分系数floatderivativegain;    //微分系数floatlasterror;     //前一拍偏差floatresult; //输出值floatintegral;//积分值float epsilon; //偏差检测阈值
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{floatthisError;thisError=vPID->setpoint-processValue;vPID->integral+=thisError;uint16_tbeta= BetaGeneration(error,vPID->epsilon);if(beta>0)
{vPID->result=vPID->proportiongain*thisError+vPID->derivativegain*(thisError-vPID->lasterror);
}
else
{
vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);
}vPID->lasterror=thisError;}

与普通的PID算法的区别就是上述代码中增加了偏差判断,来决定积分项的分离与否。

2.2、增量型PID算法实现

对于增量型PID控制,我们也可以采取相同的处理。首先定义PID对象的结构体:

/*定义结构体和公用体*/
typedef struct
{floatsetpoint;       //设定值floatproportiongain;     //比例系数floatintegralgain;      //积分系数floatderivativegain;    //微分系数floatlasterror;     //前一拍偏差floatpreerror;     //前两拍偏差floatdeadband;     //死区floatresult; //输出值float epsilon; //偏差检测阈值
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{floatthisError;floatincrement;floatpError,dError,iError;thisError=vPID->setpoint-processValue; //得到偏差值pError=thisError-vPID->lasterror;iError=thisError;dError=thisError-2*(vPID->lasterror)+vPID->preerror;uint16_tbeta= BetaGeneration(error,vPID->epsilon);if(beta>0)
{
increment=vPID->proportiongain*pError+vPID->derivativegain*dError;   //增量计算
}
else
{
increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量计算
}vPID->preerror=vPID->lasterror; //存放偏差用于下次运算vPID->lasterror=thisError;vPID->result+=increment;
}

这就实现了增量型PID控制器积分分离算法,也没有考虑任何的干扰条件,仅仅只是对数学公式的计算机语言化。

3、总结

积分分离算法的思想非常简单。当然,对于β的取值,很多人提出了改进措施,例如分多段取值,设定多个阈值ε1、ε2、ε3、ε4等,不过这些阈值也需要根据实际的系统来设定。除了分段取值外,甚至也有采用函数关系来获取β值。当然,这样处理后就不再是简单的积分分离了,特别是在增量型算法中,实际上已经演变为一种变积分算法了。已经偏离了积分分离算法的设计思想,在后面我们会进一步说明。

欢迎关注:

PID控制器开发笔记之二:积分分离PID控制器的实现相关推荐

  1. PID控制器改进笔记之二:改进PID控制器之手自动切换

    前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器.这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性 ...

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

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

  3. PID控制器开发笔记之七:微分先行PID控制器的实现

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

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

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

  5. ATECC508A芯片开发笔记(二):开发准备之 CryptoAuthLib 库简介与移植

    目录 ATECC508A芯片开发笔记(二):开发准备之 CryptoAuthLib 库简介与移植 Atmel两个官方lib介绍 一.CryptoAuthLib简介 Lib中最主要的三种对象类型: 二. ...

  6. 运维开发笔记整理-前后端分离

    运维开发笔记整理-前后端分离 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么要进行前后端分离 1>.pc, app, pad多端适应 2>.SPA开发式的流 ...

  7. 积分分离PID控制算法

    积分分离PID控制算法 积分分离PID控制: 积分分离控制基本思路: 积分分离控制算法表示: 积分分离式PID控制算法程序流程图: 注:本文内容摘自<先进PID控制MATLAB仿真(第4版)&g ...

  8. Android开发笔记(二十七)对象序列化

    什么是序列化 程序中存储和传递信息,需要有个合适的数据结构,最简单的是定义几个变量,变量多了之后再分门别类,便成了聚合若干变量的对象.代码在函数调用时可以直接传递对象,但更多的场合例如与文件交互.与网 ...

  9. Android开发笔记(二十四)res目录的结构与配置

    res目录结构 res是Android项目工程中存放各类的目录,主要包括布局.图形与配置等等.res的子目录主要有: anim : 存放动画的描述文件 drawable : 存放各类图形的描述文件,包 ...

最新文章

  1. 一个网站项目的开始,定位有多重要?
  2. 可视化的数据结构和算法
  3. 后缀数组--(可重叠最长重复子串问题)
  4. Effective Java之用私有构造器或者枚举类型强化Singleton属性(三)
  5. SAP ABAP Netweaver和Hybris Commerce的部署策略
  6. 漫谈高数——泰勒级数的物理意义
  7. LInux下du, df, top, free, pstack, su, sudo, adduser, password命令
  8. c++ array stl_C ++ STL中带有示例的array :: front()函数
  9. 【实用工具】交叉编译android版本的GDB
  10. AAC Explicit or Implicit SBR PS issue
  11. 移动端 H5图片裁剪插件,内置简单手势操作
  12. 第5 章 引用类型2
  13. 计算机蓝屏原因原理,蓝屏炸弹
  14. android红米升级失败怎么办,红米刷机失败怎么办?解决红米刷机失败教程
  15. 离线脱机版个人笔记软件的选择
  16. ATECC508A芯片开发笔记(一):初识加密芯片
  17. 大厂软件测试流程完整版
  18. 10-STM32F1-RTC and BKP
  19. 服装行业要渡“疫情劫”,赢家时尚凭什么成为增长样本?
  20. 关于导入.a文件后报错Undefined symbols for architecture arm64:

热门文章

  1. MongoDB:SpringBoot有关@Document(collection = )与@Document(collation= )注解的区别
  2. SSM:web目录下有的jsp和图片不能显示,有的可以显示的解决方法
  3. LR中url和html两种录制模式
  4. CORS预检请求详谈
  5. WebService初入
  6. 【VS开发】CTimeSpan类
  7. [Mac]Python 安装MySQLdb模块
  8. atitit.动态加载数据库配置in orm hibernate mybatis
  9. linux怎么抓sip包,Ubuntu下使用Wireshark进行抓包分析(含SIP和RTP包)
  10. php自定义商品属性,php – 可变产品属性:自定义每个显示的单选按钮文本值