This is my first 'big' mbed program so far, it is an implementation of fuzzy logic, the main.cpp is kind off a debugging program, to show how it works, I still have planned some enhancements, but any comment is well recieved, i\'m still learning What i'm looking forward in publishing this, is ways to improve the code, some general advices that may help write better code. Any comment post it here: http://mbed.org/users/Yo_Robot/notebook/fuzzy_logic/

Dependencies:   mbed

Fuzzy.cpp

Committer:
Yo_Robot
Date:
2011-03-20
Revision:
0:252f423535e5

File content as of revision 0:252f423535e5:

#include "Fuzzy.h"

extern Serial pc;

void Fuzzy::setMember( float low1, float mid1, float low2, float mid2, float hi )
{
  if( low1 < mid1 && mid1 < low2 && low2 < mid2 && mid2 < hi )
  {
     left.low_ = low1;      center.low_ = mid1;        right.low_ = low2;
     left.mid_ = mid1;      center.mid_ = low2;        right.mid_ = mid2;
     left.high_= low2;      center.high_= mid2;        right.high_= hi;
  }
  else
      pc.printf( "\nInvalid Limits Set them Again" );
}

float Fuzzy::read( limitEnum element )
{
  switch ( element )
  {
    case limit_low1:
      return left.low_;
      
    case limit_mid1:
      return left.mid_;
      
    case limit_low2:
      return left.high_;
      
    case limit_mid2:
      return right.mid_;
      
    case limit_high:
      return right.high_;
  }
  /* NO DEFAULT RETURN if requested an invalid number, stop the program */
}
 float Fuzzy::getValue( float x, Fuzzy Output )
 {
   float hLow, hMid, hHigh;
   
   hLow = fuzz( x, left );   /*  negative = Member Structure Negative */
   hMid = fuzz( x, center );
   hHigh= fuzz( x, right );
   
   calculateArea( hLow, hMid, hHigh, Output );   /* This Calcuates the areas and writes directly into the object */
   
   return defuzz( Output );  /* returns the Output value */
   
   /* So the program runs like this: When you create your Fuzzy Object and set the paramaters, you create
    * an structure that holds the limits of the three trianguls and another structures that holds the areas
    * of each of these trianguls according to a value given. 
    * 'x' can be error (x = set point - sensor), this functions first calculates the height of the  
    * triangul for all three trianguls, then passes these values (hLow, hMid, hHigh) to calculate the areas
    * and writes these areas in the object srtucture described above.
    * Finally to deffuz you only need an Output fuzzy object to set the limits desired to generate an output value
    * all other data necesary for the calculation is already whitin the structures of the object 
    */
 }
 
 float Fuzzy::getValue( float x, float y, Fuzzy memberX, Fuzzy memberY, Fuzzy Output )
 { 
   float hLowX, hMidX, hHighX;        /* Heights for Object X */
   float hLowY, hMidY, hHighY;       /* Heights for Object Y */
   float hLowLow, hLowMid, hLowHigh;
   float hMidLow, hMidMid, hMidHigh;
   float hHighLow,hHighMid,hHighHigh;
   float hLow, hMid, hHigh;
   
   hLowX = fuzz( x, memberX.left );
   hMidX = fuzz( x, memberX.center );
   hHighX= fuzz( x, memberX.right );
   
   hLowY = fuzz( y, memberY.left );
   hMidY = fuzz( y, memberY.center );
   hHighY= fuzz( y, memberY.right );
   
   hLowLow = min( hLowX, hLowY );
   hLowMid = min( hLowX, hMidY );
   hLowHigh= min( hLowX, hHighY );
   
   hMidLow = min( hMidX, hLowY );
   hMidMid = min( hMidX, hMidY );
   hMidHigh= min( hMidX, hHighY );
   
   hHighLow =min( hHighX, hLowY );
   hHighMid =min( hHighX, hMidY );
   hHighHigh=min( hHighX, hHighY);
   
   hLow = max( hLowLow, hMidLow, hHighLow );
   hMid = max( hLowMid, hMidMid, hHighMid );
   hHigh= max( hLowHigh,hMidHigh,hHighHigh);
   
   memberX.Area.left_    = hLow;
   memberX.Area.center_  = hMid;
   memberX.Area.right_   = hHigh;
   memberY.Area = memberX.Area;
   
   return memberX.defuzz( Output );
 }
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 float Fuzzy::fuzz( float value, limitStr member )
 {
   float return_value;     /* return value */
   
     if( value > member.low_ && value < member.mid_ )
       { return_value = 1 + ( value - member.mid_ )/( member.mid_ - member.low_ ); }
   
     else if( value > member.mid_ && value < member.high_ ) 
       { return_value = 1 - ( value - member.high_ )/( member.high_ - member.mid_ ); }
   
     else
       return_value = 0;
     
   return return_value;
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 float Fuzzy::min( float x1, float x2 )
 {
   if (x1 >= x2)
     return x1;
   else 
     return x2;
 }
 
 float Fuzzy::max( float x1, float x2, float x3 )
 {
   if( x1 >= x2 && x1 >= x3 )
       return x1;
   
   else if( x2 >= x1 && x2 >= x3)
       return x2;
       
   else if( x3 >= x1 && x3 >= x2)
       return x3;
    
    else
          return x2;
 }
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 void Fuzzy::calculateArea( float n, float z, float p , Fuzzy Output )
 {
   Area.left_   = ( n * ( Output.left.high_    - Output.left.low_ ) ) / 2.0 ;
   Area.right_  = ( p * ( Output.right.high_   - Output.right.low_ ) ) / 2.0 ;
   Area.center_ = ( z * ( Output.center.high_  - Output.center.low_ ) ) / 2.0 ;
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
float Fuzzy::defuzz( Fuzzy Output )
{
  float num, den;
  
  num = Area.left_ * Output.left.mid_ + Area.center_ * Output.center.mid_ + Area.right_ * Output.right.mid_;
  
  den = Area.left_ + Area.right_ + Area.center_ ;
  
  return ( num / den );
}
 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 void Fuzzy:: printArt()
 {
   pc.printf( "\n|        /\\      /\\      /\\ " );
   pc.printf( "\n|       /  \\    /  \\    /  \\ " );
   pc.printf( "\n|      /    \\  /    \\  /    \\ " );
   pc.printf( "\n|     /      \\/      \\/      \\ " );
   pc.printf( "\n|    /       /\\      /\\       \\ " );
   pc.printf( "\n|   /       /  \\    /  \\       \\ " );
   pc.printf( "\n|  /       /    \\  /    \\       \\ " );
   pc.printf( "\n| /       /      \\/      \\       \\ " );
   pc.printf( "\n--|-------|-------|-------|-------|- " );
   pc.printf( "\nlow1     mid1    low2    mid2    high \n" );
   
 }