積分飽和通俗講就是系統在乙個偏差方向上的飽和,比如乙個系統設定了輸出不會超過100,但因為出現乙個方向上的偏差積分使得輸出超過了100,此時達到了飽和狀態,如果繼續在這個方向上積分會導致pid控制超過100系統卻執行在100,相當於積分調節對系統輸出沒有作用,就出現失控的狀態,這是系統不能接受的,而且飽和積分越深,退出飽和就越久。上面是在正向的飽和,負向的飽和類似!
下面我以 位置型+抗積分飽和+積分分離的pid控制演算法c語言來觀察調節結果:(相對應的**可以參考以往的文章)
//位置型+抗積分飽和+積分分離 pid控制演算法
struct _pidpid;
void pid_init(void)
printf("pid_init begin! \n");
pid.setspeed = 0;
pid.actualspeed = 0;
pid.err = 0;
pid.err_last = 0;
pid.kp = 0.2;
pid.ki = 0.1; //增大了積分環節的值
pid.kd = 0.2;
pid.voltage = 0;
pid.integral = 0;
pid.umax = 400; //正飽和值為400
pid.umin = -200; //負飽和值為-200
printf("pid_init end! \n");
float pid_cal(float speed)
unsigned char index;
pid.setspeed = speed;
pid.err = pid.setspeed - pid.actualspeed;
if(pid.actualspeed>pid.umax) //如果上一次輸出變數出現正向的飽和
if(abs(pid.err)>200)
index = 0;
else
index = 1;
if(pid.err<0)
pid.integral += pid.err; //正飽和只積分負偏差
else if(pid.actualspeed {
if(abs(pid.err)>200)
index = 0;
else
index = 1;
if(pid.err>0)
pid.integral += pid.err; //負飽和只積分正偏差
else
if(abs(pid.err)>200) //積分分離的pid優化,可參考以往的文章
index = 0;
else
index = 1;
pid.integral += pid.err;
pid.voltage = pid.kp*pid.err +index*pid.ki*pid.integral + pid.kd*(pid.err - pid.err_last);
pid.err_last = pid.err;
pid.actualspeed = pid.voltage*1.0;
return pid.actualspeed;
int main(void)
int count = 0 ;
printf("system begin! \n");
pid_init();
while(count<1000)
float speed = pid_cal(200.0);
printf("-%d-%f-",count,speed);
count++;
return 0;
最後執行結果:
我們發現,相對以往的演算法,還演算法大大提高了調節的速度和穩定!
PID演算法的C語言實現方式
在控制系統中很多地方都用到了pid控制器,那麼pid控制器的c語言實現方式是什麼呢?什麼是pid呢?假設我們要通過控制pwm波的占空比控制輸出電壓。typedef struct pid tag pid double pidcalc pid pp,double nextpoint double sen...
一般PID的C語言實現
先看看pid的結構框圖 pid是自動控制演算法裡面最經典,同時也是最簡單的乙個演算法。其經典與簡單程度類似物理學中的牛頓力學三大定律。pid的中心思想是通過誤差來控制輸出,所以pid通常具有以下幾個關鍵的量。1 輸入量r in 2 輸出量r out 3 誤差 error 輸入量 輸出量 pid的控制...
C語言實現PID控制基本(四) 梯形演算法
時間久了 具體對比 三 的不同點,有點忘了,今天先蹭個徽章 include include struct pid pid void pid init float pid realize float speed else 偏差絕對值不大於200 差距不大時 因為實際速度大於設定最大值 設定最大值應該不...