那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是PID算法

汽車電子技術(shù) ? 來源:滑小稽筆記 ? 作者:電子技術(shù)園地 ? 2023-03-01 14:24 ? 次閱讀

2.1 PID算法數(shù)學推導過程

2.1.1 連續(xù)系統(tǒng)的PID算法

圖片

2.1.2 PID算法的離散化

圖片

2.2 位置型PID算法

2.2.1 MATLAB算法

clc
clear
%PID初始化
len = 500 ;                                                                 %運算次數(shù)
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %過程值
err = zeros(1,len);                                                       %誤差值
err_0 = 0 ;                                                                 %k時刻誤差
err_1 = 0 ;                                                                 %k-1時刻誤差
y_d_last = 0 ;                                                             %k-1時刻輸出
integral = 0;                                                              %積分值
Kp = 0.2;                                                                   %比例系數(shù)
Kd = 0.2;                                                                   %微分值
Ki = 0.015 ;                                                                %積分值
%運算過程
for k=1:1:len
y(k) = 200 ;                                                            %期望輸出
err_0 = y(k)-y_d_last;                                                 %計算偏差
    integral = integral+err_last;                                        %誤差累計
y_d_last = Kp* err_0 + Ki*integral + Kd*( err_1- err_0);        %位置型PID運算公式
err_1 = err_0 ;
    %更新參數(shù)
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%輸出圖像繪制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('輸出曲線');
xlabel('t')
ylabel('y(t)')
%誤差圖像繪制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('誤差曲線');
xlabel('t')
ylabel('e(t)')

MATLAB運行結(jié)果如下圖所示。

圖片

2.2.2 C算法

#include
struct _pid
{
    float SetSpeed ;                                               //設(shè)置速度
    float ActualSpeed ;                                             //實際速度
    float err ;                                                     //誤差
    float err_last ;                                                  //最終誤差
    float Kp , Kd , Ki ;                                              //比例系數(shù)
    float voltage ;                                                 //輸出電壓
    float integral ;                                                  //積分值
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.015 ;
}
float PID_Realize( float Speed )
{
    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 ) ;
    pid.err_last  = pid.err ;
    pid.ActualSpeed = pid.voltage*1.0 ;
    return pid.ActualSpeed ;
}
void main()
{
    int count ;
    count = 0 ;
    PID_Init() ;
    while( count<850 )
    {
        float Speed = PID_Realize( 200.0 ) ;
        count ++ ;
    }
}

2.3 增量型PID算法

2.3.1 MATLAB算法

clc
clear
%PID初始化
len = 400 ;                                                                      %運算次數(shù)
y = zeros(1,len);                                                               %期望值
y_d = zeros(1,len);                                                           %過程值
err = zeros(1,len);                                                           %誤差值
err_0 = 0 ;                                                                     %k時刻誤差
err_1 = 0 ;                                                                     %k-1時刻誤差
err_2 = 0 ;                                                                     %k-2時刻誤差
y_d_last = 0 ;                                                                  %k-1時刻輸出
increment = 0 ;                                                                 %增量
Kp = 0.2;                                                                       %比例系數(shù)
Kd = 0.2;                                                                       %微分值
Ki = 0.015 ;                                                                    %積分值
%運算過程
for k=1:1:len
y(k) = 200 ;                                                                %期望輸出
err_0 = y(k)-y_d_last;                                                    %計算偏差
    increment = Kp*(err_0-err_1) + Ki*err_0 + Kd*(err_0-2*err_1+err_2);%增量型PID運算公式
    err_2 = err_1;
    err_1 = err_0;
    y_d_last = y_d_last + increment ;                                       %輸出疊加
    %更新參數(shù)
    y_d(k) = y_d_last ;
    err(k) = err_2;
end
%輸出圖像繪制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('輸出曲線');
xlabel('t')
ylabel('y(t)')
%誤差圖像繪制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('誤差曲線');
xlabel('t')
ylabel('e(t)')

MATLAB運行結(jié)果如下圖所示。

圖片

2.3.2 C算法

#include
struct _pid
{
    float SetSpeed ;                                               //設(shè)置速度
    float ActualSpeed ;                                            //實際速度
    float err ;                                                    //誤差
    float err_next ;                                                //上一次誤差
    float err_last ;                                                  //最終誤差
    float Kp , Kd , Ki ;                                              //比例系數(shù)
}pid;
void PID_Init()
{
    pid.SetSpeed = 0 ;
    pid.ActualSpeed = 0.0 ;
    pid.err = 0.0 ;
    pid.err_last = 0.0 ;
    pid.err_next = 0.0 ;
    pid.Kp = 0.2 ;
    pid.Kd = 0.2 ;
    pid.Ki = 0.015 ;
}
float PID_Realize( float Speed )
{
    float incrementSpeed ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
incrementSpeed=
pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*( pid.err-2*pid.err_next+pid.err_last ) ;
    pid.err_last  = pid.err_next ;
    pid.err_next = pid.err ;
    pid.ActualSpeed += incrementSpeed ;
    return pid.ActualSpeed ;
}
void main()
{
    int count ;
    count = 0 ;
    PID_Init() ;
    while( count<850 )
    {
        float Speed = PID_Realize( 200.0 ) ;
        count ++ ;
    }
}

2.4 積分分離型PID算法

2.4.1 實現(xiàn)原理

為了消除系統(tǒng)的穩(wěn)態(tài)誤差,提高控制精度引入了積分環(huán)節(jié),但是在啟動,結(jié)束和大幅度增減設(shè)定時,短時間內(nèi)系統(tǒng)輸出有很大的偏差,會造成PID運算的積分積累,導致控制量超過執(zhí)行機構(gòu)可能允許的最大動作范囲所對應(yīng)的極限控制量,從而引起較大的超調(diào),甚至震蕩,為了克服這一問題,引入了積分分離的概念,基本思路是“當給定值與反饋值偏差較大時,取消積分的作用,當被控量接近給定值時,引入積分控制”,用于消除穩(wěn)態(tài)誤差,提高系統(tǒng)的精度。

2.4.2 MATLAB算法

clc
clear
%PID初始化
len = 500 ;                                                                 %運算次數(shù)
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %過程值
err = zeros(1,len);                                                       %誤差值
err_0 = 0 ;                                                                 %k時刻誤差
err_1 = 0 ;                                                                 %k-1時刻誤差
y_d_last = 0 ;                                                             %k-1時刻輸出
integral = 0;                                                              %積分值
Kp = 0.2;                                                                   %比例系數(shù)
Kd = 0.2;                                                                   %微分值
Ki = 0.015 ;                                                                %積分值
max = 400 ;                                                                 %積分上限
index = 0 ;                                                                 %積分有效性
%運算過程
for k=1:1:len
y(k) = 200 ;                                                            %期望輸出
err_0 = y(k)-y_d_last;                                                 %計算偏差
    if abs(err_0) <= y(k)
        index = 1 ;
        integral = integral+err_0;                                        %誤差累計
    else
        index = 0 ;
    end
    y_d_last = Kp*err_0 + Ki*index*integral + Kd*(err_1-err_0);   %位置型PID運算公式
err_1 = err_0 ;
    %更新參數(shù)
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%輸出圖像繪制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('輸出曲線');
xlabel('t')
ylabel('y(t)')
%誤差圖像繪制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('誤差曲線');
xlabel('t')
ylabel('e(t)')

MATLAB運行結(jié)果如下圖所示。

圖片

2.4.3 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //設(shè)置速度
    float ActualSpeed ;                                             //實際速度
    float err ;                                                     //誤差
    float err_last ;                                                  //最終誤差
    float Kp , Kd , Ki ;                                              //比例系數(shù)
    float voltage ;                                                 //輸出電壓
    float integral ;                                                  //積分值
    float umax ;                                                  //積分上限
    float umin ;                                                  //積分下限
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.1 ;
    pid.umax = 400 ;
    pid.umin = -200 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( abs(pid.err)<= pid.umax )
    {
        index = 1 ;
        pid.integral += pid.err ;
    }
    else
        index = 0 ;
    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 ;
}
void main()
{
    int count ;
    count = 0 ;
    PID_Init() ;
    while( count<1000 )
    {
        float Speed = PID_Realize( 200.0 ) ;
        count ++ ;
        printf( "%.2f\\n" , Speed ) ;
    }
}

2.5 抗積分飽和型PID算法

2.5.1 實現(xiàn)原理

所謂積分飽和現(xiàn)象是指如果系統(tǒng)存在一個方向的偏差,PID控制器的輸出會因為存在積分環(huán)節(jié)而不斷累積增大,從而導致執(zhí)行機構(gòu)達到極限位置,若控制器輸出響應(yīng)繼續(xù)增大,執(zhí)行器開度不可能再增大,此時計算機輸出控制量超出了正常運行范圍而進入飽和區(qū),一旦系統(tǒng)出現(xiàn)反向偏差,輸出響應(yīng)逐漸從飽和區(qū)退出,進入飽和區(qū)時間越長則退出飽和區(qū)的時間也就隨之增加,這段時間里,執(zhí)行機構(gòu)仍然停留在極限位置而不能隨著偏差方向立即作出相應(yīng)的改變,造成控制性能惡化,這種現(xiàn)象稱為積分飽和現(xiàn)象或積分失控現(xiàn)象。實現(xiàn)抗積分飽和算法的基本思路是計算系統(tǒng)的響應(yīng)時,首先判斷上一時刻的控制量是否超出了極限范圍,如果超過上限,則只累計反向偏差,若低于下限,則只累計正向偏差,從而避免控制量長時間停留在飽和區(qū)。

2.5.2 MATLAB算法

clc
clear
%PID初始化
len = 180 ;                                                                 %運算次數(shù)
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %過程值
err = zeros(1,len);                                                       %誤差值
err_0 = 0 ;                                                                 %k時刻誤差
err_1 = 0 ;                                                                 %k-1時刻誤差
y_d_last = 0 ;                                                             %k-1時刻輸出
integral = 0;                                                              %積分值
Kp = 0.2;                                                                   %比例系數(shù)
Kd = 0.2;                                                                   %微分值
Ki = 0.1 ;                                                                  %積分值
max = 400 ;                                                                 %積分上限
min = -200 ;                                                                %積分下限
index = 0 ;                                                                 %積分有效性
%運算過程
for k=1:1:len
y(k) = 200 ;                                                            %期望輸出
err_0 = y(k)-y_d_last;                                                 %計算偏差
    if y_d_last>max
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 < 0
                integral = integral+err_0;                                %誤差累計
            end
        else
            index = 0 ;
        end
    elseif y_d_last<min
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 > 0
                integral = integral+err_0;                                  %誤差累計
            end
        else
            index = 0 ;
        end
    else
        if abs(err_0) <= y(k)
            index = 1 ;
            integral = integral+err_0;                                      %誤差累計
        else
            index = 0 ;
        end
    end
    y_d_last = Kp*err_0 + Ki*index*integral + Kd*(err_1-err_0);   %位置型PID運算公式
err_1 = err_0 ;
    %更新參數(shù)
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%輸出圖像繪制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('輸出曲線');
xlabel('t')
ylabel('y(t)')
%誤差圖像繪制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('誤差曲線');
xlabel('t')
ylabel('e(t)')

MATLAB運行結(jié)果如下圖所示。

圖片

2.5.3 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //設(shè)置速度
    float ActualSpeed ;                                             //實際速度
    float err ;                                                     //誤差
    float err_last ;                                                  //最終誤差
    float Kp , Kd , Ki ;                                              //比例系數(shù)
    float voltage ;                                                 //輸出電壓
    float integral ;                                                  //積分值
    float umax ;                                                  //積分上限
    float umin ;                                                  //積分下限
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.1 ;
    pid.umax = 400 ;
    pid.umin = -200 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( pid.ActualSpeed>pid.umax )
    {
        if( abs(pid.err)<=200 )
        {
            index = 1 ;
            if( pid.err<0 )
                pid.integral += pid.err ;
        }
        else
            index = 0 ;
    }
    else if( pid.ActualSpeed

2.6 梯形積分PID算法

2.6.1 實現(xiàn)原理

根據(jù)梯形算法的積分環(huán)節(jié)公式

圖片

作為PID控制的積分項,其作用是消除余差,為了盡量減小余差,應(yīng)提高積分項運算精度,為此可以將矩形積分改為梯形積分,具體實現(xiàn)的語句為pid.voltage = pid.Kppid.err+indexpid.Ki pid.integral/2+pid.Kd ( pid.err-pid.err_last ) ;

2.6.2 MATLAB算法

clc
clear
%PID初始化
len = 358 ;                                                                 %運算次數(shù)
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %過程值
err = zeros(1,len);                                                       %誤差值
err_0 = 0 ;                                                                 %k時刻誤差
err_1 = 0 ;                                                                 %k-1時刻誤差
y_d_last = 0 ;                                                             %k-1時刻輸出
integral = 0;                                                              %積分值
Kp = 0.2;                                                                   %比例系數(shù)
Kd = 0.2;                                                                   %微分值
Ki = 0.1 ;                                                                  %積分值
max = 400 ;                                                                 %積分上限
min = -200 ;                                                                %積分下限
index = 0 ;                                                                 %積分有效性
%運算過程
for k=1:1:len
y(k) = 200 ;                                                            %期望輸出
err_0 = y(k)-y_d_last;                                                 %計算偏差
    if y_d_last>max
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 < 0
                integral = integral+err_0;                                %誤差累計
            end
        else
            index = 0 ;
        end
    elseif y_d_last<min
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 > 0
                integral = integral+err_0;                                  %誤差累計
            end
        else
            index = 0 ;
        end
    else
        if abs(err_0) <= y(k)
            index = 1 ;
            integral = integral+err_0;                                      %誤差累計
        else
            index = 0 ;
        end
    end
    y_d_last = Kp*err_0 + Ki*index*integral/2 + Kd*(err_1-err_0);   %PID運算公式
err_1 = err_0 ;
    %更新參數(shù)
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%輸出圖像繪制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('輸出曲線');
xlabel('t')
ylabel('y(t)')
%誤差圖像繪制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('誤差曲線');
xlabel('t')
ylabel('e(t)')

MATLAB運行結(jié)果如下圖所示。

圖片

2.6.3 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //設(shè)置速度
    float ActualSpeed ;                                             //實際速度
    float err ;                                                     //誤差
    float err_last ;                                                  //最終誤差
    float Kp , Kd , Ki ;                                              //比例系數(shù)
    float voltage ;                                                 //輸出電壓
    float integral ;                                                  //積分值
    float umax ;                                                  //積分上限
    float umin ;                                                  //積分下限
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.1 ;
    pid.umax = 400 ;
    pid.umin = -200 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( pid.ActualSpeed>pid.umax )
    {
        if( abs(pid.err)<=200 )
        {
            index = 1 ;
            if( pid.err<0 )
                pid.integral += pid.err ;
        }
        else
            index = 0 ;
    }
    else if( pid.ActualSpeed

2.7 變積分PID算法

2.7.1 實現(xiàn)原理

變積分PID可以看做是積分分離的PID算法的更一般形式,在普通的PID控制算法中,由于積分系數(shù)是常數(shù),所以在整個控制過程中,積分增量是不變的,但是,系統(tǒng)對于積分項的要求是,系統(tǒng)偏差較大時,積分作用應(yīng)該減弱甚至全無,而在偏差較小時,則應(yīng)該加強,積分系數(shù)取大了會引起超調(diào),甚至積分飽和,取小了又不能短時間內(nèi)消除靜差,因此,需要根據(jù)系統(tǒng)偏差的大小改變積分速度。

變積分PID的基本思想是改變積分項的累加速度,使其與偏差大小相對應(yīng),偏差越大,積分越慢,偏差較小,積分越快。

這里給積分系數(shù)前加一個比例系數(shù)index,使最終的比例環(huán)節(jié)的積分系數(shù)為Ki*index

2.7.1 MATLAB算法

clc
clear
%PID初始化
len = 200 ;                                                                 %運算次數(shù)
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %過程值
err = zeros(1,len);                                                       %誤差值
err_0 = 0 ;                                                                 %k時刻誤差
err_1 = 0 ;                                                                 %k-1時刻誤差
y_d_last = 0 ;                                                             %k-1時刻輸出
integral = 0;                                                              %積分值
Kp = 0.4;                                                                   %比例系數(shù)
Kd = 0.2;                                                                   %微分值
Ki = 0.2 ;                                                                %積分值
max = 400 ;                                                                 %積分上限
min = -200 ;                                                                %積分下限
index = 0 ;                                                                 %積分有效性
%運算過程
for k=1:1:len
y(k) = 200 ;                                                            %期望輸出
err_0 = y(k)-y_d_last;                                                 %計算偏差
    if abs(err_0) > max
            index = 0 ;
    elseif abs(err_0) < min
        index = 1 ;
        integral = integral+err_0;                                       %誤差累計
    else
        index = ( max-abs(err_0) )/20 ;
        integral = integral+err_0;                                       %誤差累計
    end
    y_d_last = Kp*err_0 + Ki*index*integral/2 + Kd*(err_1-err_0); %PID運算公式
err_1 = err_0 ;
    %更新參數(shù)
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%輸出圖像繪制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('輸出曲線');
xlabel('t')
ylabel('y(t)')
%誤差圖像繪制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('誤差曲線');
xlabel('t')
ylabel('e(t)')

MATLAB運行結(jié)果如下圖所示。

圖片

2.7.2 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //設(shè)置速度
    float ActualSpeed ;                                             //實際速度
    float err ;                                                     //誤差
    float err_last ;                                                  //最終誤差
    float Kp , Kd , Ki ;                                              //比例系數(shù)
    float voltage ;                                                 //輸出電壓
    float integral ;                                                  //積分值
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.4 ;
    pid.Kd = 0.2 ;
    pid.Ki = 0.2 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( abs(pid.err)>200 )
        index = 0 ;
    else if( abs(pid.err)<180 )
    {
        index = 1 ;
        pid.integral += pid.err ;
    }
    else
    {
        index = ( 200-abs(pid.err) )/20 ;
        pid.integral += pid.err ;
    }
    pid.voltage = pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*( pid.err-pid.err_last ) ;
    pid.err_last  = pid.err ;
    pid.ActualSpeed = pid.voltage*1.0 ;
    return pid.ActualSpeed ;
}
void main()
{
    int count ;
    count = 0 ;
    PID_Init() ;
    while( count<150 )
    {
        float Speed = PID_Realize( 200.0 ) ;
        count ++ ;
        printf( "%.2f\\n" , Speed ) ;
    }
}

2.8 專家PID與模糊PID算法思想

PID的控制思想非常簡單,主要就是比例,積分和微分環(huán)節(jié)的參數(shù)整定過程,對于執(zhí)行期控制模型確定或者控制模型簡單的系統(tǒng)來說,參數(shù)的整定可以通過計算獲得,對于一般精度要求不是很高的執(zhí)行器系統(tǒng),可以采用拼湊的方法進行實驗型的整定。

但是,實際的系統(tǒng)大部分屬于非線性系統(tǒng),或者說是系統(tǒng)模型不確定的系統(tǒng),如果控制精度要求較高的話,那么對于參數(shù)的整定過程也是有難度的,專家PID和模糊PID就是為了滿足這方面的需求而設(shè)計的,專家算法和模糊算法都歸屬于智能算法的范疇,智能算法最大的優(yōu)點就是在控制模型未知的情況下,可以對模型進行控制,這里需要注意的是,專家PID也好,模糊PID也好,絕對不是專家系統(tǒng)或模糊算大與PID控制算法的簡單加和,它是專家系統(tǒng)或者模糊算法在PID控制器參數(shù)整定上的應(yīng)用,也就是說,智能算法是輔助PID進行參數(shù)整定的手段。

關(guān)于專家PID的C語言實現(xiàn),需要找到一些依據(jù),還需要從PID系數(shù)本身考慮。

1、比例系數(shù)Kp的作用是加快系統(tǒng)的響應(yīng)速度,提高系統(tǒng)的調(diào)節(jié)精度,Kp越大,系統(tǒng)的響應(yīng)速度越快,調(diào)節(jié)的精度越高,但是容易產(chǎn)生超調(diào),甚至會引起系統(tǒng)不穩(wěn)定,Kp取值過小,則會降低系統(tǒng)的調(diào)節(jié)精度,拖慢響應(yīng)速度,從而延長調(diào)節(jié)時間,使系統(tǒng)的靜態(tài),動態(tài)特性變差。

2、積分系數(shù)Ki的作用是消除系統(tǒng)的穩(wěn)態(tài)誤差,Ki越大,系統(tǒng)的靜態(tài)誤差消除得越快,但是若Ki過大,在響應(yīng)過程的初期就會產(chǎn)生積分飽和的現(xiàn)象,從而引起相應(yīng)過程的較大超調(diào),若Ki過小,將使系統(tǒng)靜態(tài)誤差難以消除,影像系統(tǒng)的調(diào)節(jié)精度。

3、微分系數(shù)Kd的作用是改善系統(tǒng)的動態(tài)特性,其作用主要是在響應(yīng)過程中抑制偏差向任何方向的變化,對偏差變化進行提前預(yù)報,但是若Kd過大,會使響應(yīng)過程提前制動,從而延長調(diào)節(jié)時間,而且會降低系統(tǒng)的抗干擾性。

圖片

2.9 PID算法應(yīng)用——電機轉(zhuǎn)速控制

PID是一種廣泛應(yīng)用在控制理論中的算法,以直流電機為例,要想精確控制電機的轉(zhuǎn)速就需要形成一種閉環(huán)控制思想。首先將一個默認的輸入端的電壓值發(fā)送給直流電機,通過轉(zhuǎn)速傳感器將當前電機的轉(zhuǎn)速反饋到輸入端,通過與輸入端做運算,如果轉(zhuǎn)速高于設(shè)定的值,則減小輸入端電壓,如果轉(zhuǎn)速低于設(shè)定的值,則提高輸入端電壓,由此形成了一種閉環(huán)控制回路,即通過不停的對輸出端進行反饋,以達到精確控制的目的。為了使控制系統(tǒng)的速度更快,精確性更高,穩(wěn)定性更強,PID控制器被廣泛應(yīng)用在了這里面,現(xiàn)在我們通過MATLAB的Simulink來實現(xiàn)直流電機的PID控制。

圖片

一個直流電機的模型如上圖所示,為了簡化討論,假設(shè)轉(zhuǎn)子和轉(zhuǎn)軸都是剛體,且轉(zhuǎn)子受到的磁場恒定,轉(zhuǎn)子收到的摩擦力與速度成正比,該電機的物理參數(shù)為:

(1)轉(zhuǎn)子的轉(zhuǎn)動慣量J=0.01kg·m^2^

(2)電機摩擦系數(shù)b=0.01N···m·s

(3)電動勢常數(shù)Ke=0.01V/rad/sec

(4)電機扭矩常數(shù)Kt=0.01N·m/Amp

(5)電阻R=1Ω

(6)電感L=0.5H

圖片

我們希望控制器輸入1V電壓的時候穩(wěn)定狀態(tài)下保持0.1rad/sec的轉(zhuǎn)速,穩(wěn)定時間2s,穩(wěn)態(tài)誤差低于1%,受到階躍輸入干擾的時候超調(diào)小于5%。Matlab的仿真并不像之前學習51的時候用的Protuse一樣,可以看到直觀效果,Matlab的仿真實際是對數(shù)學的計算過程,即輸入與輸出必須都抽象成函數(shù)表達式進行,通過觀察輸出的函數(shù)表達式與波形來判斷系統(tǒng)的工作狀態(tài)與性能。我們將上面得到的復頻域下的函數(shù)表達式代入?yún)?shù),得到

圖片

通過Simulink創(chuàng)建仿真圖如下圖所示。

圖片

雙擊PID控制器的圖標,打開了以下對話框。

圖片

對話框內(nèi)的這三個參數(shù)就是PID控制器的三個參數(shù),其中Proportional代表比例環(huán)節(jié),Integral代表積分環(huán)節(jié),Derivative代表微分環(huán)節(jié),通過修改這三個參數(shù)達到實現(xiàn)控制系統(tǒng)的目的。

在PID控制中,這三個參數(shù)分別對系統(tǒng)控制有以下幾個作用:

(1)比例環(huán)節(jié)P:控制輸出響應(yīng)的速度,減小穩(wěn)態(tài)誤差,但是會增大超調(diào)量

(2)積分環(huán)節(jié)I:消除系統(tǒng)的穩(wěn)態(tài)誤差,加快達到穩(wěn)定所需的時間,但也會增大超調(diào)量

(3)微分環(huán)節(jié)D:加快動態(tài)過程,容易引起系統(tǒng)震蕩,同樣,微分環(huán)節(jié)也會增大超調(diào)量

為了滿足:

(1)穩(wěn)定時間2s

(2)穩(wěn)態(tài)誤差低于1%

(3)超調(diào)小于5%

這三個條件,我們首先修改比例環(huán)節(jié),用來滿足穩(wěn)態(tài)誤差低于1%這個參數(shù)。通過實驗發(fā)現(xiàn),當比例環(huán)節(jié)設(shè)定在100以上的時候,穩(wěn)態(tài)誤差低于1%,如下圖所示。

圖片

但是我們發(fā)現(xiàn)

圖片

即系統(tǒng)的超調(diào)量較大,達到了20%,此時需要調(diào)節(jié)微分環(huán)節(jié)達到目的,我們通過實驗發(fā)現(xiàn),當微分環(huán)節(jié)超過10時,系統(tǒng)的超調(diào)如下圖所示。

圖片

此時系統(tǒng)已經(jīng)不存在超調(diào),現(xiàn)在只需要解決穩(wěn)定時間小于2s這個參數(shù)即可,我們通過設(shè)置積分環(huán)節(jié)達到這個目的,通過實驗發(fā)現(xiàn),當系統(tǒng)的積分環(huán)節(jié)大于200時,穩(wěn)定時間小于2s。此時整個系統(tǒng)的波形如下圖所示。

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • PID
    PID
    +關(guān)注

    關(guān)注

    35

    文章

    1473

    瀏覽量

    85825
  • 穩(wěn)態(tài)誤差
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    2123
  • 系統(tǒng)
    +關(guān)注

    關(guān)注

    1

    文章

    1019

    瀏覽量

    21431
收藏 人收藏

    評論

    相關(guān)推薦

    PID算法

    PID算法
    發(fā)表于 01-15 15:01

    PID算法

    一些PID算法的資料
    發(fā)表于 07-21 17:00

    pid算法原理

    pid算法原理送給大家
    發(fā)表于 08-09 09:16

    PID算法原理

    電子資料PID算法原理
    發(fā)表于 06-13 11:41

    STM32的PID算法實例

    STM32單片機的PID算法實例,通過PID算法控制STM32的PWM輸出,反饋量是PWM低通濾波后得到的AD
    發(fā)表于 09-19 15:44

    PID算法有哪些應(yīng)用

    說到PID算法,想必大部人并不陌生,PID算法在很多方面都有重要應(yīng)用,比如電機的速度控制,恒溫槽的溫度控制,四軸飛行器的平衡控制等等,作為閉環(huán)控制系統(tǒng)中的一種重要
    發(fā)表于 07-15 09:44

    pid算法_什么是pid算法

    PID控制器是一種最優(yōu)控制。本文講述了增量式PID算法原理與數(shù)字PID算法原理與數(shù)字PID
    發(fā)表于 01-01 11:58 ?1.1w次閱讀
    <b class='flag-5'>pid</b><b class='flag-5'>算法</b>_什么是<b class='flag-5'>pid</b><b class='flag-5'>算法</b>

    PID算法溫控C語言

    基于PID算法的溫度控制系統(tǒng),PID算法溫控C語言程序
    發(fā)表于 07-12 16:05 ?51次下載

    pid算法和研究

    pid算法和研究
    發(fā)表于 11-17 18:35 ?2次下載

    PID算法再理解

    PID算法再理解
    發(fā)表于 11-17 18:35 ?2次下載

    pid算法的資料

    pid算法的資料
    發(fā)表于 12-17 10:06 ?6次下載

    PID算法的實現(xiàn)

    PID算法的實現(xiàn)
    發(fā)表于 12-20 22:54 ?3次下載

    PID算法詳解

    PID算法詳解
    發(fā)表于 12-17 20:48 ?12次下載

    PID算法設(shè)計與分析

    PID算法
    發(fā)表于 08-11 10:41 ?0次下載

    重溫經(jīng)典 PID 算法

    重溫經(jīng)典PID算法
    的頭像 發(fā)表于 03-12 11:09 ?3210次閱讀
    重溫經(jīng)典 <b class='flag-5'>PID</b> <b class='flag-5'>算法</b>
    博E百百家乐现金网| 百胜百家乐官网软件| 百家乐有几种打法| 娱乐城注册送28| 24山天机申山寅向择日| 鹤乡棋牌乐| 百家乐取胜秘笈| 金龙博彩网| 德州百家乐赌博规则| 百家乐官网游戏程序下载| 都坊百家乐的玩法技巧和规则| AG百家乐官网大转轮| bet365百科| 乐百家百家乐游戏| 六合彩网址| 百家乐赌博程序| 百家乐官网牌具公司| 大发888娱乐城在线存款| 做生意摆放什么会招财| 磐安县| 闲和庄百家乐的玩法技巧和规则 | 阿鲁科尔沁旗| 金花百家乐的玩法技巧和规则| 赌百家乐官网可以赢钱| 机率游戏| 百家乐官网五湖四海娱乐网| 尚品棋牌注册| 百家乐双层筹码盘| 百家乐官网网站建设| 大发888娱乐在线客服| 赌百家乐赢的奥妙| 最新娱乐城送彩金| 百家乐龙虎台布作弊技巧| 百家乐官网蓝盾有赢钱的吗| 大赢家棋牌游戏| 温州百家乐的玩法技巧和规则| 在线百家乐官网策略| 百家乐官网赢家公式| 大发888通宝| 缅甸百家乐网络赌博解谜| 兰桂坊百家乐官网的玩法技巧和规则|