改进初学者的PID-修改整定参数

  最近看到了Brett Beauregard发表的有关PID的系列文章,感受对于理解PID算法颇有帮助,因而将系列文章翻译过来!在自我提升的过程当中,也但愿对同道中人有所帮助。做者Brett Beauregard的原文网址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/算法

 

1、问题spa

  对于任何可靠的PID算法,拥有在系统运行时更改整定参数的能力都是必须的。翻译

 

  若是你试图在系统运行时改变整定参数,在初学PID的人看来会显得有点疯狂。让咱们看看这是为何?如下是初学者的 PID 在上述参数更改先后的状态:3d

 

  所以,咱们能够当即将这种差别归咎于积分项(或“I项”)。只有当参数发生变化时,它才会发生剧烈的变化。为何会这样?这与初学积分的人对积分的理解有关:code

 

  这种解释在 Ki 被改变以前都是能够正常工做的。而后,你忽然把这个新的 Ki 乘以你积累的整个偏差总和。这不是咱们想要的!咱们只想影响事情后续的发展。blog

2、解决方案get

  有几种方法能够处理这个问题。我在上一个库中使用的方法是从新缩放误差累计。Ki 翻了一倍?或者把误差累计削减一半。这能够避免积分项撞击,而且也能工做的很好。不过,这有点笨拙,我想出了更优雅的东西。(我不多是第一个想到这个问题,但我确实是一我的想到的。这算数!)数学

  这个方案须要一个小的基本代数 (仍是微积分?)io

 

  咱们不是让 Ki 处在积分以外,而是把它带到里面。看起来咱们视乎什么都没作,但咱们会看到,在实践中,这带来了很大的变化。ast

  如今,咱们把偏差乘以那个时候的Ki。而后咱们存储它的和。当Ki发生变化时,没有任何变化,由于全部旧的Ki都已经“存在银行”了。咱们获得一个平稳的转换,没有额外的数学运算。这可能会让我成为一个极客,但我以为这很性感。

3、代码

 1 /*working variables*/
 2 unsigned long lastTime;
 3 double Input,Output,Setpoint;
 4 double ITerm,lastInput;
 5 double kp,ki,kd;
 6 int SampleTime = 1000; //1 sec
 7 void Compute()
 8 {
 9    unsigned long now = millis();
10    int timeChange = (now - lastTime);
11    if(timeChange>=SampleTime)
12    {
13       /*Compute all the working error variables*/
14       double error = Setpoint - Input;
15       ITerm += (ki * error);
16       double dInput = (Input - lastInput);
17  
18       /*Compute PID Output*/
19       Output = kp * error + ITerm - kd * dInput;
20  
21       /*Remember some variables for next time*/
22       lastInput = Input;
23       lastTime = now;
24    }
25 }
26  
27 void SetTunings(double Kp,double Ki,double Kd)
28 {
29   double SampleTimeInSec = ((double)SampleTime)/1000;
30    kp = Kp;
31    ki = Ki * SampleTimeInSec;
32    kd = Kd / SampleTimeInSec;
33 }
34  
35 void SetSampleTime(int NewSampleTime)
36 {
37    if (NewSampleTime > 0)
38    {
39       double ratio  = (double)NewSampleTime
40                       / (double)SampleTime;
41       ki *= ratio;
42       kd /= ratio;
43       SampleTime = (unsigned long)NewSampleTime;
44    }
45 }

  所以,咱们用复合积分项变量替换了 [第4行]误差求和变量。它计算 Ki * 误差,而不只仅是误差 [第15行]。此外,因为 Ki 如今被隐藏在积分项中,所以它将从主 PID 计算 [第19行] 中删除。

4、结果

 

 

  那么,这是如何解决问题的。在修改Ki以前,它从新计算了全部误差的总和;咱们看到的每个误差值。有了这段代码,以前的误差将保持不变,而新的Ki只会影响事情的进展,这正是咱们想要的。

译注:对于本篇讨论的修改整定参数对积分项的影响问题。采用位置式PID公式确实存在这一问题,做者的解决方式也很赞。由于这就是增量式PID积分项的默认处理方式。因此若是采用增量式PID就不会存在这个问题了。

欢迎关注:

相关文章
相关标签/搜索