65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 和模糊逻辑入门

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (18投票s)

2008年2月2日

CPOL

3分钟阅读

viewsIcon

148529

downloadIcon

5310

本文以集装箱起重机控制为例,简要介绍了基于规则的模糊逻辑系统的基本技术。

引言

容器(黄色)已经从船(红色)上被吊起。它必须被放置在卡车(绿色)上方。Angle(角度)和 Distance(距离)的值由过程模拟计算得出,而 Power(功率)是控制变量,可以手动设置或由模糊逻辑控制器设置。模糊逻辑控制器使用人类操作员的经验。人类操作员能够在没有微分方程的情况下控制起重机。

实现语言控制

起重机头部位置的传感器(Distance,距离)和集装箱摇摆角度的传感器(Angle,角度)被用于自动控制这台起重机。使用这些输入来描述起重机的当前状态,例如:

IF Distance = medium AND Angle = neg_small THEN Power = pos_high 

下图显示了模糊逻辑控制器的完整结构

模糊化

必须为 if-then 规则中使用的所有变量定义语言变量。对于起重机控制器,术语是:

  1. Distance(距离):{neg_close(负近),zero(零),close(近),medium(中),far(远)}
  2. Angle(角度):{neg_big(负大),neg_small(负小),zero(零),pos_small(正小),pos_big(正大)}
  3. Power(功率):{neg_high(负高),neg_medium(负中),zero(零),pos_medium(正中),pos_high(正高)}

对于每个语言变量,每个术语都由其隶属函数定义。

考虑起重机的一种可能情况,起重机头部到目标位置的 Distance(距离)是 12 码,集装箱的 Angle(角度)是 -30 度。

12 码的 Distance(距离)属于以下模糊集合的成员:

  • medium(中)的隶属度为 0.83
  • far(远)的隶属度为 0.17
  • 其他术语的隶属度为 0.00

-30 度的 Angle(角度)属于以下模糊集合的成员:

  • neg_big(负大)的隶属度为 0.4
  • neg_small(负小)的隶属度为 0.6
  • 其他术语的隶属度为 0.00

模糊推理

使用 If-Then 规则。现在所有输入变量都已转换为语言变量值,模糊推理步骤可以识别适用于当前情况的规则,并计算输出语言变量的值。 考虑以上例子

IF 部分组合了两个条件:Distance = medium(距离 = 中)和 Angle = neg_small(角度 = 负小)。IF 部分定义了该规则在当前情况下是否有效。 在传统逻辑中,两个条件的组合可以通过布尔 AND 来计算,如下图所示:

对于模糊逻辑,布尔 AND 不能使用,因为它无法处理或多或少为真的条件。 因此,必须为模糊逻辑定义新的运算符来表示逻辑连接词,例如 ANDORNOT

上述示例的 IF 部分可以计算如下:

min{ 0,83; 0.6} = 0.6 

去模糊化

在模糊推理结束时,Power(功率)的结果以语言变量的值给出。 为了使用它来设置电机功率,必须将其转换为实际值。 语言值和相应实际值之间的关系始终由隶属函数定义给出。 下图绘制了语言变量 Power 的隶属函数。

我使用一种称为最大中心法的去模糊化方法,它与使用单例隶属函数的重心法相同。 这些去模糊化方法用于大多数模糊逻辑实现中。

代码示例

该应用程序由许多函数和对象组成,但我在此应用程序中最喜欢的是模糊逻辑。 我通过以上隶属函数和模糊逻辑的概念编写了模糊函数。 这是模糊函数:

//Fuzzy function to produce optimized power
public double fuzzy()
{
//Fuzzification of variables, distance and angle

if((angle<-60)&&(angle>=-90))
neg_small=0;
else if((angle<-10)&&(angle>=-60))
neg_small=(0.02*angle+1.2);
else if((angle<0)&&(angle>=-10))
neg_small=(-0.1*angle);
else if((angle<=90)&&(angle>=0))
neg_small=0;
if((angle<-60)&&(angle>=-90))
neg_big=1;
else if((angle>=-60)&&(angle<-10))
neg_big=(-0.02*angle-0.2);
else if((angle>=-10)&&(angle<=90))
neg_big=0;
if((distance<5)&&(distance>=-10))
medium=0;
else if((distance<10)&&(distance>=5))
medium=(0.2*distance-1);
else if((distance<22)&&(distance>=10))
medium=((-1/12)*distance+(11/6));
else if((distance<=30)&&(distance>=22))
medium=0;
if((distance<10)&&(distance>=-10))
far=0;
else if((distance<22)&&(distance>=10))
far=((1/12)*distance-(5/6));
else if((distance<=30)&&(distance>=22))
far=1;
//... other if_ then_else clauses for other terms of  distance and angle to be
// continued .

//Defuzzification of variable, power
return 
System.Math.Round(System.Math.Max(System.Math.Min(pos_small,zerodis),
    System.Math.Min(pos_small,close))*neg_medium_pow+System.Math.Max(
    System.Math.Min(zero,zerodis),System.Math.Min(zero,close))*zero_pow+System.Math.Max(
    System.Math.Max(System.Math.Min(neg_small,close),System.Math.Min(neg_big,medium)),
    System.Math.Min(zero,far))*pos_medium_pow+System.Math.Max(System.Math.Min(neg_small,
    medium),System.Math.Min(neg_small,far))*pos_high_pow,2);
}     

结论

请注意,我的模拟程序不是科学模拟。 我的应用程序不是很漂亮,因为我还是个初学者,但我认为它几乎可以正常工作。 你觉得怎么样?

祝你愉快。

历史

  • 2008 年 2 月 2 日:初始发布
© . All rights reserved.