日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

改进初学者的PID-初始化

發布時間:2024/7/23 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 改进初学者的PID-初始化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近看到了Brett Beauregard發表的有關PID的系列文章,感覺對于理解PID算法很有幫助,于是將系列文章翻譯過來!在自我提高的過程中,也希望對同道中人有所幫助。作者Brett Beauregard的原文網址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner‘s-pid-initialization/

?

1、問題所在

在前一節中,我們實現了關閉和打開 PID 的功能。我們將其關閉,但現在讓我們來看看當我們重新打開它時會發生什么:

?

呵!PID跳回到它發送的最后一個輸出值,然后從那里開始調整。這將導致我們不希望出現的輸入顛簸。

2、解決方案

這個很容易解決。因為我們現在知道什么時候打開 (從手動到自動),我們只需為一個平穩的過渡做一些初始化。這意味著對2個工作變量的存儲 (積分項和最后的輸入項) 進行處理,以防止輸出跳轉。

3、代碼

/*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 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) {double SampleTimeInSec = ((double)SampleTime)/1000;kp = Kp;ki = Ki * SampleTimeInSec;kd = Kd / SampleTimeInSec; }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; }

我們修改了 SetMode (...) 以檢測從手動到自動的轉換,并添加了初始化功能。它通過設置“積分項=輸出”來處理積分項,“最后輸入=輸入”以防止微分激增。比例項不依賴于過去的任何信息,因此不需要任何初始化。

4、最終結果

?

我們從上面的圖表中看到,正確的初始化會導致從手動到自動的無擾動切換,這正是我們所追求的。

5、更新: 為什么不 ITerm=0

我最近收到了很多問題,問為什么我沒有把 ITerm=0 設置為初始化。作為答案,我請您考慮以下方案:PID是手動的,用戶已將輸出設置為50。一段時間后,該過程穩定到75.2 的輸入。用戶將設置點75.2 打開 PID。會發生什么事?

我認為,切換到自動后,輸出值應該保持在50。由于 P 和 D 項將為零,因此發生這種情況的唯一方法是將 ITerm項初始化為“輸出”值。

如果您處于需要輸出初始化為零的情況,則無需更改上面的代碼。在將 PID 從“手動”轉換為“自動”之前,只需在調用例程中設置Output=0。

歡迎關注:

總結

以上是生活随笔為你收集整理的改进初学者的PID-初始化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。