当前位置: 首页 > news >正文

Arduino PID库 (2) –微分导致的过冲

Arduino PID库 (2) – Derivative Kick

参考:手把手教你看懂并理解Arduino PID控制库——微分冲击

  • pid内容索引-CSDN博客

  • Arduino PID库 (1)– 简介

问题

此修改将稍微调整derivative term。目标是消除一种称为“Derivative Kick”的现象。
Derivative Kick

spikes :尖峰

从第一张图看出,当设定值产生一个阶跃后,被控量 Input 随着时间慢慢向设定值靠近,第二张图反应的是设定值产生阶跃后控制量 Output 的变化,可以发现,Output 会突然产生一个较大的阶跃,具体原因可以参考 “万恶” 的 PID 经典控制方程。第三张图描述的是 Output 的梯度(也就是变化率:值变化:时间变化),同样可以发现一个阶跃,并且这个脉冲可能会非常的大(dt 非常小),远远超过 Output 变化量。同理,图中描述了当设定值突然减小,Output 及其对应的梯度变化情况。对于一般的系统来说,我们不希望这样的突变发生(可以想象如果采样周期很长,那么这个冲击会持续很长时间,系统估计就飞起来了)。当然如果你的系统需要这个冲击,那么这个问题就可以忽略
上图说明了问题。由于error=Setpoint-Input,因此Setpoint的任何更改都会导致误差的瞬时变化。这种变化的导数是无穷大(在实践中,由于 dt 不是 0,它最终是一个非常大的数字。该数字被反馈入pid方程,从而导致输出中出现尖峰。幸运的是,有一种简单的方法可以摆脱这种情况。

解决方案

在这里插入图片描述
Setpoint 这一项就会产生一个巨大的冲击,而且仅会产生一次,在下一个计算周期就会消失。处理的方法很多,最简单的就是将 Serpoint 这一项移除,也就是认为对于微分项来说不存在设定值的改变。如果这么处理,系统会不会失控呢?这种玩法已经和我们根深蒂固的经典 PID 理论不一样了啊!!这怎么整!

上述问题的答案是不会失控,我们将上述过程写成数学表达式
DonMExplain
事实证明,误差的导数等于输入的负导数,除非设定值发生变化。这最终是一个完美的解决方案。我们不是加(Kd * 误差的导数),而是减去(输入的 Kd * 导数)。这称为使用“测量导数”

代码

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double errSum, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
void Compute()
{unsigned long now = millis();int timeChange = (now - lastTime);if(timeChange>=SampleTime){/*Compute all the working error variables*/double error = Setpoint - Input;errSum += error;double dInput = (Input - lastInput);/*Compute PID Output*/Output = kp * error + ki * errSum - kd * dInput;/*Remember some variables for next time*/lastInput = Input;lastTime = now;}
}void SetTunings(double Kp, double Ki, double Kd)
{double SampleTimeInSec = ((double)SampleTime)/1000;kp = Kp;ki = Ki * SampleTimeInSec;kd = Kd / SampleTimeInSec;
}void SetSampleTime(int NewSampleTime)
{if (NewSampleTime > 0){double ratio  = (double)NewSampleTime/ (double)SampleTime;ki *= ratio;kd /= ratio;SampleTime = (unsigned long)NewSampleTime;}
}

这里的修改非常简单。我们将 +dError 替换为 -dInput。我们现在不再记住最后一个错误,而是记住最后一个输入

结果

DonM

  1. Output 梯度尖峰被去除
  2. 控制量原来存在一个尖峰被消除
  3. 被控量的微分变得较为平坦
    这些修改给我们带来的结果。请注意,输入看起来仍然大致相同。因此,我们获得了相同的性能,但我们不会在每次设定值更改时都发出巨大的输出峰值。

这可能是也可能不是什么大问题。这完全取决于您的应用程序对输出峰值的敏感程度。不过,在我看来,不突变就不需要做更多的工作,所以为什么不把事情做好呢?

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于ThinkPHP开发的校园跑腿社区小程序系统源码,包含前后端代码
  • css3的继承性
  • 十五 open CV 教程 形态学二值化和腐蚀操作
  • 结构型设计模式:桥接/组合/装饰/外观/享元
  • 【Nuxt】配置
  • 【Python 逆向滑块】(实战六)逆向滑块,并实现用Python+Node.js 生成滑块、识别滑块、验证滑块、发送短信
  • CTF web bibibi题型
  • Unity计算位置平移矩阵
  • 《Milvus Cloud向量数据库指南》——什么是高可用:深入理解数据库系统中的高可用性架构
  • 【Redis 进阶】哨兵 Sentinel(重点理解流程和原理)
  • XML 学习笔记
  • ZeroMQ(二):请求-响应模式,C和C++。
  • 中国AI大模型场景探索及产业应用调研报告
  • 类和对象(上) - c++
  • 【React】常见的 HOC 使用案例
  • 08.Android之View事件问题
  • canvas 绘制双线技巧
  • canvas绘制圆角头像
  • CSS实用技巧
  • Docker入门(二) - Dockerfile
  • go append函数以及写入
  • HTTP请求重发
  • JavaScript 基础知识 - 入门篇(一)
  • JDK9: 集成 Jshell 和 Maven 项目.
  • Js基础知识(一) - 变量
  • MaxCompute访问TableStore(OTS) 数据
  • React16时代,该用什么姿势写 React ?
  • 电商搜索引擎的架构设计和性能优化
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 回顾 Swift 多平台移植进度 #2
  • 聊聊flink的TableFactory
  • 配置 PM2 实现代码自动发布
  • 批量截取pdf文件
  • 区块链将重新定义世界
  • 如何实现 font-size 的响应式
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 原生 js 实现移动端 Touch 滑动反弹
  • 栈实现走出迷宫(C++)
  • Android开发者必备:推荐一款助力开发的开源APP
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 阿里云服务器如何修改远程端口?
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #AngularJS#$sce.trustAsResourceUrl
  • #HarmonyOS:Web组件的使用
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (42)STM32——LCD显示屏实验笔记
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (备份) esp32 GPIO
  • (待修改)PyG安装步骤
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214