模糊自适应PID算法及其运用

        模糊自适应PID算法主要是由模糊控制器和PID控制器结合而成,模糊控制器以误差e和误差变化率ec作为输入,利用模糊规则对PID控制器的参数Kp、Ki、和Kd进行自适应整定,使被控对象保持在良好的动、静态稳定状态。相比传统的PID控制,模糊自适应PID更加的灵活稳定,特别是对于时变性和非线性较大的被控对象,其优点更加突出。


设计模糊自适应PID控制需要以下步骤:

1. 模糊控制规则的确定。(模糊控制规则主要可以通过专家经验和采样数据两个方面获得)

2.利用模糊规则表对e(误差)和ec(误差变化率)进行模糊化处理得出相应的隶属度。

3.利用所得出的隶属度及相应隶属度的横坐标(eg:PB、NS)带入公式求出 Kp、Ki、Kd。

公式如下:


其中UAi(x)、UBi(y)表示求出的隶属度,Zi表示对应隶属度的横坐标(eg:PB、NS)

4.由Kp = Kp + Kp得出整定后的参数Kp、Ki、Kd,并带入PID控制器中运算。

PID公式如下:


以下为模糊自适应PID算法:

/************************************************************************************
* @author: 镜璍氺月
* @date : 2018/2/15
* @fuction name:FUZZY_PID_CONTROL
* @fuction description: 模糊自适应控制算法,为了方便测试默认e、ec在[-3,3]区间,
* 如需改变e、ec范围,需引入量化因子(Ke、Kec=N/emax)、缩放因子(Ku=umax/N)。以下代码采
*用三角隶属函数求隶属度以及加权平均法解模糊,PID采用位置式PID算法,算法仅供参考,欢迎报错。
*************************************************************************************/
#define IS_Kp 1
#define IS_Ki 2
#define IS_Kd 3

#define NL       -3
#define NM	 -2
#define NS	 -1
#define ZE	 0
#define PS	 1
#define PM	 2
#define PL	 3



static const float fuzzyRuleKp[7][7]={
	PL,	PL,	PM,	PM,	PS,	PS,	ZE,
	PL,	PL,	PM,	PM,	PS,	ZE,	ZE,
	PM,	PM,	PM,	PS,	ZE,	NS,	NM,
	PM,	PS,	PS,	ZE,	NS,	NM,	NM,
	PS,	PS,	ZE,	NS,	NS,	NM,	NM,
	ZE,	ZE,	NS,	NM,	NM,	NM,	NL,
	ZE,	NS,	NS,	NM,	NM,	NL,	NL
};

static const float fuzzyRuleKi[7][7]={
	NL,	NL,	NL,	NM,	NM,	ZE,	ZE,
	NL,	NL,	NM,	NM,	NS,	ZE,	ZE,
	NM,	NM,	NS,	NS,	ZE,	PS,	PS,
	NM,	NS,	NS,	ZE,	PS,	PS,	PM,
	NS,	NS,	ZE,	PS,	PS,	PM,	PM,
	ZE,	ZE,	PS,	PM,	PM,	PL,	PL,
	ZE,	ZE,	PS,	PM,	PL,	PL,	PL
};

static const float fuzzyRuleKd[7][7]={
	PS,	PS,	ZE,	ZE,	ZE,	PL,	PL,
	NS,	NS,	NS,	NS,	ZE,	NS,	PM,
	NL,	NL,	NM,	NS,	ZE,	PS,	PM,
	NL,	NM,	NM,	NS,	ZE,	PS,	PM,
	NL,	NM,	NS,	NS,	ZE,	PS,	PS,
	NM,	NS,	NS,	NS,	ZE,	PS,	PS,
	PS,	ZE,	ZE,	ZE,	ZE,	PL,	PL
};

typedef struct{
	float Kp;
	float Ki;
	float Kd;
}PID;






PID fuzzy(float e,float ec)
{

     float etemp,ectemp;
     float eLefttemp,ecLefttemp;
     float eRighttemp ,ecRighttemp;

     int eLeftIndex,ecLeftIndex;
     int eRightIndex,ecRightIndex;
     PID      fuzzy_PID;
     etemp = e > 3.0 ? 0.0 : (e < - 3.0 ? 0.0 : (e >= 0.0 ? (e >= 2.0 ? 2.5: (e >= 1.0 ? 1.5 : 0.5)) : (e >= -1.0 ? -0.5 : (e >= -2.0 ? -1.5 : (e >= -3.0 ? -2.5 : 0.0) ))));

     eLeftIndex = (int)e;
     eRightIndex = eLeftIndex;
     eLeftIndex = (int)((etemp-0.5) + 3);        //[-3,3] -> [0,6]
     eRightIndex = (int)((etemp+0.5) + 3);

     eLefttemp =etemp == 0.0 ? 0.0:((etemp+0.5)-e);
     eRighttemp=etemp == 0.0 ? 0.0:( e-(etemp-0.5));

     ectemp = ec > 3.0 ? 0.0 : (ec < - 3.0 ? 0.0 : (ec >= 0.0 ? (ec >= 2.0 ? 2.5: (ec >= 1.0 ? 1.5 : 0.5)) : (ec >= -1.0 ? -0.5 : (ec >= -2.0 ? -1.5 : (ec >= -3.0 ? -2.5 : 0.0) ))));

     ecLeftIndex = (int)((ectemp-0.5) + 3);        //[-3,3] -> [0,6]
     ecRightIndex = (int)((ectemp+0.5) + 3);

     ecLefttemp =ectemp == 0.0 ? 0.0:((ectemp+0.5)-ec);
     ecRighttemp=ectemp == 0.0 ? 0.0:( ec-(ectemp-0.5));

/*************************************反模糊*************************************/




	fuzzy_PID.Kp = (eLefttemp * ecLefttemp *  fuzzyRuleKp[ecLeftIndex][eLeftIndex]                    
					+ eLefttemp * ecRighttemp * fuzzyRuleKp[ecRightIndex][eLeftIndex]
					+ eRighttemp * ecLefttemp * fuzzyRuleKp[ecLeftIndex][eRightIndex]
					+ eRighttemp * ecRighttemp * fuzzyRuleKp[ecRightIndex][eRightIndex]);

	fuzzy_PID.Ki =   (eLefttemp * ecLefttemp * fuzzyRuleKi[ecLeftIndex][eLeftIndex]
					+ eLefttemp * ecRighttemp * fuzzyRuleKi[ecRightIndex][eLeftIndex]
					+ eRighttemp * ecLefttemp * fuzzyRuleKi[ecLeftIndex][eRightIndex]
					+ eRighttemp * ecRighttemp * fuzzyRuleKi[ecRightIndex][eRightIndex]);

	fuzzy_PID.Kd = (eLefttemp * ecLefttemp *    fuzzyRuleKd[ecLeftIndex][eLeftIndex]
					+ eLefttemp * ecRighttemp * fuzzyRuleKd[ecRightIndex][eLeftIndex]
					+ eRighttemp * ecLefttemp * fuzzyRuleKd[ecLeftIndex][eRightIndex]
					+ eRighttemp * ecRighttemp * fuzzyRuleKd[ecRightIndex][eRightIndex]);
return fuzzy_PID;

}


float speed_pid()
{
        float tar = 0,cur = 0;                //目标值 , 实际值
	static PID pid= {0, 0, 0};      //赋予初值kp,ki,kd
	static int sumE = 0;                   //累加偏差
	static int lastE = 0;

	PID OUT = {0, 0, 0};
	float e = -1,ec = -2.6;



	e = tar - cur;             //目标值 - 实际值
	ec = e - lastE;            //误差变化率
	sumE += e;
	lastE = e;
	OUT = fuzzy(e, ec);      //模糊控制调整  kp,ki,kd

	return (pid.Kp+OUT.Kp)*e + (pid.Kd+OUT.Kd)*ec + (pid.Ki+OUT.Ki)*sumE;
}
可直接应用于对象,需要传入传感器的值于speed_pid()的cur,并更改tar值,赋值pid初始参数。
static PID pid= {0, 0, 0};    //需要自己赋值


  • 87
    点赞
  • 652
    收藏
    觉得还不错? 一键收藏
  • 34
    评论
模糊自适应PID控制算法是由模糊控制器和PID控制器结合而成的一种控制算法模糊控制器以误差e和误差变化率ec作为输入,通过利用模糊规则对PID控制器的参数Kp、Ki和Kd进行自适应整定,实现对被控对象保持在良好的动态和静态稳定状态。相比传统的PID控制模糊自适应PID控制算法更加灵活稳定,特别适用于时变性和非线性较大的被控对象。 该算法的步骤包括: 1. 输入量的量化:将输入量进行量化,以便于后续处理。 2. 输入值的模糊化:将输入值进行模糊化,将其映射到模糊集合上,以便于进行模糊逻辑推理。 3. 建立模糊规则表:根据具体的控制需求和系统特性,设计模糊规则表,用于定义模糊控制器的行为。包括Kp、Ki和Kd的模糊规则设计。 4. 解模糊处理:根据模糊控制器的输出,使用解模糊方法将模糊的控制信号转化为具体的控制参数,使其能够被系统所使用。 模糊自适应PID控制算法在实际应用中有着广泛的应用,特别是在涉及到时变性和非线性较大的被控对象的控制问题上,它的优势更加突出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [模糊自适应整定PID控制](https://blog.csdn.net/lihaoyubiss/article/details/122688409)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [模糊自适应PID算法及其运用](https://blog.csdn.net/a841771798/article/details/79323118)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值