Fuzzy libray for embedded targets developed by zerokol. Read more on: http://zerokol.com/product/51e93616e84c5571b7000018/2/en edit by Bruno Alfano - corrected deallocation of FuzzyOutput
Fuzzy library by Zerokol. Read more on: http://zerokol.com/product/51e93616e84c5571b7000018/2/en
edit by Bruno Alfano - corrected deallocation bug for FuzzyOutput
Fuzzy.cpp@2:460b409e26e8, 2015-06-24 (annotated)
- Committer:
- astaff15
- Date:
- Wed Jun 24 15:08:13 2015 +0000
- Revision:
- 2:460b409e26e8
- Parent:
- 0:66cd67db4f1b
Corrected FuzzyOutput destructor bug
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
astaff15 | 0:66cd67db4f1b | 1 | /* |
astaff15 | 0:66cd67db4f1b | 2 | * Robotic Research Group (RRG) |
astaff15 | 0:66cd67db4f1b | 3 | * State University of Piaui (UESPI), Brazil - Piauí - Teresina |
astaff15 | 0:66cd67db4f1b | 4 | * |
astaff15 | 0:66cd67db4f1b | 5 | * Fuzzy.cpp |
astaff15 | 0:66cd67db4f1b | 6 | * |
astaff15 | 0:66cd67db4f1b | 7 | * Author: Msc. Marvin Lemos <marvinlemos@gmail.com> |
astaff15 | 0:66cd67db4f1b | 8 | * AJ Alves <aj.alves@zerokol.com> |
astaff15 | 0:66cd67db4f1b | 9 | * Co authors: Douglas S. Kridi <douglaskridi@gmail.com> |
astaff15 | 0:66cd67db4f1b | 10 | * Kannya Leal <kannyal@hotmail.com> |
astaff15 | 0:66cd67db4f1b | 11 | */ |
astaff15 | 0:66cd67db4f1b | 12 | #include "Fuzzy.h" |
astaff15 | 0:66cd67db4f1b | 13 | |
astaff15 | 0:66cd67db4f1b | 14 | // CONSTRUTORES |
astaff15 | 0:66cd67db4f1b | 15 | Fuzzy::Fuzzy(){ |
astaff15 | 0:66cd67db4f1b | 16 | // Iniciando os ponteiros como nulo |
astaff15 | 0:66cd67db4f1b | 17 | // FuzzyInput |
astaff15 | 0:66cd67db4f1b | 18 | this->fuzzyInputs = NULL; |
astaff15 | 0:66cd67db4f1b | 19 | this->fuzzyInputsCursor = NULL; |
astaff15 | 0:66cd67db4f1b | 20 | // FuzzyOutput |
astaff15 | 0:66cd67db4f1b | 21 | this->fuzzyOutputs = NULL; |
astaff15 | 0:66cd67db4f1b | 22 | this->fuzzyOutputsCursor = NULL; |
astaff15 | 0:66cd67db4f1b | 23 | // FuzzyRule |
astaff15 | 0:66cd67db4f1b | 24 | this->fuzzyRules = NULL; |
astaff15 | 0:66cd67db4f1b | 25 | this->fuzzyRulesCursor = NULL; |
astaff15 | 0:66cd67db4f1b | 26 | } |
astaff15 | 0:66cd67db4f1b | 27 | |
astaff15 | 0:66cd67db4f1b | 28 | // DESTRUTOR |
astaff15 | 0:66cd67db4f1b | 29 | Fuzzy::~Fuzzy(){ |
astaff15 | 0:66cd67db4f1b | 30 | this->cleanFuzzyInputs(this->fuzzyInputs); |
astaff15 | 0:66cd67db4f1b | 31 | this->cleanFuzzyOutputs(this->fuzzyOutputs); |
astaff15 | 0:66cd67db4f1b | 32 | this->cleanFuzzyRules(this->fuzzyRules); |
astaff15 | 0:66cd67db4f1b | 33 | } |
astaff15 | 0:66cd67db4f1b | 34 | |
astaff15 | 0:66cd67db4f1b | 35 | // MÉTODOS PÚBLICOS |
astaff15 | 0:66cd67db4f1b | 36 | bool Fuzzy::addFuzzyInput(FuzzyInput* fuzzyInput){ |
astaff15 | 0:66cd67db4f1b | 37 | fuzzyInputArray* aux; |
astaff15 | 0:66cd67db4f1b | 38 | |
astaff15 | 0:66cd67db4f1b | 39 | // Alocando espaço na memória |
astaff15 | 0:66cd67db4f1b | 40 | if((aux = (fuzzyInputArray *) malloc(sizeof(fuzzyInputArray))) == NULL){ |
astaff15 | 0:66cd67db4f1b | 41 | return false; |
astaff15 | 0:66cd67db4f1b | 42 | } |
astaff15 | 0:66cd67db4f1b | 43 | |
astaff15 | 0:66cd67db4f1b | 44 | aux->fuzzyInput = fuzzyInput; |
astaff15 | 0:66cd67db4f1b | 45 | aux->next = NULL; |
astaff15 | 0:66cd67db4f1b | 46 | |
astaff15 | 0:66cd67db4f1b | 47 | if(this->fuzzyInputs == NULL){ |
astaff15 | 0:66cd67db4f1b | 48 | this->fuzzyInputs = aux; |
astaff15 | 0:66cd67db4f1b | 49 | this->fuzzyInputsCursor = aux; |
astaff15 | 0:66cd67db4f1b | 50 | }else{ |
astaff15 | 0:66cd67db4f1b | 51 | this->fuzzyInputsCursor->next = aux; |
astaff15 | 0:66cd67db4f1b | 52 | this->fuzzyInputsCursor = aux; |
astaff15 | 0:66cd67db4f1b | 53 | } |
astaff15 | 0:66cd67db4f1b | 54 | |
astaff15 | 0:66cd67db4f1b | 55 | return true; |
astaff15 | 0:66cd67db4f1b | 56 | } |
astaff15 | 0:66cd67db4f1b | 57 | |
astaff15 | 0:66cd67db4f1b | 58 | bool Fuzzy::addFuzzyOutput(FuzzyOutput* fuzzyOutput){ |
astaff15 | 0:66cd67db4f1b | 59 | fuzzyOutputArray *aux; |
astaff15 | 0:66cd67db4f1b | 60 | // Alocando espaço na memória |
astaff15 | 0:66cd67db4f1b | 61 | if((aux = (fuzzyOutputArray *) malloc(sizeof(fuzzyOutputArray))) == NULL){ |
astaff15 | 0:66cd67db4f1b | 62 | return false; |
astaff15 | 0:66cd67db4f1b | 63 | } |
astaff15 | 0:66cd67db4f1b | 64 | aux->fuzzyOutput = fuzzyOutput; |
astaff15 | 0:66cd67db4f1b | 65 | aux->next = NULL; |
astaff15 | 0:66cd67db4f1b | 66 | |
astaff15 | 0:66cd67db4f1b | 67 | // Ordenando o fuzzyOutput |
astaff15 | 0:66cd67db4f1b | 68 | fuzzyOutput->order(); |
astaff15 | 0:66cd67db4f1b | 69 | |
astaff15 | 0:66cd67db4f1b | 70 | if(this->fuzzyOutputs == NULL){ |
astaff15 | 0:66cd67db4f1b | 71 | this->fuzzyOutputs = aux; |
astaff15 | 0:66cd67db4f1b | 72 | this->fuzzyOutputsCursor = aux; |
astaff15 | 0:66cd67db4f1b | 73 | }else{ |
astaff15 | 0:66cd67db4f1b | 74 | this->fuzzyOutputsCursor->next = aux; |
astaff15 | 0:66cd67db4f1b | 75 | this->fuzzyOutputsCursor = aux; |
astaff15 | 0:66cd67db4f1b | 76 | } |
astaff15 | 0:66cd67db4f1b | 77 | return true; |
astaff15 | 0:66cd67db4f1b | 78 | } |
astaff15 | 0:66cd67db4f1b | 79 | |
astaff15 | 0:66cd67db4f1b | 80 | bool Fuzzy::addFuzzyRule(FuzzyRule* fuzzyRule){ |
astaff15 | 0:66cd67db4f1b | 81 | fuzzyRuleArray* aux; |
astaff15 | 0:66cd67db4f1b | 82 | // Alocando espaço na memória |
astaff15 | 0:66cd67db4f1b | 83 | if((aux = (fuzzyRuleArray *) malloc(sizeof(fuzzyRuleArray))) == NULL){ |
astaff15 | 0:66cd67db4f1b | 84 | return false; |
astaff15 | 0:66cd67db4f1b | 85 | } |
astaff15 | 0:66cd67db4f1b | 86 | aux->fuzzyRule = fuzzyRule; |
astaff15 | 0:66cd67db4f1b | 87 | aux->next = NULL; |
astaff15 | 0:66cd67db4f1b | 88 | |
astaff15 | 0:66cd67db4f1b | 89 | if(this->fuzzyRules == NULL){ |
astaff15 | 0:66cd67db4f1b | 90 | this->fuzzyRules = aux; |
astaff15 | 0:66cd67db4f1b | 91 | this->fuzzyRulesCursor = aux; |
astaff15 | 0:66cd67db4f1b | 92 | }else{ |
astaff15 | 0:66cd67db4f1b | 93 | this->fuzzyRulesCursor->next = aux; |
astaff15 | 0:66cd67db4f1b | 94 | this->fuzzyRulesCursor = aux; |
astaff15 | 0:66cd67db4f1b | 95 | } |
astaff15 | 0:66cd67db4f1b | 96 | return true; |
astaff15 | 0:66cd67db4f1b | 97 | } |
astaff15 | 0:66cd67db4f1b | 98 | |
astaff15 | 0:66cd67db4f1b | 99 | bool Fuzzy::setInput(int fuzzyInputIndex, float crispValue){ |
astaff15 | 0:66cd67db4f1b | 100 | fuzzyInputArray *aux; |
astaff15 | 0:66cd67db4f1b | 101 | aux = this->fuzzyInputs; |
astaff15 | 0:66cd67db4f1b | 102 | |
astaff15 | 0:66cd67db4f1b | 103 | while(aux != NULL){ |
astaff15 | 0:66cd67db4f1b | 104 | if(aux->fuzzyInput->getIndex() == fuzzyInputIndex){ |
astaff15 | 0:66cd67db4f1b | 105 | aux->fuzzyInput->setCrispInput(crispValue); |
astaff15 | 0:66cd67db4f1b | 106 | return true; |
astaff15 | 0:66cd67db4f1b | 107 | } |
astaff15 | 0:66cd67db4f1b | 108 | aux = aux->next; |
astaff15 | 0:66cd67db4f1b | 109 | } |
astaff15 | 0:66cd67db4f1b | 110 | return false; |
astaff15 | 0:66cd67db4f1b | 111 | } |
astaff15 | 0:66cd67db4f1b | 112 | |
astaff15 | 0:66cd67db4f1b | 113 | bool Fuzzy::fuzzify(){ |
astaff15 | 0:66cd67db4f1b | 114 | fuzzyInputArray* fuzzyInputAux; |
astaff15 | 0:66cd67db4f1b | 115 | |
astaff15 | 0:66cd67db4f1b | 116 | fuzzyOutputArray *fuzzyOutputAux; |
astaff15 | 0:66cd67db4f1b | 117 | |
astaff15 | 0:66cd67db4f1b | 118 | fuzzyInputAux = this->fuzzyInputs; |
astaff15 | 0:66cd67db4f1b | 119 | while(fuzzyInputAux != NULL){ |
astaff15 | 0:66cd67db4f1b | 120 | fuzzyInputAux->fuzzyInput->resetFuzzySets(); |
astaff15 | 0:66cd67db4f1b | 121 | fuzzyInputAux = fuzzyInputAux->next; |
astaff15 | 0:66cd67db4f1b | 122 | } |
astaff15 | 0:66cd67db4f1b | 123 | |
astaff15 | 0:66cd67db4f1b | 124 | fuzzyOutputAux = this->fuzzyOutputs; |
astaff15 | 0:66cd67db4f1b | 125 | while(fuzzyOutputAux != NULL){ |
astaff15 | 0:66cd67db4f1b | 126 | fuzzyOutputAux->fuzzyOutput->resetFuzzySets(); |
astaff15 | 0:66cd67db4f1b | 127 | fuzzyOutputAux = fuzzyOutputAux->next; |
astaff15 | 0:66cd67db4f1b | 128 | } |
astaff15 | 0:66cd67db4f1b | 129 | |
astaff15 | 0:66cd67db4f1b | 130 | // Calculando a pertinência de todos os FuzzyInputs |
astaff15 | 0:66cd67db4f1b | 131 | fuzzyInputAux = this->fuzzyInputs; |
astaff15 | 0:66cd67db4f1b | 132 | while(fuzzyInputAux != NULL){ |
astaff15 | 0:66cd67db4f1b | 133 | fuzzyInputAux->fuzzyInput->calculateFuzzySetPertinences(); |
astaff15 | 0:66cd67db4f1b | 134 | fuzzyInputAux = fuzzyInputAux->next; |
astaff15 | 0:66cd67db4f1b | 135 | } |
astaff15 | 0:66cd67db4f1b | 136 | |
astaff15 | 0:66cd67db4f1b | 137 | // Avaliando quais regras foram disparadas |
astaff15 | 0:66cd67db4f1b | 138 | fuzzyRuleArray* fuzzyRuleAux; |
astaff15 | 0:66cd67db4f1b | 139 | fuzzyRuleAux = this->fuzzyRules; |
astaff15 | 0:66cd67db4f1b | 140 | // Calculando as pertinências de totos os FuzzyInputs |
astaff15 | 0:66cd67db4f1b | 141 | while(fuzzyRuleAux != NULL){ |
astaff15 | 0:66cd67db4f1b | 142 | fuzzyRuleAux->fuzzyRule->evaluateExpression(); |
astaff15 | 0:66cd67db4f1b | 143 | fuzzyRuleAux = fuzzyRuleAux->next; |
astaff15 | 0:66cd67db4f1b | 144 | } |
astaff15 | 0:66cd67db4f1b | 145 | |
astaff15 | 0:66cd67db4f1b | 146 | // Truncado os conjuntos de saída |
astaff15 | 0:66cd67db4f1b | 147 | fuzzyOutputAux = this->fuzzyOutputs; |
astaff15 | 0:66cd67db4f1b | 148 | while(fuzzyOutputAux != NULL){ |
astaff15 | 0:66cd67db4f1b | 149 | fuzzyOutputAux->fuzzyOutput->truncate(); |
astaff15 | 0:66cd67db4f1b | 150 | fuzzyOutputAux = fuzzyOutputAux->next; |
astaff15 | 0:66cd67db4f1b | 151 | } |
astaff15 | 0:66cd67db4f1b | 152 | |
astaff15 | 0:66cd67db4f1b | 153 | return true; |
astaff15 | 0:66cd67db4f1b | 154 | } |
astaff15 | 0:66cd67db4f1b | 155 | |
astaff15 | 0:66cd67db4f1b | 156 | bool Fuzzy::isFiredRule(int fuzzyRuleIndex){ |
astaff15 | 0:66cd67db4f1b | 157 | fuzzyRuleArray *aux; |
astaff15 | 0:66cd67db4f1b | 158 | aux = this->fuzzyRules; |
astaff15 | 0:66cd67db4f1b | 159 | while(aux != NULL){ |
astaff15 | 0:66cd67db4f1b | 160 | if(aux->fuzzyRule->getIndex() == fuzzyRuleIndex){ |
astaff15 | 0:66cd67db4f1b | 161 | return aux->fuzzyRule->isFired(); |
astaff15 | 0:66cd67db4f1b | 162 | } |
astaff15 | 0:66cd67db4f1b | 163 | aux = aux->next; |
astaff15 | 0:66cd67db4f1b | 164 | } |
astaff15 | 0:66cd67db4f1b | 165 | return false; |
astaff15 | 0:66cd67db4f1b | 166 | } |
astaff15 | 0:66cd67db4f1b | 167 | |
astaff15 | 0:66cd67db4f1b | 168 | float Fuzzy::defuzzify(int fuzzyOutputIndex){ |
astaff15 | 0:66cd67db4f1b | 169 | fuzzyOutputArray *aux; |
astaff15 | 0:66cd67db4f1b | 170 | aux = this->fuzzyOutputs; |
astaff15 | 0:66cd67db4f1b | 171 | while(aux != NULL){ |
astaff15 | 0:66cd67db4f1b | 172 | if(aux->fuzzyOutput->getIndex() == fuzzyOutputIndex){ |
astaff15 | 0:66cd67db4f1b | 173 | return aux->fuzzyOutput->getCrispOutput(); |
astaff15 | 0:66cd67db4f1b | 174 | } |
astaff15 | 0:66cd67db4f1b | 175 | aux = aux->next; |
astaff15 | 0:66cd67db4f1b | 176 | } |
astaff15 | 0:66cd67db4f1b | 177 | return 0; |
astaff15 | 0:66cd67db4f1b | 178 | } |
astaff15 | 0:66cd67db4f1b | 179 | |
astaff15 | 0:66cd67db4f1b | 180 | // MÉTODOS PRIVADOS |
astaff15 | 0:66cd67db4f1b | 181 | void Fuzzy::cleanFuzzyInputs(fuzzyInputArray* aux){ |
astaff15 | 0:66cd67db4f1b | 182 | if(aux != NULL){ |
astaff15 | 0:66cd67db4f1b | 183 | // Esvaziando a memória alocada |
astaff15 | 0:66cd67db4f1b | 184 | this->cleanFuzzyInputs(aux->next); |
astaff15 | 0:66cd67db4f1b | 185 | free(aux); |
astaff15 | 0:66cd67db4f1b | 186 | } |
astaff15 | 0:66cd67db4f1b | 187 | } |
astaff15 | 0:66cd67db4f1b | 188 | |
astaff15 | 0:66cd67db4f1b | 189 | void Fuzzy::cleanFuzzyOutputs(fuzzyOutputArray* aux){ |
astaff15 | 0:66cd67db4f1b | 190 | if(aux != NULL){ |
astaff15 | 0:66cd67db4f1b | 191 | // Esvaziando a memória alocada |
astaff15 | 0:66cd67db4f1b | 192 | this->cleanFuzzyOutputs(aux->next); |
astaff15 | 0:66cd67db4f1b | 193 | free(aux); |
astaff15 | 0:66cd67db4f1b | 194 | } |
astaff15 | 0:66cd67db4f1b | 195 | } |
astaff15 | 0:66cd67db4f1b | 196 | |
astaff15 | 0:66cd67db4f1b | 197 | void Fuzzy::cleanFuzzyRules(fuzzyRuleArray* aux){ |
astaff15 | 0:66cd67db4f1b | 198 | if(aux != NULL){ |
astaff15 | 0:66cd67db4f1b | 199 | // Esvaziando a memória alocada |
astaff15 | 0:66cd67db4f1b | 200 | this->cleanFuzzyRules(aux->next); |
astaff15 | 0:66cd67db4f1b | 201 | free(aux); |
astaff15 | 0:66cd67db4f1b | 202 | } |
astaff15 | 0:66cd67db4f1b | 203 | } |