#include <string.h>
#include <stdio.h>
#include <math.h>
#include "pid_fuzzy.h"
//注1:自适应模糊pid最重要的就是论域的选择,要和你应该控制的对象相切合
//注2:以下各阀值、限幅值、输出值均需要根据具体的使用情况进行更改
//注3:因为我的控制对象惯性比较大,所以以下各部分取值较小
//论域e:[-5,5] ec:[-0.5,0.5]
//误差的阀值,小于这个数值的时候,不做PID调整,避免误差较小时频繁调节引起震荡
#define Emin 0.0
#define Emid 0.08
#define Emax 0.6
//调整值限幅,防止积分饱和
#define Umax 5
#define Umin -5
//输出值限幅
#define Pmax 7200
#define Pmin 0
#define NB 0
#define NM 1
#define NS 2
#define ZO 3
#define PS 4
#define PM 5
#define PB 6
int kp[7][7]= { {PB,PB,PM,PM,PS,ZO,ZO},
{PB,PB,PM,PS,PS,ZO,ZO},
{PM,PM,PM,PS,ZO,NS,NS},
{PM,PM,PS,ZO,NS,NM,NM},
{PS,PS,ZO,NS,NS,NM,NM},
{PS,ZO,NS,NM,NM,NM,NB},
{ZO,ZO,NM,NM,NM,NB,NB}
};
int kd[7][7]= { {PS,NS,NB,NB,NB,NM,PS},
{PS,NS,NB,NM,NM,NS,ZO},
{ZO,NS,NM,NM,NS,NS,ZO},
{ZO,NS,NS,NS,NS,NS,ZO},
{ZO,ZO,ZO,ZO,ZO,ZO,ZO},
{PB,NS,PS,PS,PS,PS,PB},
{PB,PM,PM,PM,PS,PS,PB}
};
int ki[7][7]= { {NB,NB,NM,NM,NS,ZO,ZO},
{NB,NB,NM,NS,NS,ZO,ZO},
{NB,NM,NS,NS,ZO,PS,PS},
{NM,NM,NS,ZO,PS,PM,PM},
{NM,NS,ZO,PS,PS,PM,PB},
{ZO,ZO,PS,PS,PM,PB,PB},
{ZO,ZO,PS,PM,PM,PB,PB}
};
/**************求隶属度(三角形)***************/
float FTri(float x,float a,float b,float c)//FuzzyTriangle
{
if(x<=a)
return 0;
else if((a<x)&&(x<=b))
return (x-a)/(b-a);
else if((b<x)&&(x<=c))
return (c-x)/(c-b);
else if(x>c)
return 0;
else
return 0;
}
/*****************求隶属度(梯形左)*******************/
float FTraL(float x,float a,float b)//FuzzyTrapezoidLeft
{
if(x<=a)
return 1;
else if((a<x)&&(x<=b))
return (b-x)/(b-a);
else if(x>b)
return 0;
else
return 0;
}
/*****************求隶属度(梯形右)*******************/
float FTraR(float x,float a,float b)//FuzzyTrapezoidRight
{
if(x<=a)
return 0;
if((a<x)&&(x<b))
return (x-a)/(b-a);
if(x>=b)
return 1;
else
return 1;
}
/****************三角形反模糊化处理**********************/
float uFTri(float x,float a,float b,float c)
{
float y,z;
z=(b-a)*x+a;
y=c-(c-b)*x;
return (y+z)/2;
}
/*******************梯形(左)反模糊化***********************/
float uFTraL(float x,float a,float b)
{
return b-(b-a)*x;
}
/*******************梯形(右)反模糊化***********************/
float uFTraR(float x,float a,float b)
{
return (b-a)*x +a;
}
/**************************求交集****************************/
float fand(float a,float b)
{
return (a<b)?a:b;
}
/**************************求并集****************************/
float forr(float a,float b)
{
return (a<b)?b:a;
}
float ec;
/*========== PID计算部分 ======================*/
int PID_realize(PID *structpid,uint16_t s,uint16_t in)
{
float pwm_var;//pwm调整量
float iError;//当前误差
float set,input;
//计算隶属度表
float es[7],ecs[7],e;
float form[7][7];
int i=0,j=0;
int MaxX=0,MaxY=0;
//记录隶属度最大项及相应推理表的p、i、d值
float lsd;
int temp_p,temp_d,temp_i;
float detkp,detkd,detki;//推理后的结果
//输入格式的转化及偏差计算
set=(float)s/100.0;
input=(float)in/100.0;
iError = set - input; // 偏差
e=iError;
ec=iError-structpid->LastError;
//当温度差的绝对值小于Emax时,对pid的参数进行调整
if(fabs(iError)<=Emax)
{
//计算iError在es与ecs中各项的隶属度
es[NB]=FTraL(e*5,-3,-1); //e
es[NM]=FTri(e*5,-3,-2,0);
es[NS]=FTri(e*5,-3,-1,1);
es[ZO]=FTri(e*5,-2,0,2);
es[PS]=FTri(e*5,-1,1,3);
es[PM]=FTri(e*5,0,2,3);
es[PB]=FTraR(e*5,1,3);
ecs[NB]=FTraL(ec*30,-3,-1);//ec
ecs[NM]=FTri(ec*30,-3,-2,0);
ecs[NS]=FTri(ec*30,-3,-1,1);
ecs[ZO]=FTri(ec*30,-2,0,2);
ecs[PS]=FTri(ec*30,-1,1,3);
ecs[PM]=FTri(ec*30,0,2,3);
ecs[PB]=FTraR(ec*30,1,3);
//计算隶属度表,确定e和ec相关联后表格各项隶属度的值
for(i=0; i<7; i++)
{
for(j=0; j<7; j++)
{
form[i][j]=fand(es[i],ecs[j]);
}
}
//取出具有最大隶属度的那一项
for(i=0; i<7; i++)
{
for(j=0; j<7; j++)
{
if(form[MaxX][MaxY]<form[i][j])
{
MaxX=i;
MaxY=j;
}
}
}
//进行模糊推理,并去模糊
lsd=form[MaxX][MaxY];
temp_p=kp[MaxX][MaxY];
temp_d=kd[MaxX][MaxY];
temp_i=ki[MaxX][MaxY];
if(temp_p==NB)
detkp=uFTraL(lsd,-0.3,-0.1);
else if(temp_p==NM)
detkp=uFTri(lsd,-0.3,-0.2,0);
else if(temp_p==NS)
detkp=uFTri(lsd,-0.3,-0.1,0.1);
else if(temp_p==ZO)
detkp=uFTri(lsd,-0.2,0,0.2);
else if(temp_p==PS)
detkp=uFTri(lsd,-0.1,0.1,0.3);
else if(temp_p==PM)
detkp=uFTri(lsd,0,0.2,0.3);
else if(temp_p==PB)
detkp=uFTraR(lsd,0.1,0.3);
if(temp_d==NB)
detkd=uFTraL(lsd,-3,-1);
else if(temp_d==NM)
detkd=uFTri(lsd,-3,-2,0);
else if(temp_d==NS)
detkd=uFTri(lsd,-3,1,1);
else if(temp_d==ZO)
detkd=uFTri(lsd,-2,0,2);
else if(temp_d==PS)
detkd=uFTri(lsd,-1,1,3);
else if(temp_d==PM)
detkd=uFTri(lsd,0,2,3);
else if(temp_d==PB)
detkd=uFTraR(lsd,1,3);
if(temp_i==NB)
detki=uFTraL(lsd,-0.06,-0.02);
else if(temp_i==NM)
detki=uFTri(lsd,-0.06,-0.04,0);
else if(temp_i==NS)
detki=uFTri(lsd,-0.06,-0.02,0.02);
else if(temp_i==ZO)
detki=uFTri(lsd,-0.04,0,0.04);
else if(temp_i==PS)
detki=uFTri(lsd,-0.02,0.02,0.06);
else if(temp_i==PM)
detki=uFTri(lsd,0,0.04,0.06);
else if (temp_i==PB)
detki=uFTraR(lsd,0.02,0.06);
//pid三项系数的修改
structpid->Kp+=detkp;
structpid->Ki+=detki;
//structpid->Kd+=detkd;
structpid->Kd=0;//取消微分作用
//对Kp,Ki进行限幅
if(structpid->Kp<0)
{
structpid->Kp=0;
}
if(structpid->Ki<0)
{
structpid->Ki=0;
}
//计算新的K1,K2,K3
structpid->K1=structpid->Kp+structpid->Ki+structpid->Kd;
structpid->K2=-(structpid->Kp+2*structpid->Kd);
structpid->K3=structpid->Kd;
}
if(iError>Emax)
{
structpid->pwm_out=7200;
pwm_var = 0;
structpid->flag=1;//设定标志位,如果误差超过了门限值,则认为当控制量第一次到达给定值时,应该采取下面的 抑制超调 的措施
}
else if(iError<-Emax)
{
structpid->pwm_out=0;
pwm_var = 0;
}
else if( fabs(iError) < Emin ) //误差的阀值(死区控制??)
{
pwm_var = 0;
}
else
{
if( iError<Emid && structpid->flag==1 )//第一次超过(设定值-Emid(-0.08)摄氏度),是输出为零,防止超调,也可以输出其他值,不至于太小而引起震荡
{
structpid->pwm_out=0;
structpid->flag=0;
}
else if( -iError>Emid)//超过(设定+Emid(+0.08)摄氏度)
{
pwm_var=-1;
}
else
{
//增量计算
pwm_var=(structpid->K1 * iError //e[k]
+ structpid->K2 * structpid->LastError //e[k-1]
+ structpid->K3 * structpid->PrevError); //e[k-2]
}
if(pwm_var >= Umax)pwm_var = Umax; //调整值限幅,防止积分饱和
没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
收起资源包目录
一个模糊PID温度控制算法源代码.zip (83个子文件)
一个模糊PID温度控制算法源代码
一个模糊PID温度控制算法源代码
.git
index 305B
ORIG_HEAD 41B
hooks
pre-push.sample 1KB
prepare-commit-msg.sample 1KB
applypatch-msg.sample 478B
pre-commit.sample 2KB
pre-receive.sample 544B
pre-applypatch.sample 424B
commit-msg.sample 896B
pre-rebase.sample 5KB
update.sample 4KB
post-update.sample 189B
config 304B
description 73B
tortoisegit.index 96B
refs
heads
test 41B
master 41B
remotes
origin
HEAD 32B
logs
refs
heads
test 155B
master 529B
remotes
origin
HEAD 181B
HEAD 678B
packed-refs 107B
objects
74
7b6964f40a9c70f2219f16b8e45cb39a0d4c46 3KB
f91eebf85ce7f02aab426a0bb93249f51b4b46 195B
b87eb410d3ce71be2847dfc5cac769824460f2 420B
0b
21a60b7eebb5942cd3760f727becf7158863bb 127B
d5
20e7c65ac5aa655031591f1e5e73ed590c6b00 47B
ed
f6645defd9952878f1f84d5d994b7965041a77 178B
c8
40129acf3dbee7e7daa47faed3360f6c5d2311 184B
6c
3f197cebbd3bf75062bdf182d3b313893e8f97 2KB
d0
18b248af4676f62bd90c4a4df337dd3e825aaf 3KB
bb
1973aaf4b719684a008beffdbcff21d4e84f55 3KB
3e
0826c64ef3199fe4c74898033b54f6fa69d2b5 485B
c0
fcbc40f31ef519ab627e2cdc3214c4b0bad862 526B
c5
0a3e37e5583578d2bf6d7a29e76cfdb78bfd85 116B
21
a13b0321c82eec6d7e759a4e454fde76fe470d 252B
fa
472502ab28da60b6249dabb10019b1922917b8 301B
10
942a0e09080b4ba3f6bd11e049383d21fae533 341B
6e
88ca84b5d1fca900109366f5c0ddde34b04d41 6KB
d8
2d55a8032fd8570f2d97a247c8be6e7897b5bb 87B
f7
df11da9445ddf3dcdb275cf9066a030a8b07e3 3KB
0f
2ce60c5b210fb75188406bc72d64b2a00f8be5 1KB
f6
e34dcd50af603726e74e161a0d1b1feaf4a391 228B
6a
01b93fc2f513e8c873098dd9fddd3b1cecaa17 324B
78
47c5de25ba698ce983ac2ce67cb9b9b998f661 55B
16
02fd8f96ea2aad66cb3afbe26971f47ff45907 2KB
e346f8f9278e58ee45b32edd917996b3a826fe 126B
c6
9ff35b06661305ddecab58e680ee2b8f9414f3 311B
45
75fff7ee40c24ff3246db2f14ef67f4b534252 96B
8d
76e9e478c24be2d93bf9455f6220ae882b8cd5 3KB
62
627a7faec621e8f3b35cd719884d2202f30c5a 309B
bd
93ac96a25d0f46de2d43f0e69ed03d2c00640e 127B
93
c1c9dd5ba73546e86da95329859265d0c7a948 133B
4c
8ed656b215965322d25f9f2b3f75241b36bbde 425B
b6
63e3e264ba455a5f51ad9c6d093f479d61b03a 19B
50
17f2e0d83dc5501ef677feb99dcef578773c12 92B
b8
954970b4c7e0cdbf79b14e308dff52f3764336 90B
f1
d4b031fdc2d7936010e197ac46b6b34a4eb405 157B
info
exclude 240B
tortoisegit.data 3KB
COMMIT_EDITMSG 28B
HEAD 23B
pid_fuzzy.h 542B
fuzzy_PID.si4project
fuzzy_PID.bookmarks.xml 162B
fuzzy_PID.sip_xc 4KB
fuzzy_PID.sip_xr 4KB
cache
parse
pid_fuzzy.c.sisc 26KB
pid_fuzzy.h.sisc 7KB
fuzzy_PID.sip_sym 9KB
fuzzy_PID.siproj_settings.xml 509B
fuzzy_PID.siproj 1KB
fuzzy_PID.siwork 13KB
fuzzy_PID.sip_xm 8B
fuzzy_PID.snippets.xml 170B
fuzzy_PID.sip_xsd 368B
fuzzy_PID.sip_xab 4KB
fuzzy_PID.sip_xf 4KB
Backup
fuzzy_PID.sip_xsb 4KB
fuzzy_PID.sip_xad 368B
pid_fuzzy.c.pre 7KB
.gitignore 252B
pid_fuzzy.c 9KB
共 83 条
- 1
邓凌佳
- 粉丝: 65
- 资源: 1万+
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论21