PID--積分分離法--003


#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;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM