智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 3715|回复: 8
打印 上一主题 下一主题

模糊控制程序

[复制链接]

9

主题

60

帖子

0

精华

高级会员

Rank: 4

积分
566
QQ
威望
301
贡献
203
兑换币
0
注册时间
2010-4-29
在线时间
31 小时
跳转到指定楼层
1#
发表于 2010-4-29 20:22:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于8051的模糊控制程序
程序为模糊控制程序,基于8位单片机,为模糊控制算法程序,实现简单的模糊控制,经实践总结得出,当调整幅度较大时,会出现振荡,系统难以达到稳定,这就需要更高一级的算法控制调整,当调整幅度较小时,系统可以很快达到稳定。
以下为模糊算法源程序:
/*****************************************************************************************************************
                                                  模糊控制算法子程序
develop by lunhui zhang
date 06/20/06
*****************************************************************************************************************/
#i nclude "reg52.h"
//------------------------------------------------------------------------------------
// 定义差距输入常量
#define GAP_ZERO     0x00
#define GAP_VSMALL   0x01
#define GAP_SMALL    0x02
#define GAP_MEDIUM   0x03
#define GAP_BIG      0x04
// 定义控制输出常量
#define TURN_ZERO    0x80
#define TURN_VSMALL  0x81
#define TURN_SMALL   0x82
#define TURN_MEDIUM  0x83
#define TURN_BIG     0x84
//-------------定义常量----------------------------------------------------------------
#define MU_MAX 0XFF                               //模糊度的最大值为0XFF代表面1
#define RULE_TOT 10                               //规则数个数
#define MF_TOT 5                                  //成员函数的个数
#define IO_NUM 0x07
#define LABEL_NUM 0x70
#define DEFAULT_VALUE 0x00
//----------------定义数据库-----------------------------------------------------------
unsigned char code output_memf[MF_TOT]={0, 15, 35, 60, 102};// OUTPUT TURNING NUMBER:
                                                               //ZERO, VSMALL, SMALL, MEDIUM, BIG
unsigned char code input_memf[MF_TOT][4]={
// 输入功能函数以点斜式方式存储. 第一维成员函数标号第二维是点斜式数据
//距离功能函数
{ 0x00, 0x00, 0x00, 0x0d }, // VSLOW
{ 0x00, 0x0d, 0x14, 0x0d }, // SLOW
{ 0x1e, 0x0d, 0x32, 0x0d }, // MEDIUM
{ 0x3C, 0x0d, 0x50, 0x0d }, // FAST
{ 0x50, 0x09, 0x6e, 0x00 }  // VFAST
                                          };
//-----------定义模糊系统规则-----------------------------------------------------------
unsigned char code rules[RULE_TOT]={
// if...  then...
GAP_ZERO,TURN_ZERO,
GAP_VSMALL,TURN_VSMALL,
GAP_SMALL,TURN_SMALL,
GAP_MEDIUM,TURN_MEDIUM,
GAP_BIG,TURN_BIG
                                   };
//-----------定义各变量-----------------------------------------------------------------
unsigned char outputs[MF_TOT],fuzzy_out;            //模糊输出mu值
//-----------子程序函数头申明-----------------------------------------------------------
void fuzzy_engine(uchar);
uchar compute_memval(uchar,uchar);
void defuzzify(void);
/***************************************************************************************************************/
uchar compute_memval(uchar input,uchar label)
           {
              int data temp;
              if (input < input_memf[label][0])
                 {                                 // 如果输入不在曲线下u值为0
                     return 0;
                                       }
              else
                 {
                    if (input < input_memf[label][2])
                       {
                         temp=input;              // 用点斜式计算mu
                         temp-=input_memf[label][0];
                         if (!input_memf[label][1])
                           {
                             temp=MU_MAX;
                                                       }
                         else
                           {
                             temp*=input_memf[label][1];
                                                                     }
                         if (temp < 0x100)
                            {                     // 如果结果不超过1
                               return temp;       // 返回计算结果
                                              }
                         else
                            {
                               return MU_MAX;     // 确保mu值在范围内
                                              }
                                                         }
                    else
                      {                           // 输入落在第二条斜线上
                        temp=input;               // 用点斜式方法计算 mu
                        temp-=input_memf[label][2];
                        temp*=input_memf[label][3];
                        temp=MU_MAX-temp;
                        if (temp < 0)
                           {                      // 确保结果不小于0
                              return 0;
                                            }
                        else
                           {
                              return temp;        // mu为正 – 返回结果
                                            }
                                                       }
                                                                     }
                              return 0;
                                                                          }
/*******************************************************************************
Function: defuzzify
Description: 计算模糊输出的重心并调用函数把它
转换成可被系统使用的输出量
Parameters: 无.
Returns: 无.
Side Effects: outputs[][] 数组被清零.
*******************************************************************************/
void defuzzify(void)
     {
        unsigned long numerator, denominator;
        unsigned char j;
        numerator=0;                         // 恢复总数值
        denominator=0;
        for (j=0; j<MF_TOT; j++)
            {                                // 计算总和值
               numerator+=(outputs[j]*output_memf[j]);
               denominator+=outputs[j];
               outputs[j]=0; // 清零输出作为参考使用                                                              }
               if (denominator)
                  {                                  // 确保分母是0的情况不发生
                    fuzzy_out=numerator/denominator; // 确定 COG
                                                        }
              else
                  {
                    fuzzy_out=DEFAULT_VALUE; // 没有规则被触发
                                                                 }
                                                                       }
                        }
/*******************************************************************************
Function: fuzzy_engine
Description: 实施规则基中的规则
Parameters: 无
Returns: 无.
Side Effects: 无
********************************************************************************/
unsigned char bdata clause_val;                        // 保存当前的分支进行快速访问
sbit clause_type = clause_val^7;                       // 表示分支是否是条件分支或者是结果分支
void fuzzy_engine(uchar input)
     {
       bit then;                                       // 当正在分析结果时置位
       unsigned char if_val,                           // 保存当前规则中条件分支中的值
                     clause,                           // 规则基中当前的分支
                         mu,                           // 保存当前分支中的值
                      label=0;                           // 被条件使用的成员函数
                     then=0;                           // 设第一个分支是条件分支
               if_val=MU_MAX;                          // max out mu for the first rule
      for (clause=0; clause<RULE_TOT; clause++)
          {                                            // 遍历每条规则
            clause_val=rules[clause];                  // 读入当前的分支
            if (!clause_type)
               {                                       // 当前的分支是不是条件分支
                 if (then)
                    {                                  // 是否正在分析结果...
                      then=0;
                      if_val=MU_MAX;                    // 复位mu
                                          }
                 mu=compute_memval(input, label);        // 得到条件分支的值
     if_val=mu;
     label++;
                                                    }
            else
              {                                       // 当前分支是结果
                then=1;            // 置位标志位,如果当前规则的mu比参考的值要大,保存这个值作为新的模糊输出
                if (outputs[clause_val&0x07] < if_val)
                 {
                    outputs[clause_val&0x07]=if_val;
                                                                                         }
                                                                                            }
                                                                                                }
          defuzzify(); // 用COG方法计算模糊输出和反模糊输出
                                                                                                       }
//------------------------------------------------------------------------------

16

主题

209

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1763
威望
748
贡献
819
兑换币
10
注册时间
2009-11-26
在线时间
98 小时
2#
发表于 2010-4-29 20:45:45 | 只看该作者
怎么说也是楼主的心意  顶起来
回复 支持 反对

使用道具 举报

4

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
406
QQ
威望
327
贡献
29
兑换币
0
注册时间
2010-3-16
在线时间
25 小时
3#
发表于 2010-4-29 21:02:51 | 只看该作者
顶起!
回复 支持 反对

使用道具 举报

2

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
威望
276
贡献
60
兑换币
20
注册时间
2010-2-6
在线时间
11 小时
4#
发表于 2010-4-30 20:19:56 | 只看该作者
楼主能解释一下吗?
我没太看懂。。。
回复 支持 反对

使用道具 举报

2

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
威望
276
贡献
60
兑换币
20
注册时间
2010-2-6
在线时间
11 小时
5#
发表于 2010-4-30 20:34:57 | 只看该作者
回复 支持 反对

使用道具 举报

21

主题

348

帖子

0

精华

功勋会员

大将

Rank: 10Rank: 10Rank: 10

积分
9534

资源大师奖章论坛骨干奖章优秀版主奖章

QQ
威望
827
贡献
8337
兑换币
0
注册时间
2009-11-17
在线时间
185 小时
6#
发表于 2010-12-12 20:38:16 | 只看该作者
确实不错,学习了,等我有能力写更好的程序时,和你交流啊
回复 支持 反对

使用道具 举报

21

主题

348

帖子

0

精华

功勋会员

大将

Rank: 10Rank: 10Rank: 10

积分
9534

资源大师奖章论坛骨干奖章优秀版主奖章

QQ
威望
827
贡献
8337
兑换币
0
注册时间
2009-11-17
在线时间
185 小时
7#
发表于 2010-12-14 08:51:09 | 只看该作者
交流一下啊,好像你的程序在规则0那个地方有点问题,因为输出在output[0]这个的隶属函数好像求的不准,因为输出值都是0,但你的隶属函数值太大可能影响用 重心法 求的中心值,这是个人的看法,也许有某个地方没看懂,请指教
回复 支持 反对

使用道具 举报

2

主题

36

帖子

0

精华

高级会员

Rank: 4

积分
807
QQ
威望
299
贡献
410
兑换币
0
注册时间
2010-9-25
在线时间
49 小时
8#
发表于 2011-2-25 20:21:59 | 只看该作者
看不懂,我也来顶一下
回复 支持 反对

使用道具 举报

1

主题

31

帖子

0

精华

高级会员

Rank: 4

积分
512
威望
279
贡献
117
兑换币
6
注册时间
2012-6-7
在线时间
58 小时
毕业学校
湖南大学
9#
发表于 2012-11-20 19:26:08 | 只看该作者
顶起
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-27 21:25 , Processed in 0.083764 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表