Fuzzy Logic to C

Talk about Arduino board, sheilds. Sharing Arduino projects, program, problems, solutions, suggestions..... many more, all are welcome.

Fuzzy Logic to C

Postby JDM » Wed Oct 31, 2012 7:09 am

Hi everyone.

Suppose that i've created the following Fuzzy control in Matlab, where the output will be the number of time in seconds.

Picture1.png

6.JPG
6.JPG (49.14 KiB) Viewed 2555 times



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! =(
JDM
Novice
 
Posts: 16
Joined: Thu Oct 25, 2012 4:18 pm

Return to Arduino Based

Who is online

Users browsing this forum: No registered users and 12 guests

cron