//***********************************************************************
// Matlab .fis to arduino C converter v2.0.1.25122016
// - Karthik Nadig, USA
// Please report bugs to:
// https://github.com/karthiknadig/ArduinoFIS/issues
// If you don't have a GitHub account mail to karthiknadig@gmail.com
//***********************************************************************
#include "fis_header.h"
String A, B;
// Number of inputs to the fuzzy inference system
const int fis_gcI = 2;
// Number of outputs to the fuzzy inference system
const int fis_gcO = 1;
// Number of rules to the fuzzy inference system
const int fis_gcR = 9;
FIS_TYPE g_fisInput[fis_gcI];
FIS_TYPE g_fisOutput[fis_gcO];
// Setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
// initialize the Analog pins for input.
// Pin mode for Input: input1
pinMode(0 , INPUT);
// Pin mode for Input: input2
pinMode(1 , INPUT);
// initialize the Analog pins for output.
// Pin mode for Output: output
pinMode(2 , OUTPUT);
}
// Loop routine runs over and over again forever:
void loop() {
if (Serial.available()) {
String justRates = Serial.readStringUntil('\n');
int aSpaceIndex = justRates.indexOf(",");
int bSpaceIndex = justRates.indexOf(",", aSpaceIndex + 1);
A = (justRates.substring(0, aSpaceIndex));
B = (justRates.substring(aSpaceIndex + 1, bSpaceIndex));
int x = A.toInt();
int y = B.toInt();
Serial.println("A : " + String(A) + " B : " + String(B));
// Read Input: input1
g_fisInput[0] = x;
// Read Input: input2
g_fisInput[1] = y;
g_fisOutput[0] = 0;
fis_evaluate();
// Set output vlaue: output
analogWrite(2 , g_fisOutput[0]);
Serial.println(g_fisOutput[0]);
}
}
//***********************************************************************
// Support functions for Fuzzy Inference System
//***********************************************************************
// Gaussian Member Function
FIS_TYPE fis_gaussmf(FIS_TYPE x, FIS_TYPE* p)
{
FIS_TYPE s = p[0], c = p[1];
FIS_TYPE t = (x - c) / s;
return exp(-(t * t) / 2);
}
FIS_TYPE fis_prod(FIS_TYPE a, FIS_TYPE b)
{
return (a * b);
}
FIS_TYPE fis_probor(FIS_TYPE a, FIS_TYPE b)
{
return (a + b - (a * b));
}
FIS_TYPE fis_sum(FIS_TYPE a, FIS_TYPE b)
{
return (a + b);
}
FIS_TYPE fis_array_operation(FIS_TYPE *array, int size, _FIS_ARR_OP pfnOp)
{
int i;
FIS_TYPE ret = 0;
if (size == 0) return ret;
if (size == 1) return array[0];
ret = array[0];
for (i = 1; i < size; i++)
{
ret = (*pfnOp)(ret, array[i]);
}
return ret;
}
//***********************************************************************
// Data for Fuzzy Inference System
//***********************************************************************
// Pointers to the implementations of member functions
_FIS_MF fis_gMF[] =
{
fis_gaussmf
};
// Count of member function for each Input
int fis_gIMFCount[] = { 3, 3 };
// Count of member function for each Output
int fis_gOMFCount[] = { 9 };
// Coefficients for the Input Member Functions
FIS_TYPE fis_gMFI0Coeff1[] = { 2.06130253937487, 0.246877358937878 };
FIS_TYPE fis_gMFI0Coeff2[] = { 1.55130611406437, 5.64719384224608 };
FIS_TYPE fis_gMFI0Coeff3[] = { 0.756873995521849, 27.000838863279 };
FIS_TYPE* fis_gMFI0Coeff[] = { fis_gMFI0Coeff1, fis_gMFI0Coeff2, fis_gMFI0Coeff3 };
FIS_TYPE fis_gMFI1Coeff1[] = { 142.009256148267, 390.581074772965 };
FIS_TYPE fis_gMFI1Coeff2[] = { 140.906651425662, 722.503198624614 };
FIS_TYPE fis_gMFI1Coeff3[] = { 141.931284820756, 1054.44632396324 };
FIS_TYPE* fis_gMFI1Coeff[] = { fis_gMFI1Coeff1, fis_gMFI1Coeff2, fis_gMFI1Coeff3 };
FIS_TYPE** fis_gMFICoeff[] = { fis_gMFI0Coeff, fis_gMFI1Coeff };
// Coefficients for the Output Member Functions
FIS_TYPE fis_gMFO0Coeff1[] = { 0, 0, 4.18244207402222 };
FIS_TYPE fis_gMFO0Coeff2[] = { 0, 0, 1.44961297726191 };
FIS_TYPE fis_gMFO0Coeff3[] = { 0, 0, -0.368050242260879 };
FIS_TYPE fis_gMFO0Coeff4[] = { 0, 0, 4.33138615173981 };
FIS_TYPE fis_gMFO0Coeff5[] = { 0, 0, 1.5928210476751 };
FIS_TYPE fis_gMFO0Coeff6[] = { 0, 0, -0.448924883325473 };
FIS_TYPE fis_gMFO0Coeff7[] = { 0, 0, -0.00652070543486851 };
FIS_TYPE fis_gMFO0Coeff8[] = { 0, 0, -0.0137518922235143 };
FIS_TYPE fis_gMFO0Coeff9[] = { 0, 0, -0.337080359760686 };
FIS_TYPE* fis_gMFO0Coeff[] = { fis_gMFO0Coeff1, fis_gMFO0Coeff2, fis_gMFO0Coeff3, fis_gMFO0Coeff4, fis_gMFO0Coeff5, fis_gMFO0Coeff6, fis_gMFO0Coeff7, fis_gMFO0Coeff8, fis_gMFO0Coeff9 };
FIS_TYPE** fis_gMFOCoeff[] = { fis_gMFO0Coeff };
// Input membership function set
int fis_gMFI0[] = { 0, 0, 0 };
int fis_gMFI1[] = { 0, 0, 0 };
int* fis_gMFI[] = { fis_gMFI0, fis_gMFI1};
// Output membership function set
int* fis_gMFO[] = {};
// Rule Weights
FIS_TYPE fis_gRWeight[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
// Rule Type
int fis_gRType[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
// Rule Inputs
int fis_gRI0[] = { 1, 1 };
int fis_gRI1[] = { 1, 2 };
int fis_gRI2[] = { 1, 3 };
int fis_gRI3[] = { 2, 1 };
int fis_gRI4[] = { 2, 2 };
int fis_gRI5[] = { 2, 3 };
int fis_gRI6[] = { 3, 1 };
int fis_gRI7[] = { 3, 2 };
int fis_gRI8[] = { 3, 3 };
int* fis_gRI[] = { fis_gRI0, fis_gRI1, fis_gRI2, fis_gRI3, fis_gRI4, fis_gRI5, fis_gRI6, fis_gRI7, fis_gRI8 };
// Rule Outputs
int fis_gRO0[] = { 1 };
int fis_gRO1[] = { 2 };
int fis_gRO2[] = { 3 };
int fis_gRO3[] = { 4 };
int fis_gRO4[] = { 5 };
int fis_gRO5[] = { 6 };
int fis_gRO6[] = { 7 };
int fis_gRO7[] = { 8 };
int fis_gRO8[] = { 9 };
int* fis_gRO[] = { fis_gRO0, fis_gRO1, fis_gRO2, fis_gRO3, fis_gRO4, fis_gRO5, fis_gRO6, fis_gRO7, fis_gRO8 };
// Input range Min
FIS_TYPE fis_gIMin[] = { -4.4, 390 };
// Input range Max
FIS_TYPE fis_gIMax[] = { 42.1, 1055 };
// Output range Min
FIS_TYPE fis_gOMin[] = { 0 };
// Output range Max
FIS_TYPE fis_gOMax[] = { 4 };
//***********************************************************************
// Data dependent support functions for Fuzzy Inference System
//***********************************************************************
// None for Sugeno
//***********************************************************************
// Fuzzy Inference System
//***********************************************************************
void fis_evaluate()
{
FIS_TYPE fuzzyInput0[] = { 0, 0, 0 };
FIS_TYPE fuzzyInput1[] = { 0, 0, 0 };
FIS_TYPE* fuzzyInput[fis_gcI] = { fuzzyInput0, fuzzyInput1, };
FIS_TYPE fuzzyOutput0[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
FIS_TYPE* fuzzyOutput[fis_gcO] = { fuzzyOutput0, };
FIS_TYPE fuzzyRules[fis_gcR] = { 0 };
FIS_TYPE fuzzyFires[fis_gcR] = { 0 };
FIS_TYPE* fuzzyRuleSet[] = { fuzzyRules, fuzzyFires };
FIS_TYPE sW = 0;
// Transforming input to fuzzy Input
int i, j, r, o;
for (i = 0; i < fis_gcI; ++i)
{
for (j = 0; j < fis_gIMFCount[i]; ++j)
{
fuzzyInput[i][j] =
(fis_gMF[fis_gMFI[i][j]])(g_fisInput[i], fis_gMFICoeff[i][j]);
}
}
int index = 0;
for (r = 0; r < fis_gcR; ++r)
{
if (fis_gRType[r] == 1)
{
fuzzyFires[r] = 1;
for (i = 0; i < fis_gcI; ++i)
{
index = fis_gRI[r][i];
if (index > 0)
fuzzyFires[r] = fis_prod(fuzzyFires[r], fuzzyInput[i][index - 1]);
else if (index < 0)
fuzzyFires[r] = fis_prod(fuzzyFires[r], 1 - fuzzyInput[i][-index - 1]);
else
fuzzyFires[r] = fis_prod(fuzzyFires[r], 1);
}
}
else
{
fuzzyFires[r] = 0;
for (i = 0; i < fis_gcI; ++i)
{
index = fis_gRI[r][i];
if (index > 0)
fuzzyFires[r] = fis_probor(fuzzyFires[r], fuzzyInput[i][index - 1]);
else if (index < 0)
fuzzyFires[r] = fis_probor(fuzzyFires[r], 1 - fuzzyInput[i][-index - 1]);
else
fuzzyFires[r] = fis_probor(fuzzyFires[r], 0);
}
}
fuzzyFires[r] = fis_gRWeight[r] * fuzzyFires[r];
sW += fuzzyFires[r];
}
if (sW == 0)
{
for (o = 0; o < fis_gcO; ++o)
{
g_fisOutput[o] = ((fis_gOMax[o] + fis_gOMin[o]) / 2);
}
}
else
{
for (o = 0; o < fis_gcO; ++o)
{
FIS_TYPE sWI = 0.0;
for (j = 0; j < fis_gOMFCount[o]; ++j)
{
fuzzyOutput[o][j] = fis_gMFOCoeff[o][j][fis_gcI];
for (i = 0; i < fis_gcI; ++i)
{
fuzzyOutput[o][j] += g_fisInput[i] * fis_gMFOCoeff[o][j][i];
}
}
for (r = 0; r < fis_gcR; ++r)
{
index = fis_gRO[r][o] - 1;
sWI += fuzzyFires[r] * fuzzyOutput[o][index];
}
g_fisOutput[o] = sWI / sW;
}
}
}