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

Files at this revision

API Documentation at this revision

Comitter:
Yo_Robot
Date:
Sun Mar 20 04:20:47 2011 +0000
Commit message:
v0.1 - still under test

Changed in this revision

Fuzzy.cpp Show annotated file Show diff for this revision Revisions of this file
Fuzzy.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 252f423535e5 Fuzzy.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Fuzzy.cpp	Sun Mar 20 04:20:47 2011 +0000
@@ -0,0 +1,186 @@
+#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" );
+   
+ }
+ 
+ 
+ 
+ 
+ 
+ 
+ 
diff -r 000000000000 -r 252f423535e5 Fuzzy.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Fuzzy.h	Sun Mar 20 04:20:47 2011 +0000
@@ -0,0 +1,79 @@
+#include "mbed.h"
+
+/* ===================-  STRUCTURES -=========================================== */
+
+struct limitStr             /* Limits of each Fuzzy Member */
+{
+  float low_;    /* Lower limit of the Member                  /\                */
+  float mid_;    /* Center of the Member                      /  \               */
+  float high_;   /* Higher limit of the Member               /  | \              */ 
+                /*                                     low /  mid \ high        */
+ };             /*                                                              */
+                /*                                                              */
+struct areaStr
+{
+  float left_;     /* values of the areas of each member */
+  float center_;
+  float right_;
+};
+
+enum limitEnum   // public enum constructor
+{
+  limit_low1,
+  limit_mid1,
+  limit_low2,
+  limit_mid2,
+  limit_high
+};
+    
+/* ===================- FUZZY CLASS -=========================================== */
+class Fuzzy
+{
+  public:
+    
+    void  setMember( float low1, float mid1, float low2, float mid2, float hi );
+    limitEnum limit;             // Enumerated names of the limits
+    float read( limitEnum element );
+    float getValue ( float x, Fuzzy Output );
+    float getValue ( float x, float y, Fuzzy memberX, Fuzzy memberY, Fuzzy output );
+    void  printArt();
+  
+  private:
+    
+    limitStr         left, center, right;    // Holds the values
+    areaStr          Area;                     // 
+    
+    float fuzz( float value, limitStr member );
+  /* ****************************************************************************** *
+   * Fuzzifier (Fusificador):                                                       *
+   * This Function calculates the degree of membership of the 'value' passed in the *
+   * 'member' function it belongs to.                                               *
+   *                                                                                *
+   * 'value' = any float form 'low1' to 'hi' of that particular member              *
+   * ****************************************************************************** */
+    
+    float min( float x1, float x2 );
+    /* *************************************************************************** *
+     * Calculates the minimum value of the two arguments                           *
+     * *************************************************************************** */
+         
+    float max( float x1, float x2, float x3 );
+    /* *************************************************************************** *
+     * Calculates the maximum value of the three arguments                         *
+     * *************************************************************************** */
+    
+    void calculateArea( float n, float z, float p , Fuzzy Output );
+    /* *************************************************************************** *
+     * Calculates the area of the given value to the Output Membership             *
+     * 'n' Negative Function
+     * 'z' Zero Function
+     * 'p' Positive Function
+     * *************************************************************************** */
+    
+     float defuzz( Fuzzy Output );
+     /* *************************************************************************** *
+      * This function calculates the final output to return, The object already     *
+      * the values defined, it needs an Oputput membership to generate a return     *
+      * value                                                                       * 
+      * *************************************************************************** */
+};
\ No newline at end of file
diff -r 000000000000 -r 252f423535e5 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Mar 20 04:20:47 2011 +0000
@@ -0,0 +1,152 @@
+#include "mbed.h"
+#include "Fuzzy.h"
+ 
+Serial pc ( USBTX,USBRX );   /* Global Variable for debugging purposes PC */
+
+void printMenu();
+void setLimits( Fuzzy &Member ); 
+void SimpleFuzzy( Fuzzy &Input, Fuzzy &Output );
+void DoubleFuzzy( Fuzzy &MemberX, Fuzzy &MemberY, Fuzzy &Output );
+
+int main() 
+{
+    char ch;
+    Fuzzy Error;
+    Fuzzy Dt;
+    Fuzzy PWM;
+    Error.printArt();
+    printMenu();
+    do
+    {
+      ch = pc.getc();
+      pc.printf( "%c", ch );
+      switch ( ch )
+      {
+        case '1':
+          setLimits( Error );
+          break;
+        
+        case '2':
+          setLimits( Dt );
+          break;
+        
+        case '3':
+          setLimits( PWM );
+          break;
+        
+        case '4':
+          SimpleFuzzy( Error, PWM );
+          break;
+        
+        case '5':
+          DoubleFuzzy( Error, Dt, PWM );
+          break;
+        
+        case '6':
+          pc.printf( "\n--------end-----------------" );
+          break;
+      }
+    }while( ch != '6' );
+}
+
+
+void setLimits( Fuzzy &Member )
+{
+  float low1, mid1, low2, mid2, hi;
+  
+  pc.printf( "\nlow1 = " );
+  pc.scanf( "%f", &low1 );
+  pc.printf( "%f",low1 );
+  
+  pc.printf( "\nmid1 = " );
+  pc.scanf( "%f", &mid1 );
+  pc.printf( "%f",mid1 );
+  
+  pc.printf( "\nlow2 = " );
+  pc.scanf( "%f", &low2 );
+  pc.printf( "%f",low2 );
+  
+  pc.printf( "\nmid2 = " );
+  pc.scanf( "%f", &mid2 );
+  pc.printf( "%f",mid2 );
+  
+  pc.printf( "\nhigh = " );
+  pc.scanf( "%f", &hi);
+  pc.printf( "%f",hi );
+  
+  Member.setMember( low1, mid1, low2, mid2, hi );
+}
+
+
+void SimpleFuzzy( Fuzzy &Input, Fuzzy &Output )
+{
+  float value_in, value_out, read_input1, read_input2;
+  do
+  {
+    Input.limit = limit_low1;
+    read_input1 = Input.read( Input.limit );
+    
+    Input.limit = limit_high;
+    read_input2 = Input.read( Input.limit );
+    
+    pc.printf( "\n Give a value between %f and %f : ", read_input1, read_input2 );
+    pc.scanf( "%f", &value_in );
+    pc.printf("%f", value_in);
+      
+  }while ( !( value_in > read_input1    &&   value_in < read_input2 ) );  // Within Limits 
+  
+  value_out = Input.getValue( value_in, Output );
+  pc.printf( "\nFor value %f, your output is %f.", value_in, value_out );
+  
+}
+
+void DoubleFuzzy( Fuzzy &MemberX, Fuzzy &MemberY, Fuzzy &Output )
+{
+  float valueX, valueY, valueOut, read_input1, read_input2;
+  
+  do
+  {
+    MemberX.limit = limit_low1;
+    read_input1 = MemberX.read( MemberX.limit );
+    
+    MemberX.limit = limit_high;
+    read_input2 = MemberX.read( MemberX.limit );
+    
+    pc.printf( "\n Give a value between %f and %f : ", read_input1, read_input2 );
+    pc.scanf( "%f", &valueX );
+    pc.printf("%f", valueX);
+       
+  }while ( !( valueX > read_input2    &&   valueX < read_input2 ) );  // Within Limits 
+    
+  do
+  {
+    
+    MemberY.limit = limit_low1;
+    read_input1 = MemberY.read( MemberY.limit );
+    
+    MemberY.limit = limit_high;
+    read_input2 = MemberY.read( MemberY.limit );
+    
+    pc.printf( "\n Give a value between %f and %f : ", read_input1, read_input2 );
+    pc.scanf( "%f", &valueY );
+    pc.printf("%f", valueY);
+        
+  }while ( !( valueY > read_input1    &&   valueY < read_input2 ) );  // Within Limits 
+    
+    valueOut = MemberX.getValue( valueX, valueY, MemberX, MemberY, Output );
+    pc.printf( "\nFor value %f and %f, your output is %f.", valueX, valueY, valueOut );
+  
+}
+
+void printMenu()
+{
+  pc.printf( "\n\n --== Fuzzy Logic ==--\n" );
+  pc.printf( "\nSelect an option: " );
+  pc.printf( "\n[1] Set Limits X" );
+  pc.printf( "\n[2] Set Limits Y" );
+  pc.printf( "\n[3] Set Limits Output" );
+  pc.printf( "\n[4] One Argument Fuzzy" );
+  pc.printf( "\n[5] Two Argument Fuzzy" );
+  pc.printf( "\n[6] Exit\n" );  
+}
+
diff -r 000000000000 -r 252f423535e5 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Mar 20 04:20:47 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912