Error fuzzy logic eFLL Library

hello every one, i have some problem my code in fuzzy with eFLL Library. i try make a code same with tutorial the article from

but i have some problem if i want to compile the file show the error about it

i try to change "," with "*&" but not works, the result of error must be same. why its happen ? thanks for advance

The error shows that you are passing three FuzzySet to joinWithAND() but the library can only join ONE FuzzySet to One FuzzyRuleAntecedent or join two FuzzyRuleAntecedent together.

bool joinWithAND(FuzzySet* fuzzySet, FuzzyRuleAntecedent* fuzzyRuleAntecedent);
bool joinWithAND(FuzzyRuleAntecedent* fuzzyRuleAntecedent, FuzzySet* fuzzySet);
bool joinWithAND(FuzzyRuleAntecedent* fuzzyRuleAntecedent1, FuzzyRuleAntecedent* fuzzyRuleAntecedent2);

for now i try to make code for this, but the result still error sir

I might be able to help if you post your entire sketch.

this is the all my sketch sir, thanks in advance

fuzzy_aja.zip (3.8 KB)

Your sketch compiles without error or warning for me. I'm using Arduino 1.8.13 and an Arduino UNO. What version of Arduino are you using? What Arduino board are you compiling for?

I have V1.4.1 of eFFL installed. What version of the library are you using?

What error are you getting?

I tried running your sketch on an Arduino UNO and ran out of memory at "rule 7". Here is a version of Fuzzy.cpp that checks for and reports various errors caused by running out of memory. Put it in the eFLL library.

 /*
 * Robotic Research Group (RRG)
 * State University of Piauí (UESPI), Brazil - Piauí - Teresina
 *
 * Fuzzy.cpp
 *
 *      Author: AJ Alves <aj.alves@zerokol.com>
 *          Co authors: Dr. Ricardo Lira <ricardor_usp@yahoo.com.br>
 *                      Msc. Marvin Lemos <marvinlemos@gmail.com>
 *                      Douglas S. Kridi <douglaskridi@gmail.com>
 *                      Kannya Leal <kannyal@hotmail.com>
 */
#include "Fuzzy.h"
#include <Arduino.h>

// CONTRUCTORS
Fuzzy::Fuzzy()
{
    // Initializing pointers with NULL
    // FuzzyInput
    this->fuzzyInputs = NULL;
    // FuzzyOutput
    this->fuzzyOutputs = NULL;
    // FuzzyRule
    this->fuzzyRules = NULL;
}

// DESTRUCTOR
Fuzzy::~Fuzzy()
{
    this->cleanFuzzyInputs(this->fuzzyInputs);
    this->cleanFuzzyOutputs(this->fuzzyOutputs);
    this->cleanFuzzyRules(this->fuzzyRules);
}

// PUBLIC METHODS

// Method to include a new FuzzyInput into Fuzzy
bool Fuzzy::addFuzzyInput(FuzzyInput *fuzzyInput)
{
    if (fuzzyInput == NULL)
    {
      // return false if in out of memory
      Serial.println("NULL fuzzyInput in Fuzzy::addFuzzyInput()");
      return false;
    }
    
    // auxiliary variable to handle the operation
    fuzzyInputArray *newOne;
    // allocating in memory
    if ((newOne = (fuzzyInputArray *)malloc(sizeof(fuzzyInputArray))) == NULL)
    {
        // return false if in out of memory
        Serial.println("Memory alloction failed in Fuzzy::addFuzzyInput()");
        return false;
    }
    // building the object
    newOne->fuzzyInput = fuzzyInput;
    newOne->next = NULL;
    // if it is the first FuzzyInput, set it as the head
    if (this->fuzzyInputs == NULL)
    {
        this->fuzzyInputs = newOne;
    }
    else
    {
        // auxiliary variable to handle the operation
        fuzzyInputArray *aux = this->fuzzyInputs;
        // find the last element of the array
        while (aux != NULL)
        {
            if (aux->next == NULL)
            {
                // make the ralations between them
                aux->next = newOne;
                return true;
            }
            aux = aux->next;
        }
    }
    return true;
}

// Method to include a new FuzzyOutput into Fuzzy
bool Fuzzy::addFuzzyOutput(FuzzyOutput *fuzzyOutput)
{
    if (fuzzyOutput == NULL)
    {
      // return false if in out of memory
      Serial.println("NULL fuzzyOutput in Fuzzy::addFuzzyOutput()");
      return false;
    }
    
    // auxiliary variable to handle the operation
    fuzzyOutputArray *newOne;
    // allocating in memory
    if ((newOne = (fuzzyOutputArray *)malloc(sizeof(fuzzyOutputArray))) == NULL)
    {
        // return false if in out of memory
        Serial.println("Memory alloction failed in Fuzzy::addFuzzyOutput()");
        return false;
    }
    // building the object
    newOne->fuzzyOutput = fuzzyOutput;
    newOne->next = NULL;
    // sorting the fuzzyOutput
    fuzzyOutput->order();
    // if it is the first FuzzyOutput, set it as the head
    if (this->fuzzyOutputs == NULL)
    {
        this->fuzzyOutputs = newOne;
    }
    else
    {
        // auxiliary variable to handle the operation
        fuzzyOutputArray *aux = this->fuzzyOutputs;
        // find the last element of the array
        while (aux != NULL)
        {
            if (aux->next == NULL)
            {
                // make the ralations between them
                aux->next = newOne;
                return true;
            }
            aux = aux->next;
        }
    }
    return true;
}

// Method to include a new FuzzyRule into Fuzzy
bool Fuzzy::addFuzzyRule(FuzzyRule *fuzzyRule)
{
    if (fuzzyRule == NULL)
    {
      // return false if in out of memory
      Serial.println("NULL fuzzyRule in Fuzzy::addFuzzyRule()");
      return false;
    }
    
    // auxiliary variable to handle the operation
    fuzzyRuleArray *newOne;
    // allocating in memory
    if ((newOne = (fuzzyRuleArray *)malloc(sizeof(fuzzyRuleArray))) == NULL)
    {
        // return false if in out of memory
        Serial.print("Memory alloction failed in Fuzzy::addFuzzyRule() index ");
        Serial.println(fuzzyRule->getIndex());
        Serial.flush();
        return false;
    }
    // building the object
    newOne->fuzzyRule = fuzzyRule;
    newOne->next = NULL;
    // if it is the first FuzzyOutput, set it as the head
    if (this->fuzzyRules == NULL)
    {
        this->fuzzyRules = newOne;
    }
    else
    {
        // auxiliary variable to handle the operation
        fuzzyRuleArray *aux = this->fuzzyRules;
        // find the last element of the array
        while (aux != NULL)
        {
            if (aux->next == NULL)
            {
                // make the ralations between them
                aux->next = newOne;
                return true;
            }
            aux = aux->next;
        }
    }
    return true;
}

// Method to set a crisp value to one FuzzyInput
bool Fuzzy::setInput(int fuzzyInputIndex, float crispValue)
{
    // auxiliary variable to handle the operation
    fuzzyInputArray *aux;
    // instantiate with the first element from array
    aux = this->fuzzyInputs;
    // while not in the end of the array, iterate
    while (aux != NULL)
    {
        // if the FuzzyInput index match with the desired
        if (aux->fuzzyInput->getIndex() == fuzzyInputIndex)
        {
            // set crisp value for this FuzzyInput and return true
            aux->fuzzyInput->setCrispInput(crispValue);
            return true;
        }
        aux = aux->next;
    }
    // if no FuzzyInput was found, return false
    Serial.print("No input found in Fuzzy::setInput(");
    Serial.print(fuzzyInputIndex);
    Serial.println(")");
    return false;
}

// Method to start the calculate of the result
bool Fuzzy::fuzzify()
{
    // auxiliary variable to handle the operation
    fuzzyInputArray *fuzzyInputAux;
    fuzzyOutputArray *fuzzyOutputAux;
    fuzzyRuleArray *fuzzyRuleAux;
    // to reset the data of all FuzzyInput and FuzzyOutput objects
    // instantiate with first element of the array
    fuzzyInputAux = this->fuzzyInputs;
    // while not in the end of the array, iterate
    while (fuzzyInputAux != NULL)
    {
        // for each FuzzyInput, reset its data
        fuzzyInputAux->fuzzyInput->resetFuzzySets();
        fuzzyInputAux = fuzzyInputAux->next;
    }
    // instantiate with first element of the array
    fuzzyOutputAux = this->fuzzyOutputs;
    // while not in the end of the array, iterate
    while (fuzzyOutputAux != NULL)
    {
        // for each FuzzyOutput, reset its data
        fuzzyOutputAux->fuzzyOutput->resetFuzzySets();
        fuzzyOutputAux = fuzzyOutputAux->next;
    }
    // to calculate the pertinence of all FuzzyInput objects
    // instantiate with first element of the array
    fuzzyInputAux = this->fuzzyInputs;
    // while not in the end of the array, iterate
    while (fuzzyInputAux != NULL)
    {
        // for each FuzzyInput, calculate its pertinence
        fuzzyInputAux->fuzzyInput->calculateFuzzySetPertinences();
        fuzzyInputAux = fuzzyInputAux->next;
    }
    // to evaluate which rules were triggered
    // instantiate with first element of the array
    fuzzyRuleAux = this->fuzzyRules;
    // while not in the end of the array, iterate
    while (fuzzyRuleAux != NULL)
    {
        // for each FuzzyRule, evaluate its expressions
        fuzzyRuleAux->fuzzyRule->evaluateExpression();
        fuzzyRuleAux = fuzzyRuleAux->next;
    }
    // to truncate the output sets
    // instantiate with first element of the array
    fuzzyOutputAux = this->fuzzyOutputs;
    // while not in the end of the array, iterate
    while (fuzzyOutputAux != NULL)
    {
        // for each FuzzyOutput, truncate the result
        fuzzyOutputAux->fuzzyOutput->truncate();
        fuzzyOutputAux = fuzzyOutputAux->next;
    }
    return true;
}

// Method to verify if one specific FuzzyRule was triggered
bool Fuzzy::isFiredRule(int fuzzyRuleIndex)
{
    // auxiliary variable to handle the operation
    fuzzyRuleArray *aux;
    // instantiate with first element of the array
    aux = this->fuzzyRules;
    // while not in the end of the array, iterate
    while (aux != NULL)
    {
        // if the FuzzyRule index match with the desired
        if (aux->fuzzyRule->getIndex() == fuzzyRuleIndex)
        {
            // return the calculated result
            return aux->fuzzyRule->isFired();
        }
        aux = aux->next;
    }
    // if no FuzzyRule was found, return false
    Serial.print("No rule found in Fuzzy::isFiredRule(");
    Serial.print(fuzzyRuleIndex);
    Serial.println(")");
    return false;
}

// Method to retrieve the result of the process for one specific FuzzyOutput
float Fuzzy::defuzzify(int fuzzyOutputIndex)
{
    // auxiliary variable to handle the operation
    fuzzyOutputArray *aux;
    // instantiate with first element of the array
    aux = this->fuzzyOutputs;
    // while not in the end of the array, iterate
    while (aux != NULL)
    {
        // if the FuzzyOutput index match with the desired
        if (aux->fuzzyOutput->getIndex() == fuzzyOutputIndex)
        {
            // return the calculated result
            return aux->fuzzyOutput->getCrispOutput();
        }
        aux = aux->next;
    }
    Serial.print("No output found in Fuzzy::defuzzify(");
    Serial.print(fuzzyOutputIndex);
    Serial.println(")");
    return 0;
}

// PRIVATE METHODS

// Method to recursively clean all FuzzyInput from memory
void Fuzzy::cleanFuzzyInputs(fuzzyInputArray *aux)
{
    if (aux != NULL)
    {
        this->cleanFuzzyInputs(aux->next);
        // emptying allocated memory
        free(aux);
    }
}

// Method to recursively clean all FuzzyOutput from memory
void Fuzzy::cleanFuzzyOutputs(fuzzyOutputArray *aux)
{
    if (aux != NULL)
    {
        this->cleanFuzzyOutputs(aux->next);
        // emptying allocated memory
        free(aux);
    }
}

// Method to recursively clean all FuzzyRule from memory
void Fuzzy::cleanFuzzyRules(fuzzyRuleArray *aux)
{
    if (aux != NULL)
    {
        this->cleanFuzzyRules(aux->next);
        // emptying allocated memory
        free(aux);
    }
}

forgive me sir, for the compile error I have solved it, now the error problem I mean is the result of processing not on compilation. I have checked again on Antecedents and Consequents but the result still error sir , currently I am using the latest version which is 1.4.1. for now i try to cek in arduino mega and proteus. in proteus the result can display but the result not for all can be print

then i try in arduino mega for real simulation the result cant display the output and cant makes looping

Is there a possibility that this is caused by too many input-output and rules? because I use input 3 and output 4 for rules as much as 27. some people say it doesn't matter if it is used on an arduino mega but when I simulate the results are still not as expected

Yes. If there is not enough memory to hold all of your inputs, outputs, and rules you will get null pointers when trying to allocate memory. The sketch can crash if any of those pointers is accidentally used to store data.

EVERY time you call 'new()' to create a FuzzySet, FuzzyInput, FuzzyOutput, FuzzyRuleAntecedent, FuzzyRuleConsequent , or FuzzyRule you should make sure the resulting pointer is not NULL.

EVERY time you call 'fuzzy->addFuzzyRule()' to add a rule to the fuzzy logic you should make sure that the returned value is 'true' meaning that the add was successful.

oke sir i will try to decrease of rules and input output. thanks for your helping me