打印

帮忙看哈用这个模糊控制的规则

[复制链接]
1586|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhouhuan815|  楼主 | 2010-5-21 16:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序为模糊控制程序,基于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方法计算模糊输出和反模糊输出
                                                                                                       }
//------------------------------------------------------------------------------

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

1

帖子

1

粉丝