Having problem with defuzzification.
I wrote this code and everything seems fine unless the output value. It can be seen that the fired outputs and their values are correct but the output values seem not right. ` #include <Fuzzy.h> // For scope, instantiate all objects you will need to access in loop() // It may be just one Fuzzy, but for demonstration, this sample will print all FuzzySet pertinence // Fuzzy Fuzzy *fuzzy = new Fuzzy();
// Fuzzy Membership Function names
// Fuzzy Membership Function for input number 1 FuzzySet *NBI1 = new FuzzySet(-2, -2, -1, -0.5); FuzzySet *NMI1 = new FuzzySet(-1, -0.5, -0.5, 0); FuzzySet *ZEI1 = new FuzzySet(-0.5, 0, 0, 0.5); FuzzySet *PMI1 = new FuzzySet(0, 0.5, 0.5, 1); FuzzySet *PBI1 = new FuzzySet(0.5, 1, 2, 2);
// Fuzzy Membership Function for input number 2 FuzzySet *NBI2 = new FuzzySet(-2, -2, -1, -0.5); FuzzySet *NMI2 = new FuzzySet(-1, -0.5, -0.5, 0); FuzzySet *ZEI2 = new FuzzySet(-0.5, 0, 0, 0.5); FuzzySet *PMI2 = new FuzzySet(0, 0.5, 0.5, 1); FuzzySet *PBI2 = new FuzzySet(0.5, 1, 2, 2);
// Fuzzy Membership Function for output number 1 FuzzySet *NBO1 = new FuzzySet(-2, -2, -1, -0.5); FuzzySet *NMO1 = new FuzzySet(-1, -0.5, -0.5, 0); FuzzySet *ZEO1 = new FuzzySet(-0.5, 0, 0, 0.5); FuzzySet *PMO1 = new FuzzySet(0, 0.5, 0.5, 1); FuzzySet *PBO1 = new FuzzySet(0.5, 1, 2, 2);
void setup() { // Set the Serial output Serial.begin(115200); // Set a random seed randomSeed(analogRead(0)); // Every setup must occur in the function setup()
FuzzyInput *Input_1 = new FuzzyInput(1); Input_1->addFuzzySet(NBI1); Input_1->addFuzzySet(NMI1); Input_1->addFuzzySet(ZEI1); Input_1->addFuzzySet(PMI1); Input_1->addFuzzySet(PBI1); fuzzy->addFuzzyInput(Input_1);
FuzzyInput *Input_2 = new FuzzyInput(2); Input_2->addFuzzySet(NBI2); Input_2->addFuzzySet(NMI2); Input_2->addFuzzySet(ZEI2); Input_2->addFuzzySet(PMI2); Input_2->addFuzzySet(PBI2); fuzzy->addFuzzyInput(Input_2);
FuzzyOutput *Output_1 = new FuzzyOutput(1); Output_1->addFuzzySet(NBO1);
FuzzyRuleConsequent *THEN_Output_1_NBO1 = new FuzzyRuleConsequent(); THEN_Output_1_NBO1->addOutput(NBO1);
Output_1->addFuzzySet(NMO1);
FuzzyRuleConsequent *THEN_Output_1_NMO1 = new FuzzyRuleConsequent(); THEN_Output_1_NMO1->addOutput(NMO1);
Output_1->addFuzzySet(ZEO1);
FuzzyRuleConsequent *THEN_Output_1_ZEO1 = new FuzzyRuleConsequent(); THEN_Output_1_ZEO1->addOutput(ZEO1);
Output_1->addFuzzySet(PMO1);
FuzzyRuleConsequent *THEN_Output_1_PMO1 = new FuzzyRuleConsequent(); THEN_Output_1_PMO1->addOutput(PMO1);
Output_1->addFuzzySet(PBO1);
FuzzyRuleConsequent *THEN_Output_1_PBO1 = new FuzzyRuleConsequent(); THEN_Output_1_PBO1->addOutput(PBO1);
fuzzy->addFuzzyOutput(Output_1);
// Add following rules inside setup()
// Building FuzzyRule number: 1 FuzzyRuleAntecedent *IFIn1_NBI1_AND_In2_NBI2 = new FuzzyRuleAntecedent(); IFIn1_NBI1_AND_In2_NBI2->joinWithAND(NBI1,NBI2); FuzzyRule *fuzzyRule_1 = new FuzzyRule(1,IFIn1_NBI1_AND_In2_NBI2, THEN_Output_1_NBO1); fuzzy->addFuzzyRule(fuzzyRule_1);
// Building FuzzyRule number: 2 FuzzyRuleAntecedent *IFIn1_NBI1_AND_In2_NMI2 = new FuzzyRuleAntecedent(); IFIn1_NBI1_AND_In2_NMI2->joinWithAND(NBI1,NMI2); FuzzyRule *fuzzyRule_2 = new FuzzyRule(2,IFIn1_NBI1_AND_In2_NMI2, THEN_Output_1_NBO1); fuzzy->addFuzzyRule(fuzzyRule_2);
// Building FuzzyRule number: 3 FuzzyRuleAntecedent *IFIn1_NBI1_AND_In2_ZEI2 = new FuzzyRuleAntecedent(); IFIn1_NBI1_AND_In2_ZEI2->joinWithAND(NBI1,ZEI2); FuzzyRule *fuzzyRule_3 = new FuzzyRule(3,IFIn1_NBI1_AND_In2_ZEI2, THEN_Output_1_NBO1); fuzzy->addFuzzyRule(fuzzyRule_3);
// Building FuzzyRule number: 4 FuzzyRuleAntecedent *IFIn1_NBI1_AND_In2_PMI2 = new FuzzyRuleAntecedent(); IFIn1_NBI1_AND_In2_PMI2->joinWithAND(NBI1,PMI2); FuzzyRule *fuzzyRule_4 = new FuzzyRule(4,IFIn1_NBI1_AND_In2_PMI2, THEN_Output_1_NMO1); fuzzy->addFuzzyRule(fuzzyRule_4);
// Building FuzzyRule number: 5 FuzzyRuleAntecedent *IFIn1_NBI1_AND_In2_PBI2 = new FuzzyRuleAntecedent(); IFIn1_NBI1_AND_In2_PBI2->joinWithAND(NBI1,PBI2); FuzzyRule *fuzzyRule_5 = new FuzzyRule(5,IFIn1_NBI1_AND_In2_PBI2, THEN_Output_1_ZEO1); fuzzy->addFuzzyRule(fuzzyRule_5);
// Building FuzzyRule number: 6 FuzzyRuleAntecedent *IFIn1_NMI1_AND_In2_NBI2 = new FuzzyRuleAntecedent(); IFIn1_NMI1_AND_In2_NBI2->joinWithAND(NMI1,NBI2); FuzzyRule *fuzzyRule_6 = new FuzzyRule(6,IFIn1_NMI1_AND_In2_NBI2, THEN_Output_1_NBO1); fuzzy->addFuzzyRule(fuzzyRule_6);
// Building FuzzyRule number: 7 FuzzyRuleAntecedent *IFIn1_NMI1_AND_In2_NMI2 = new FuzzyRuleAntecedent(); IFIn1_NMI1_AND_In2_NMI2->joinWithAND(NMI1,NMI2); FuzzyRule *fuzzyRule_7 = new FuzzyRule(7,IFIn1_NMI1_AND_In2_NMI2, THEN_Output_1_NBO1); fuzzy->addFuzzyRule(fuzzyRule_7);
// Building FuzzyRule number: 8 FuzzyRuleAntecedent *IFIn1_NMI1_AND_In2_ZEI2 = new FuzzyRuleAntecedent(); IFIn1_NMI1_AND_In2_ZEI2->joinWithAND(NMI1,ZEI2); FuzzyRule *fuzzyRule_8 = new FuzzyRule(8,IFIn1_NMI1_AND_In2_ZEI2, THEN_Output_1_NMO1); fuzzy->addFuzzyRule(fuzzyRule_8);
// Building FuzzyRule number: 9 FuzzyRuleAntecedent *IFIn1_NMI1_AND_In2_PMI2 = new FuzzyRuleAntecedent(); IFIn1_NMI1_AND_In2_PMI2->joinWithAND(NMI1,PMI2); FuzzyRule *fuzzyRule_9 = new FuzzyRule(9,IFIn1_NMI1_AND_In2_PMI2, THEN_Output_1_ZEO1); fuzzy->addFuzzyRule(fuzzyRule_9);
// Building FuzzyRule number: 10 FuzzyRuleAntecedent *IFIn1_NMI1_AND_In2_PBI2 = new FuzzyRuleAntecedent(); IFIn1_NMI1_AND_In2_PBI2->joinWithAND(NMI1,PBI2); FuzzyRule *fuzzyRule_10 = new FuzzyRule(10,IFIn1_NMI1_AND_In2_PBI2, THEN_Output_1_PMO1); fuzzy->addFuzzyRule(fuzzyRule_10);
// Building FuzzyRule number: 11 FuzzyRuleAntecedent *IFIn1_ZEI1_AND_In2_NMI2 = new FuzzyRuleAntecedent(); IFIn1_ZEI1_AND_In2_NMI2->joinWithAND(ZEI1,NMI2); FuzzyRule *fuzzyRule_11 = new FuzzyRule(11,IFIn1_ZEI1_AND_In2_NMI2, THEN_Output_1_NMO1); fuzzy->addFuzzyRule(fuzzyRule_11);
// Building FuzzyRule number: 12 FuzzyRuleAntecedent *IFIn1_ZEI1_AND_In2_ZEI2 = new FuzzyRuleAntecedent(); IFIn1_ZEI1_AND_In2_ZEI2->joinWithAND(ZEI1,ZEI2); FuzzyRule *fuzzyRule_12 = new FuzzyRule(12,IFIn1_ZEI1_AND_In2_ZEI2, THEN_Output_1_ZEO1); fuzzy->addFuzzyRule(fuzzyRule_12);
// Building FuzzyRule number: 13 FuzzyRuleAntecedent *IFIn1_ZEI1_AND_In2_PMI2 = new FuzzyRuleAntecedent(); IFIn1_ZEI1_AND_In2_PMI2->joinWithAND(ZEI1,PMI2); FuzzyRule *fuzzyRule_13 = new FuzzyRule(13,IFIn1_ZEI1_AND_In2_PMI2, THEN_Output_1_PMO1); fuzzy->addFuzzyRule(fuzzyRule_13);
// Building FuzzyRule number: 14 FuzzyRuleAntecedent *IFIn1_ZEI1_AND_In2_PBI2 = new FuzzyRuleAntecedent(); IFIn1_ZEI1_AND_In2_PBI2->joinWithAND(ZEI1,PBI2); FuzzyRule *fuzzyRule_14 = new FuzzyRule(14,IFIn1_ZEI1_AND_In2_PBI2, THEN_Output_1_PBO1); fuzzy->addFuzzyRule(fuzzyRule_14);
// Building FuzzyRule number: 15 FuzzyRuleAntecedent *IFIn1_PMI1_AND_In2_NBI2 = new FuzzyRuleAntecedent(); IFIn1_PMI1_AND_In2_NBI2->joinWithAND(PMI1,NBI2); FuzzyRule *fuzzyRule_15 = new FuzzyRule(15,IFIn1_PMI1_AND_In2_NBI2, THEN_Output_1_NMO1); fuzzy->addFuzzyRule(fuzzyRule_15);
// Building FuzzyRule number: 16 FuzzyRuleAntecedent *IFIn1_PMI1_AND_In2_NMI2 = new FuzzyRuleAntecedent(); IFIn1_PMI1_AND_In2_NMI2->joinWithAND(PMI1,NMI2); FuzzyRule *fuzzyRule_16 = new FuzzyRule(16,IFIn1_PMI1_AND_In2_NMI2, THEN_Output_1_ZEO1); fuzzy->addFuzzyRule(fuzzyRule_16);
// Building FuzzyRule number: 17 FuzzyRuleAntecedent *IFIn1_PMI1_AND_In2_ZEI2 = new FuzzyRuleAntecedent(); IFIn1_PMI1_AND_In2_ZEI2->joinWithAND(PMI1,ZEI2); FuzzyRule *fuzzyRule_17 = new FuzzyRule(17,IFIn1_PMI1_AND_In2_ZEI2, THEN_Output_1_PMO1); fuzzy->addFuzzyRule(fuzzyRule_17);
// Building FuzzyRule number: 18 FuzzyRuleAntecedent *IFIn1_PMI1_AND_In2_PMI2 = new FuzzyRuleAntecedent(); IFIn1_PMI1_AND_In2_PMI2->joinWithAND(PMI1,PMI2); FuzzyRule *fuzzyRule_18 = new FuzzyRule(18,IFIn1_PMI1_AND_In2_PMI2, THEN_Output_1_PBO1); fuzzy->addFuzzyRule(fuzzyRule_18);
// Building FuzzyRule number: 19 FuzzyRuleAntecedent *IFIn1_PMI1_AND_In2_PBI2 = new FuzzyRuleAntecedent(); IFIn1_PMI1_AND_In2_PBI2->joinWithAND(PMI1,PBI2); FuzzyRule *fuzzyRule_19 = new FuzzyRule(19,IFIn1_PMI1_AND_In2_PBI2, THEN_Output_1_PBO1); fuzzy->addFuzzyRule(fuzzyRule_19);
// Building FuzzyRule number: 20 FuzzyRuleAntecedent *IFIn1_PBI1_AND_In2_NBI2 = new FuzzyRuleAntecedent(); IFIn1_PBI1_AND_In2_NBI2->joinWithAND(PBI1,NBI2); FuzzyRule *fuzzyRule_20 = new FuzzyRule(20,IFIn1_PBI1_AND_In2_NBI2, THEN_Output_1_ZEO1); fuzzy->addFuzzyRule(fuzzyRule_20);
// Building FuzzyRule number: 21 FuzzyRuleAntecedent *IFIn1_PBI1_AND_In2_NMI2 = new FuzzyRuleAntecedent(); IFIn1_PBI1_AND_In2_NMI2->joinWithAND(PBI1,NMI2); FuzzyRule *fuzzyRule_21 = new FuzzyRule(21,IFIn1_PBI1_AND_In2_NMI2, THEN_Output_1_PMO1); fuzzy->addFuzzyRule(fuzzyRule_21);
// Building FuzzyRule number: 22 FuzzyRuleAntecedent *IFIn1_PBI1_AND_In2_ZEI2 = new FuzzyRuleAntecedent(); IFIn1_PBI1_AND_In2_ZEI2->joinWithAND(PBI1,ZEI2); FuzzyRule *fuzzyRule_22 = new FuzzyRule(22,IFIn1_PBI1_AND_In2_ZEI2, THEN_Output_1_PBO1); fuzzy->addFuzzyRule(fuzzyRule_22);
// Building FuzzyRule number: 23 FuzzyRuleAntecedent *IFIn1_PBI1_AND_In2_PMI2 = new FuzzyRuleAntecedent(); IFIn1_PBI1_AND_In2_PMI2->joinWithAND(PBI1,PMI2); FuzzyRule *fuzzyRule_23 = new FuzzyRule(23,IFIn1_PBI1_AND_In2_PMI2, THEN_Output_1_PBO1); fuzzy->addFuzzyRule(fuzzyRule_23);
// Building FuzzyRule number: 24 FuzzyRuleAntecedent *IFIn1_PBI1_AND_In2_PBI2 = new FuzzyRuleAntecedent(); IFIn1_PBI1_AND_In2_PBI2->joinWithAND(PBI1,PBI2); FuzzyRule *fuzzyRule_24 = new FuzzyRule(24,IFIn1_PBI1_AND_In2_PBI2, THEN_Output_1_PBO1); fuzzy->addFuzzyRule(fuzzyRule_24);
// Building FuzzyRule number: 25 FuzzyRuleAntecedent *IFIn1_ZEI1_AND_In2_NBI2 = new FuzzyRuleAntecedent(); IFIn1_ZEI1_AND_In2_NBI2->joinWithAND(ZEI1,NBI2); FuzzyRule *fuzzyRule_25 = new FuzzyRule(25,IFIn1_ZEI1_AND_In2_NBI2, THEN_Output_1_NBO1); fuzzy->addFuzzyRule(fuzzyRule_25);
} void loop() { // add your codes here
// This part is for testing your code float input_1 = -0.241; fuzzy->setInput(1, input_1); Serial.print("input1 = "); Serial.println(input_1);
float input_2 = 0.672; fuzzy->setInput(2, input_2); Serial.print("input1 = "); Serial.println(input_2);
fuzzy->fuzzify();
Serial.println("Inputs: "); Serial.print("input1 : "); Serial.print(" NBI1->"); Serial.print(NBI1->getPertinence()); Serial.print(" NMI1->"); Serial.print(NMI1->getPertinence()); Serial.print(" ZEI1->"); Serial.print(ZEI1->getPertinence()); Serial.print(" PMI1->"); Serial.print(PMI1->getPertinence()); Serial.print(" PBI1->"); Serial.print(PBI1->getPertinence()); Serial.println(" ");
Serial.print("input2 : "); Serial.print(" NBI2->"); Serial.print(NBI2->getPertinence()); Serial.print(" NMI2->"); Serial.print(NMI2->getPertinence()); Serial.print(" ZEI2->"); Serial.print(ZEI2->getPertinence()); Serial.print(" PMI2->"); Serial.print(PMI2->getPertinence()); Serial.print(" PBI2->"); Serial.print(PBI2->getPertinence()); Serial.println(" ");
Serial.println("Outputs: "); float output_1 = fuzzy->defuzzify(1); Serial.print(" NBO1->"); Serial.print(NBO1->getPertinence()); Serial.print(" NMO1->"); Serial.print(NMO1->getPertinence()); Serial.print(" ZEO1->"); Serial.print(ZEO1->getPertinence()); Serial.print(" PMO1->"); Serial.print(PMO1->getPertinence()); Serial.print(" PBO1->"); Serial.print(PBO1->getPertinence()); Serial.println(" ");
Serial.println("=========== Results: ==========="); Serial.print("output1: "); Serial.println(output_1);
Serial.println("======== Check Fired Rules ========"); for(int i=1; i<25; i++){ if (fuzzy->isFiredRule(i) ==1){ Serial.print("Rule number ("); Serial.print(i); Serial.println(") is fired."); } } delay(5000); } `
Also, this is the output:
input1 = -0.24 input1 = 0.67 Inputs: input1 : NBI1->0.00 NMI1->0.48 ZEI1->0.52 PMI1->0.00 PBI1->0.00 input2 : NBI2->0.00 NMI2->0.00 ZEI2->0.00 PMI2->0.66 PBI2->0.34 Outputs: NBO1->0.00 NMO1->0.00 ZEO1->0.48 PMO1->0.52 PBO1->0.34 =========== Results: =========== output1: -0.06 ======== Check Fired Rules ======== Rule number (9) is fired. Rule number (10) is fired. Rule number (13) is fired. Rule number (14) is fired.
I used output pertinence and calculated the output by hand using the centroid method! and using Matlab fuzzy toolbox both have the same answer output1: 0.292 but I really don't know why defuzzify command do not give the write answer!!
both input 1 and 2 are correct but the output is not... right? for this case, is it 0.292 or -0.594 (matlab and manual calculated)?