原创 虎头蛇尾说模糊

2008-4-29 10:29 2399 3 3 分类: 工业电子
脑子一发热就想写点东西。
首先声明,我通篇所说模糊是指飞思卡尔的模糊推理机实现,而非智能控制的模糊算法。
    其实模糊调出来已经好几天了,调的那会儿就说最后要写篇心得。steve和我说,那有什么好写,缺乏技术含量。是啊。又不是创造出一种自己的模糊算法,没啥得意的。可好歹是作为菜鸟的我第一次使用模糊推理机,磕磕碰碰也遇到不少问题,最后好歹都解决了。写下来,高手见了别笑话;如果遇到模糊推理机刚起步的朋友,希望对你能有帮助。
    模糊算法的实现实际上就三个步骤,首先把精确量转化成模糊量,然后进行模糊推理,最后解模糊。这三部曲其实不用我说,地球人都知道的。那为什么还要拿出来说呢?虽然以前就学过模糊算法,也做过相关实验,但我始终没搞清楚模糊数学和模糊控制的区别。这次真正应用起来,才发现以前那一堆乱七八糟让我头痛的东西其实只不过是我临时抱佛脚还不甚熟练的模糊数学罢了。模糊控制算法本身其实是很好理解的:把我们通常精确世界里的量都转化成模糊量,然后根据设定的规则去推理出模糊输出,最后把模糊输出反过来转换成精确量用于控制。至于怎样进行模糊量与精确量的互换呢?这之间有个桥梁就是隶属函数。至于那个查询表啊什么的,完全是因为很多控制器没有提供专门的模糊推理机,为了减少模糊数学的计算,于是用了枚举的方法,列举出大量的输入输出组合形成的一张查询表。真正模糊控制的时候就可以不用计算直接查表得到最终结果。
    但飞思卡尔s12CPU提供了模糊指令方便了模糊运算,这就让我们省去了人工计算的麻烦。据说模糊指令的执行时间也比较短。可我看了一下指令执行的时钟流程图,没发现简单到哪里,只是一气呵成 少浪费点时间而已,算起来还不都一样。(个人观点,不一定对)
    datasheet上能找到完整的模糊推理机的通用代码。这里不再复述。这些代码前后很紧凑,于是用到XY变址寄存器,在知识库中的不同变量的存储顺序与格式的要求也很高。
    存储格式要注意的是隶属度函数的表达和模糊规则的存储格式,此外一般不会出大问题。隶属度函数采用梯形表达,四个字节表示一个模糊变量,分别对应隶属度图的左结点,右结点,左斜率,又斜率。我这里纯文字说明不是很清晰,建议找一份datasheet来看,我看的是《HCS12 V1.5 Core User Guide Version1.2》中附录B Fuzzy Logic Support。其中有具体介绍。关于模糊规则的存储格式主要是前件与后件之间、规则与规则之间的间隔符号以及模糊规则表结束的问题。我看了几本书,好像每本书上说的都多多少少有些差异。这好像和不同版本的飞思卡尔or摩托罗拉的CPU核相关,就我用的S12核(我的是mc9s12dp128)来说,前件与后件的隔离用OxFE,每条规则间的隔离也是OxFE,最后模糊规则表结束用OxFF表示。
    存储顺序建议按照书上推荐的来,如果你手头没有这样一本hcs12的书,我列一下我的变量定义的顺序:
#pragma abs_address 0x1000
unsigned char Efuzzy[28]={0,64,0,8,   //NB          --0x1000  //参数1的隶属度函数
  ……
  192,255,8,0};         //PB
unsigned char det_Efuzzy[12]={0,128,0,6,  //NB      --0x101C  //参数2的隶属度函数
  ……
  128,255,6,0};             //PB
unsigned char OUT[7]={0,20,40,60,80,100,120};
unsigned char IMV1[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//参数1模糊化   --0x302f
unsigned char IMV2[3]={0x00,0x00,0x00};                    //参数2模糊化   --0x3036
unsigned char OMV[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//模糊化的输出  --0x1039
unsigned char rules[105]={0x00,0x07,0xFE,0x0A,0xFE,       //              --0x1040
  ……
              0x06,0x09,0xFE,0x10,0xFF};
unsigned char result[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//存放精确量的结果  --0x10a9
#pragma end_abs_address
只要看各个变量的定义顺序就可以了。因为好多模糊指令执行过后XY寄存器会自动加1,按照这个顺序来定义变量方便编程。注意到是16位单片机,XY加1实际上增加的是一个字,两个字节。所以如果你想立即数寻址的话注意XY的内容是变量所在地址(字节为单位)的一半。
    还有论域的问题。这里默认输入输出变量的论域都是0-255,用户可根据自己需要进行相应的变换。
-------------------------------------------
不想写了,暂时到此为止吧。
虎头蛇尾……b.gif

文章评论0条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /2 下一条