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

  我们已经设计了PID控制器,并根据实际使用的情况对器进行了诸多的改进。在这一篇中我们将讨论如何改进PID控制器超调的问题。

1、问题提出

  在前面的文章中,我们曾推导过增量式PID控制器的公式,并且对其进行了离散化以适用于程序实现,具体的离散化公式如下:

  以这个公式为基础,我们实现的增量式PID控制器,只需要根据偏差计算增量并调整输出就能实现自动调节了。但是我们分析一下就会发现,如果参数设置的不合适,或者偏差的数值比较大,那么计算得到的增量值就会很大,这样输出的变化就会很大,这种情况下就容易出现超调的问题。
超调一旦出现,可能需要较长时间才能让系统稳定,严重的甚至会造成振荡。这自然不是我们想要的结果,所以我们希望PID控制器具有能够防止超调能力。

2、分析设计

  关于超调这个问题,我们先来分析一下什么因素能够造成超调。所谓超调我们可以理解为过度的调整反而造成了系统的不稳定。那究竟哪些情况会造成过度调整呢?一般来讲过于频繁的调节、输入信号的突然大幅度变化、输出信号的陡变以及被控对象的特性。
  对于上述情况我们来逐一分析一下应对办法。首先是过于频繁的调节,很多时候我们可能觉得调节的快可以加快系统的响应。但实际上与系统本身的特性有关。如果系统不存在滞后或者滞后的特性很小,自然是没有问题的。但很多时候,系统会存在比较大的滞后特性,那么过于频繁的调节就会快速累积输出控制从而产生超调。这种情况下我们可以增大调节周期来稳定系统。
  其次我们来看输入信号的突然大幅度变化的影响。我们这里所说的输入信号是指PID控制器的设定值。在一个稳定系统中,大幅度改变设定值会使偏差急剧增大,而大的偏差往往会造成控制器的输出快速累积,这种快速累积往往就会造成超调。这种情况下,我们可以控制设定值的变化速度来改善。一般让设定值线性缓慢变化,至于步进值则可根据系统的特性调整。
  再来看看输出信号的陡变的影响,有些时候因为参数设置与系统的匹配问题,即使偏差变化不大输出的变化也会很大。这个时候控制变量会因此而产生较大变化,这一变化会增大偏差,进一步影响输出,如此循环累积就可能产生超调。特别是一些反应比较快的系统更容易出现这种情况。一般我们可以通过限制输出的变化来防止这种现象。
  而被控对象的特性主要表现在系统的滞后特性方面,一般来说越是滞后的系统越不容易调稳,也越是容易出现超调甚至振荡。应对这一情况一般也可以采用减缓调节的方式来调整。具体方式也是前面的三种。

3、软件实现

  我们已经分析了产生超调的主要原因以及应对的办法,接下来我们就来考虑怎么改进PID控制器以达到防超调的效果。针对前述提到的几种情况我们来分别设计软件上的实现方式。
  对于调节相对频繁的问题,我们的PID控制器设计时就已考虑到采样周期是可调整的,所以我们只需根据不同的被控对象来适当地调整它就好了。而对于设定值的大幅度突变和调节输出的陡变两种情况,我们引入两个参数,一个参数用于开关设定值时平滑处理功能,一个参数用于设置输出增量限幅功能的开关。我们采用两个枚举来实现这一功能,具体定义如下:

/*定义设定值平滑枚举类型*/
typedef enum ClassicPIDSM{SMOOTH_DISABLE,       //不启用设定值平滑SMOOTH_ENABLE         //启用设定值平滑
}ClassicPIDSMType;/*定义防止输出陡变的枚举*/
typedef enum ClassicPIDPAC{PREVENT_ABRUPT_DISABLE,       //不启用输出防陡变PREVENT_ABRUPT_ENABLE         //启用输出防陡变
}ClassicPIDPACType;

  同样的我们需要在PID对象类型中增加相应的属性。我们为PID控制器对象类型添加设定值平滑参数以及输出增量限幅参数,所以我们实现PID控制器的对象类型定义如下:

/*定义PID对象类型*/
typedef struct CLASSIC
{float *pPV;                   //测量值指针float *pSV;                   //设定值指针float *pMV;                   //输出值指针uint16_t *pMA;               //手自动操作指针#if PID_PARAMETER_STYLE > (0)float *pKp;                   //比例系数指针float *pKi;                   //积分系数指针float *pKd;                   //微分系数指针
#elsefloat *pPb;                   //比例带float *pTi;                   //积分时间,单位为秒float *pTd;                   //微分时间,单位为秒float ts;                     //采样周期,单位为秒
#endiffloat setpoint;               //设定值float lasterror;              //前一拍偏差float preerror;               //前两拍偏差float deadband;               //死区float result;                 //PID控制器计算结果float output;                 //输出值0-100%float maximum;                //输出值上限float minimum;                //输出值下限float errorabsmax;            //偏差绝对值最大值float errorabsmin;            //偏差绝对值最小值float alpha;                  //不完全微分系数float deltadiff;              //微分增量float integralValue;          //积分累计量float gama;                   //微分先行滤波系数float lastPv;                 //上一拍的过程测量值float lastDeltaPv;            //上一拍的过程测量值增量ClassicPIDDRType direct;      //正反作用ClassicPIDSMType sm;          //设定值平滑ClassicPIDCSType cas;         //串级设定ClassicPIDPACType pac;        //输出防陡变
}CLASSICPID;

  修改了PID控制器对象的定义,我们还需要对PID控制器做必要的改进。我们添加设定值平滑操作,并通过设置参数sm来控制是否启用该操作。我们添加输出防陡变的操作,并通过配置参数pac来决定是否启用。具体实现如下:

void PIDRegulator(CLASSICPID *vPID)
{float thisError;float result;float factor;float increment;float pError,dError,iError;float kp,ki,kd;#if PID_PARAMETER_STYLE > (0)kp=*vPID->pKp;ki=*vPID->pKi;kd=*vPID->pKd;
#elseif((*vPID->pTi)<vPID->ts){*vPID->pTi=vPID->ts;}kp=100.0/(*vPID->pPb);ki=kp*(vPID->ts/(*vPID->pTi));kd=kp*((*vPID->pTd)/vPID->ts);
#endifif(*vPID->pMA<1)      //手动模式{vPID->output=*vPID->pMV;//设置无扰动切换vPID->result=(vPID->maximum-vPID->minimum)*vPID->output/(float)100.0+vPID->minimum;*vPID->pSV=*vPID->pPV;vPID->setpoint=*vPID->pSV;}else                  //自动模式{if(vPID->sm==SMOOTH_ENABLE) //设定值平滑变化{SmoothSetpoint(vPID);}else{if(vPID->cas==CASCADE)    //串级处理{vPID->setpoint=(vPID->maximum-vPID->minimum)*(*vPID->pSV)/(float)100.0+vPID->minimum;}else{vPID->setpoint=*vPID->pSV;}}thisError=vPID->setpoint-(*vPID->pPV); //得到偏差值result=vPID->result;if (fabsf(thisError)>vPID->deadband){pError=thisError-vPID->lasterror;iError=(thisError+vPID->lasterror)/(float)2.0;dError=thisError-2*(vPID->lasterror)+vPID->preerror;//变积分系数获取factor=VariableIntegralCoefficient(thisError,vPID->errorabsmax,vPID->errorabsmin);//计算微分项增量带不完全微分vPID->deltadiff=kd*(1-vPID->alpha)*dError+vPID->alpha*vPID->deltadiff;increment=kp*pError+ki*factor*iError+vPID->deltadiff;   //增量计算}else{if((fabsf(vPID->setpoint-vPID->minimum)<vPID->deadband)&&(fabsf((*vPID->pPV)-vPID->minimum)<vPID->deadband)){result=vPID->minimum;}increment=0.0;}//输出变化幅度if(vPID->pac==PREVENT_ABRUPT_ENABLE){increment=fabsf(increment)>fabsf(thisError)?thisError:increment;}//正反作用设定if(vPID->direct==DIRECT){result=result+increment;}else{result=result-increment;}/*对输出限值,避免超调和积分饱和问题*/if(result>=vPID->maximum){result=vPID->maximum;}if(result<=vPID->minimum){result=vPID->minimum;}  vPID->preerror=vPID->lasterror;  //存放偏差用于下次运算vPID->lasterror=thisError;vPID->result=result;vPID->output=(vPID->result-vPID->minimum)/(vPID->maximum-vPID->minimum)*(float)100.0;*vPID->pMV=vPID->output;}
}

  在这里我们将设定值平滑的步进值按量程比例固定了,但实际上设定值平滑的步进值应该根据采样周期来调整。并且在不同的被控系统中也应该做适当调整。而输出防陡变的阈值我们采用了偏差值。

4、总结

  在这一篇中,我们分析了引起超调的几点原因并思考了各自的应对策略。依据这些,我们改进了PID控制器使其具备有防超调的基本功能。我们在温度控制和流量控制中实际使用了改进过的PID控制器,对超调的抑制作用是非常明显的。但需要指出的是如果设定值平滑的步进值设置过小或是输出增量限幅的阈值过小将会使得调节过程极其缓慢。
  一般来说象温度、物位等滞后相对比较大的系统使用设定值平滑会有比较好的效果,而增加输出增量限幅则可能会调节的比较缓慢。而流量、压力等滞后相对较小的系统使用输出增量限幅会有比较好的效果,而增加设定值平滑则有可能是的调节变得缓慢。
  最后我们简单说一下调节周期的问题。调节周期的选择是一个需要认真考虑的问题。即使我们采用相同的参数整定,采用相同的防超调处理,当调节周期不同时,效果可能会有较大差异,所以调节周期必须确定好。一般来说,滞后大的系统调节周期需要设置的长一点,而滞后小的系统调节周期需要设置的短一点,具体还需要根据控制要求来设置。

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件设计开发笔记3:基于QT的Modbus RTU主站

Modbus是一种常见的工业系统通讯协议。在我们的设计开发工作中经常使用到它。在这一篇中我们将简单实现一个基于QT的Modbus RTU主站上位工具。 1、概述 Modbus RTU主站应用很常见&#xff0c;有一些是通用的&#xff0c;有一些是专用的。而这里我们希望实现一个主要针对我们的…

外设驱动库开发笔记45:MS4515DO压力传感器驱动

很多时候我们需要检测流量和压力这些参数&#xff0c;比如我们要检测大气压&#xff0c;或者通过测量差压来获得输送流体的流量等&#xff0c;都需要用到压力传感器。这一篇我们就来讨论MS4515DO压力传感器的数据获取。 1、功能概述 MS4515DO是TE公司推出的一款基于PCB安装的小…

外设驱动库开发笔记48:MCP4725单通道DAC驱动

在产品设计过程中&#xff0c;我们经常会遇到数模转换的应用需求。在本篇种我们就来讨论一下MCP4725单通道数模转换器的驱动设计与实现。 1、功能概述 MCP4725是一个低功耗&#xff0c;高精度&#xff0c;单通道&#xff0c;12位缓冲电压输出数字到模拟转换器(DAC)与非易失性存…

如何确保不使用动态内存

在许多嵌入式应用程序中&#xff0c;内存分配必须是静态的&#xff0c;而不是动态的。意味着在应用程序中不应使用对malloc()或free()等内容的调用&#xff0c;因为它们可能会在运行时失败&#xff08;内存不足、堆碎片&#xff09;。 但是&#xff0c;当与第三方库甚至 C/C 标…

go 单元测试 testing 打印输出_2020,你需掌握go 单元测试进阶篇

本文说明go语言自带的测试框架未提供或者未方便地提供的测试方案&#xff0c;主要是用于解决写单元测试中比较头痛的依赖问题。也就是伪造模式&#xff0c;经典的伪造模式有桩对象(stub),模拟对象(mock)和伪对象(fake)。比较幸运的是&#xff0c;社区有丰富的第三方测试框架支持…

一文读懂Git工作流

Git是目前最流行的代码管理工具&#xff0c;相信大家也都是在用Git来管理自己团队的源代码。 团队一般为了规范开发&#xff0c;保持良好的代码提交记录以及维护 Git 分支结构清晰&#xff0c;方便后续维护等&#xff0c;都会迫切需要一个比较规范的 Git 工作流。 本文就是在…

xbox360fsd更新游戏封面_游戏类短视频创作指南

一&#xff0e;起步阶段1.内容发布垂直&#xff0c;整体风格一致&#xff0c;选定一个品类的游戏内容风格持续更新注意&#xff1a;冷启动时期不要频繁更换游戏类型2.账号IP化 根据自身风格特色打造独特的风格账号。有利延长账号生命周期&#xff0c;提升粉丝转化率。搞笑、中二…

开发者们都在关注的网站

开发者们都在关注的网站 &#x1f609; 综合类&#xff08;5个&#xff09; 1、GitHub 全球最大的编程开源社区&#xff0c;很多优秀的开源项目都在上边&#xff0c;不知道这个都不要说自己是程序员&#x1f602; 访问地址&#xff1a;https://github.com 2、CSDN 全球最大中…

ios framework 调用第三方 framework_Python基础:标准库和常用的第三方库

Python的标准库有&#xff1a;名称作用datetime为日期和时间处理同时提供了简单和复杂的方法。zlib直接支持通用的数据打包和压缩格式&#xff1a;zlib&#xff0c;gzip&#xff0c;bz2&#xff0c;zipfile&#xff0c;以及 tarfile。random提供了生成随机数的工具。math为浮点…

作图神器ProcessOn - 免费好用

因工作需要&#xff0c;我经常需要花一些流程图&#xff0c;时序图&#xff0c;架构图什么的&#xff0c;之前使用的Windows系统&#xff0c;大部分情况下就用的Visio来画图。后来为了工作方便&#xff0c;换成了Mac电脑&#xff0c;结果发现Mac上没有Visio&#xff0c;然后就在…

三电平igbt死区时间计算_基于大功率三电平IGBT模块并联的参考设计

当前的可再生能源行业中&#xff0c;光伏和风力发电均面临着补贴逐步退坡&#xff0c;平价上网时代即将到来的挑战。为应对这一挑战&#xff0c;光伏逆变器和风力变流器厂家研发的新品单机功率越来越高&#xff0c;以取得更低的单位功率成本。市场上1.5MW的集中式光伏逆变器和3…

手把手教你搭建开发环境之Java开发

大家好呀&#xff0c;从今天开始&#xff0c;我们的手把手系列教程就正式开始啦。 如果你觉得本文对你有一些帮助&#xff0c;欢迎大家关注、点赞、分享给需要的小伙伴们&#xff0c;谢谢大家啦。 前言 Java虽然是一个比较老的语言&#xff0c;但到现在依然充满了活力&#x…

opc服务器组态文件已写保护_远程组态软件不仅方便了PLC无线远程监控,也大大降低了工程成本...

远程组态软件不仅方便了PLC无线远程监控&#xff0c;也大大降低了工程成本组态软件远程监控1.本地上位SCADA系统采集分布各地现场PLC等设备运行的数据&#xff0c;并可以下发控制指令&#xff1b;2.提供稳定的OPC接口服务&#xff0c;常年稳定运行&#xff0c;规模可达10万数据…

奇妙的安全旅行之加密算法概述

前言 hi&#xff0c;大家好呀&#xff0c;信息安全作为当前社会中比较重要的一个课题&#xff0c;已经覆盖了人们生活的方方面面&#xff0c;虽然有时候我们可能并没有意识到&#xff0c;其实信息安全防护已经在背后默默的保护我们的信息安全了。例如&#xff0c;当你在互联网…

怎么调节电机启动值_开关式智能充电机-全自动充电机-铅酸电池充电机品牌-济南能华...

开关式智能充电机-全自动充电机-铅酸电池充电机品牌-济南能华NHCD系列 全自动智能充电机&#xff0c;可调智能充电机&#xff0c;可调直流充电机&#xff0c;可调全自动充电机 &#xff0c;可调蓄电池充电机 便携式可调智能充电机 便携式全自动充电机 大功率可调充电机 大功率智…

奇妙的安全旅行之MD算法

hi&#xff0c;大家好&#xff0c;今天我们开始介绍消息摘要算法中的MD&#xff08;Message Digest&#xff09;算法&#xff0c;MD算法家族包括&#xff1a;MD2&#xff0c;MD4&#xff0c;MD5&#xff0c;MD算法生成的消息摘长度要都是128位的。 其中MD5算法是消息摘要算法的…

的图层类型有哪些_东莞都市领航平面设计培训班都学习哪些内容?

平面设计的工作稳定性是很高的&#xff0c;经济繁荣时期毫无疑问&#xff0c;即使经济下滑&#xff0c;仍不会有很大影响&#xff0c;以前两年为例&#xff0c;北美的大规模裁员浪潮&#xff0c;给高科技行业带来巨大冲击&#xff0c;放慢了高科技产品的开发速度&#xff0c;当…

dockerfile拉取私库镜像_还在用Alpine作为你Docker的Python开发基础镜像?其实Ubuntu更好一点...

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_173一般情况下&#xff0c;当你想为你的Python开发环境选择一个基础镜像时&#xff0c;大多数人都会选择Alpine&#xff0c;为什么&#xff1f;因为它太小了&#xff0c;仅仅只有 5 MB 左右&#xff08;对比 Ubuntu 系列镜像接…

2020,再见;2021,我来了!

现在是2021年1月16日下午16点33分&#xff0c;星期六。此时北京正在通报昨日新冠肺炎新增病例情况&#xff0c;这种每天戴口罩的鬼日子还不知道什么时候能结束。最近由于天气变冷&#xff0c;病毒更容易存活和传播&#xff0c;最近一个月就突然又变的非常紧张起来了&#xff0c…

cuda tensorflow版本对应_Windows10下安装tensorflow-gpu(2.2.0)安装教程(避坑+保姆式教学)...

本文实现了Windows10下GPU版本的tensorflow2.2.0的安装&#xff0c;用到的软件主要包括&#xff1a;CUDA 10.2 cuDNN Anaconda tensorflow-gpu 2.2.0。&#xff08;注&#xff1a;此教程在Win7环境下也同样适用&#xff01;另附报错缺少cudart64_101.dll的解决办法&#xff…