Last active
February 27, 2020 13:30
-
-
Save sash13/62164733f72e8d902be0afa2bc2d4b72 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Simple generator for eFLL library | |
https://blog.zerokol.com/2012/09/arduinofuzzy-fuzzy-library-for-arduino.html | |
now only support fuzzy system with if ... then ... (without or, and etc). | |
multiple input and output also supported | |
Example usage. | |
1. Open FIS editor in matlab | |
>> fuzzy | |
2. Edit your fuzzy system add input outputs and rules | |
3. File->Export to workspace with name for example Untitled | |
4. Run function fis2eFLLCode(Untitled) for view code | |
5. For saving code to file, run fis2eFLLCode(Untitled, 'nameFile.m') | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function code = fis2eFLLCode(fis, fileName) | |
if nargin<2 | |
fileName = 0; | |
end | |
% Init help variables | |
code = ''; | |
out_code = {}; | |
inOutNames = {}; | |
% Add header data | |
out_code{end+1} = {'#include <Fuzzy.h>' 'Fuzzy *fuzzy = new Fuzzy();' '//'}; | |
% Generate input/output SETs | |
[out_code{end+1}, inputs]= eFLLInOutGen(fis.input); | |
[out_code{end+1}, outputs]= eFLLInOutGen(fis.output); | |
% Start of setup function | |
out_code{end+1} = {'//Setup' 'void setup()' '{' 'Serial.begin(9600);' 'randomSeed(analogRead(0));' '//'}; | |
% Adding sets to input/output | |
[out_code{end+1}, inOutNames{end+1}] = eFLLInOutInitGen(inputs, 1); | |
[out_code{end+1}, inOutNames{end+1}] = eFLLInOutInitGen(outputs, 0); | |
% Generate rules | |
out_code{end+1} = eFLLRuleGen(fis.rule, inputs, outputs, inOutNames); | |
% End of setup function | |
out_code{end+1} = {'End' '}' '//'}; | |
% Generate loop | |
out_code{end+1} = {'//Loop' 'void loop()' '{' '//'}; | |
out_code{end+1} = eFLLloopGen(inputs, outputs, inOutNames); | |
out_code{end+1} = {'End' '}' '//'}; | |
% Compile output file | |
for k = 1 : length(out_code) | |
code = strcat(code, strjoin(out_code{k}, char(10))); | |
end | |
if fileName | |
fid = fopen(fileName,'wt'); | |
fprintf(fid, code); | |
fclose(fid); | |
end | |
%Generate FuzzySet Rules | |
function [code, puts] = eFLLInOutGen(data) | |
fuzzySet = 'FuzzySet *%s = new FuzzySet(%s, %s, %s, %s); // %s'; | |
code = {}; | |
puts = {}; | |
for in = data | |
code{end+1} = ['//Fuzzy_' in.name]; | |
localInputs = {}; | |
for mf = in.mf | |
if length(mf.params) == 3 | |
code{end+1} = sprintf(fuzzySet, [in.name '_' mf.name], num2str(mf.params(1)), num2str(mf.params(2)), num2str(mf.params(2)), num2str(mf.params(3)), mf.type); | |
elseif length(mf.params) == 4 | |
code{end+1} = sprintf(fuzzySet, [in.name '_' mf.name], num2str(mf.params(1)), num2str(mf.params(2)), num2str(mf.params(3)), num2str(mf.params(4)), mf.type); | |
end | |
localInputs{end+1} = [in.name '_' mf.name]; | |
end | |
puts{end+1} = localInputs; | |
%strjoin(code, char(10)) | |
%code{end+1} = sprintf(fuzzySet, inputs(1).mf.name, strjoin(num2str(inputs(1).mf.params), ', ')) | |
end | |
code{end+1} = '//'; | |
end | |
function [code, names] = eFLLInOutInitGen(funs, inOut) | |
code = {}; | |
names = {}; | |
if inOut | |
code{end+1} = '//FuzzyInputs'; | |
else | |
code{end+1} = '//FuzzyOutputs'; | |
end | |
for k = 1 : length(funs) | |
item = funs{k}; | |
%item = item{:}(1); | |
name = strsplit(item{1}, '_'); | |
name = name(1); | |
names{end+1} = name{:}; | |
if inOut | |
code{end+1} = sprintf('FuzzyInput *%s = new FuzzyInput(%s);', name{:}, num2str(k)); | |
else | |
code{end+1} = sprintf('FuzzyOutput *%s = new FuzzyOutput(%s);', name{:}, num2str(k)); | |
end | |
itter = funs{k}; | |
for j = 1 : length(itter) | |
item = itter{j}; | |
code{end+1} = sprintf('%s->addFuzzySet(%s);', name{:}, item); | |
end | |
if inOut | |
code{end+1} = sprintf('fuzzy->addFuzzyInput(%s);', name{:}); | |
else | |
code{end+1} = sprintf('fuzzy->addFuzzyOutput(%s);', name{:}); | |
end | |
end | |
code{end+1} = '//'; | |
end | |
function code = eFLLRuleGen(rules, in, out, names) | |
code = {}; | |
code{end+1} = '//FuzzyRules'; | |
ifConds = {}; | |
thenConds = {}; | |
for k = 1 : length(rules) | |
item = rules(k); | |
if item.antecedent(2) == 0 | |
inputName = names{1}; | |
outputName = names{2}; | |
inputSetName = in{1}; | |
outputSetName = out{1}; | |
single = inputSetName(item.antecedent(1)); | |
addOutput = outputSetName(abs(item.consequent)); | |
ifCond = sprintf('if%s%s', uppercase(inputName(1)), uppercase(single)); | |
thenCond = sprintf('then%s%s', uppercase(outputName(1)), uppercase(addOutput)); | |
fuzzyRule = sprintf('fuzzyRule%s', num2str(k)); | |
code{end+1} = '//'; | |
code{end+1} = sprintf('// Building FuzzyRule "IF %s = %s THEN %s = %s"', uppercase(inputName(1)), uppercase(single), uppercase(outputName(1)), uppercase(addOutput)); | |
if ~any(strcmp(ifConds, ifCond)) | |
code{end+1} = sprintf('FuzzyRuleAntecedent *%s = new FuzzyRuleAntecedent();', ifCond); | |
ifConds{end+1} = ifCond; | |
end | |
code{end+1} = sprintf('%s->joinSingle(%s);', ifCond, single{:}); | |
if ~any(strcmp(thenConds, thenCond)) | |
code{end+1} = sprintf('FuzzyRuleConsequent *%s = new FuzzyRuleConsequent();', thenCond); | |
thenConds{end+1} = thenCond; | |
end | |
code{end+1} = sprintf('%s->addOutput(%s);', thenCond, addOutput{:}); | |
code{end+1} = sprintf('FuzzyRule *%s =new FuzzyRule(1, %s, %s);', fuzzyRule, ifCond, thenCond); | |
code{end+1} = sprintf('fuzzy->addFuzzyRule(%s);', fuzzyRule); | |
end | |
end | |
code{end+1} = '//'; | |
end | |
function code = eFLLloopGen(inputs, outputs, inOutNames) | |
code = {}; | |
code{end+1} = '//'; | |
for k = 1 : length(inOutNames{1}) | |
names = inOutNames{1}; | |
code{end+1} = sprintf('Serial.print("\t\t\t%s: ");', names{k}); | |
code{end+1} = sprintf('float %s = random(0, 100)/100.0;', names{k}); | |
code{end+1} = sprintf('Serial.println(%s);', names{k}); | |
code{end+1} = sprintf('fuzzy->setInput(%s, %s);', num2str(k), names{k}); | |
end | |
code{end+1} = 'fuzzy->fuzzify();'; | |
for k = 1 : length(inOutNames{2}) | |
names = inOutNames{2}; | |
code{end+1} = sprintf('float %s = fuzzy->defuzzify(%s);', names{k}, num2str(k)); | |
code{end+1} = sprintf('Serial.print("\t\t\t%s: ");', names{k}); | |
code{end+1} = sprintf('Serial.println(%s);', names{k}); | |
end | |
code{end+1} = 'delay(12000);'; | |
code{end+1} = '//'; | |
end | |
function out = uppercase(text) | |
text = text{:}; | |
out = [upper(text(1)), lower(text(2:length(text)))]; | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment