PID算法Demo
来源:互联网 发布:linux显示文本名 编辑:程序博客网 时间:2024/06/05 08:12
pre
最近在准备做一些事的时候可能需要用到PID算法,所以今天下午基于网上的一些教程和博客写了一遍,在写的过程中遇到了一些疑惑和坑,这里分享一个整个过程和最后的成果,留作日后参考。
需求
场景: 锅炉调温
现在有一加热热水锅炉,我们需要他稳定提供70度的热水,当前室温25度,用来加热的水是温度为50度的温水。
锅炉的加热功率能够瞬时加热水到40度,同时功率可以调整,支持从0W到最高瓦数的瞬时切换(这里都是测试数据,不要带入现实)
水会自然散热,散热曲线符合二次曲线,假设曲线为 0.2 *( temperature - environment)^2
增量式PID算法
(这里只使用了增量式的PID,所以不讨论其他类型的PID)
PID算法设计三个变量,分别是偏差的比例(P)、积分(I)和微分(D)。增量式PID套用的公式为
u(k)=Kp * [e(k)-e(k-1)]+Ki * e(k)+Kd * [e(k)-2e(k-1)+e(k-2)]
下面是对上式中变量的解释
u(k): PID的阶段输出,预期dt下的增量,几何意义上是,拟合曲线在当前时间tk下的切线斜率
Kp : 从公式中看出是用来动态调节步伐的,(进小远大)
Ki : 当前偏差的缩放洗漱
Kd : 对前两项值得2次修正调整,使最后的曲线尽可能平滑。 也就是减少扰动
PID参数调整的规则被总结如下(源自论坛)
参数整定找最佳, 从小到大顺序查。
先是比例后积分, 最后再把微分加。
曲线振荡很频繁, 比例度盘要放大。
曲线漂浮绕大弯, 比例度盘往小扳。
曲线偏离回复慢, 积分时间往下降。
曲线波动周期长, 积分时间再加长。
曲线振荡频率快, 先把微分降下来。
动差大来波动慢, 微分时间应加长。
理想曲线两个波, 前高后低四比一。
一看二调多分析, 调节质量不会低。
解决方案
语言采用我熟悉的java,我实现了一套测试环境(模拟锅炉运行环境),基于一些可扩展的想法和某种强迫症,我最终采用了如下设计
PID相关的核心代码如下
class PIDHeat implements Heat{ float lastError; float preError; final float P_const = 40f; final float I_const = 150f; final float D_const = 1f; public PIDHeat(){ preError = lastError = 0; } private float range(float heatTemp){ if(heatTemp < 0){ return 0; } if(heatTemp > 40){ return 40; } return heatTemp; } @Override public float heat() { float currentError = target - current; System.out.println("PID params "+ currentError + " " + lastError + " " + preError); float heatTemp = P_const * (currentError-lastError) + I_const * currentError + D_const * (currentError + preError -2*lastError); preError = lastError; lastError = currentError; heatTemp = range(heatTemp); System.out.println("PID out "+ heatTemp); return heatTemp; } }
类图是后来补的,所以有些出入,但基本正确。
实现的时候采用了java内部类相关的性质,所以如果需要移植到其他语言上去需要做少部分调整。
项目代码存放位置
github仓库链接
Q&A
PID算法除了口诀之外,有什么更加直观的方式么?
在wiki百科上有一张动态图可以提供一定的帮助调整过程中,最后值不收敛,奔着正负无穷去?
在我的实践中存在开始时dt并不足够小的问题
方法中存在微分假设,只有在dt足够小下才满足向着最小值收敛的预期,在dt较大时,最终的结果可能会发散向无穷大,这个问题在选择剃度下降下降速率α问题上也有着体现。
reference
https://baike.baidu.com/item/PID%E7%AE%97%E6%B3%95
http://www.arduino.cn/thread-12813-1-1.html
http://www.dfrobot.com.cn/community/thread-14783-1-1.html
http://www.crazepony.com/book/wiki/algorithm-pid.html
- PID算法Demo
- pid算法
- PID算法
- PID算法
- PID算法
- PID算法
- PID算法
- PID算法
- PID算法
- 51单片机PID算法程序---PID算法
- 形象解释PID算法+PID算法源代码
- 形象解释PID算法+PID算法源代码
- PID算法(zt)
- PID算法的实现
- 数字PID算法
- PID算法理解
- 标准的PID算法
- 单片机实现PID算法
- 在Intellij Idea中怎么引入c标签
- [bzoj3626][LNOI2014]LCA 树链剖分
- ns2仿真学习(二)-tcp拥塞窗口的跟踪
- 接口限流算法总结
- NOIP模拟 最佳序列【二分答案+线段树(单调队列)】
- PID算法Demo
- openGL之glsl入门2--helloworld
- Spring整合ehcache
- nodeJS入门教程
- 学习阿里巴巴开发手册-12
- 2013NOIP普级组第一题--计数问题(参考洛谷题解)
- Hdu--Rescue之bfs加优先队列
- 【实战】从网络地址上下载图片
- Android --- MediaPlayer的使用详解