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

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

1、带死区PID的基本思想

带死区的PID控制算法就是检测偏差值,若是偏差值达到一定程度,就进行调节。若是偏差值较小,就认为没有偏差。用公式表示如下:

其中的死区值得选择需要根据具体对象认真考虑,因为该值太小就起不到作用,该值选取过大则可能造成大滞后。

带死区的PID算法,对无论位置型还是增量型的表达式没有影响,不过它是一个非线性系统。

除以上描述之外还有一个问题,在零点附近时,若偏差很小,进入死去后,偏差置0会造成积分消失,如是系统存在静差将不能消除,所以需要人为处理这一点。

2、算法实现

前面我们描述了带死区的PID控制的基本思想。在接下来我们来实现这一思想,同样是按位置型和增量型来分别实现。

2.1、位置型PID算法实现

前面我们对微分项、积分项采用的不同的优化算法,他们都可以与死区一起作用于PID控制。这一节我们就来实现一个采用抗积分饱和、梯形积分、变积分算法以及不完全微分算法和死区控制的PID算法。首先依然是定义一个PID结构体。

/*定义结构体和公用体*/
typedef struct
{float setpoint;               /*设定值*/float kp;                     /*比例系数*/float ki;                     /*积分系数*/float kd;                     /*微分系数*/float lasterror;              /*前一拍偏差*/float preerror;               /*前两拍偏差*/float deadband;               /*死区*/float result;                 /*PID控制器计算结果*/float output;                 /*输出值0-100%*/float maximum;                /*输出值上限*/float minimum;                /*输出值下限*/float errorabsmax;            /*偏差绝对值最大值*/float errorabsmin;            /*偏差绝对值最小值*/float alpha;                  /*不完全微分系数*/float derivative;              /*微分项*/float integralValue;          /*积分累计量*/
}CLASSICPID;

接下来我们实现带死区、抗积分饱和、梯形积分、变积分算法以及不完全微分算法的增量型PID控制器。

void PIDRegulator(CLASSICPID vPID,float pv)
{float thisError;float result;float factor;thisError=vPID->setpoint-pv; //得到偏差值result=vPID->result;if(fabs(thisError)>vPID->deadband){vPID-> integralValue= vPID-> integralValue+ thisError;//变积分系数获取factor=VariableIntegralCoefficient(thisError,vPID->errorabsmax,vPID->errorabsmin);//计算微分项增量带不完全微分vPID-> derivative =kd*(1-vPID->alpha)*(thisError-vPID->lasterror +vPID->alpha*vPID-> derivative;result=vPID->kp*thisError+vPID->ki*vPID->integralValue +vPID-> derivative;}else{if((abs(vPID->setpoint-vPID->minimum)<vPID->deadband)&&(abs(pv-vPID->minimum)<vPID->deadband)){result=vPID->minimum;}}/*对输出限值,避免超调和积分饱和问题*/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=((result-vPID->minimum)/(vPID->maximum-vPID->minimum))*100.0;
}

2.2、增量型PID算法实现

在位置型PID中我们实现了比较全面的PID控制器,对于增量型PID我们也相应的实现这样一个控制器。除了这些结合外,其他的优化算法也可以结合使用,可以根据具体的需要来实现。首先依然是定义一个PID结构体。

/*定义结构体和公用体*/
typedef struct
{float setpoint;               /*设定值*/float kp;                     /*比例系数*/float ki;                     /*积分系数*/float kd;                     /*微分系数*/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;              /*微分增量*/
}CLASSICPID;

接下来我们实现带死区、抗积分饱和、梯形积分、变积分算法以及不完全微分算法的增量型PID控制器。

void PIDRegulator(CLASSICPID vPID,float pv)
{float thisError;float result;float factor;float increment;float pError,dError,iError;thisError=vPID->setpoint-pv; //得到偏差值result=vPID->result;if(fabs(thisError)>vPID->deadband){pError=thisError-vPID->lasterror;iError=(thisError+vPID->lasterror)/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=vPID->kp*pError+vPID->ki*factor*iError+vPID->deltadiff;   //增量计算}else{if((fabs(vPID->setpoint-vPID->minimum)<vPID->deadband)&&(fabs(pv-vPID->minimum)<vPID->deadband)){result=vPID->minimum;}increment=0.0;}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=((result-vPID->minimum)/(vPID->maximum-vPID->minimum))*100.0;
}

3、总结

引入死区的主要目的是消除稳定点附近的波动,由于测量值的测量精度和干扰的影响,实际系统中测量值不会真正稳定在某一个具体的值,而与设定值之间总会存在偏差,而这一偏差并不是系统真实控制过程的反应,所以引入死区就能较好的消除这一点。

当然,死区的大小对系统的影响是不同的。太小可能达不到预期的效果,而太大则可能对系统的正常变化造成严重滞后,需要根据具体的系统对象来设定。

欢迎关注:

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

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

相关文章

GPU环境配置指南(Ubuntu16.04+CUDA+CUDNN)

前言 这两天由于种种原因&#xff0c;反复重装系统并配置了深度学习开发环境&#xff0c;无意中便总结了一份环境配置指南出来&#xff0c;所幸再稍加整理&#xff0c;和大家分享出来。 本指南确认无误的环境是&#xff1a; 系统是Ubuntu16.04 GPU是NVIDIA GTX1070 CUDA安装8.…

在多任务(RTOS)环境中使用看门狗

最近在SEGGER的博客上看到一篇有关在实时操作系统使用看门狗的文章。从一个失败的太空项目出发&#xff0c;分析了看门狗的作用及使用&#xff0c;自我感觉很有启发&#xff0c;特此翻译此文并推荐给各位同仁。为了阅读方便&#xff0c;有些航天领域名词本人添加了注释&#xf…

天池竞赛-津南数字制造算法挑战赛【赛场二】解决方案分享

天池竞赛-津南数字制造算法挑战赛【赛场二】解决方案分享 一、前言 竞赛页面 团队名BugFlow&#xff0c;最终排名35/2157 虽然成绩一般&#xff0c;但是作为一支目标检测领域的新手队伍&#xff0c;仅仅有一块1070显卡&#xff0c;从零开始拿到这个排名&#xff0c;也算有一…

tensorflow 如何获取模型中想要的张量

当我们想要改造或者利用某一预训练模型来完成一些其它任务时&#xff0c;一个常用且必备的操作是从指定模型中获取到我们感兴趣的张量&#xff08;tensor&#xff09;。 例如我想使用一个已经训练好的CNN模型中间的某一层的结果作为特征向量来完成另一个相关任务&#xff0c;就…

信息摘要算法之三:SHA256算法分析与实现

前面一篇中我们分析了SHA的原理&#xff0c;并且以SHA1为例实现了相关的算法&#xff0c;在这一片中我们将进一步分析SHA2并实现之。 1、SHA简述 前面的篇章中我们已经说明过&#xff0c;SHA实际包括有一系列算法&#xff0c;分别是SHA-1、SHA-224、SHA-256、SHA-384以及SHA-…

focal loss的几种实现版本(Keras/Tensorflow)

起源于在工作中使用focal loss遇到的一个bug&#xff0c;我仔细的学习多个靠谱的focal loss讲解及实现版本 通过测试&#xff0c;我发现了这样一个奇怪的现象&#xff0c;几乎每个版本的focal loss实现对同样的输入计算出的loss都是不同的。 通过仔细的比对和思考&#xff0c…

基于ARM Cortex-M和Eclipse的SWO单总线输出

最近在MCU on Eclipse网站上看到Erich Styger所写的一篇有关通过SWD的跟踪接口SWO获取ARM Cortex-M相关信息的文章&#xff0c;文章结构明晰&#xff0c;讲解透彻&#xff0c;本人深受启发&#xff0c;特意将其翻译过来供各位同仁参考。当然限于个人水平&#xff0c;有不当之处…

包管理工具conda极简教程

包管理工具conda极简教程 conda的作用 Anaconda是目前非常流行的一个python包管理器&#xff0c;自带很多流行的python库&#xff0c;包括numpy&#xff0c;pandas等&#xff0c;当然还有conda。而Conda是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装多个版本…

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

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

借助百度识图爬取数据集

背景 一个能够实际应用的深度学习模型&#xff0c;背后的数据集往往都花费了大量的人力财力&#xff0c;通过聘用标注团队对真实场景数据进行标注生产出来&#xff0c;大多数情况不太可能使用网络来源的图片。但在项目初期的demo阶段&#xff0c;或者某些特定的场合下&#xf…

通过printf从目标板到调试器的输出

最近在SEGGER的博客上看到Johannes Lask写的一篇关于在调试时使用printf函数从目标MCU输出信息到调试器的文章&#xff0c;自我感觉很有启发&#xff0c;特此翻译此文并推荐给各位同仁。当然限于个人水平&#xff0c;有不当之处恳请指正。原文网址&#xff1a;https://blog.seg…

小心使用tf.image.resize_images,填坑经验分享给你

上上周&#xff0c;我在一个项目上线前对模型进行测试时出现了问题&#xff0c;这个问题困扰了我近两周&#xff0c;终于找到了问题根源&#xff0c;做个简短总结分享给你&#xff0c;希望对大家有帮助。 问题描述&#xff1a; 线上线下测试结果不一致&#xff0c;且差异很大…

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

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

AutoML 与 Bayesian Optimization 概述

1. AutoML 概述 AutoML是指对于一个超参数优化任务&#xff08;比如规定计算资源内&#xff0c;调整网络结构找到准确率最高的网络&#xff09;&#xff0c;尽量减少人为干预&#xff0c;使用某种学习机制&#xff0c;来调节这些超参数&#xff0c;使得目标问题达到最优。 这…

使用Eclipse进行Makefile项目

最近在MCU on Eclipse网站上看到Erich Styger所写的一篇有关在Eclipse中使用Makefile创建项目的文章&#xff0c;文章讲解清晰明了非常不错&#xff0c;所以呢没人将其翻译过来供各位同仁参考。当然限于个人水平&#xff0c;有不当之处恳请指正。原文网址&#xff1a;https://m…

Git commit 常用表情快速查询

git commit 的时候&#xff0c;添加表情符号可以更好的表明本次提交的性质&#xff0c;也更有趣。 常用表情符号如下&#xff1a; emoji emoji代码 commit说明 &#x1f3a8; (调色板) :art: 改进代码结构/代码格式 ⚡️ (闪电) :zap: 提升性能 &#x1f40e; (赛马)…

C语言学习及应用笔记之一:C运算符优先级及使用问题

C语言中的运算符绝对是C语言学习和使用的一个难点&#xff0c;因为在2011版的标准中&#xff0c;C语言的运算符的数量超过40个&#xff0c;甚至比关键字的数量还要多。这些运算符有单目运算符、双目运算符以及三目运算符&#xff0c;又涉及到左结合和右结合的问题&#xff0c;真…

Docker用法整理

Docker教程推荐 两个不错的参考资料&#xff1a; https://yeasy.gitbooks.io/docker_practice/content/introduction/ https://www.cnblogs.com/bethal/p/5942369.html 镜像&#xff1a; 查看镜像 docker images ls 删除镜像 docker image rm <image id> 拉取镜像 …

使用FreeRTOS进行性能和运行时分析

在MCU on Eclipse网站上看到Erich Styger在2月25日发的博文&#xff0c;一篇关于使用FreeRTOS进行性能和运行分析的文章&#xff0c;本人觉得很有启发&#xff0c;特将其翻译过来以备参考。当然限于个人水平&#xff0c;有描述不当之处恳请指正。原文网址&#xff1a;https://m…

生成微信公众号对应二维码的两种简单方法

方法1 在浏览器中打开下面的链接 https://open.weixin.qq.com/qr/code?usernameName 其中Name替换为对应公众号的微信号 例如&#xff0c;我们打算生成公众号 AI算法联盟 的二维码 只需首先关注这个公众号 在其详细信息中&#xff0c;查找到微信号信息&#xff1a;AIReport…