The simplest solution here is to create a Fuzzy Control Language file and just load this. (One could also create a system obect using pyfuzzy objects, but this needs much more code to write.)
Line number relate to the example below. Anything between (* ... *)
are comments.
VAR_INPUT ... END_VAR
defines all inputs you want to use. You define the name and the type (anything else than REAL is not supported now.)
VAR_OUTPUT ... END_VAR
defines all outputs you want to use. You define the name and the type (anything else than REAL is not supported
now.)
FUZZIFY ... END_FUZZIFY
define the membership fuzzy sets belonging to an input. The list (x1, m1) (x2, m2) ... (xn,
mn)
with m in [0,1], defines a fuzzy set using the Polygon
class. But it also possible to use all other defined in fuzzy.set by writing
SetClassName(param1, param2, ...)
(eg. SFunction(0.0, 1.0)
.)
DEFUZZIFY ... END_DEFUZZIFY
define the membership fuzzy sets and defuzzification metod belonging to an output. Membership fuzzy
sets are defined the same as at the inputs.
ACCU defines how the memberships are accumulated before doing the defuzzification.
METHOD defines the defuzzification method. Valid values are COG, COGS, and all class names in fuzzy.defuzzify.
FUZZIFY ... END_FUZZIFY
defines the fuzzy rules.
AND or OR define which fuzzy norm is used for AND or OR. Each class from fuzzy.norm can be used. If the norm needs paramters write it as NormClassName(param1,
param2, ...)
.
FUNCTION_BLOCK dummy 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 DEFUZZIFY Aggressiveness TERM Run_Away := 1 ; TERM Fight_Defensively := 2 ; TERM All_Out_Attack := 3 ; ACCU:MAX; METHOD: COGS;(*MoM;*) DEFAULT := 0; 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_BLOCKMore examples can be found here. The file FCLTest.py takes a filename from command line and tries to output all fuzzy sets using gnuplot (works only with Python 2, because the Gnuplot module does not work with Python 3.)
import fuzzy.storage.fcl.Reader system = fuzzy.storage.fcl.Reader.Reader().load_from_file("your_definitions.fcl") # preallocate input and output values my_input = { "in_var1" : 0.0, "in_var2" : 0.0 } my_output = { "out_var" : 0.0 } # if you need only one calculation you do not need the while while ...: # set input values my_input["in_var1"] = ... my_input["in_var2"] = ... # calculate system.calculate(my_input, my_output) # now use outputs ... = my_output["out_var"]