zoukankan      html  css  js  c++  java
  • 改进初学者的PID-正反作用

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

    1、问题所在

      将PID连接过程分为两组:直接作用和反向作用。到目前为止,我所展示的所有例子都是直接行动。也就是说,输出的增加会导致输入的增加。对于反向作用过程,情况正好相反。例如,在冰箱中,冷却水的增加会导致温度下降。要使初学者 PID 使用反向过程,kp、ki 和 kp 的符号都必须为负数。

    这本身不是问题,但用户必须选择正确的符号,并确保所有参数都具有相同的符号。

    2、解决方案

      为了让这个过程简单一点,我要求 kp、ki 和 kp 都是大于等于0的。如果用户连接到反向进程,则使用SetControllerDirection函数指定反向进程。这可以确保所有参数都具有相同的符号,并使事情操作起来更直观。

    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 double outMin,outMax;
      8 bool inAuto = false;
      9  
     10 #define MANUAL 0
     11 #define AUTOMATIC 1
     12  
     13 #define DIRECT 0
     14 #define REVERSE 1
     15 int controllerDirection = DIRECT;
     16  
     17 void Compute()
     18 {
     19    if(!inAuto) return;
     20    unsigned long now = millis();
     21    int timeChange = (now - lastTime);
     22    if(timeChange>=SampleTime)
     23    {
     24       /*Compute all the working error variables*/
     25       double error = Setpoint - Input;
     26       ITerm+= (ki * error);
     27       if(ITerm > outMax) ITerm= outMax;
     28       else if(ITerm < outMin) ITerm= outMin;
     29       double dInput = (Input - lastInput);
     30  
     31       /*Compute PID Output*/
     32       Output = kp * error + ITerm- kd * dInput;
     33       if(Output > outMax) Output = outMax;
     34       else if(Output < outMin) Output = outMin;
     35  
     36       /*Remember some variables for next time*/
     37       lastInput = Input;
     38       lastTime = now;
     39    }
     40 }
     41  
     42 void SetTunings(double Kp,double Ki,double Kd)
     43 {
     44    if (Kp<0 || Ki<0|| Kd<0) return;
     45  
     46   double SampleTimeInSec = ((double)SampleTime)/1000;
     47    kp = Kp;
     48    ki = Ki * SampleTimeInSec;
     49    kd = Kd / SampleTimeInSec;
     50  
     51   if(controllerDirection ==REVERSE)
     52    {
     53       kp = (0 - kp);
     54       ki = (0 - ki);
     55       kd = (0 - kd);
     56    }
     57 }
     58  
     59 void SetSampleTime(int NewSampleTime)
     60 {
     61    if (NewSampleTime > 0)
     62    {
     63       double ratio  = (double)NewSampleTime
     64                       / (double)SampleTime;
     65       ki *= ratio;
     66       kd /= ratio;
     67       SampleTime = (unsigned long)NewSampleTime;
     68    }
     69 }
     70  
     71 void SetOutputLimits(double Min,double Max)
     72 {
     73    if(Min > Max) return;
     74    outMin = Min;
     75    outMax = Max;
     76  
     77    if(Output > outMax) Output = outMax;
     78    else if(Output < outMin) Output = outMin;
     79  
     80    if(ITerm > outMax) ITerm= outMax;
     81    else if(ITerm < outMin) ITerm= outMin;
     82 }
     83  
     84 void SetMode(int Mode)
     85 {
     86     bool newAuto = (Mode == AUTOMATIC);
     87     if(newAuto == !inAuto)
     88     {  /*we just went from manual to auto*/
     89         Initialize();
     90     }
     91     inAuto = newAuto;
     92 }
     93  
     94 void Initialize()
     95 {
     96    lastInput = Input;
     97    ITerm = Output;
     98    if(ITerm > outMax) ITerm= outMax;
     99    else if(ITerm < outMin) ITerm= outMin;
    100 }
    101  
    102 void SetControllerDirection(int Direction)
    103 {
    104    controllerDirection = Direction;
    105 }

    4PID 完成

      差不多结束了。我们已经把“初学者的PID”变成了我目前知道的最健壮的控制器。对于那些正在寻找PID库的详细解释的读者,我希望您得到了您想要的。对于那些正在编写自己的PID的人,我希望您能够收集到一些想法,这些想法可以为您节省一些时间。

    最后说明两点:

    1. 如果这个系列中的东西看起来不对,请告诉我。我可能错过了什么,或者可能只需要在我的解释中更清楚。无论哪种方式,我都想知道。
    2. 这只是一个基本的PID。为了简单起见,我有意省略了许多其他问题。在我的脑海中:前馈,重置平铺,整数数学,不同的PID形式,使用速度而不是位置。如果有兴趣让我探讨这些话题,请让我知道。

    欢迎关注:

  • 相关阅读:
    前端 CSS 与HTML 学习笔记详细讲解
    Python-Django之DRF
    Flask
    flask
    Python
    Python爬虫
    前端开发规范
    为什么 [] == ![] 输出是true?
    javascript准确判断各种数据类型
    JavaScript数组扁平化常用方法总结
  • 原文地址:https://www.cnblogs.com/foxclever/p/11523716.html
Copyright © 2011-2022 走看看