欢迎访问:武汉绘芯科技有限公司官方网站
服务热线
027-87052087
当前位置:首页 > 行业动态 >

南昌滑轨电视 模糊自顺应PID算法及其运用

文章出处:网络整理 作者:佚名 人气: 时间:2021-02-09 13:05

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

模糊算法与pid

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

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

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

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

公式如下:

模糊算法与pid

模糊pid算法c程序_模糊pid控制算法程序_模糊算法与pid

其中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;
}

可直接应用于对象模糊算法与pid,需要传入传感器的值于speed_pid()的cur,并更改tar值,赋值pid初始数据。

static PID pid= {0, 0, 0};    //需要自己赋值

行业动态
联系我们
武汉绘芯科技有限公司

服务热线:027-87052087

技术支持:13329706647

地址:武汉市江夏区藏龙岛九凤街谭湖一路8号

在线客服

扫码与我交流