瞎扯PID算法

前一段时间基于PID(等比例微分积分控制)做了个资源调度器。如果感兴趣可以移步我的github查看对应的代码。

其实PID算法几乎就是自控领域的基础,但对于软件行业来说,这种简单有效且可变的控制模式并没有太多的得到利用。

简单的说,PID是基于一个线性关联(并不要求是“正比例”)的一对值——作用值和反馈值的控制器。比如水龙头就是这样一对值,龙头拧的角度是作用值,而出水量就是反馈值。由于它对于两者之间的线性关系并不敏感(也就是说:你开龙头的时候并不关心转动相同的角度和出的水是成比例的),这也就给一些相对复杂的操作提供了控制的可能。最有趣的一点就是,PID关注的是反馈值,是根据反馈值去调整作用值(也就是说:你并不关心龙头开的角度,你只要关心水的流量够不够)。

如下图中,假设我们要将目标值从0提升到1,也就是蓝色线表达的变化,在不同的设定下的PID都会尽可能的收敛到该设定值上。

PID_varyingP
在软件上,比较典型的就是某项资源的分配控制。比如主机的数量和执行同一个任务的时间有的时候是很难对等的,如果硬是要回归出一个线性函数,那将是一个非常复杂的过程。借助PID这种不变应万变的控制方式就可以简单粗暴的搞定这个控制;另外,对于阈值的控制,即便引入了“双向阀”的设计,但在现实中抖动几乎是无法避免的,而PID最初的设计就是为了减少抖动的。

贴个伪代码:Kp,Ki,Kd是设定值,me。

previous_error = 0
integral = 0
loop:
  error = setpoint - measured_value // 计算当前值与目标值的差距
  integral = integral + error*dt   // dt为时间的变化
  derivative = (error - previous_error)/dt // 反馈值的变化除以时间变化
  output = Kp*error + Ki*integral + Kd*derivative // 换算出作用值
  previous_error = error
  wait(dt)
  goto loop

毕竟这是在运算资源还是很匮乏的时代就有的算法,其实还是蛮好理解的。

从上图也可以看的出,不同的PID对曲线的影响是很大的,那对于3个值的设定就牵扯到了Cohen-Coon整定法

K是控制对象的增益,L是等效滞后时间,T是等效滞后时间常数,则:

  • Kp = 4T / 3KL + 1 / 4K
  • Ki = L ( 32T + 6L )  / ( 13T + 8L )
  • Kd = 0.5L

少谈写理论的话,聪明的国人还是有一套口诀的 😀

  参数整定找最佳,从小到大顺序查
  先是比例后积分,最后再把微分加
  曲线振荡很频繁,比例度盘要放大
  曲线漂浮绕大湾,比例度盘往小扳
  曲线偏离回复慢,积分时间往下降
  曲线波动周期长,积分时间再加长
  曲线振荡频率快,先把微分降下来
  动差大来波动慢。微分时间应加长
  理想曲线两个波,前高后低4比1
   一看二调多分析,调节质量不会低

推荐阅读:
又到了反思这一年的时间了。好吧
gearman,学习好莱坞大片
有感于网络上各个文档之间的翻译
作为开源软件的一个重要组成部分

发表评论

电子邮件地址不会被公开。 必填项已用*标注

请补全下列算式: *

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据