Suppose that i've created the following Fuzzy control in Matlab, where the output will be the number of time in seconds.
And from googling so many time, i found this useful website that can translate the Fuzzy control from Matlab to C code that is useable to Arduino. Here's the link: http://makeproto.com/blog/?p=35
I name my Matlab file as tankps.fis. Here's the translated code in C:
- CODE: SELECT_ALL_CODE
#include "tankps.h"
// Not Function
float _not(float x)
{
return (float)(1.0-x);
}
// Generates the values in the range [min,max] with increments
// defined by 'step'.
void generate(float minimum, float maximum, float st, float* values,int length)
{
float x = minimum;
int i;
for(i=0;i<length;i++,x+=st)
values[i] = x;
}
// Sets all elements in the array with the same value
void set(float* values,int length,float value)
{
int i;
for(i=0;i<length;i++)
values[i] = value;
}
// Product of elements in an array
float prod_array(float* x, int length)
{
float m = 1;
int i=0;
for(;i<length;i++)
m *= x[i];
return m;
}
// Probabilistic OR
float probor(float* x, int length)
{
float m = 0;
int i=0;
for(;i<length;i++)
m = m + x[i] - m*x[i];
return m;
}
// Centroid of points
void centroid(float* x, float* y, int length, float* Cx, float* Cy)
{
float a = 0;
float tx = 0;
// float ty = 0;
float t = 0;
int i = 0;
int l = length - 1;
for(;i<l;i++)
{
t = ((x[i] * y[i+1]) - (x[i+1] * y[i]));
a += t/2;
tx = (x[i] + x[i+1]) * t;
// ty = (y[i] + y[i+1]) * t;
}
*Cx = (tx /(6 * a));
// *Cy = (ty /(6 * a));
}
// Gaussian Member Function
float gaussmf(float x, float s, float c)
{
float t = x-c;
return _exp(-(t * t) / (2 * s * s));
}
// Triangular Member Function
float trimf(float x, float a, float b, float c)
{
return (float)max(min((x - a) / (b - a), (c - x) / (c - b)), 0);
}
// Aggregation code for membership functions that require 2 setting values
void aggregate2(float* rules, int* ruleIndexes, int ruleIndexLength, float* xArr, float *yArr, int resultLength,_mffloat2 mf,float a,float b)
{
int i=0, j=0;
for(;i<resultLength;i++)
{
for(j=0;j<ruleIndexLength;j++)
{
float t = rules[ruleIndexes[j]] * mf(xArr[i],a,b);
yArr[i] = yArr[i] + t - yArr[i]*t;
}
}
}
// Aggregation code for membership functions that require 3 setting values
void aggregate3(float* rules, int* ruleIndexes, int ruleIndexLength, float* xArr, float *yArr, int resultLength,_mffloat3 mf,float a,float b,float c)
{
int i=0, j=0;
for(;i<resultLength;i++)
{
for(j=0;j<ruleIndexLength;j++)
{
float t = rules[ruleIndexes[j]] * mf(xArr[i],a,b,c);
yArr[i] = yArr[i] + t - yArr[i]*t;
}
}
}
void tankps(float* inputs, float* outputs)
{ // Transformation of inputs to fuzzy inputs.
// Input variable input
float Inputs1[3];
// Input term 'sink'for variable 'input'
Inputs1[0] = gaussmf(inputs[0],0.3,-1);
// Input term 'null'for variable 'input'
Inputs1[1] = gaussmf(inputs[0],0.3,-2.776E-17);
// Input term 'rise'for variable 'input'
Inputs1[2] = gaussmf(inputs[0],0.2998,1);
// Input variable level
float Inputs2[3];
// Input term 'sinking'for variable 'level'
Inputs2[0] = gaussmf(inputs[1],0.03,-0.1);
// Input term 'none'for variable 'level'
Inputs2[1] = gaussmf(inputs[1],0.03,-1.301E-18);
// Input term 'rising'for variable 'level'
Inputs2[2] = gaussmf(inputs[1],0.02998,0.1);
// Build all the conditions.
// Variable to store the condition result
float R[5];
float CondR[2];
// Handle conditions for rule 1
CondR[0] = Inputs1[1];
R[0] = 1 * prod_array(CondR,1);
// Handle conditions for rule 2
CondR[0] = Inputs1[2];
R[1] = 1 * prod_array(CondR,1);
// Handle conditions for rule 3
CondR[0] = Inputs1[0];
R[2] = 1 * prod_array(CondR,1);
// Handle conditions for rule 4
CondR[0] = Inputs1[1];
CondR[1] = Inputs2[2];
R[3] = 1 * prod_array(CondR,2);
// Handle conditions for rule 5
CondR[0] = Inputs1[1];
CondR[1] = Inputs2[0];
R[4] = 1 * prod_array(CondR,2);
// Basic output processing
int res = 100;
float step;
float xMin;
float xMax;
float x[res];
float y[res];
float t;
int value[5];
// Output variable valve
xMin = 0;
xMax = 10;
t=0;
step = (xMax - xMin) / (float)(res - 1);
generate(xMin, xMax, step, x, res);
set(y, res, 0);
value[0] = 2;
aggregate3(R,value,1,x,y,res,trimf,0,0.5,1);
value[0] = 3;
aggregate3(R,value,1,x,y,res,trimf,2,2.5,3);
value[0] = 0;
aggregate3(R,value,1,x,y,res,trimf,4.5,5,5.5);
value[0] = 4;
aggregate3(R,value,1,x,y,res,trimf,6,6.5,7);
value[0] = 1;
aggregate3(R,value,1,x,y,res,trimf,9,9.5,10);
centroid(x, y, res, &outputs[0], &t);
}
Well now my problem is, i don't know how to access the inputs and output of the translated code. The instruction given (on the link) in step 5 is to create an array of inputs and an array of outputs. I don't understand the step 6, which it says:
Call the system function with a pointer to the inputs and a pointer to the outputs (the function will have the same name as your .FIS file).
HELP please! =(