zoukankan      html  css  js  c++  java
  • 改进初学者的PID-微分冲击

      最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-derivative-kick/

    1、问题

      这个修改将稍微调整微分项。其目标是消除一种被称为“微分冲击”的现象。

     

      上图说明了问题。由于error = Setpoint-Input,设定值的任何变化都会导致偏差的瞬时变化。这种变化的导数是无穷大(实际上,由于dt不是0,它只是一个非常大的数字。)这个数字被输入PID方程,这导致输出中出现不希望的峰值。幸运的是,有一种简单的方法可以摆脱这种情况。

    2、解决方案

     

      事实证明,当设定值发生变化时,偏差的导数等于输入的负导数。这最终成为一个完美的解决方案。我们减去(Kd *输入的导数)而不是添加(Kd *偏差的导数)。这被称为使用“基于测量的微分”。

    3、代码

     1 /*working variables*/
     2 unsigned long lastTime;
     3 double Input,Output,Setpoint;
     4 double errSum,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       errSum += error;
    16       double dInput = (Input - lastInput);
    17  
    18       /*Compute PID Output*/
    19       Output = kp * error + ki * errSum - 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 }

      这里的修改非常简单。我们用-dInput替换+ dError。我们现在需要记住lastInput,而不是记住lastError

    4、结果

     

      以下是这些修改对我们的影响。请注意,输入看起来仍然相同。所以我们得到相同的性能,但是每次设定点改变时我们都不会发出巨大的输出尖峰。

      这也许没什么大不了的。这完全取决于应用程序对输出峰值有多敏感。但在我看来,没有冲击就不需要做更多的工作,所以为什么不把事情做好呢?

    欢迎关注:

  • 相关阅读:
    可变参数模板的递归解析
    在Ubuntu上安装多个版本的g++ 并进行默认版本切换
    不错的威盾PHP加密专家解密算法
    文章相关性分析详细介绍
    c#连接mysql中文乱码解决方案(MySql.Data.dll)
    firefox用12306Helper 0.2结合ie tab+自动订火车票和完成支付全攻略
    Nutch命令大全
    Jtable利用SetModel进行数据绑定
    在php中使用CKEDITOR在线编辑器
    Nutch1.2搜索引擎使用详解
  • 原文地址:https://www.cnblogs.com/foxclever/p/11219274.html
Copyright © 2011-2022 走看看