eFLL - Uma Biblioteca Fuzzy para Arduino e Sistemas Embarcados

Read this article in English


Lógica Fuzzy é uma extensão da lógica booleana tradicional que através de variáveis linguísticas permite expressar valores lógicos intermediários entre o FALSO e VERDADEIRO, descrevendo com maior eficiência o princípio da incerteza do mundo real.

Sistemas Fuzzy são aplicações praticas que empregam a Lógica Fuzzy nas tomadas de decisões com base nos termos e variáveis linguísticas, tendo na robótica e na eletrônica um grande espaço e utilidade.

Desenvolvida pelo Robotic Research Group (RRG) na Universidade Estadual do Piauí (UESPI-Teresina) a biblioteca eFLL (Embedded Fuzzy Logic Library) é uma opção versátil, leve e eficiente de trabalhar com a Lógica Fuzzy em sistemas embarcados.



Por favor, reporte Bugs e sugestões via comentários ou na página oficial do projeto no GitHub.

Como instalar

Modo Fácil

1º Passo: Abra o Arduino IDE

2º Passo: No menu principal, vá em SKETCH >> INCLUIR BIBLIOTECA >> GERENCIAR BIBLIOTECAS

3º Passo: Procure por "eFLL" ou "Fuzzy"

4º Passo: eFLL aparecerá na listagem, para finalizar, apenas aperte em INSTALAR, agora já pode incluir a eFLL nos seus sketchs

Modo Antigo

1º Passo: Vá a página oficial do projeto no GitHub: eFLL

2º Passo: Faça um clone do projeto usando o Git ou faço o download em  Donwload pelo botão "Downloas as zip".

3º Passo: Clone ou descompacte os arquivos para a pasta de bibliotecas do Arduino:

Obs: Renomeie a pasta de "eFLL-master" para "eFLL"

no Ubuntu (/usr/share/arduino/libraries/) caso instalado via apt-get;
no Windows, Mac ou Linux (Onde você baixou o IDE Arduino, a pasta de biblioteca está dentro)

Pronto, a biblioteca está pronta para ser usada.

Como importar

Caso a instalação da biblioteca tenha sido realizada com sucesso, para importar a biblioteca é fácil:

1º Passo: Abra o seu Arduino IDE, vá a aba no menu superior SKETCKS → BIBLIOTECA → Importar eFLL

Características

Escrita em C++/C, usa apenas a biblioteca padrão da linguagem C "stdlib.h", por isso a eFLL é uma biblioteca destinada não somente ao Arduino, mas qualquer Sistema Embarcado ou não que tenham seus comandos escritos em C.

Não possui limitações explicitas de quantidade de Conjuntos Fuzzy, Regras Fuzzy, Entradas ou Saídas, estas limitam-se a capacidade de processamento e armazenamento de cada microcontrolador

A biblioteca utiliza o processo:
(MAX-MIN) e (Mínimo de Mamdani) para a inferência e composição e (Centro de Área) para a desfuzzyficação, no universo contínuo.

Testes realizados utilizando a biblioteca GTest para C, Google Inc

Exemplo simples:

Controle de velocidade de um robô, entrada: Distância obstáculo frontal.



Breve documentação

Objeto Fuzzy - Este objeto engloba todo o Sistema Fuzzy, através dele, é possível manipular os Conjuntos Fuzzy, as Regras Linguísticas, entradas e saídas.

Objeto FuzzyInput  - Este objeto literalmente agrupa todos os Conjuntos Fuzzy de entradas que pertencem ao mesmo domínio

Objeto FuzzyOutput  - Este objeto é semelhante ao FuzzyInput, é usado para agrupa todos os Conjuntos Fuzzy de saída que pertencem ao mesmo domínio.

Objeto FuzzySet - Este é um dos principais objetos da Biblioteca Fuzzy, com é possível modelar cada conjunto do sistema em questão. Atualmente a biblioteca suporta as funções de pertinência triangular, trapezoidal e singleton, que são montadas com base nos pontos A, B, C e D que são passados por parâmetro no construtor FuzzySet(float a, float b, float c, float d), exemplos:

Função de pertinência triangular:

FuzzySet* fs = FuzzySet(10, 20, 20, 30);

FuzzySet* fs = FuzzySet(10, 33, 33, 33);

FuzzySet* fs = FuzzySet(5, 5, 5, 30);

Função de pertinência trapezoidal:
FuzzySet* fs = FuzzySet(10, 20, 30, 40);


FuzzySet* fs = FuzzySet(0, 0, 10, 20);
Qualquer valor abaixo de 10 terá pertinência = 1

FuzzySet* fs = FuzzySet(20, 30, 40, 40);
Qualquer valor acima de 30 terá pertinência = 1

Função de pertinência Singleton:
FuzzySet* fs = FuzzySet(20, 20, 20, 20);

Objeto FuzzyRule - Este objeto é usado para montar a base de regras do objeto Fuzzy, que contem um ou mais deste. Instanciado com FuzzyRule fr = new FuzzyRule(ID, antecedent, consequente)

Objeto FuzzyRuleAntecedent - Este objeto é usado para compor o objeto FuzzyRule, responsável por montar a expressão condicional do antecedente de um FuzzyRule, exemplos:

"SE distancia = pequena ENTAO velocidade = lenta"

FuzzyRuleAntecedent* ifDistanceSmall = new FuzzyRuleAntecedent(); ifDistanceSmall->joinSingle(small);

O método joinSingle(FuzzySet* fuzzySet); é usado para montar expressões simples de SE isto ENTÃO aquilo. Para compor expressões mais complexas existem outros métodos especiais.

"SE temperatura = quente E pressão = alta ENTAO risco = grande"

FuzzyRuleAntecedent* ifTemperatureHotAndPressureHight = new FuzzyRuleAntecedent();
ifTemperatureHotAndPressureHight->joinWithAND(hot, hight); 

"SE temperatura = quente OU pressão = alta ENTAO risco = grande"

FuzzyRuleAntecedent* ifTemperatureHotAndPressureHight = new FuzzyRuleAntecedent();
ifTemperatureHotAndPressureHight->joinWithOR(hot, hight);

Os métodos joinWithAND(FuzzySet* fuzzySet1, FuzzySet* fuzzySet2); e joinWithOR(FuzzySet* fuzzySet1, FuzzySet* fuzzySet2); podem fazer composições logicas entre os Conjuntos Fuzzy. Estes métodos possuem ainda variações mais avançadas que permitem aprimorar mais ainda a expressão, são eles:

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

exemplos:

"SE (velocidade = alta E distância = pequena) OR combustível = pouco ENTAO velocidade = pequena E consumo = baixo"

FuzzyRuleAntecedent* speedHightAndDistanceSmall = new FuzzyRuleAntecedent();
speedHightAndDistanceSmall->joinWithAND(hight, small); 

FuzzyRuleAntecedent* fuelLow = new FuzzyRuleAntecedent();
fuelLow->joinSingle(low); 

// Este objeto FuzzyRuleAntecedente é que será usada para compor o objeto FuzzyRule 
FuzzyRuleAntecedent* ifSpeedHightAndDistanceSmallOrFuelLow = new FuzzyRuleAntecedent();
ifSpeedHightAndDistanceSmallOrFuelLow->joinWithOR(speedHightAndDistanceSmall, fuelLow); 

Se fazendo valer destes métodos, qualquer expressão pode ser montada, pois um objeto FuzzyRuleAntecedent pode ser usado para compor outro objeto FuzzyRuleAntecedent, das mais diversas formas. OBS:. no exemplo anterior, o antecedente final foi composto pelos objetos speedHightAndDistanceSmall e
fuelLow mas este último poderia ser substituído sem perda pelo objeto FuzzySet low, já que o mesmo é uma expressão simples, sem nenhum operador condicional:

FuzzyRuleAntecedent* speedHightAndDistanceSmall = new FuzzyRuleAntecedent();
speedHightAndDistanceSmall->joinWithAND(hight, small); 

// Este objeto FuzzyRuleAntecedente é que será usada para compor o objeto FuzzyRule 
FuzzyRuleAntecedent* ifSpeedHightAndDistanceSmallOrFuelLow = new FuzzyRuleAntecedent();
ifSpeedHightAndDistanceSmallOrFuelLow->joinWithOR(speedHightAndDistanceSmall, low); 

Objeto FuzzyRuleConsequente - Este objeto é usado para compor o objeto FuzzyRule, responsavel por montar a expressão de saída de um FuzzyRule, exemplos:

"SE distancia = pequena ENTAO velocidade = lenta"

FuzzyRuleConsequent* thenSpeedSlow = new FuzzyRuleConsequent(); 
thenSpeedSlow->addOutput(slow);

O que resultaria em um objeto FuzzyRule:

FuzzyRule* fuzzyRule = new FuzzyRule(2, ifDistanceSmall, thenSpeedSlow);

"SE (velocidade = alta E distância = pequena) OR combustível = pouco ENTAO velocidade = pequena E consumo = baixo"

FuzzyRuleConsequent* thenSpeedSmallAndFeedTine = new FuzzyRuleConsequent(); thenSpeedSmallAndFeedSmall->addOutput(small);

thenSpeedSmallAndFeedSmall->addOutput(tine);  

Para o objeto FuzzyRuleConsequent toda a expressão é montada com o método addOutput(FuzzySet* fuzzySet);

O que resultaria em um objeto FuzzyRule:

FuzzyRule* fuzzyRule = new FuzzyRule(2, ifSpeedHightAndDistanceSmallOrFuelLow, thenSpeedSmallAndFeedTine);

Após montar um objeto FuzzyRule, use o método addFuzzyRule(FuzzyRule* fuzzyRule); do objeto Fuzzy para adicionar a regra na base de regras, repita o mesmo processo para todas as regras.

Dica

Estes são todos os objetos da biblioteca eFLL que são utilizados no processo. O passo seguinte, e geralmente interativo é manipulado por três métodos do objeto Fuzzy, o primeiro:

bool setInput(int ID, float valor);

É utilizado para repassar o valor de entrada crispe para o sistema, note que o primeiro parâmetro é o ID do objeto FuzzyInput ao qual o parâmetro valor é destinado.

bool fuzzify();

É utilizado para iniciar o processo de fuzzyficação, composição e inferência.

E por fim: float defuzzify(int ID);

É utilizado para finalizar o processo de fuzzyficação,  note que o ID que é passado por parametro é o ID do FuzzyOutput ao qual se deseja obter o valor desfuzzificado.

Dica: Algumas vezes é necessário conhecer a pertinência com a qual algum, ou cada Conjunto Fuzzy foi ativado. Para isso, utilize o método float getPertinence(); do objeto FuzzySet para objet esse valor, exemplo:

FuzzySet* hot = new FuzzySet(30, 50, 50, 70);
...
... // Após a fuzzyficação com ->fuzzyfy();
...
float pertinenceOfHot = hot->getPertinence();

Ou saber se determinada regra foi ativada, utilize o método bool isFiredRule(int ruleId) do objeto Fuzzy.

FuzzyRule* fuzzyRule = new FuzzyRule(2, ifDistanceSmall, thenSpeedSlow);
...
... // Após a fuzzyficação com ->fuzzyfy();
...
bool wasTheRulleFired = fuzzy->isFiredRule(2);

Exemplo avançado:


eFLL - Uma Biblioteca Fuzzy para Arduino e Sistemas Embarcados eFLL - Uma Biblioteca Fuzzy para Arduino e Sistemas Embarcados Reviewed by AJ Alves on sexta-feira, setembro 28, 2012 Rating: 5

31 comentários:

pablodutra disse...

Agora sim hein! Vou fazer um teste e em breve postarei um comentário sobre a experiência! Agradeço desde já pela biblioteca!

AJ Alves disse...

Para quem quiser ver um exemplo utilizando o método Fuzzy::isFiredRule(id); vejam https://gist.github.com/4110773

Unknown disse...

Estou gostando muito dessa Biblioteca e gostaria de ter contato com o Autor. Parabéns !!!

Helton Castanheira
Eng. de Controle e Automação
Crea: 22.666 D PA
Mestrando Eng. Mecânica - IME RJ
e-mail: heltoncastanheira@yahoo.com.br

Unknown disse...

Cara, eu nao estou conseguindo instalar o arquivo! Quando eu entro escreve a seguinte mensagem:
the library "eFLL-master" cannot be used.
Library names must contain only basic letters and numbers(ASCII only and no spaces, and it cannot start with a number)

oq será q é?

Unknown disse...

Cara, eu nao estou conseguindo instalar o arquivo! Quando eu entro escreve a seguinte mensagem:
the library "eFLL-master" cannot be used.
Library names must contain only basic letters and numbers(ASCII only and no spaces, and it cannot start with a number)

oq será q é?

AJ Alves disse...

Olá Henriqque, não compreendi exatamente seu problema, onde é que ocorre esse erro? no Arduino IDE. O que me parece é que é o nome da pasta, se for, renomeia ela só para "eFLL"

Unknown disse...

Sim, vc descompacta a pasta eFLL-master na pasta de library do Arduino! Ae quando vc abre o Ide, aparece essa mensagem, antes de abrir mesmo o programa, quando a imagem de apresentação esta ainda aparecendo! Ae quando eu vou em importar nao tem a opção eFLL!

AJ Alves disse...

Afirmativo Henrique, altere o nome da pasta que está dentro da pasta "arduino/libraries" de "eFLL-master" para "eFLL", creio que o erro desaparecerá.

Unknown disse...

Muito Obrigado, deu certo!

Anônimo disse...

cara... muito boa a biblioteca, eu testei e é uma maravilha...

porem, estou fazendo o meu e simulei no matlab e agora estou passando os valores para a biblioteca...

fuzzy->setInput(1, 10);
fuzzy->setInput(2, 30);
fuzzy->setInput(3, -15);


o 10, 30 e -15... são de onde?

AJ Alves disse...

Olá, o 10, 30 e -15 são as entradas dos objetos FuzzyInput, nesse caso, são três FuzzyInputs, o de ID 1 recebe 10 o de ID 2 recebe 30 e o de ID 3 recebe -15

Unknown disse...

Cara.. muito obrigado...

eu coloquei sensor de intensidade de luz de temperaturae um sensor 0/1 de chuva... e mudei, portanto, esses 10, 30 e -15.. colocando os sensores em seus lugares.

Fui para o matlab e calculei lá as coordenadas para os ranges que propus...

Estabeleci 11 regras, dizendo como estava o clima...


Funcionou muuuito bem!!!
Eu envio o link via rede local wiki e a pagina me responde como o clima está =D


Muito obrigado!!!

Unknown disse...

realmente, muito bom!!!

AJ Alves disse...

Fico muito feliz em ver que a biblioteca é útil!

Ângelo disse...

Gostei muito da Lib.
Mas me perdoe minha ignorância, não seria mais fácil usar um switch-case? Sério mesmo, fiquei na dúvida, pois esse código pesa muito mais na ROM do Arduino....

AJ Alves disse...

Ángelo, realmente diante dos simples exemplos que fiz, fica difícil perceber o poder dessa técnica, pois o objetivo é fazer entender a biblioteca e não a técnica. Recomendo que pesquise para entender mais.

Ângelo disse...

Mas eu gostei muito mesmo. Bem legal. Acredito que a lógica fuzzy com arduino seria melhor aplicada quando comessássemos a trabalhar com teoria de conjuntos, do tipo, 3 LDRs em pontos distintos de um mesmo aposento, por exemplo. Ainda, diversos sensores de temperatura poderia controlar a velocidade e a direção do ar-condicionado.
Do tipo, seria extremamente útil para aplicações de domótica, por exemplo.

O que você acha?

Unknown disse...

Boa Tarde meu amigo. Estou tentando utilizar a sua biblioteca para desenvolver um robô que desvia de obstáculos. Ele possui 4 sensores infravermelhos da Sharp ( 3 frontais e um traseiro ). Estou com um pouco de dificuldade para saber quais dados coloco na função "FuzzySet(0, 20, 20, 40)". As fotos do seu site não estão carregando. Sabe dizer quando voltará ao normal? Você poderia me enviar esse manual?

Unknown disse...

Boa tarde!
o seu código foi feito orientado a objetos em C++ né?.
estou querendo implementar um projeto, sendo que em um microcontrolador PIC (que só tem compilador em C) como eu posso fazer?

AJ Alves disse...

Bem, Unknown, eu nunca mexi com PIC, mas tenho quase certeza que é possivel trabalhar com C++, da uma pesquisada, essa biblioteca utiliza apenas a stdlib justamente para ser o mais compatível possível.

Unknown disse...

Obrigado por responder tão rápido.
o problema é que não existe compilador orientado a objeto para PIC.
Você teria um fluxograma, ou algo parecido, do seu codigo.?

Unknown disse...

Tem que adicionar tanto os arquivos .h e .cpp, para podercompilar?

qual a diferença dos dois?

AJ Alves disse...

sim Marco, é necessário os .h e .cpp, basicamente é convenção, os .h são só para referenciar as classes e métodos, o código de implementação mesmo fica nos .cpp...Tudo poderia ficar tranquilamente junto no .cpp, mas por convenção que gera organização e outras coisas mais, faz-se essa divisão.

No github, na pasta uml tem um diagrama de classes: https://github.com/zerokol/eFLL/blob/master/uml/class-diagram.png

Unknown disse...

Se eu criar uma interrupção, o codigo ainda irá funcionar?

Unknown disse...

Estou tendo problemas com pertinências de valores negativos.
O resultado está dando errado.

alguém com esse problema?

AJ Alves disse...

marco capozzoli, quanto a questão da interrupção, o código deve funcionar normalmente, o que você deve fazer é respeitar os aspectos de concorrência naturais. Quanto ao erro de pertinências negativas, confira se os conjuntos estão ordenados corretamente, eu sei que você sabe, mas por exemplo, -40 é menor que -20 e essa ordem deve ser respeitada na formação dos conjuntos.

Unknown disse...

Amigo, Bom dia.
Estou escrevendo meu TCC, e utilizo a eFLL num projeto de controle de umidade do solo. Gostaria de referenciá-lo mais então faltando informações sobre o evento e o ano que seu artigo foi publicado sendo que titulo do artigo é:
"DESENVOLVIMENTO DE UMA BIBLIOTECA FUZZY PARA O CONTROLE AUTÔNOMO DE UM ROBÔ MÓVEL EM AMBIENTE DESCONHECIDO".
Aguardo resposta o mais breve possível, pois tenho que entregar o TCC até dia 05.05.2016.
Obrigado

Anônimo disse...

AJ Alves, primeiramente gostaria de parabenizar você pelo código... realmente é muito interessante e versátil...

Estou realizando um código com a sua biblioteca fuzzy no Arduino UNO. Consegui simular todos os seus exemplos normal. Porém o código que estou criando necessita de 20 regras fuzzy, e para esta quantidade não está funcionando sendo a saída em 0 a todo o tempo. Daí, com este problema, comecei a ceifar as regras fuzzy e quando mantive somente 15 regras funcionou. Existe alguma limitação no código de quantidade de regras fuzzy? Será que se mudar o modelo do Arduino funciona? Esta limitação é do controlador?

Fico no aguardo.

Silva disse...

Estou utilizando a biblioteca para um projeto, como faço para colocar os devidos créditos?

AJ Alves disse...

Silva, coloque o nome da biblioteca e link do github

mujibhd disse...

hi man, can you help me to add setpoint to this fuzzy..
thank you

Tecnologia do Blogger.