Free Fuzzy Logic Library


Home | License | History | Class Hierarchy | API | Code Details | FCL | Developers | Downloads | A SourceForge.net Project


FCL

FCL stands for Fuzzy Control Language, which is a standard for Fuzzy Control Programming published by the International Electrotechnical Commission (IEC). The specifications for the FCL syntax can be found in IEC document 61131-7. Unfortunately, this standard is not freely available and must be purchased (see www.iec.ch or www.ansi.org). However, the Draft 1.0 version from 1997 is available and I have not noticed any significant differences between the draft and the final version.

 FFLL is able to load files that adhere to the IEC 61131-7 standard.

Here's a generic FCL outline:

General FCL Notes:

  • (* and *) are used as comment delimiters
  • The RANGE comment after variable declarations is NOT part of the standard FCL. It was added so FFLL will know the variable's range
  • FCL refers to the individual sets in a variable as TERMs. In other fuzzy logic literature you will see these referred to as sets or fuzzy subset
  • The points that define a TERM are declared in (x, y) pairs. The x value is within the RANGE of the variable and the y value is between 0 and 1
  • The RULEBLOCK name is not used in FFLL, but it's included to comply with FCL standards
  • Rule conditions are variable term's ANDed together
  • The rule conclusion is a term from the output variable
  • You can find more details on FFLL and FCLs compliance by checking out the FCL production rules.
FUNCTION_BLOCK
VAR_INPUT
    <variable name> REAL; (* RANGE(<variable minimum value> .. <variable maximum value>) *) 
END_VAR
VAR_OUTPUT
    <variable name> REAL; (* RANGE(<variable minimum value> .. <variable maximum value>) *) 
END_VAR
FUZZIFY <variable name>
    TERM <term (or set) name> := <points that make up the term> ;
END_FUZZIFY
DEFUZZIFY valve 
    METHOD: <defuzzification method>;
END_DEFUZZIFY
RULEBLOCK <ruleblock name>
    <operator>:<algorithm>;
    ACCUM:<accumulation method>;
    RULE <rule number>: IF <condition> THEN <conclusion>;
END_RULEBLOCK
END_FUNCTION_BLOCK

 

 

Here's an example of a real FCL file that's used to calculate the aggressiveness of an AI controlled character based on its health and its enemy’s health. The model has two input variables: Our_Health and Enemy_Health and one output variable: Aggressiveness. Note that the sets that comprise the conditional part of the rules (specified in the RULEBLOCK section) are ANDed together in the order that the variables they belong to are declared in the FCL file.

FUNCTION_BLOCK
VAR_INPUT
    Our_Health      REAL; (* RANGE(0 .. 100) *) 
    Enemy_Health    REAL; (* RANGE(0 .. 100) *) 
END_VAR
VAR_OUTPUT
    Aggressiveness  REAL; (* RANGE(0 .. 4) *) 
END_VAR
FUZZIFY Our_Health
    TERM Near_Death := (0, 0) (0, 1) (50, 0) ;
    TERM Good := (14, 0) (50, 1) (83, 0) ;
    TERM Excellent := (50, 0) (100, 1) (100, 0) ;
END_FUZZIFY
FUZZIFY Enemy_Health
    TERM Near_Death := (0, 0) (0, 1) (50, 0) ;
    TERM Good := (14, 0) (50, 1) (83, 0) ;
    TERM Excellent := (50, 0) (100, 1) (100, 0) ;
END_FUZZIFY
FUZZIFY Aggressiveness
    TERM Run_Away := 1 ;
    TERM Fight_Defensively := 2 ;
    TERM All_Out_Attack := 3 ;
END_FUZZIFY
DEFUZZIFY valve
    METHOD: MoM;
END_DEFUZZIFY
RULEBLOCK first

AND:MIN;
ACCU:MAX;
RULE 0: IF (Our_Health IS Near_Death) AND (Enemy_Health IS Near_Death) THEN (Aggressiveness IS Fight_Defensively);
RULE 1: IF (Our_Health IS Near_Death) AND (Enemy_Health IS Good) THEN (Aggressiveness IS Run_Away);
RULE 2: IF (Our_Health IS Near_Death) AND (Enemy_Health IS Excellent) THEN (Aggressiveness IS Run_Away);
RULE 3: IF (Our_Health IS Good) AND (Enemy_Health IS Near_Death) THEN (Aggressiveness IS All_Out_Attack);
RULE 4: IF (Our_Health IS Good) AND (Enemy_Health IS Good) THEN (Aggressiveness IS Fight_Defensively);
RULE 5: IF (Our_Health IS Good) AND (Enemy_Health IS Excellent) THEN (Aggressiveness IS Fight_Defensively);
RULE 6: IF (Our_Health IS Excellent) AND (Enemy_Health IS Near_Death) THEN (Aggressiveness IS All_Out_Attack);
RULE 7: IF (Our_Health IS Excellent) AND (Enemy_Health IS Good) THEN (Aggressiveness IS All_Out_Attack);
RULE 8: IF (Our_Health IS Excellent) AND (Enemy_Health IS Excellent) THEN (Aggressiveness IS Fight_Defensively);
END_RULEBLOCK
END_FUNCTION_BLOCK