智能车竞赛模糊PID过程详解,附matlab模拟代码,使用的C代码在我的另一篇文章中

目录


普通位置式PID控制

PID 控制分为比例,微分,积分三项,其公式如下:

U (t) = Kp ∗ err (t) + Kd ∗ [err (t) − err (t − 1)] + Ki ∗ ∑err (t) 

PID 控制的比例环节为 P,P 越大参数的比例作用越明显,响应更快,消除误差的 能力越强,但是系统的惯性也越强。比例太大时会造成系统的震荡,使系统不稳定,造 成超调。 PID 控制的微分环节为 D,D 能够反映偏差的变化趋势,对超调进行预防控制。在 输出有变大或变小趋势时输出一个阻止其变化的控制信号,防止其出现过冲或超调。 PID 控制的积分环节为 I,可以用于消除静态误差,使系统具有“记忆功能”。如果 积分作用太强,积分输出变化过快,就会引起积分过头的现象,产生积分超调和振荡, 影响系统整体的稳定性。 PID 控制的框图如下:

 模糊PID控制

传统的 PID 控制在面对不同工况时的适应性较差,当误差较大时需要有较大的 Kp 进行修正,提高响应速度,而当误差较小时,较大的 Kp 又将造成超调和过冲现象。为 解决传统 PID 参数自适应性差的问题,可对 PID 参数进行动态调整,使用模糊算法动 态调整 Kp。

区间划分

模糊 PID 的核心在于动态 Kp,其输入参数为 E 和 EC,即误差和这次误差与上次误 差的差值。将车辆置于赛道上测量直道以及弯道的误差范围,测得误差区间为 [-15,15], 误差的差值范围为 [-6,6],划分区间为 [-15,-10,-5,0,5,10,15] 和 [-6,-4,-1.8,0,1.8,4,6]。

模糊化

将输入的误差和误差的差值模糊化。对划分的两个误差区间 [-15,-10,-5,0,5,10,15] 和 [-6,-4,-1.8,0,1.8,4,6], 分别用 [负大,负中,负小,中性,正小,正中,正大] 表示,得到 专家模糊表如下: 对输入的 E 和 EC 进行模糊化,以输入的 [E,EC] 为 [12.5,3] 为例。E 处于 [4,6],及 [正 中,正大] 区间,其对正中的隶属度为 (12.5 − 10) / (15 − 10) = 50%,对正大的隶属度 为 (15 − 12.5) / (15 − 10) = 50%。EC 处于 [1.8,4],及 [正小,正中] 区间,其对正小的隶 属度为 (3 − 1.8) / (4 − 1.8) = 54.55%,对正中的隶属度为 (4 − 3) / (4 − 1.8) = 45.45%。

清晰化

根据输入 E 和 EC 的隶属度,对输出值进行清晰化。在模糊表中,[E= 正中,EC= 正 小] 坐标对应的值为 3,则输入属于 3 的隶属度为 50% × 54.55% = 27.275%,[E= 正中, EC= 正中] 坐标对应的值为 4,则输入的属于 4 的隶属度为 50% × 45.45% = 22.725%,

[E= 正大,EC= 正小] 对应的值为 4,则输入属于 4 的隶属度为 50%×54.55% = 27.275%, [E= 正大,EC= 正中] 对应的值为 5,则输入属于 5 的隶属度为 50%×45.45% = 22.725%。 根据以上求解的隶属度计算输出的值为 3 × 27.275% + 4 × 22.725% + 4 × 27.275% + 5 × 22.725% = 3.9545。

改进

为了便于参数的调整,对模糊 PID 进行改进,引入 U 语言和 Kp 的最大值 Kp_m, 将 Kp 的范围投影在 [0,Kp_m] 的范围内。

以 Kp_m = 21 为例,对 Kp_m 进行线性分割,将其划分为 [0,3.5,7,10.5,14, 17.5,21]。

对求得的 E 和 EC 隶属度求小。对于 [E= 正中,EC= 正小],求其 E 对正中和 EC 对正 小隶属度中的最小值作为 [E= 正中,EC= 正小] 坐标的隶属度。E 对正中的隶属度为 50%, EC 对正小的隶属度为 54.55%,则 [E= 正中,EC= 正小] 坐标的隶属度为 50%。求得各坐 标隶属度如下表:

 

 对隶属于同一值的坐标隶属度保留最大。[E= 正中,EC= 正中] 和 [E= 正大,EC= 正 小] 坐标对应的值均为 4,其坐标的隶属度为 45.45% 和 50%,则保留 [E= 正大,EC= 正 小] 的隶属度 50%,[E= 正中,EC= 正中] 的隶属度改为 0。更正后各坐标值隶属度如下:

根据 [E,EC] 模糊值求得其位于 Kpm 线性分割中的哪一段。Kpm 共被线性分割为 7 段,第 0 段为 0,第 1 段为 3.5,第 2 段为 7,第 3 段为 10.5,第 4 段为 14,第 5 段为 17.5,第 6 段为 21。由上表可得,隶属于第 3 段 10.5 的隶属度为 45.45%,隶属于第 4 段 14 的隶属度为 50%,隶属于第 5 段 17.5 的隶属度为 50%。 求解输出值为

模糊PID的MATLAB代码

 根据模糊 PID 的实现步骤,模拟不同的 E 和 EC 输入,绘制三维坐标图如下:

由图可得,模糊 PID 具有自适应性,对于误差较小的情况,其输出的 Kp 值较 小,在修正误差时造成过冲和超调的可能性就越低,在误差大的情况,其输出的 Kp 值 大,对误差的修正幅度就越大,响应越快。

将C语言的代码移植到Matlab上,可以一步步运行,更好地了解模糊PID地原理,以及模糊PID的效果

模糊PID的m测试使用文件,可一步步运行了解详细过程

clear;clc
E = 14; EC = 0;
%输入的E为err,EC为err的差值,即(err-err_last)
%模糊Kp
kp_m = 10.5;
%模糊规则表
rule_p = [  
            6 , 5 , 4 , 4 , 3 , 0 , 0;
            6 , 4 , 3 , 3 , 2 , 0 , 0;
            4 , 3 , 2 , 1 , 0 , 1 , 2;
            2 , 1 , 1 , 0 , 1 , 1 , 2;
            2 , 1 , 0 , 1 , 2 , 3 , 4;
            0 , 0 , 2 , 3 , 3 , 4 , 6;
            0 , 1 , 3 , 4 , 4 , 5 , 6;
                                        ];                                        
    
%输入量P语言值特征点
% EFF = [-15,-9,-3.5,0,3.5,9,15];
EFF = [-30,-20,-10,0,10,20,30];

%输入量D语言值特征点
DFF = [-15,-10,-5,0,5,10,15];
%输出量U语言值特征点(根据赛道类型选择不同的输出值)
for i2 = 1:7
    UFF(i2) = kp_m / 6 *(i2-1);
end

%偏差,偏差微分以及输出值的精确量
U=0;

PF = [0,0]; DF = [0,0]; UF = [0,0,0,0];
%偏差,偏差微分以及输出值的隶属度
Pn=0;Dn=0;Un=[0,0,0,0];
% t1=0;t2=0;t3=0;t4=0;temp1=0;temp2=0;

%确定隶属度
%根据PD的指定语言值获得有效隶属度
if(   E>EFF(1) && E<EFF(7)  )
    if( E <= EFF(2) )
        Pn = -2;
        PF(1) = ( EFF(2) - E )/( EFF(2) - EFF(1) );%EFF(2)的隶属度
    elseif( E <= EFF(3) )
        Pn = -1;
        PF(1) = ( EFF(3) - E )/( EFF(3) - EFF(2) );%EFF(3)的隶属度
    elseif( E<= EFF(4) )
        Pn = 0;
        PF(1) = ( EFF(4) - E  )/( EFF(4) - EFF(3) );
    elseif( E<= EFF(5) )
        Pn = 1;
        PF(1) = ( EFF(5) - E )/( EFF(5) - EFF(4) );
    elseif( E<= EFF(6) )
        Pn = 2;
        PF(1) = ( EFF(6) - E )/( EFF(6) - EFF(5) );
    elseif( E <= EFF(7) )
        Pn = 3;
        PF(1) = ( EFF(7) - E )/( EFF(7) - EFF(6) );
    end
 %不在给定区间内   
elseif( E <= EFF(1) )
    Pn = -2;
    PF(1) = 1;
elseif( E >= EFF(7) )
    Pn = 3;
    PF(1) = 0;
end

PF(2) = 1 - PF(1);

%判断D的隶属度
if(   EC>DFF(1) && EC<DFF(7)  )
    if( EC <= DFF(2) )
        Dn = -2;
        DF(1) = ( DFF(2) - EC )/( DFF(2) - DFF(1) );
    elseif( EC <= DFF(3) )
        Dn = -1;
        DF(1) = ( DFF(3) - EC )/( DFF(3) - DFF(2) );
    elseif( EC<= DFF(4) )
        Dn = 0;
        DF(1) = ( DFF(4) - EC  )/( DFF(4) - DFF(3) );
    elseif( EC<= DFF(5) )
        Dn = 1;
        DF(1) = ( DFF(5) - EC )/( DFF(5) - DFF(4) );
    elseif( EC<= DFF(6) )
        Dn = 2;
        DF(1) = ( DFF(6) - EC )/( DFF(6) - DFF(5) );
    elseif( EC <= DFF(7) )
        Dn = 3;
        DF(1) = ( DFF(7) - EC )/( DFF(7) - DFF(6) );
    end
 %不在给定区间内   
elseif( EC <= DFF(1) )
    Dn = -2;
    DF(1) = 1;
elseif( EC >= DFF(7) )
    Dn = 3;
    DF(1) = 0;
end

DF(2) = 1 - DF(1);

%使用误差范围优化后的规则表rule[7][7]
%输出值使用13个隶属函数,中心值由UFF[7]指定
%一般都是四个规则有效
Un(1)=rule_p(Pn+3,Dn+3);
Un(2)=rule_p(Pn+4,Dn+3);
Un(3)=rule_p(Pn+3,Dn+4);
Un(4)=rule_p(Pn+4,Dn+4);

if( PF(1) <= DF(1) ) %求小
    UF(1) = PF(1);
else
    UF(1) = DF(1);
end
if( PF(2) <= DF(1) )
    UF(2) = PF(2);
else
    UF(2) = DF(1);
end
if( PF(1) <= DF(2) )
    UF(3) = PF(1);
else
    UF(3) = DF(2);
end
if(PF(2) <= DF(2) )
    UF(4) = PF(2);
else
    UF(4) = DF(2);
end

%同隶属度函数输出语言值求最大
if( Un(1) == Un(2) )
    if( UF(1) > UF(2) )
        UF(2) = 0;
    else
        UF(1) = 0;
    end
end

if( Un(1) == Un(3) )
    if( UF(1) > UF(3) )
        UF(3) = 0;
    else
        UF(1) = 0;
    end
end

if( Un(1) == Un(4) )
    if( UF(1) > UF(4) )
        UF(4) = 0;
    else
        UF(1) = 0;
    end
end

if( Un(2) == Un(3) )
    if( UF(2) > UF(3) )
        UF(3) = 0;
    else
        UF(2) = 0;
    end
end

if( Un(2) == Un(4) )
    if( UF(2) > UF(4) )
        UF(4) = 0;
    else
        UF(2) = 0;
    end
end

if( Un(3) == Un(4) )
    if( UF(3) > UF(4) )
        UF(4) = 0;
    else
        UF(3) = 0;
    end
end 

t1 = UF(1) * UFF( Un(1)+1 );
t2 = UF(2) * UFF( Un(2)+1 );
t3 = UF(3) * UFF( Un(3)+1 );
t4 = UF(4) * UFF( Un(4)+1 );
temp1 = t1 + t2 + t3 + t4;
temp2 = UF(1) + UF(2) + UF(3) + UF(4);

if( temp2 == 0 )
    U = 0;
else
    U = temp1/temp2;
end

Kp = U;

模糊PID的主函数和功能函数matlab代码

clear;clc
%%
Ei = -20:0.1:20;
ECi = -20:0.1:20;

[E,EC] = meshgrid(Ei,ECi);

for i = 1:401
    for j = 1:401
         Kp(i,j) = Kp_Fuzzy( E(i,j) , EC(i,j) )    ;
    end
end

mesh(E,EC,Kp)
xlabel("E");
ylabel("EC");
zlabel("Kp");
function [Kp] = Kp_Fuzzy(E,EC)
%输入的E为err,EC为err的差值,即(err-err_last)
%模糊Kp
kp_m = 20;
%模糊规则表
rule_p = [  
            6 , 5 , 4 , 4 , 3 , 0 , 0;
            6 , 4 , 3 , 3 , 2 , 0 , 0;
            4 , 3 , 2 , 1 , 0 , 1 , 2;
            2 , 1 , 1 , 0 , 1 , 1 , 2;
            2 , 1 , 0 , 1 , 2 , 3 , 4;
            0 , 0 , 2 , 3 , 3 , 4 , 6;
            0 , 1 , 3 , 4 , 4 , 5 , 6;
                                        ];                                        
    
%输入量P语言值特征点
% EFF = [-15,-9,-3.5,0,3.5,9,15];
EFF = [-15,-10,-5,0,5,10,15];

%输入量D语言值特征点
DFF = [-6,-4,-1.8,0,1.8,4,6];
%输出量U语言值特征点(根据赛道类型选择不同的输出值)
for i2 = 1:7
    UFF(i2) = kp_m / 6 *(i2-1);
end

%偏差,偏差微分以及输出值的精确量
U=0;

PF = [0,0]; DF = [0,0]; UF = [0,0,0,0];
%偏差,偏差微分以及输出值的隶属度
Pn=0;Dn=0;Un=[0,0,0,0];
% t1=0;t2=0;t3=0;t4=0;temp1=0;temp2=0;

%确定隶属度
%根据PD的指定语言值获得有效隶属度
if(   E>EFF(1) && E<EFF(7)  )
    if( E <= EFF(2) )
        Pn = -2;
        PF(1) = ( EFF(2) - E )/( EFF(2) - EFF(1) );%EFF(2)的隶属度
    elseif( E <= EFF(3) )
        Pn = -1;
        PF(1) = ( EFF(3) - E )/( EFF(3) - EFF(2) );%EFF(3)的隶属度
    elseif( E<= EFF(4) )
        Pn = 0;
        PF(1) = ( EFF(4) - E  )/( EFF(4) - EFF(3) );
    elseif( E<= EFF(5) )
        Pn = 1;
        PF(1) = ( EFF(5) - E )/( EFF(5) - EFF(4) );
    elseif( E<= EFF(6) )
        Pn = 2;
        PF(1) = ( EFF(6) - E )/( EFF(6) - EFF(5) );
    elseif( E <= EFF(7) )
        Pn = 3;
        PF(1) = ( EFF(7) - E )/( EFF(7) - EFF(6) );
    end
 %不在给定区间内   
elseif( E <= EFF(1) )
    Pn = -2;
    PF(1) = 1;
elseif( E >= EFF(7) )
    Pn = 3;
    PF(1) = 0;
end

PF(2) = 1 - PF(1);

%判断D的隶属度
if(   EC>DFF(1) && EC<DFF(7)  )
    if( EC <= DFF(2) )
        Dn = -2;
        DF(1) = ( DFF(2) - EC )/( DFF(2) - DFF(1) );
    elseif( EC <= DFF(3) )
        Dn = -1;
        DF(1) = ( DFF(3) - EC )/( DFF(3) - DFF(2) );
    elseif( EC<= DFF(4) )
        Dn = 0;
        DF(1) = ( DFF(4) - EC  )/( DFF(4) - DFF(3) );
    elseif( EC<= DFF(5) )
        Dn = 1;
        DF(1) = ( DFF(5) - EC )/( DFF(5) - DFF(4) );
    elseif( EC<= DFF(6) )
        Dn = 2;
        DF(1) = ( DFF(6) - EC )/( DFF(6) - DFF(5) );
    elseif( EC <= DFF(7) )
        Dn = 3;
        DF(1) = ( DFF(7) - EC )/( DFF(7) - DFF(6) );
    end
 %不在给定区间内   
elseif( EC <= DFF(1) )
    Dn = -2;
    DF(1) = 1;
elseif( EC >= DFF(7) )
    Dn = 3;
    DF(1) = 0;
end

DF(2) = 1 - DF(1);

%使用误差范围优化后的规则表rule[7][7]
%输出值使用13个隶属函数,中心值由UFF[7]指定
%一般都是四个规则有效
Un(1)=rule_p(Pn+3,Dn+3);
Un(2)=rule_p(Pn+4,Dn+3);
Un(3)=rule_p(Pn+3,Dn+4);
Un(4)=rule_p(Pn+4,Dn+4);

if( PF(1) <= DF(1) ) %求小
    UF(1) = PF(1);
else
    UF(1) = DF(1);
end
if( PF(2) <= DF(1) )
    UF(2) = PF(2);
else
    UF(2) = DF(1);
end
if( PF(1) <= DF(2) )
    UF(3) = PF(1);
else
    UF(3) = DF(2);
end
if(PF(2) <= DF(2) )
    UF(4) = PF(2);
else
    UF(4) = DF(2);
end

%同隶属度函数输出语言值求最大
if( Un(1) == Un(2) )
    if( UF(1) > UF(2) )
        UF(2) = 0;
    else
        UF(1) = 0;
    end
end

if( Un(1) == Un(3) )
    if( UF(1) > UF(3) )
        UF(3) = 0;
    else
        UF(1) = 0;
    end
end

if( Un(1) == Un(4) )
    if( UF(1) > UF(4) )
        UF(4) = 0;
    else
        UF(1) = 0;
    end
end

if( Un(2) == Un(3) )
    if( UF(2) > UF(3) )
        UF(3) = 0;
    else
        UF(2) = 0;
    end
end

if( Un(2) == Un(4) )
    if( UF(2) > UF(4) )
        UF(4) = 0;
    else
        UF(2) = 0;
    end
end

if( Un(3) == Un(4) )
    if( UF(3) > UF(4) )
        UF(4) = 0;
    else
        UF(3) = 0;
    end
end 

t1 = UF(1) * UFF( Un(1)+1 );
t2 = UF(2) * UFF( Un(2)+1 );
t3 = UF(3) * UFF( Un(3)+1 );
t4 = UF(4) * UFF( Un(4)+1 );
temp1 = t1 + t2 + t3 + t4;
temp2 = UF(1) + UF(2) + UF(3) + UF(4);

if( temp2 == 0 )
    U = 0;
else
    U = temp1/temp2;
end

Kp = U;

end

模糊PID的使用和调参技巧

模糊PID的使用和调参技巧放在另一篇推文中,链接如下:

智能车竞赛模糊PID代码与使用方法_小博特的博客-CSDN博客

版权声明:本文为博主作者:小博特原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/piginthesouth/article/details/127659702

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2024年4月16日
下一篇 2024年4月16日

相关推荐