#include <stdio.h> #include <stdlib.h> #include <string.h> /****************************************************************** 積分分離的 PID 控制算法 在普通 PID 控制中, 引入積分環節的目的, 主要是為了消除靜差, 提高 控制精度。 但是在啟動、 結束或大幅度增減設定時, 短時間內系統輸出有很大的 偏差, 會造成 PID 運算的積分積累, 導致控制量超過執行機構可能允許的最大動 作范圍對應極限控制量, 從而引起較大的超調, 甚至是震盪, 這是絕對不允許的。 為了克服這一問題, 引入了積分分離的概念, 其基本思路是 當被控量與設 定值偏差較大時, 取消積分作用; 當被控量接近給定值時, 引入積分控制, 以消 除靜差, 提高精度。 其具體實現代碼如下: *******************************************************************/ typedef struct { float SetSpeed; //定義設定值 float ActualSpeed; //定義實際值 float err; //定義偏差值 float err_last; //定義上一個偏差值 float Kp,Ki,Kd; //定義比例、 積分、 微分系數 float voltage; //定義電壓值(控制執行器的變量) float integral; //定義積分值 } PID ; void PID_Init(); float PID_realize(float speed); PID pid ; FILE* out ; int main() { out = fopen("C:\\Users\\Administrator\\Desktop\\log.txt","w"); if(out) { printf("File open err...\n"); } printf("System begin \n"); PID_Init(); unsigned long count=0; while(count<2000) { float speed=PID_realize(200.0); printf("%f\n",speed); fprintf(out,"%f\n",speed); fflush(out); count++; } fclose(out); return 0; } void PID_Init() { printf("PID_init begin \n"); pid.SetSpeed=0.0; pid.ActualSpeed=0.0; pid.err=0.0; pid.err_last=0.0; pid.voltage=0.0; pid.integral=0.0; pid.Kp=0.2; pid.Ki=0.015; pid.Kd=0.2; printf("PID_init end \n"); } float PID_realize(float speed) { int index = 0 ; pid.SetSpeed=speed; pid.err=pid.SetSpeed-pid.ActualSpeed; // pid.integral+=pid.err; // pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last); if(abs(pid.err)>200) { 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; }