完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.前言
模糊PID已经在实际生活当中有应用了,至于它是否真的比传统PID要好,各位就自行判断。本文基于博主做的项目中的经验总结而成,借助代码一步步推理至实现。有不错的控温效果,精度很高,但耗时挺长。 2.实现步骤 2.1输入量的量化与模糊化 在温度控制中,能够得到的数据就是温差(Error)和温差变化率(iError),所以首先确定我们的输入有两个:Error、Error。模糊PID的特点就是模糊,我们将确切的输入进行量化,就是模糊的第一步。量化就是通过量化函数将输入映射到几个数字级别,一般都是相对于0对称的数字区间。具体投射到怎样的区间根据实际情况而定。 举个例子:温控器件工作温度是25c°,目标常控温度为20c°,那么输入数据的范围为:±5c°,又由于温控器件温度变化率最大为±0.3(变化率的大小需要实际测定,具体与每周期采样时间有关)。那么,我们需要设置量化函数的两个分母为:5与0.3,因此在温控过程中,温差逐渐减少,所以量化值Error/MaxE的值随着温差减少而减小,能够表征温控当前温度与目标温度的差距(方便减小P控制和增大I控制,细品)。 代码用的是±6. //输入值的量化论域(-6-》6) static void LinearQuantization(FUZZYPID *vPID,float _Real_Value,float *qValue) { float thisError; float deltaError; thisError=vPID-》setVaule-_Real_Value; //计算当前偏差 deltaError=thisError-vPID-》lasterror; //计算偏差增量 //E和EC的量化 qValue[0]=6.0*thisError/(vPID-》maximum-vPID-》minimum); qValue[1]=3.0*deltaError/(vPID-》maximum-vPID-》minimum); // printf(“qValue[0]:%frn,qValue[1]:%frn”,qValue[0],qValue[1]); } 2.2规则库 #define NB -6 #define NM -4 #define NS -1 #define ZO 0 #define PS 1 #define PM 4 #define PB 6 //规则库 static const float ruleKp[7][7]={ PB, PB, PM, PM, PS, PS, ZO, PB, PB, PM, PM, PS, ZO, ZO, PM, PM, PM, PS, ZO, NS, NM, PM, PS, PS, ZO, NS, NM, NM, PS, PS, ZO, NS, NS, NM, NM, ZO, ZO, NS, NM, NM, NM, NB, ZO, NS, NS, NM, NM, NB, NB }; static const float ruleKi[7][7]={ NB, NB, NB, NM, NM, ZO, ZO, NB, NB, NM, NM, NS, ZO, ZO, NM, NM, NS, NS, ZO, PS, PS, NM, NS, NS, ZO, PS, PS, PM, NS, NS, ZO, PS, PS, PM, PM, ZO, ZO, PS, PM, PM, PB, PB, ZO, ZO, PS, PM, PB, PB, PB }; static const float ruleKd[7][7]={ PS, PS, ZO, ZO, ZO, PB, PB, NS, NS, NS, NS, ZO, NS, PM, NB, NB, NM, NS, ZO, PS, PM, NB, NM, NM, NS, ZO, PS, PM, NB, NM, NS, NS, ZO, PS, PS, NM, NS, NS, NS, ZO, PS, PS, PS, ZO, ZO, ZO, ZO, PB, PB }; ``` 由代码可知,分7个等级,成3个表格,表格的正中心表示温控达到目标温度且变化率为0;表格左上方表示温差处于负的大值,且误差变化率处于负的大值,此时温控处于快速接近目标温度的误差较大期(假设输入为负且误差为负是系统开始时的输入),所以大家可以仔细分析表格不同位置所蕴含的系统当前所处状态,在中点附近,同一个位置可以有两种不同的解释(制冷or加热) 注:上述表格是指输入数据的隶属度的投影,横坐标为变化率从左到右为负大到正大,纵坐标为误差变化率从上到下为负大到正大。 2.3隶属度函数 //隶属度计算函数 static void CalcMembership(float *ms,float qv,int * index) { if((qv》=NB)&&(qv《NM)) { index[0]=0; index[1]=1; ms[0]=-0.5*qv-2.0; //y=-0.5x-2.0 ms[1]=0.5*qv+3.0; //y=0.5x+3.0 } else if((qv》=NM)&&(qv《NS)) { index[0]=1; index[1]=2; ms[0]=-0.5*qv-1.0; //y=-0.5x-1.0 ms[1]=0.5*qv+2.0; //y=0.5x+2.0 } else if((qv》=NS)&&(qv《ZO)) { index[0]=2; index[1]=3; ms[0]=-0.5*qv; //y=-0.5x ms[1]=0.5*qv+1.0; //y=0.5x+1.0 } else if((qv》=ZO)&&(qv《PS)) { index[0]=3; index[1]=4; ms[0]=-0.5*qv+1.0; //y=-0.5x+1.0 ms[1]=0.5*qv; //y=0.5x } else if((qv》=PS)&&(qv《PM)) { index[0]=4; index[1]=5; ms[0]=-0.5*qv+2.0; //y=-0.5x+2.0 ms[1]=0.5*qv-1.0; //y=0.5x-1.0 } else if((qv》=PM)&&(qv《=PB)) { index[0]=5; index[1]=6; ms[0]=-0.5*qv+3.0; //y=-0.5x+3.0 ms[1]=0.5*qv-2.0; //y=0.5x-2.0 } } 不多说,代入几个特殊数字就知道什么意思了:例如0, 0.5 2.5等,就可以知道隶属度是指某个值属于它附近两个等级的程度(1显而易见的属于0与1等级),这里需要分别计算误差和误差变化率的隶属度。 2.4模糊推理 实际上,2.3的隶属度计算已经实现了模糊推理的功能,将隶属度分别算好之后,我们已经知道了四个等级所对应的隶属度大小,可以在表格上确定四个值(这里的值指的是PID三个参数),而输入值的量化等级(各两个等级)*它们对应的四个值(PID),就完成了模糊推理到解模糊 2.5解模糊 //采用重心法计算pid增量值 pidvalue[0]=msE[0]*(msEC[0]*ruleKp[indexE[0]][indexEC[0]]+msEC[1]*ruleKp[indexE[0]][indexEC[1]]) +msE[1]*(msEC[0]*ruleKp[indexE[1]][indexEC[0]]+msEC[1]*ruleKp[indexE[1]][indexEC[1]]); pidvalue[1]=msE[0]*(msEC[0]*ruleKi[indexE[0]][indexEC[0]]+msEC[1]*ruleKi[indexE[0]][indexEC[1]]) +msE[1]*(msEC[0]*ruleKi[indexE[1]][indexEC[0]]+msEC[1]*ruleKi[indexE[1]][indexEC[1]]); pidvalue[2]=msE[0]*(msEC[0]*ruleKd[indexE[0]][indexEC[0]]+msEC[1]*ruleKd[indexE[0]][indexEC[1]]) +msE[1]*(msEC[0]*ruleKd[indexE[1]][indexEC[0]]+msEC[1]*ruleKd[indexE[1]][indexEC[1]]); 这段代码包括了模糊推理与解模糊两个步骤,配合2.4看,同时别忘了代入具体值计算,有助于理解。 3总结 模糊PID的思想很有意思,但在实际应用中是否能得到真正有效的应用,就需要结合自己项目的实际去完成表格的调整,输入输出正负号、以及当前系统状态等等,这都是需要在实验中一步步去调试才能得到最终适合自己的那个结果。 若有读取温度曲线、stm32串口以及在stm32上实现FreeRTOS的需要。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1801 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1629 浏览 1 评论
1096 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
735 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1684 浏览 2 评论
1944浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
745浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
579浏览 3评论
601浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
565浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 13:59 , Processed in 0.953902 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号