手撕PID(带死区、积分分离、不完全微分)

您所在的位置:网站首页 分段积分的c怎么确定 手撕PID(带死区、积分分离、不完全微分)

手撕PID(带死区、积分分离、不完全微分)

2024-07-17 17:01:42| 来源: 网络整理| 查看: 265

手撕PID(带死区、积分分离、不完全微分) 一、位置式PID二、积分分离三、不完全微分PID四、带死区的PIDc++程序实现

一、位置式PID

ΔU(k)=kp*(err(k)-err(k-1))+kie(k)+kd(e(k)-2*e(k-1)+e(k-2)) U(k)=U(k-1)+ΔU(k)

二、积分分离

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

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

三、不完全微分PID

微分项有引入高频干扰的风险,但若在控制算法中加入低通滤波器,则可使系统性能得到改善。方法之一就是在PID算法中加入一个一阶低通滤波器。这就是所谓的不完全微分,其结构图如下:

在这里插入图片描述 微分部分表达式为: 在这里插入图片描述 其中 其中α的取值在0和1之间,有滤波常数和采样周期确定

四、带死区的PID

带死区的PID控制算法就是检测偏差值,若是偏差值达到一定程度,就进行调节。若是偏差值较小,就认为没有偏差。用公式表示如下: 在这里插入图片描述 其中的死区值得选择需要根据具体对象认真考虑,因为该值太小就起不到作用,该值选取过大则可能造成大滞后。

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

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

c++程序实现

#头文件

#ifndef PID_H #define PID_H typedef struct { float kp; float ki; float kd; float ek;//当前误差 float ekk;//上一次误差 float ekkk; //上两次误差 float alpha;//不完全微分系数 float lastDev;//上一次微分环节的增量 float separationThreshold;//积分分离阈值,误差大于阈值时PD,误差小于阈值时PID float ekDeadZone;//PID死区 float increment; //PID增量 float lastOutputValue;//上一次PID输出值 float upLimit;//输出上限 float lowLimit;//输出下限 }PidParameter; class PID{ public: //增量式PID int IncrementalPID(float exceptionValue,float feedbackValue,float outputValue); //积分分离式PID,防止超调 int integrationSeparationPID(float exceptionValue,float feedbackValue,float outputValue); //不完全微分PID,微分环节加低通滤波,抑振高频噪声 int incompleteDifferentialPID(float exceptionValue,float feedbackValue,float outputValue); //带死区的PID,偏差限定最小值,小于最小值则为0,防止系统稳定点频繁调节 int deadZonePID(float exceptionValue,float feedbackValue,float outputValue); //带积分分离、死区的不完全微分的增量式PID int fullPID(float exceptionValue,float feedbackValue,float outputValue); private: PidParameter pidParam; }; #endif // PID_H

#源文件

#include "PID.h" #include "math.h" int PID::IncrementalPID(float exceptionValue,float feedbackValue,float outputValue) { pidParam.kp=10; pidParam.ki=10; pidParam.kd=10; pidParam.ek=exceptionValue-feedbackValue; pidParam.increment = pidParam.kp*(pidParam.ek-pidParam.ekk)+pidParam.ki*pidParam.ek+pidParam.kd*(pidParam.ek-2*pidParam.ekk+pidParam.ekkk); pidParam.ekkk=pidParam.ekk; pidParam.ekk=pidParam.ek; outputValue = outputValue+pidParam.increment; return 0; } int PID::integrationSeparationPID(float exceptionValue,float feedbackValue,float outputValue) { pidParam.kp=10; pidParam.ki=10; pidParam.kd=10; pidParam.separationThreshold=5; pidParam.ek=exceptionValue-feedbackValue; if(pidParam.ek pidParam.increment = pidParam.kp*(pidParam.ek-pidParam.ekk)+pidParam.kd*(pidParam.ek-2*pidParam.ekk+pidParam.ekkk); } pidParam.ekkk=pidParam.ekk; pidParam.ekk=pidParam.ek; outputValue = outputValue+pidParam.increment; return 0; } int PID::incompleteDifferentialPID(float exceptionValue,float feedbackValue,float outputValue) { float proportion=pidParam.ek-pidParam.ekk; float integration=pidParam.ek; float differ=pidParam.kd*(1-pidParam.alpha)*(pidParam.ek-2*pidParam.ekk+pidParam.ekkk)+pidParam.alpha*pidParam.lastDev; pidParam.increment=pidParam.kp*proportion+pidParam.ki*integration+pidParam.kd*differ; pidParam.lastDev=differ; pidParam.ekkk=pidParam.ekk; pidParam.ekk=pidParam.ek; outputValue = outputValue+pidParam.increment; return 0; } int PID::deadZonePID(float exceptionValue,float feedbackValue,float outputValue) { pidParam.kp=10; pidParam.ki=10; pidParam.kd=10; pidParam.ek=exceptionValue-feedbackValue; if((pidParam.ek-pidParam.ekDeadZone)) { pidParam.increment=0; pidParam.ek=0; }else { pidParam.increment = pidParam.kp*(pidParam.ek-pidParam.ekk)+pidParam.ki*pidParam.ek+pidParam.kd*(pidParam.ek-2*pidParam.ekk+pidParam.ekkk); } pidParam.ekkk=pidParam.ekk; pidParam.ekk=pidParam.ek; outputValue = outputValue+pidParam.increment; if(outputValue>pidParam.upLimit) { outputValue=pidParam.upLimit; } if(outputValue float up=0;//比例环节的输出 float ui=0;//积分环节的输出 float uk=0;//微分环节的输出 outputValue=0; pidParam.ek=exceptionValue-feedbackValue; if(abs(pidParam.ek) if(abs(pidParam.ek)>pidParam.separationThreshold)//积分分离,误差大于阈值采用PID控制,误差小于阈值采用PID控制 防止超调 { pidParam.ek=0; } up=pidParam.kp*(pidParam.ek-pidParam.ekk); ui=pidParam.ki*pidParam.ek; uk=pidParam.kd*(1-pidParam.alpha)*(pidParam.ek-2*pidParam.ekk+pidParam.ekkk)+pidParam.lastDev;//不完全微分环节,alpha为0~1的滤波系数 消除微分环节引入的高频噪声 pidParam.increment=up+ui+uk; } pidParam.lastDev=uk; pidParam.ekkk=pidParam.ekk; pidParam.ekk=pidParam.ek; outputValue=outputValue+pidParam.increment; if(outputValue>pidParam.upLimit) { outputValue=pidParam.upLimit; } if(outputValue


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭