手把手教你看懂並理解Arduino PID控制庫——方向

引子

本文將分析《手把手教你看懂並理解Arduino PID控制庫》中:調節方向的問題函數

問題定義

一個完善的PID控制器的調節方式,應該有兩種:ui

一、正向調節,也就是輸出增大,那麼被控量也會增大spa

二、反向調節,與正向調節相對應,輸出增大,被控量卻減少.net

上述兩種方式很容易理解,舉個例子,例如在溫度控制的加熱控制中,加熱輸出增大,那麼溫度隨之上升(正向調節),而在對應的製冷控制中,若是製冷輸出增大,那麼溫度應該是隨之降低的(方向調節)。code

解決方案

這個問題很容易解決,在代碼中,僅須要將Kp、Ki、Kd設定爲負的便可,在代碼中,提供了一個函數SetControllerDirection和兩個宏DIRECT和REVERSE用於控制輸出的方向,若是須要正向輸出,在構造PID以後,調用SetControllerDirection(DIRECT)便可將輸出設爲正向(正向是默認的,構造PID的時候,默認是正向調節),反之亦然。blog

代碼

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
double outMin, outMax;
bool inAuto = false;
 
#define MANUAL 0
#define AUTOMATIC 1
 
#define DIRECT 0
#define REVERSE 1
int controllerDirection = DIRECT;
 
void Compute()
{
   if(!inAuto) return;
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
      /*Compute all the working error variables*/
      double error = Setpoint - Input;
      ITerm+= (ki * error);
      if(ITerm > outMax) ITerm= outMax;
      else if(ITerm < outMin) ITerm= outMin;
      double dInput = (Input - lastInput);
 
      /*Compute PID Output*/
      Output = kp * error + ITerm- kd * dInput;
      if(Output > outMax) Output = outMax;
      else if(Output < outMin) Output = outMin;
 
      /*Remember some variables for next time*/
      lastInput = Input;
      lastTime = now;
   }
}
 
void SetTunings(double Kp, double Ki, double Kd)
{
   if (Kp<0 || Ki<0|| Kd<0) return;
 
  double SampleTimeInSec = ((double)SampleTime)/1000;
   kp = Kp;
   ki = Ki * SampleTimeInSec;
   kd = Kd / SampleTimeInSec;
 
  if(controllerDirection ==REVERSE)
   {
      kp = (0 - kp);
      ki = (0 - ki);
      kd = (0 - kd);
   }
}
 
void SetSampleTime(int NewSampleTime)
{
   if (NewSampleTime > 0)
   {
      double ratio  = (double)NewSampleTime
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}
 
void SetOutputLimits(double Min, double Max)
{
   if(Min > Max) return;
   outMin = Min;
   outMax = Max;
 
   if(Output > outMax) Output = outMax;
   else if(Output < outMin) Output = outMin;
 
   if(ITerm > outMax) ITerm= outMax;
   else if(ITerm < outMin) ITerm= outMin;
}
 
void SetMode(int Mode)
{
    bool newAuto = (Mode == AUTOMATIC);
    if(newAuto == !inAuto)
    {  /*we just went from manual to auto*/
        Initialize();
    }
    inAuto = newAuto;
}
 
void Initialize()
{
   lastInput = Input;
   ITerm = Output;
   if(ITerm > outMax) ITerm= outMax;
   else if(ITerm < outMin) ITerm= outMin;
}
 
void SetControllerDirection(int Direction)
{
   controllerDirection = Direction;
}

結語

至此,PID控制器的介紹已經完畢,這僅僅是一個很普通的PID控制器,具有了PID控制的基本要素,而且考慮了一切特殊的狀況,大大增長了環境適應性。get

而後PID控制的一個大大大大問題,就是如何選取合適的Kp、Ki、Kd參數用於知足變幻無窮的應用場景,目前調節PID參數主要仍是靠經驗和不斷地試湊,人們也不斷地在尋求如何選取合適的PID參數的方法。針對上述問題,應運而生了一個命題「自動調諧PID」控制器,即咱們在作PID控制的時候,不須要給出很是精確的PID參數,系統會自動幫助咱們找到一組「較爲」合適的PID控制參數,這樣既可大大減少了對經驗和試湊的要求。it

在後續的文章中,將介紹如下幾個命題:io

一、如何進行自動調參,目前主流的自動調參方式有哪些?ast

二、介紹RELAY METHOD方式的自動調參庫是如何實現的

三、整合了PID及自動調參的PID控制庫

NOTE:若有不足之處請告知。^.^

NEXT

PS:轉載請註明出處:歐陽天華

相關文章
相關標籤/搜索