![]() |
General Programming »
Algorithms & Recipes »
Fuzzy Logic
Intermediate
License: The Common Public License Version 1.0 (CPL)
Tagaki Sugeno Fuzzy System implementation in C#By Matthias ReichenbachSimple API to define your own Fuzzy System in C# based in the Tugaki-Sugeno Fuzzy System |
C#, .NET, Visual Studio, Architect, Dev
|
||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Recently I was assigned a project in my Artificial Intelligence Curse that required Fuzzy Logic to solve a simple problem. The idea was to have a Soccer Playing Robot that would go after the soccer ball given some simple Fuzzy Rules.
As usual, I started the project looking for some already made implementation of a fuzzy system (I know I know, but it works!). To my surprise, I found plenty of articles on the subject, but none providing a simple framework to build your own Fuzzy System.
Hence this article. The code provided here is not intended to be a complete implementation of a Fuzzy System, but rather be a good starting point for your own needs. As a bonus, I included the soccer playing robot as a sample of using the FuzzyLogic Namespace.
This is just a simple crash curse introduction to what Fuzzy Systems are. It is not mathematical nor formal centered, but rather very technical.
We all use Logic in our programming day, but that logic is one in which things are true or false. No in between. This works great for deterministic situations. Unfortunately, our mind doesn't work like that and rarely treats facts as completely true or completely false.
Fuzzy Logic aims at recreating how the mind works by eliminating the absolute true or false and giving degrees of membership. These allow you to have an idea of how much a variable is one value or the other.
Based on the research I had to do for the soccer playing robot, I drew these conclusions about what fuzzy systems are:
(direction, 80°) :== {(north, 0.9),(west,0),(south,0),(east,0.1)}
A Fuzzy Rules Set based on the Tagaki-Sugeno lets one easily calculate a crisp output from all the fuzzy values. The Fuzzy Rules Set would have a finite number of rules, all having the same crisp variable in the decision part. The final value of the crisp variable would be a weighted average of each Rule's crisp value. The weight of each rule is determined by the multiplication of the membership degrees of each (<linguistic variable>,<linguistic value>) pair.
As you review the code, you'll see it is very simplistic. As it was developed with a specific purpose in mind, the classes lack plenty of would-be useful methods. However, I did strive to make the code as OO as I could so that other people could easily add their own code.
Let's get down to business. The Project defines a new FuzzyLogic Namespace which has:
TagakiSugenoFuzzySystem. This class lets you define a set of rules, all defining the same crisp variable and calculate the aggregated crisp outputTagakiSugenoFuzzyRule. This class defines a rule in the Tagaki-Sugeno System. It is defined by an array of Linguistic values and a crisp output.IMembershipFunction. Defines an interface that lest you create your own membership function for VariableValue. VariableValue. Defines a Linguistic value and has an IMembershipFuncition that defines a Membership function for the specific value. Variable. Is composed of a list of VariableValueFuzzySet. This associates a crisp value with a variable and provides a method to calculate the membership of the crisp value with each VariableValue of the Variable. To get an idea of how you could work with this namespace, I'll walk you through the soccer playing robot sample.
For the sample I'll define a Fuzzy System that steers a soccer playing robot towards the soccer ball. To do this I define 2 linguistic variables with its associated values like this:
distance: left, center, right angle: north, west, south, east The angle refers to where the ball is in respect to the robots heading. The distance defines if the ball is in the left side, center or right of the robot.
In the attached project you can find the constructor of the Form1 form. This is where I define the fuzzy system to calculate how much the robots wheels must turn.
We start the definition of the system with its variables:
distancia.addValue(new VariableValue
("left", new TriangleMembershipFunction(-4000, -10, 0)));
distancia.addValue(new VariableValue
("center", new TriangleMembershipFunction(-10, 0, 10)));
distancia.addValue(new VariableValue
("right", new TriangleMembershipFunction(0, 10, 4000)));
angulo.addValue(new VariableValue
("north", new TriangleMembershipFunction(0, 90, 180)));
angulo.addValue(new VariableValue
("west", new TriangleMembershipFunction(90, 180, 270)));
angulo.addValue(new VariableValue
("south", new TriangleMembershipFunction(180, 270, 360)));
angulo.addValue(new VariableValue
("east", new InverseTrapezoidalMembershipFunction(0, 90, 270, 360)));
Next we define the Fuzzy Rules by which our system will work. Here are the first three:
system.addRule(new TagakiSugenoFuzzyRule(15, new string[] { "north", "left" }));
system.addRule(new TagakiSugenoFuzzyRule(0, new string[] { "north", "center" }));
system.addRule(new TagakiSugenoFuzzyRule(-15, new string[] { "north", "right" }));
Let's examine the first rule. It is saying that if the angle is pointing north, and the ball is on the robots left side the wheels should turn 15°. The same logic applies for the rest of the rules.
Once the Fuzzy system is completely defined, we can start pumping out results. To do this, we define the input FuzzySets for the system like this:
FuzzySet setDistancia = new FuzzySet(distancia, robot.getDistancia(posPelota));
FuzzySet setAngulo = new FuzzySet(angulo, robot.getAngulo(posPelota));
FuzzySet[] sets = { setAngulo, setDistancia };
Once the sets are in place we can feed them to the Fuzzy System to get a crisp result and implement the resulting decision from the system. Here, we'll move the robot 5 units in the direction the robot is moving after turning the amount of the Crisp Output the Fuzzy system gives.
robot.angRobot += Math.PI * system.CrispOutput(sets) / 180;
robot.posRobot.X += (float)(5 * Math.Cos(robot.angRobot));
robot.posRobot.Y += (float)(5 * Math.Sin(robot.angRobot));
One serious limitation the current code implementation has is that every rule must have the exact same number of conditionals and in the exact same order. This can easily be changed, but due to time constrains was not done. If interest from the community arises, I could find the time to do it, or even better put it on SourceForge.
| You must Sign In to use this message board. | ||||||||
|
||||||||
|
||||||||
|
||||||||
|
||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 5 Oct 2008 Editor: Deeksha Shenoy |
Copyright 2008 by Matthias Reichenbach Everything else Copyright © CodeProject, 1999-2009 Web09 | Advertise on the Code Project |