Skip to content

Instantly share code, notes, and snippets.

@sash13
Last active February 27, 2020 13:30
Show Gist options
  • Save sash13/62164733f72e8d902be0afa2bc2d4b72 to your computer and use it in GitHub Desktop.
Save sash13/62164733f72e8d902be0afa2bc2d4b72 to your computer and use it in GitHub Desktop.
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')
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