精华内容
下载资源
问答
  • 智能小车自动寻迹过程中,方向控制与速度控制都存在高度非线性的问题。采用模糊 PID 控制算法,实现...该方案运用于智能车控制系统,克服了传统 PID 控制的不足,通过模糊规则进行推理决策,实现了 PID 参数的实时优化
  • 基于视觉的智能车模糊PID控制算法 ,基于freescale公司的16位HCS12单片机设计一种智能车系统。系统摄像头采集路径信息,通过单片机 的模糊推理机在线整定PID参数,使小车能按照任意给定的黑色引导线平稳地寻迹。
  • 飞思卡尔智能车----模糊PID算法通俗讲

    万次阅读 多人点赞 2018-02-02 11:14:15
    在讲解模糊PID前,我们先要了解PID控制器的原理(本文主要介绍模糊PID的运用,对PID控制器的原理不做详细介绍)。PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分...

     在讲解模糊PID前,我们先要了解PID控制器的原理(本文主要介绍模糊PID的运用,对PID控制器的原理不做详细介绍)。PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分单元I和微分单元D组成。PID控制的基础是比例控制;积分控制可消除稳态误差,但可能增加超调;微分控制可加快大惯性系统响应速度以及减弱超调趋势。

     

    1.1传统PID控制

     

     

     

     传统PID控制器自出现以来,凭借其结构简单、稳定性好、工作可靠、调整方便等优点成为工业控制主要技术。当被控对象的结构和参数具有一定的不确定性,无法对其建立精确的模型时,采用PID控制技术尤为方便。PID控制原理简单、易于实现,但是其参数整定异常麻烦。对于小车的速度控制系统而言,由于其为时变非线性系统不同时刻需要选用不同的PID参数,采用传统的PID控制器,很难使整个运行过程具有较好的运行效果。

     

    1.2模糊PID控制

     

     模糊PID控制,即利用模糊逻辑并根据一定的模糊规则对PID的参数进行实时的优化,以克服传统PID参数无法实时调整PID参数的缺点。模糊PID控制包括模糊化,确定模糊规则,解模糊等组成部分。小车通过传感器采集赛道信息,确定当前距赛道中线的偏差E以及当前偏差和上次偏差的变化ec,根据给定的模糊规则进行模糊推理,最后对模糊参数进行解模糊,输出PID控制参数。

     

     

     

    2.1模糊化

     

     模糊控制器主要由三个模块组成:模糊化,模糊推理,清晰化。具体如下图所示。而我们将一步步讲解如何将模糊PID算法运用到智能车上。(最好用笔一步步自己写一遍!!!)

     

     

     

     

     首先我们的智能车会采集到赛道的相关数据,例如摄像头车,其采集到的数据经过算法处理之后会得到与中线的偏差E,以及当前偏差和上次偏差的变化(差值)EC两个值(即此算法为2维输入,同理也可以是1维和3维,但2维更适合智能车)。例如此时车偏离中线的距离为150,而上一时刻偏离中线的距离为120,则E为150,EC为150 - 120 = 30。

     其次我们要对这两个值进行模糊化。这里我们对E进行举例。摄像头车采集回来的E是有范围的,即与中线的偏差是在一个区间内可行的。在这里我们假设该区间为-240到240,即小车偏离中线的最大距离为240,正负即为左右。再假设中线偏差变化率的可行区间为-40到+40。

     

            接着我们要对这两个值进行模糊化。我现在将E的区间(-240 到 240)分成8个部分,那么他们分别为-240 ~ -180,-180 ~ -120 ,-120 ~ -60,-60 ~ 0,0 ~ 60,60 ~ 120,120 ~ 180,180 ~ 240。然后我们把-180,-120,-60,0,60,120,180分别用NB,NM,NS,ZO,PS,PM,PB表示(个人理解N为negative,P为positive,B为big,M为middle,S为small,ZO为zero)。例如,当E = 170时,此时的E属于PM和PB之间,而此时的E也会对应2(或1)个隶属度。E隶属于PM(120)的百分比为(180 - 170) /  (180 - 120) = 1 / 6 ,而同理隶属于PB(180)的百分比为(170 - 120) / (180 - 120) = 5 / 6  。意思就是120到180进行线性分割了,E离PM和PB哪个更近,则隶属于哪个就更大(当输出值E大于180(PB)时,则隶属度为1,隶属度值为PB,即E完全隶属于PB,同理当E小于 - 180 (NB)时也一样)。同理也可以对EC进行模糊化

     

    2.2 模糊推理

           对于采集回来的E和EC,我们可以推出它们各所占的隶属度,此时我们可以根据模糊规则表去找出输出值所对应的隶属度

     

     

         我们假设为E的两个隶属度值为PM、PB,E属于PM的隶属度为a(a < 1),则属于PB的隶属度为(1 - a)。再假设EC的两个隶属度值为NB、NM,EC属于NM的隶属度为b,则属于NB的隶属度为(1 - b)。而在假设中,E属于PM的隶属度为a,EC属于NB的隶属度为( 1 - b ),则输出值属于ZO的隶属度为a *( 1 - b )(看图)。

     

     

           同理我们可以得出,当输出值属于ZO的另外两个隶属度为a * b, ( 1 - a ) * ( 1 - b) ,而输出值属于NS的隶属度为 ( 1 - a ) *  b

           在这里我们先证明一个条件,将这四个隶属度加起来,刚好等于1。这是因为

            (a + (1 - a)) * (b + (1 - b)) = a * b + ( 1 - a ) *  b  + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b )   (下图)

           即一个十字相乘的概念。这个等式说明输出值的隶属度之和等于1(第三步求解的时候需要用到隶属度之和)

     

     

    因此,我们知道了输出值为ZO的隶属度和为 a * b + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b ) ,输出值为NS的隶属度为 ( 1 - a ) *  b 。

     

    2.3 清晰化

           对于输出值,我们同样采用给予隶属度的办法。例如,我们把输出值假设为[1000,1400](即舵机的摆角值范围)的区间同样划分为八个部分,即7个隶属值NB,NM,NS,ZO,PS,PM,PB。根据上一步所得出的结论,我们就可以用隶属度乘以相应的隶属值算出输出值的解,即 (a * b + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b ) ) * ZO   +    ( 1 - a ) *  b * NS。到此为止,整个模糊过程就结束了。

         

    3 模糊PID

          我们已经知道了整个模糊的过程,但上述的过程还不够完美。因为我们的输出值只有一个输出,并没有实现PID。因此我们可以先对E和EC进行模糊化,然后分别对kp和ki和kd(PID的三个参数)进行求解,再套入公式。

     

     

         一般的我们也可以只用kp,kd,不用ki。而模糊规则表一般的论文已经基本给出。因此带入算法之后我们的难度也只是在于调节kp,kd,和适当调节规则表。当然调节的难度会大于普通的PID,因为还要定kp,kd的输出范围,调得不好可能效果并没有普通的PID好。

     

    4. 部分解释

         4.1对于部分论文所说的重心法解模糊,其实就是上述方法。公式如下。

     

          式中μ(Zi) * Zi相当于文章上面的a * b + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b ) ) * ZO   +    ( 1 - a ) *  b * NS,即隶属度乘以隶属度值之和,而μ(Zi)之和就是输出值的隶属度之和,我们已经证明它是等于1的。

     

     

     

     

    展开全文
  • 基于模糊自适应PID的列车智能驾驶算法
  • 模糊算法,包括智能车模糊规则的设计,通过查表法实现模糊控制,与传统的PID算法相比,控制效果更好,运行更加平稳。
  • 算法(一):智能小车速度控制(PID模糊控制)

    万次阅读 多人点赞 2020-03-22 10:42:36
    概览一、前言二、基于PID 的速度控制1.PID控制器2.PID速度控制二、基于模糊控制的速度控制1....在实现智能小车速度的闭环控制时首选简单有效的PID控制算法。 二、基于PID 的速度控制 1.PID控制器 PID(Proportion I...

    一、前言

    本科的时候参加飞思卡尔比赛,在队友的神助攻下有幸拿了国奖,比赛中使用了模糊控制算法。这段时间正好看到了模糊控制算法,就把以前的代码翻出来,顺便总结一下PID和模糊控制算法,希望自己能养成记录知识点的好习惯。

    二、基于PID 的速度控制

    在控制领域,PID算法是应用最广泛的算法之一。小到电机的转速,大到机器人稳定性的控制。在实现智能小车速度的闭环控制时首选简单有效的PID控制算法。

    1.PID控制器

    PID(Proportion Integration Differentiation)控制器包括P比例、I积分和D微分三个控制单元,协同工作保证控制系统快速到达并稳定于目标值。PID控制算法的公式:
    u(t)=Kperr(t)+Kierr(t)dt+Kdderr(t)dtu(t)=K_perr(t)+K_i\int err(t)dt +K_d\frac{derr(t)}{dt}
    对其进行离散化:
    u(n)=Kperr(n)+Kik=0nerr(k)+Kd(err(n)err(n1))u(n)=K_perr(n)+K_i\sum_{k=0}^n err(k) +K_d(err(n)-err(n-1))

    1)KpK_p比例控制
    控制器的反应速度与KpK_p有关,该系数越大,控制系统反应更灵敏。但是KpK_p过大会引起较大的超调,并产生震荡,破坏系统的稳定性。因此在调整KpK_p参数时应从低到高增加,选择系统达到响应快并稳定的效果时的参数。

    2)KiK_i积分控制
    只要控制系统存在误差,该系数对系统的作用就会不断增强。只有误差err消失即系统稳定在目标值时,控制作用才不会变化。由此可见积分控制的调节会消除系统的静态误差。

    3)KdK_d微分控制
    为了抑制系统的超调和振荡,在控制系统中增加微分控制。通过对控制系统未来的预估,及时对控制量进行调整,提升系统的稳定性。

    2.PID速度控制

    刚开始对小车的速度控制采用位置式PID控制算法,即常用的PID控制算法。但是位置式PID算法使用过去误差的累加值,容易产生较大的累计误差。而且由于小车的目标速度时刻在变化,err值需要不断的累加,可能出现err_sum溢出的情况。因此对位置式加以变换,得到增量式PID控制算法:
    u=u(n)u(n1)=Kp(err(n)err(n1))+Kierr(n)+Kd(err(n)2err(n1)+err(n2))\triangle u=u(n)-u(n-1)=K_p(err(n)-err(n-1))+K_ierr(n) +K_d(err(n)-2err(n-1)+err(n-2))
    由此计算出:
    u(n)=u(n1)+Kp(err(n)err(n1))+Kierr(n)+Kd(err(n)2err(n1)+err(n2)) u(n) = u(n-1) + K_p(err(n)-err(n-1))+K_ierr(n) +K_d(err(n)-2err(n-1)+err(n-2))

    int speed_control(void)
    {
    	int i;
    	speed_set=get_speed_set();//设置车速                  
    	
    	//设置PID参数
    	kp_motor=33;
    	ki_motor=0.038;
    	kd_motor=0.04;
    
    	for(i=0;i<9;i++)
    		error[i]=error[i+1];
    	error[9]=speed_set-speed;	
    
    	de=kp_motor*(error[9]-error[8])+ki_motor*error[9]-kd_motor*(speed_save[9]-2*speed_save[8]+speed_save[7]);
    	pwm1 = pwm1_old+de;
      	
      	speed_set_old=speed_set;
      	pwm1_old=pwm1; 
      	return pwm1;//输出PWM波
    }
    

    二、基于模糊控制的速度控制

    拥有响应迅速地速度控制系统对于提升小车的速度是不够的,还需要根据赛道情况设置不同的车速以实现小车最快地通过不同的路况。这时,可以考虑模糊控制的思想根据路况及小车当前的状态对目标车速进行设置。

    1.变量的模糊化

    在模糊控制中,输入输出变量大小用语言形式进行描述。常选用的7个语言值为{负大,负中,负小,零,正小,正中,正大},即{NB,NM,NS,O,PS,PM,PB}。

    对小车当前行驶方向和赛道方向形成的偏差e及其变化率ec作为模糊控制器的输入,小车的目标车速为模糊控制器的输出。设偏差值的模糊量为E,偏差变化率模糊量为EC,U为目标车速。为了让速度切换更加细腻流畅,设置偏差e、偏差变化ec和控制量u的基本论域为[-6,6],并划分为13个等级,即{-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6}。

    E、EC和U均使用三角形隶属函数进行模糊化

    三角形隶属函数

    
    /**
    * 列坐标:NB,NM,NS,O,PS,PM,PB
    * 横坐标:-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6
    * @param 建立输入、输出隶属度函数,进行微调调整模糊量的范围
    */
    /***************************************误差隶属度函数***************************************/
    float Input1_Terms_Membership[7][13] =
    { 1,0.15,0,0,0,0,0,0,0,0,0,0,0,
    0,0.2,1,0.2,0,0,0,0,0,0,0,0,0,
    0,0,0,0.2,1,0.2,0,0,0,0,0,0,0,
    0,0,0,0,0,0.1,1,0.1,0,0,0,0,0,
    0,0,0,0,0,0,0,0.1,1,0.1,0,0,0,
    0,0,0,0,0,0,0,0,0,0.2,1,0.2,0,
    0,0,0,0,0,0,0,0,0,0,0,0.2,1
    };
    /***************************************误差变化率隶属度函数***************************************/
    float Input2_Terms_Membership[7][13] =
    { 1,0.15,0,0,0,0,0,0,0,0,0,0,0,
    0,0.2,1,0.2,0,0,0,0,0,0,0,0,0,
    0,0,0,0.2,1,0.2,0,0,0,0,0,0,0,
    0,0,0,0,0,0.1,1,0.1,0,0,0,0,0,
    0,0,0,0,0,0,0,0.1,1,0.1,0,0,0,
    0,0,0,0,0,0,0,0,0,0.2,1,0.2,0,
    0,0,0,0,0,0,0,0,0,0,0,0.2,1
    };
    /***************************************输出(速度)***************************************/
    float Output_Terms_Membership[7][13] =
    { 1,0.15,0,0,0,0,0,0,0,0,0,0,0,
    0,0.2,1,0.2,0,0,0,0,0,0,0,0,0,
    0,0,0,0.2,1,0.2,0,0,0,0,0,0,0,
    0,0,0,0,0,0.1,1,0.1,0,0,0,0,0,
    0,0,0,0,0,0,0,0.1,1,0.1,0,0,0,
    0,0,0,0,0,0,0,0,0,0.2,1,0.2,0,
    0,0,0,0,0,0,0,0,0,0,0,0.2,1
    };
    

    2.模糊查询表的计算

    对模糊量EC、E和U设置相关的模糊控制规则表
    模糊控制规则表

    /**
    * 纵轴为E(error),横轴为EC(error_delta),值为速度七档NB(0),NM(1),NS(2),Z(3),PS(4),PM(5),PB(6)速度由小变大再变小
    * 列坐标:E(NB,NM,NS,O,PS,PM,PB)
    * 横坐标:EC(NB,NM,NS,O,PS,PM,PB)
    * 值:U(1:NB:2,NM,3:NS,4:O,5:PS,6:PM,7:PB)
    * @param 模糊控制规则表,调整速度变化趋势
    */
    int Rule[7][7] =
    { 1,1,2,2,6,7,7,
     1,1,2,2,6,6,6,
     1,2,3,4,5,6,6,
     1,3,4,4,4,5,7,
     2,2,3,4,5,6,7,
     2,2,2,2,6,7,7,
     1,1,2,2,6,7,7
    };//调试参数
    

    规则库蕴含的模糊关系:

    R=(E×EC)×CR=(E\times EC)\times C

    其中,模糊运算×\times表示“取小”。

    计算出模糊规则蕴含的模糊关系R后,通过遍历E和EC所有的论域对模糊值进行选取并计算模糊输出值:

    U=(E×EC)RU^*=(E^* \times EC^*)\circ R

    其中,\circ表示模糊矩阵的合成,类似于普通矩阵的乘积运算,将乘积运算换成“取小”,将加法运算换成“取大”。

    在遍历过程中,对E和EC所有论域对应的模糊输出值一一采取加权平均法去模糊化,得到最终的模糊控制器查询表。

    float  R[169][13] = { 0 };
    float R1[13][13] = { 0 };
    float AdBd1[13][13] = { 0 };
    float R2[169] = { 0 };
    float AdBd2[169] = { 0 };
    float R3[169][13] = { 0 };
    float  Cd[13] = { 0 };
    float Fuzzy_Table[13][13] = { 0 };
    float SPEED[13] = { 200,220,230,240,250,270,300,270,250,240,230,220,200 };//调试参数
    int Max_Input1_value = 0, Max_Input2_value = 0;
    
    /**
    * @param 模糊化过程实现论域内不同值对应隶属度最大的语言值
    */
    int  E_MAX(int e)
    {
    	int i = 0, max = 0;
    	for (i = 0; i < 7; i++)
    		if (Input1_Terms_Membership[i][e] > Input1_Terms_Membership[max][e])
    			max = i;
    	return max;
    }
    
    int  EC_MAX(int ex)
    {
    	int i = 0, max = 0;
    	for (i = 0; i < 7; i++)
    		if (Input2_Terms_Membership[i][ex] > Input1_Terms_Membership[max][ex])
    			max = i;
    	return max;
    }
    
    void calculate()
    {
    	/***************************************计算所有规则模糊关系的并集Rule***************************************/
    	int i = 0, j = 0, k = 0;
    	int Input1_value_index = 0, Input2_value_index = 0;
    
    	//计算Rule(初始化),计算Rij,并对所有的R取并集,R=(EXEC)XU
    	for (Input1_Terms_Index = 0; Input1_Terms_Index < 7; Input1_Terms_Index++)
    		for (Input2_Terms_Index = 0; Input2_Terms_Index < 7; Input2_Terms_Index++)
    		{
    			// E和EC的语言值两两组合及其输出计算Rule
    			Output_Terms_Index = Rule[Input1_Terms_Index][Input2_Terms_Index] - 1;
    			k = 0;
    			for (i = 0; i < 13; i++)
    				for (j = 0; j < 13; j++)
    				{
    					// E和EC进行取小运算
    					if (Input1_Terms_Membership[Input1_Terms_Index][i] < Input2_Terms_Membership[Input2_Terms_Index][j])
    						R1[i][j] = Input1_Terms_Membership[Input1_Terms_Index][i];
    					else
    						R1[i][j] = Input2_Terms_Membership[Input2_Terms_Index][j];
    					// 转换R1矩阵为R2一维向量
    					R2[k] = R1[i][j];
    					k++;
    				}
    			///<A=Input1_Terms_Membership[Input1_Terms_Index],B=Input2_Terms_Membership[Input2_Terms_Index]
    			///<R1=AXB建立13x13的矩阵,R2=R1'把矩阵转成169x1的列向量
    			for (i = 0; i < 169; i++)
    				for (j = 0; j < 13; j++)
    				{
    					// R1(E, EC)与U进行取小运算
    					if (R2[i] < Output_Terms_Membership[Output_Terms_Index][j])
    						R3[i][j] = R2[i];
    					else
    						R3[i][j] = Output_Terms_Membership[Output_Terms_Index][j];
    					// R进行取大运算,为所有规则模糊关系的并集
    					if (R3[i][j] > R[i][j])
    						R[i][j] = R3[i][j];
    				}
    		}
    
    
    	/*************************对于每种可能的E、EC的精确取值模糊化后进行推理得到模糊输出Cd,Cd=(AdxBd)oR*************************/
    	for (Input1_value_index = 0; Input1_value_index < 13; Input1_value_index++) {
    		for (Input2_value_index = 0; Input2_value_index < 13; Input2_value_index++)
    		{
    			for (j = 0; j < 13; j++)
    				Cd[j] = 0;
    			int kd = 0;
    			float temp = 0;
    			Max_Input1_value = E_MAX(Input1_value_index);	///<找出误差隶属度最大的语言值
    			Max_Input2_value = EC_MAX(Input2_value_index);	///<找出误差变化率隶属度最大的语言值
    			for (i = 0; i < 13; i++)
    				for (j = 0; j < 13; j++)
    				{
    					// E(Ad)和EC(Bd)进行取小运算
    					if (Input1_Terms_Membership[Max_Input1_value][i] < Input2_Terms_Membership[Max_Input2_value][j])
    						AdBd1[i][j] = Input1_Terms_Membership[Max_Input1_value][i];
    					else
    						AdBd1[i][j] = Input2_Terms_Membership[Max_Input2_value][j];
    					AdBd2[kd] = AdBd1[i][j];
    					kd++;
    				}
    			for (i = 0; i < 169; i++)
    				for (j = 0; j < 13; j++)
    				{
    					// 模糊矩阵的合成,将乘积运算换成“取小”,将加法运算换成“取大”
    					if (AdBd2[i] < R[i][j])
    						temp = AdBd2[i];
    					else
    						temp = R[i][j];
    					if (temp > Cd[j])
    						Cd[j] = temp;
    				}
    
    
    			/*************************去模糊化(加权平均法),计算实际输出*************************/
    			float sum1 = 0, sum2 = 0;
    			float OUT;
    			for (i = 0; i < 13; i++)
    			{
    				sum1 = sum1 + Cd[i];
    				sum2 = sum2 + Cd[i] * SPEED[i];
    			}
    			OUT = (int)(sum2 / sum1 + 0.5);///<四舍五入
    			Fuzzy_Table[Input1_value_index][Input2_value_index] = OUT;
    			cout << OUT << ",";
    		}
    		cout << endl;
    	}
    }
    

    3.模糊查询表设置车速

    将模糊查询表复制进入代码程序,将实际的e和ec映射到论域中后,在模糊查询表中查询结果并设置目标车速。

    int_16 Fuzzy_Table[13][13]= 
    { 
    203,211,211,211,226,226,230,230,228,210,210,210,210,
    209,221,221,221,238,238,241,241,237,231,231,231,227,
    209,221,221,221,238,238,241,241,237,231,231,231,227,
    209,221,221,221,238,238,241,241,237,231,231,231,227,
    215,238,238,238,245,245,266,266,246,237,237,237,232,
    215,238,238,238,245,245,266,266,246,237,237,237,232,
    218,250,250,250,276,276,283,283,280,245,245,245,216,
    218,250,250,250,276,276,283,283,280,245,245,245,216,
    232,240,240,240,250,250,271,271,246,236,236,236,217,
    226,230,230,230,236,236,239,239,236,214,214,214,208,
    226,230,230,230,236,236,239,239,236,214,214,214,208,
    226,230,230,230,236,236,239,239,236,214,214,214,208,
    211,211,211,211,226,226,230,230,228,208,208,208,203
    }  ;
    
    int_16 get_speed_set(void) {
    	int_16 E = 0, EC = 0;
    	int_16 speed_target;
    	static int_16 re_pos = 0, ek = 0, eck = 0;
    	float ke = 400, kec = 10;
    	ek = 2500 - row;
    	eck = 2500 - row - re_pos;
    	re_pos = ek;
    
    	if (ek > 0) {
    
    		E = (int_32)(ek / ke + 0.5);
    	}
    	else {
    
    		E = (int_32)(ek / ke - 0.5);
    	}
    	//将E的论域转换到模糊控制器的论域
    	if (E > 6)
    		E = 6;
    	else if (E < -6)
    		E = -6;
    	if (eck > 0) {
    
    		EC = (int_16)(eck / kec + 0.5);
    	}
    	else {
    
    		EC = (int_16)(eck / kec - 0.5);
    	}//将EC的论域转换到模糊控制器的论域
    	if (EC > 6)
    		EC = 6;
    	else if (EC < -6)
    		EC = -6;
    
    	speed_target = (int_16)(Fuzzy_Table[E + 6][EC + 6]);
    	return speed_target ;
    }
    

    三、总结

    本文首先对PID控制器进行了简单的阐述,并应用于车速控制中。然后引入模糊控制对目标车速进行设置,实现速度的平稳过渡。PID算法和模糊控制算法在保证行驶平稳性的前提下,最大幅度地提升小车的行驶速度。

    参考资料
    [1]详细讲解PID控制
    [2]PID控制算法原理(抛弃公式,从本质上真正理解PID控制)
    [3]初识PID-搞懂PID概念
    [4]模糊控制——基本原理
    [5]基于单目视觉的智能车速度模糊控制系统
    [6]模糊算法在智能车控制中的应用

    展开全文
  • 模糊PID算法

    2019-12-19 15:24:06
    在讲解模糊PID前,我们先要了解PID控制器的原理(本文主要介绍模糊PID的运用,对PID控制器的原理不做详细介绍)。PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分...

     在讲解模糊PID前,我们先要了解PID控制器的原理(本文主要介绍模糊PID的运用,对PID控制器的原理不做详细介绍)。PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分单元I和微分单元D组成。PID控制的基础是比例控制;积分控制可消除稳态误差,但可能增加超调;微分控制可加快大惯性系统响应速度以及减弱超调趋势。


    1.1传统PID控制

    传统PID控制器自出现以来,凭借其结构简单、稳定性好、工作可靠、调整方便等优点成为工业控制主要技术。当被控对象的结构和参数具有一定的不确定性,无法对其建立精确的模型时,采用PID控制技术尤为方便。PID控制原理简单、易于实现,但是其参数整定异常麻烦。对于小车的速度控制系统而言,由于其为时变非线性系统不同时刻需要选用不同的PID参数,采用传统的PID控制器,很难使整个运行过程具有较好的运行效果。

     

    1.2模糊PID控制

     

     模糊PID控制,即利用模糊逻辑并根据一定的模糊规则对PID的参数进行实时的优化,以克服传统PID参数无法实时调整PID参数的缺点。模糊PID控制包括模糊化,确定模糊规则,解模糊等组成部分。小车通过传感器采集赛道信息,确定当前距赛道中线的偏差E以及当前偏差和上次偏差的变化ec,根据给定的模糊规则进行模糊推理,最后对模糊参数进行解模糊,输出PID控制参数。

    2.1模糊化

     

     模糊控制器主要由三个模块组成:模糊化,模糊推理,清晰化。具体如下图所示。而我们将一步步讲解如何将模糊PID算法运用到智能车上。(最好用笔一步步自己写一遍!!!)

     首先我们的智能车会采集到赛道的相关数据,例如摄像头车,其采集到的数据经过算法处理之后会得到与中线的偏差E,以及当前偏差和上次偏差的变化(差值)EC两个值(即此算法为2维输入,同理也可以是1维和3维,但2维更适合智能车)。例如此时车偏离中线的距离为150,而上一时刻偏离中线的距离为120,则E为150,EC为150 - 120 = 30。

     其次我们要对这两个值进行模糊化。这里我们对E进行举例。摄像头车采集回来的E是有范围的,即与中线的偏差是在一个区间内可行的。在这里我们假设该区间为-240到240,即小车偏离中线的最大距离为240,正负即为左右。再假设中线偏差变化率的可行区间为-40到+40。

     

            接着我们要对这两个值进行模糊化。我现在将E的区间(-240 到 240)分成8个部分,那么他们分别为-240 ~ -180,-180 ~ -120 ,-120 ~ -60,-60 ~ 0,0 ~ 60,60 ~ 120,120 ~ 180,180 ~ 240。然后我们把-180,-120,-60,0,60,120,180分别用NB,NM,NS,ZO,PS,PM,PB表示(个人理解N为negative,P为positive,B为big,M为middle,S为small,ZO为zero)。例如,当E = 170时,此时的E属于PM和PB之间,而此时的E也会对应2(或1)个隶属度。E隶属于PM(120)的百分比为(180 - 170) /  (180 - 120) = 1 / 6 ,而同理隶属于PB(180)的百分比为(170 - 120) / (180 - 120) = 5 / 6  。意思就是120到180进行线性分割了,E离PM和PB哪个更近,则隶属于哪个就更大(当输出值E大于180(PB)时,则隶属度为1,隶属度值为PB,即E完全隶属于PB,同理当E小于 - 180 (NB)时也一样)。同理也可以对EC进行模糊化。

     

    2.2 模糊推理

           对于采集回来的E和EC,我们可以推出它们各所占的隶属度,此时我们可以根据模糊规则表去找出输出值所对应的隶属度。

     

         我们假设为E的两个隶属度值为PM、PB,E属于PM的隶属度为a(a < 1),则属于PB的隶属度为(1 - a)。再假设EC的两个隶属度值为NB、NM,EC属于NM的隶属度为b,则属于NB的隶属度为(1 - b)。而在假设中,E属于PM的隶属度为a,EC属于NB的隶属度为( 1 - b ),则输出值属于ZO的隶属度为a *( 1 - b )(看图)。

           同理我们可以得出,当输出值属于ZO的另外两个隶属度为a * b, ( 1 - a ) * ( 1 - b) ,而输出值属于NS的隶属度为 ( 1 - a ) *  b。

           在这里我们先证明一个条件,将这四个隶属度加起来,刚好等于1。这是因为

            (a + (1 - a)) * (b + (1 - b)) = a * b + ( 1 - a ) *  b  + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b )   (下图)

           即一个十字相乘的概念。这个等式说明输出值的隶属度之和等于1(第三步求解的时候需要用到隶属度之和)。

    因此,我们知道了输出值为ZO的隶属度和为 a * b + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b ) ,输出值为NS的隶属度为 ( 1 - a ) *  b 。

     

    2.3 清晰化

           对于输出值,我们同样采用给予隶属度的办法。例如,我们把输出值假设为[1000,1400](即舵机的摆角值范围)的区间同样划分为八个部分,即7个隶属值NB,NM,NS,ZO,PS,PM,PB。根据上一步所得出的结论,我们就可以用隶属度乘以相应的隶属值算出输出值的解,即 (a * b + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b ) ) * ZO   +    ( 1 - a ) *  b * NS。到此为止,整个模糊过程就结束了。

         

    3 模糊PID

          我们已经知道了整个模糊的过程,但上述的过程还不够完美。因为我们的输出值只有一个输出,并没有实现PID。因此我们可以先对E和EC进行模糊化,然后分别对kp和ki和kd(PID的三个参数)进行求解,再套入公式。

         一般的我们也可以只用kp,kd,不用ki。而模糊规则表一般的论文已经基本给出。因此带入算法之后我们的难度也只是在于调节kp,kd,和适当调节规则表。当然调节的难度会大于普通的PID,因为还要定kp,kd的输出范围,调得不好可能效果并没有普通的PID好。

     

    4. 部分解释

         4.1对于部分论文所说的重心法解模糊,其实就是上述方法。公式如下。

          式中μ(Zi) * Zi相当于文章上面的(a * b + a * ( 1 - b ) + ( 1 - a ) * ( 1 - b ) ) * ZO   +    ( 1 - a ) *  b * NS,即隶属度乘以隶属度值之和,而μ(Zi)之和就是输出值的隶属度之和,我们已经证明它是等于1的。
     

    参考

    [1] https://blog.csdn.net/weixin_36340979/article/details/79168052

    [2] https://blog.csdn.net/foxclever/article/details/83932107

    展开全文
  • 备战第16届智能车-控制处理进阶-模糊PID算法

    千次阅读 多人点赞 2020-11-22 14:36:41
    备战第16届智能车-控制处理进阶-模糊PID算法一、前言二、代码部分1、模糊分布表2、计算模糊完成的Kp\Kd三、总结 一、前言 模糊PID算法近几年被广泛用于智能车竞赛之中 博主将用最简单的方式让初学者明白如何使用 ...

    一、前言

    模糊PID算法近几年被广泛用于智能车竞赛之中
    博主将用最简单的方式让初学者明白如何使用
    建议先理解基础的PID算法

    二、代码部分

    1、模糊分布表

    根据经验而来的,个人不建议更改

    int rule[7][7]=
    {
    	{ 6 , 5 , 4 , 3 , 2 , 1 , 0},//0
    	{ 5 , 4 , 3 , 2 , 1 , 0 , 1},//1
    	{ 4 , 3 , 2 , 1 , 0 , 1 , 2},//2
    	{ 3 , 2 , 1 , 0 , 1 , 2 , 3},//3
    	{ 2 , 1 , 0 , 1 , 2 , 3 , 4},//4
    	{ 1 , 0 , 1 , 2 , 3 , 4 , 5},//5
    	{ 0 , 1 , 2 , 3 , 4 , 5 , 6},//6
    };//模糊规则表
    

    2、计算模糊完成的Kp\Kd

    EFF:Kp的取值分为7等份
    DFF:Kd的取值分为7等份
    UFF:Kp或者Kd对应的误差的取值范围等分
    E:此时的误差
    EC:误差的误差
    说明:Kp与Kd的计算方式一样,只需要更改UFF的范围即可,返回值即为Kp\Kd
    计算完成以后即可带入PID公式计算位置式PID或者增量式PID

    float Fuzzy(float E,float EC)
    {
        /*输入量P语言值特征点*/
        float EFF[7]={-15,-10,-5,0,5,10,15};
        /*输入量D语言值特征点*/
        float DFF[7]={-12,-8,-4,0,4,8,12};
        /*输出量U语言值特征点(根据赛道类型选择不同的输出值)*/
        float UFF[7]={0,5,10,15,20,25,30};
    
        float U=0;  /*偏差,偏差微分以及输出值的精确量*/
        float PF[2]={0},DF[2]={0},UF[4]={0};
        /*偏差,偏差微分以及输出值的隶属度*/
        int Pn=0,Dn=0,Un[4]={0};
        float t1=0,t2=0,t3=0,t4=0,temp1=0,temp2=0;
        /*隶属度的确定*/
        /*根据PD的指定语言值获得有效隶属度*/
        if(E>EFF[0] && E<EFF[6])
        {
            if(E<=EFF[1])
            {
                Pn=-2;
                PF[0]=(EFF[1]-E)/(EFF[1]-EFF[0]);
            }
            else if(E<=EFF[2])
            {
                Pn=-1;
                PF[0]=(EFF[2]-E)/(EFF[2]-EFF[1]);
            }
            else if(E<=EFF[3])
            {
                Pn=0;
                PF[0]=(EFF[3]-E)/(EFF[3]-EFF[2]);
            }
            else if(E<=EFF[4])
            {
                Pn=1;
                PF[0]=(EFF[4]-E)/(EFF[4]-EFF[3]);
            }
            else if(E<=EFF[5])
            {
                Pn=2;
                PF[0]=(EFF[5]-E)/(EFF[5]-EFF[4]);
            }
            else if(E<=EFF[6])
            {
                Pn=3;
                PF[0]=(EFF[6]-E)/(EFF[6]-EFF[5]);
            }
        }
    
        else if(E<=EFF[0])
        {
            Pn=-2;
            PF[0]=1;
        }
        else if(E>=EFF[6])
        {
            Pn=3;
            PF[0]=0;
        }
    
        PF[1]=1-PF[0];
    
    
        //判断D的隶属度
        if(EC>DFF[0]&&EC<DFF[6])
        {
            if(EC<=DFF[1])
            {
                Dn=-2;
                DF[0]=(DFF[1]-EC)/(DFF[1]-DFF[0]);
            }
            else if(EC<=DFF[2])
            {
                Dn=-1;
                DF[0]=(DFF[2]-EC)/(DFF[2]-DFF[1]);
            }
            else if(EC<=DFF[3])
            {
                Dn=0;
                DF[0]=(DFF[3]-EC)/(DFF[3]-DFF[2]);
            }
            else if(EC<=DFF[4])
            {
                Dn=1;
                DF[0]=(DFF[4]-EC)/(DFF[4]-DFF[3]);
            }
            else if(EC<=DFF[5])
            {
                Dn=2;
                DF[0]=(DFF[5]-EC)/(DFF[5]-DFF[4]);
            }
            else if(EC<=DFF[6])
            {
                Dn=3;
                DF[0]=(DFF[6]-EC)/(DFF[6]-DFF[5]);
            }
        }
        //不在给定的区间内
        else if (EC<=DFF[0])
        {
            Dn=-2;
            DF[0]=1;
        }
        else if(EC>=DFF[6])
        {
            Dn=3;
            DF[0]=0;
        }
    
        DF[1]=1-DF[0];
    
        /*使用误差范围优化后的规则表rule[7][7]*/
        /*输出值使用13个隶属函数,中心值由UFF[7]指定*/
        /*一般都是四个规则有效*/
        Un[0]=rule[Pn+2][Dn+2];
        Un[1]=rule[Pn+3][Dn+2];
        Un[2]=rule[Pn+2][Dn+3];
        Un[3]=rule[Pn+3][Dn+3];
    
        if(PF[0]<=DF[0])    //求小
            UF[0]=PF[0];
        else
            UF[0]=DF[0];
        if(PF[1]<=DF[0])
            UF[1]=PF[1];
        else
            UF[1]=DF[0];
        if(PF[0]<=DF[1])
            UF[2]=PF[0];
        else
            UF[2]=DF[1];
        if(PF[1]<=DF[1])
            UF[3]=PF[1];
        else
            UF[3]=DF[1];
        /*同隶属函数输出语言值求大*/
        if(Un[0]==Un[1])
        {
            if(UF[0]>UF[1])
                UF[1]=0;
            else
                UF[0]=0;
        }
        if(Un[0]==Un[2])
        {
            if(UF[0]>UF[2])
                UF[2]=0;
            else
                UF[0]=0;
        }
        if(Un[0]==Un[3])
        {
            if(UF[0]>UF[3])
                UF[3]=0;
            else
                UF[0]=0;
        }
        if(Un[1]==Un[2])
        {
            if(UF[1]>UF[2])
                UF[2]=0;
            else
                UF[1]=0;
        }
        if(Un[1]==Un[3])
        {
            if(UF[1]>UF[3])
                UF[3]=0;
            else
                UF[1]=0;
        }
        if(Un[2]==Un[3])
        {
            if(UF[2]>UF[3])
                UF[3]=0;
            else
                UF[2]=0;
        }
        t1=UF[0]*UFF[Un[0]];
        t2=UF[1]*UFF[Un[1]];
        t3=UF[2]*UFF[Un[2]];
        t4=UF[3]*UFF[Un[3]];
        temp1=t1+t2+t3+t4;
        temp2=UF[0]+UF[1]+UF[2]+UF[3];//模糊量输出
        U=temp1/temp2;
        return U;
    }
    

    三、总结

    这段代码可以让初学者迅速上手模糊PID,博主认为帮助更大。
    如果想了解更深层次的原理,大家可以自行百度,理论讲得好的有很多。

    展开全文
  • 的方法,实现了对方向和速度的优化控制,即采用模糊算法智能车方向进行控制;采用模糊PID 算法实 现了对于智能车的速度控制。从而使智能车能够根据路况的变化, 做出相应的控制决策。控制策略是在 Freescale ...
  • 本人搭建的一些Carsim与Simulink的联合仿真模型,包括车道保持(LKA),自适应巡航(ACC),轨迹跟随,横向控制,预瞄跟随,单点预瞄,多点预瞄,滑模变结构控制,模糊控制等算法的介绍和实现,该下载资料不为CSDN...
  • 第3章 智能汽车设计基础软件;第3章 智能汽车设计基础软件;3.1 编程语言简介;3.1 编程语言简介;3.2 控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID控制算法;3.2.1 PID...
  • Arduino智能小车直线控制-模糊PID控制

    千次阅读 多人点赞 2020-04-20 22:07:10
    本文主要由三部分构成:模糊PID控制器的原理,模糊PID控制器C++的实现与测试,把模糊PID控制算法应用于Arduino 智能小车走直线的过程中。 一,模糊PID原理 模糊PID控制流程如下图所示,把目标值Xtarget与...
  • 一种基于模糊控制的智能车转向控制算法研究一种基于模糊控制的智能车转向控制算法研究
  • 以第四届“飞思卡尔”杯全国大学生智能汽车大赛为背景,介绍了基于视觉传感器的智能车控制算法,包括方向控制和速度控制。在PID算法模糊控制算法几乎为所有参赛队伍所采用的背景下,提出了“最优曲率法”,并使用...
  • 模糊_PID_自整定算法理解

    热门讨论 2012-04-25 22:25:12
    入门级别的模糊_PID_自整定算法理解方法,让你很快理解PID自整定控制策略,便于编程,飞思卡尔智能车时使用,很好用
  • 所以要想手眼协调,智能车控制得当,好的视觉处理算法和好的PID调试都密不可分。不然也不会有专门的PID调试的岗位了。废话不多说,下面是我整理的一些资料。 摘录自智能车界的老学长刘键的一篇文章。如果...
  • 本文将前馈控制引入到了智能车系统的控制中,有效地改善了...同时,利用模糊控制具有对参数变化不敏感和鲁棒性强的特点[2],本文将模糊算法PID算法相结合,有效地提高了智能车的适应性和鲁棒性,改善了系统的控制性能
  • 这个是PID模糊控制器的设计及在智能车转向控制上的应用,可以指导你如何设计PID模糊控制器算法,应用于智能车转向控制上。
  • 让你很快理解PID自整定控制策略,便于编程,飞思卡尔智能车时使用,很好用。入门级别的。
  • 普通PID、变结构PID、微分先行PID模糊PID、专家PID
  • 模糊控制PID

    2014-06-25 10:27:42
    智能车模糊模糊控制算法集合!
  • 选取车辆当前位姿和参考位姿来构造车辆的动态位姿误差,建立车辆路径跟踪闭环控制系统的 ...利用常规 和模糊自适应 控制算法分别进行仿真实验 仿真结果表明,模糊自适应 改善了控制器的动态性能且具有较好的自适应能力
  • 今天调入车库的舵机PD时发现了一个重大bug,就是很有可能我写的模糊pid是有问题的。我之前一直以为输出限制为0就和普通PID一样,结果发现并不是,这里贴出关于模糊的代码,当时也是跟着网上的来写的,也不会验证代码...
  • 2、NXP智能车__参考算法.pdf; 3、PID算法原理、调试经验和代码.pdf; 4、边缘跟踪算法.vsd; 5、舵机滤波算法.txt; 6、经典滤波算法.pdf; 7、控制方法的c语言实现-王帅(摩尔吧).pdf; 8、模糊神经...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 617
精华内容 246
关键字:

智能车的模糊算法pid