不用浮點實現pid 關於PID公式實現的一點困惑。

2021-10-17 05:26:09 字數 1462 閱讀 3450

查資料發現網上關於pid的實現方式有增量式pid和位置式pid兩種。

struct _pidpid;

/*增量式實現*/

float pidcal(float speed)//輸入實測速度,返回執行器pwm的數值pid;

struct err_queenerr_queen;//定義乙個儲存過去誤差值的環形陣列,用於積分。//因為電機響應速度很快,只取最新的10個值來影響本次輸出

float pidcal(float speed)

pid.actualspeed = speed;

pid.err = pid.setspeed - pid.actualspeed;

err_queen.errs[err_queen.num]=pid.err;

pid.integral += err_queen.errs[err_queen.num]-err_queen.errs[(err_queen.num==9)?0:(err_queen.num+1)];

//將最新的誤差值加入積分值並減去最舊的資料 pid.err_2 = pid.err_1;

pid.err_1 = pid.err;

err_queen.num ++ ;

if(err_queen.num==10)

err_queen.num=0;

pid.pwm += pid.kp*pid.err + pid.ki*pid.integral +pid.kd*(pid.err-pid.err_1);

return pid.pwm;

pid.pwm +=pid.kp*pid.err +pid.ki*pid.integral +pid.kd*(pid.err-pid.err_1);

這樣的公式才能在電機穩定的情況下 pid.pwm輸出乙個大體穩定的值。電機速度如果有波動,產生pid.err,pid.pwm會在pid.err的作用下細微變化調整電機速度。其中pid.kp起主要作用,pid.ki,pid.kd係數較小,視情況調整。

由於理解不了網上的**,但是大家都在用應該沒問題啊。我的**實現實際上是將位置式的pid實現進行累加。而且這樣的做效果最好。所以寫在這裡大家幫忙分析。到底怎麼回事。

實驗環境:使用hall感測器換向和測速,方波六步換向驅動。電機為2個磁極對。雖然電機轉動一圈產生12個hall邊沿事件,但是由於hall感測器的占空比做不到完全50%,因此6個邊沿事件才能完成一次測速。即轉動一圈更新2個速度值。

pid控制頻率為20hz,(600r/min以下的速度不控制)。積分值只累加10個,因為電機響應很快,0.5s前的狀態對現在意義不大。

pwm頻率28.8khz,pwm週期值為2500,pwm=1000大概等於電機2000r/min。

可以看出轉速波動不大

Pid控制演算法 增量型pid演算法的C 實現

上一節中介紹了最簡單的位置型pid的實現手段,這一節主要講解增量式pid的實現方法.實現過程仍然是分為定義變數 初始化變數 實現控制演算法函式 演算法測試四個部分,這裡直接給出 了。pid.h ifndef pid h define pid h typedef struct pidpid class...

關於PID演算法的難點理解

基本算式 離散寫法 連續寫法 比例調節 部分最容易理解,將期望值和目前所在的狀態值作差得error k 即e k 其係數即根據差值得調節速度大小 積分調節 是為了解決比例調節一常見軟肋,即穩態誤差。穩態誤差 用水池灌水的比方可以很好理解,比如放入90 水時,出水速度大小恰好等於比例調節項,使得系統穩...

PID演算法的理解及實現

關於理解pid控制演算法最典型的乙個例子就是乙個漏水的水缸的問題。網上有很多講解pid的帖子會講到這個例子。這裡我也把我自己對於pid的理解用這個例子闡述一遍。有個漏水的水缸,而且漏水的速度還不是恆定的。然後我們還有個水桶,我們可以控制往水缸裡面加水或者從水缸裡面舀水出來。另外我們可以檢測水平面。現...