Ernesto Palacios
/
Fuzzy
Revision 0:252f423535e5, committed 2011-03-20
- Comitter:
- Yo_Robot
- Date:
- Sun Mar 20 04:20:47 2011 +0000
- Commit message:
- v0.1 - still under test
Changed in this revision
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