Hope your'e all in the best of your health and spirits.
I am encountering a small problem with the code of Fuzzy logic I generated through this website:
http://www.makeproto.com/projects/fuzzy/matlab_arduino_FIST/index.php
There seems to be a definition problem with the problem. I am posting the code here.
This is the header file.
typedef float (*_mffloat2)(float,float,float);
typedef float (*_mffloat3)(float,float,float,float);
typedef float (*_mffloat4)(float,float,float,float,float);
typedef double (*_mfdouble2)(double,double,double);
typedef double (*_mfdouble3)(double,double,double,double);
typedef double (*_mfdouble4)(double,double,double,double,double);
#define M_LN2 0.693147180559945309417
union
{
double d;
struct{ int j,i;}n;
}_eco;
#define EXP_A (1048576/M_LN2)
#define EXP_C 60801
#define _exp(y) (_eco.n.i = EXP_A * (y) + (1072693248 - EXP_C), _eco.d)
Here is the actual code.
You need to go only to the Aggregate3 function. where my compiler says that "_mmfloat3" has not been declared. I have the header file copied in the sketch folder. Please any help with this would be appreciated.
#include <fuzzyadilspeedorignal.h>
#include <Servo.h>
Servo myservo; //create servo object
int pos = 0; //servo position
int inputs[] = {0, 45, 90, 135, 180}; //positions (in degrees) to send to the servo
int outputs[] = {0, 0, 0, 0, 0};
int numPositions = 5;
void setup()
{
//control servo via pin 9
myservo.attach(9, 750, 2550);
//start serial comm. for debugging
Serial.begin(9600);
}
// 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;
}
// Returns the smallest element of an array
float min_array(float* x, int length)
{
if(length <= 0) return (float)0;
float m = x[0];
int i=1;
for(;i<length;i++)
m = min(m,x[i]);
return m;
}
// Returns the largest element of an array
float max_array(float* x, int length)
{
if(length <= 0) return (float)0;
float m = x[0];
int i=1;
for(;i<length;i++)
m = max(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));
}
// 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 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++)
{yArr[i] = max(yArr[i],min(rules[ruleIndexes[j]],mf(xArr[i],a,b,c)));}
}
}
void fuzzyadilspeedorignal(float* Inputs, float* outputs)
{ // Transformation of inputs to fuzzy inputs.
// Input variable error_e
float Inputs1[7];
// Input term 'NB'for variable 'error_e'
Inputs1[0] = trimf(inputs[0],-1.333,-1,-0.55);
// Input term 'NM'for variable 'error_e'
Inputs1[1] = trimf(inputs[0],-1,-0.55,-0.2);
// Input term 'NS'for variable 'error_e'
Inputs1[2] = trimf(inputs[0],-0.55,-0.2,0);
// Input term 'Z'for variable 'error_e'
Inputs1[3] = trimf(inputs[0],-0.2,0,0.2);
// Input term 'PS'for variable 'error_e'
Inputs1[4] = trimf(inputs[0],0,0.2,0.55);
// Input term 'PM'for variable 'error_e'
Inputs1[5] = trimf(inputs[0],0.2,0.55,1);
// Input term 'PB'for variable 'error_e'
Inputs1[6] = trimf(inputs[0],0.55,1,1.334);
// Build all the conditions.
// Variable to store the condition result
float R[49];
float CondR[1];
// Handle conditions for rule 1
CondR[0] = Inputs1[0];
R[0] = 1 * min_array(CondR,1);
// Handle conditions for rule 2
CondR[0] = Inputs1[0];
R[1] = 1 * min_array(CondR,1);
// Handle conditions for rule 3
CondR[0] = Inputs1[0];
R[2] = 1 * min_array(CondR,1);
// Handle conditions for rule 4
CondR[0] = Inputs1[0];
R[3] = 1 * min_array(CondR,1);
// Handle conditions for rule 5
CondR[0] = Inputs1[0];
R[4] = 1 * min_array(CondR,1);
// Handle conditions for rule 6
CondR[0] = Inputs1[0];
R[5] = 1 * min_array(CondR,1);
// Handle conditions for rule 7
CondR[0] = Inputs1[0];
R[6] = 1 * min_array(CondR,1);
// Handle conditions for rule 8
CondR[0] = Inputs1[1];
R[7] = 1 * min_array(CondR,1);
// Handle conditions for rule 9
CondR[0] = Inputs1[1];
R[8] = 1 * min_array(CondR,1);
// Handle conditions for rule 10
CondR[0] = Inputs1[1];
R[9] = 1 * min_array(CondR,1);
// Handle conditions for rule 11
CondR[0] = Inputs1[1];
R[10] = 1 * min_array(CondR,1);
// Handle conditions for rule 12
CondR[0] = Inputs1[1];
R[11] = 1 * min_array(CondR,1);
// Handle conditions for rule 13
CondR[0] = Inputs1[1];
R[12] = 1 * min_array(CondR,1);
// Handle conditions for rule 14
CondR[0] = Inputs1[1];
R[13] = 1 * min_array(CondR,1);
// Handle conditions for rule 15
CondR[0] = Inputs1[2];
R[14] = 1 * min_array(CondR,1);
// Handle conditions for rule 16
CondR[0] = Inputs1[2];
// Basic output processing
int res = 100;
float step;
float xMin;
float xMax;
float x[res];
float y[res];
float t;
int value[49];
// Output variable Outputcontrol
xMin = -1;
xMax = 1;
t=0;
step = (xMax - xMin) / (float)(res - 1);
generate(xMin, xMax, step, x, res);
set(y, res, 0);
value[0] = 0;
value[1] = 1;
value[2] = 2;
value[3] = 3;
value[4] = 7;
value[5] = 8;
value[6] = 9;
value[7] = 14;
value[8] = 15;
value[9] = 21;
aggregate3(R,value,10,x,y,res,trimf,-1.25,-1,-0.6);
value[0] = 4;
value[1] = 10;
value[2] = 16;
value[3] = 22;
value[4] = 28;
aggregate3(R,value,5,x,y,res,trimf,-1,-0.6,-0.33);
value[0] = 5;
value[1] = 11;
value[2] = 17;
value[3] = 23;
value[4] = 29;
value[5] = 30;
value[6] = 35;
aggregate3(R,value,7,x,y,res,trimf,-0.6,-0.27,0);
value[0] = 6;
value[1] = 12;
value[2] = 18;
value[3] = 24;
value[4] = 31;
value[5] = 36;
value[6] = 42;
aggregate3(R,value,7,x,y,res,trimf,-0.2,0,0.2);
value[0] = 13;
value[1] = 19;
value[2] = 25;
value[3] = 32;
value[4] = 37;
value[5] = 43;
value[6] = 44;
aggregate3(R,value,7,x,y,res,trimf,0,0.27,0.6);
value[0] = 20;
value[1] = 26;
value[2] = 33;
value[3] = 38;
value[4] = 45;
aggregate3(R,value,5,x,y,res,trimf,0.33,0.6,1);
value[0] = 27;
value[1] = 34;
value[2] = 39;
value[3] = 40;
value[4] = 41;
value[5] = 46;
value[6] = 47;
value[7] = 48;
aggregate3(R,value,8,x,y,res,trimf,0.6,1,1.25);
centroid(x, y, res, &outputs[0], &t);
}
void loop()
{
int i = 0;
//iterate over positions
fuzzyadilspeedorignal(inputs, outputs);
for(i = 0; i < numPositions; i++)
{
pos = outputs[i];
//print debug output
Serial.println("SETTING:");
Serial.println(pos);
//tell servo to set the new position
myservo.write(pos);
//wait for two seconds
delay(2000);
}
}