This is the second article in the Fuzzy Dot Net series and in this article we will look at how to put some of the concepts expressed in the first article into practice using the classes that were given in the first article. In this article we are going to look at the Fuzzy Dot Net Sample application. This application is a simplification of a central heating system. The reason that the application is a simplification of a central heating system is because I am trying to get across the way in which a program that uses fuzzy logic should be written and how the "fuzziness" is introduced to the program. At no point does the program aim for accuracy in it's representation of temperatures and I am knowingly leaving myself open to the argument that the fuzzy logic itself could be implemented better than it is. This as I say is done deliberately and I will even be pointing to a few areas in the article myself where I have knowingly cut back on the amount of fuzzy logic used in the program so as to make the code easier to understand for beginners.
First of all we'll take a look at the application it self and see what it is trying to do and how it measures the various changes in temperature that can occur within the given room that it is modeling. Then we will get down to the real business of the article and look at how fuzzy logic is used in the application as well as at ways in which the further application of fuzzy logic could improve the accuracy and results of the application.
The Fuzzy Dot Net Sample Application
Above is a picture of the Fuzzy Dot Net Sample Application. This application models the temperature in a room and when the through constant monitoring adjusts the temperature accordingly, with the centre of the triangular bitmap in the image being the current temperature. Because the temperature is constantly changing within the room the imaginary heater is constantly trying to compensate by heating up or cooling down the room. The image above shows the start settings for the program which give the starting temperature of the room and the ideal temperature that we are aiming to keep the room at. Note that the Ideal Temperature has been made read only as the heater panel is not currently flexible enough to cope with changes to the desired temperature.
The room settings panel above shows the amount of temperature lost whenever the room timer is called, note that this is accumulative and the number of seconds it takes between each firing of the room timer. This represents the amount of heat lost from the room in general i.e. through the walls rather than any specific loss of heat from doors or windows
The door settings panel above shows the amount of temperature lost whenever the door timer is called, note that this is accumulative and the number of seconds it takes between each firing of the door timer. The door settings represent the idea that a certain amount of heat is lost from the room through the door. This can be due to either the gap around the edges of the door or the fact that the door is opened when the timer is fired.
The window settings panel above shows the amount of temperature lost for each of the two windows when the each window timer is called. As well as having a different loss of temperature for each window, both windows have their own timer settings as well. The window settings represent the amount of heat lost through the windows either through the faulty seals leading to gaps around the edges of the window connections or because the windows have been opened. There are two of them as the idea is that they are of different sizes and therefore produce a different rate of heat loss.
The outside settings panel above shows the amount of temperature that is lost to the temperature on the outside of the room. The Outside Temperature setting is supposed to represent the outside temperature and the reflect how much heat would be lost by the difference between the temperature outside of the room and the temperature inside, although this has not been implemented yet. The timer interval is the number of seconds between the timer firing.
The heater settings represent the number of heat units the heater is to put out if the code is at a certain temperature. This is used by the main "update" timer and there is option to change the time at which the update timer fires. The settings here will be discussed in detail shortly.
Running The Sample Application
When you first start the sample application the temperature bitmap will hover just above the forty mark. This is due to the fact that the heater settings are slightly out and wont reach the desired optimal temperature on their own. I could have coded this but thought that it would provide some slight entertainment value in allowing people to see if they can get it to stay around the fifty mark.
The program could have been coded so that it would lock at certain temperature but I felt that this wouldn't have been realistic in a fuzzy logic program. The idea of the program is that the code is constantly trying to adjust to temperature levels that are always changing for one reason or another admittedly this is only a simulated effect but it brings the behaviour of the program closer to what it would be in the real world.
Fuzzy Logic In The Sample Application
As stated earlier the idea behind fuzzy logic is that we are dealing not with fixed numbers but with what are largely ranges of numbers that are identified "usually" by some term or another that makes sense to the world we are modeling. At any given point we may or may not know exactly what the true value of these numbers are, only that they fit within some predetermined range of numbers. As you can see from the heater settings above the main fuzzy logic values used within the application are concerned with the temperature that the room is currently at and the heaters response to the temperature. For a given value between freezing and medium the heater will increment the value of the output of the heater by a user increment able amount and for a value within the range of warm and boiling the heater will decrement the value of the output of the heater by a user increment able amount.
The values for the heater are defined in the code as
heaterSet.Name = "Heater Set";
FuzzyNumber temp26 = new FuzzyNumber( "Freezing", 0, 10 );
FuzzyNumber temp27 = new FuzzyNumber( "Very Cold", 11, 20 );
FuzzyNumber temp28 = new FuzzyNumber( "Cold", 21, 30 );
FuzzyNumber temp29 = new FuzzyNumber( "Cool", 31, 40 );
FuzzyNumber temp30 = new FuzzyNumber( "Medium", 41, 50 );
FuzzyNumber temp31 = new FuzzyNumber( "Warm", 51, 60 );
FuzzyNumber temp32 = new FuzzyNumber( "Warmer", 61, 70 );
FuzzyNumber temp33 = new FuzzyNumber( "Quite Hot", 71, 80 );
FuzzyNumber temp34 = new FuzzyNumber( "Hot", 81, 90 );
FuzzyNumber temp35 = new FuzzyNumber( "Boiling", 91, 100 );
heaterSet[ 0 ] = temp26;
heaterSet[ 1 ] = temp27;
heaterSet[ 2 ] = temp28;
heaterSet[ 3 ] = temp29;
heaterSet[ 4 ] = temp30;
heaterSet[ 5 ] = temp31;
heaterSet[ 6 ] = temp32;
heaterSet[ 7 ] = temp33;
heaterSet[ 8 ] = temp34;
heaterSet[ 9 ] = temp35;
The Fuzzy Number Set class has a private variable called
setValue this variables can be accessed through the
FuzzySetValue accessor and is used as the value for the set of Fuzzy Numbers. This is in contrast to the demonstration code given in the first article which relies on the individual values contained within the Fuzzy Numbers class. So at this point we are thinking of the set as a single specific value rather than it being a collection of different values.
This single value will be within the range of one of the values included in the set and these ranges go from freezing to boiling as can be seen from the code that sets up array above. The other values used within the code are for the doors and the windows, etc. The code given below is for the
doorSet and is almost identical to the code for setting up the rest of the items that affect the temperature.
roomSet.Name = "Room Set";
FuzzyNumber temp16 = new FuzzyNumber( "Warm", 0, 10 );
FuzzyNumber temp17 = new FuzzyNumber( "Cool", 11, 20 );
FuzzyNumber temp18 = new FuzzyNumber( "Cooler", 21, 30 );
FuzzyNumber temp19 = new FuzzyNumber( "Cold", 31, 40 );
FuzzyNumber temp20 = new FuzzyNumber( "Freezing", 41, 50 );
roomSet[ 0 ] = temp16;
roomSet[ 1 ] = temp17;
roomSet[ 2 ] = temp18;
roomSet[ 3 ] = temp19;
roomSet[ 4 ] = temp20;
The code sets up five areas of temperature starting at warm and the higher the value for the given item will reduce the temperature in the room to as high as freezing which would require the timer to be called a number of times at the default settings. Remember that the higher these values are the more they will reduce the temperature in the room.
The way the application works is that when each timer is called the value for that item is increased by the value in numeric control on it's setting panel. Once the update timer is called then the code checks to see what area the value for say the room is in. This is done by using the
IsTerm function in the Fuzzy Number Set class which is :-
public bool IsTerm( string strTerm )
for( int i=0; i<this.Count; i++ )
if( ( ( FuzzyNumber )FuzzyArray[ i ] ).Name == strTerm )
FuzzyNumber temp = ( FuzzyNumber )FuzzyArray[ i ];
if( temp.Maximum >= this.setValue &&
temp.Minimum <= this.setValue )
IsTerm function simply cycles through the set and checks to see if the term passed into the function is used as a heading for one of the Fuzzy Numbers. If the term is found to be the name of one of the Fuzzy Numbers within the set then the code does a quick check that the values are accurate before it will return true for the function.
So this means that if the we are checking to see if the value for the door falls between the range of what we call "Cooler" in the code then the
IsTerm function is called with the Term Cooler and if the function returns true then the code will assign a value to a variable in the code called
nHeater. This variable is used to accumulate the values from all the doors, windows etc. and is then subtracted from the value for the
It should be noted that this is what I was talking about earlier about simplifying the code. For this Sample code I have chosen the path of assigning a fixed value at this point. If this was to be a real world piece of code it would probably not work like this. In the real world we would be using Fuzzy Logic Rules that would be expressed something like "If Room temperature loss is warm then heater Setting is cool". The end result for this piece of code is probably identical whatever way it is done but I refer you to the section below for a fuller explanation of Fussy Logic Rules.
nHeater variable has been subtracted from the
heaterSet value then we check to see which area the
heaterSet falls into. This is where the heater settings panel comes in, so if the value for the heater set falls within the range of the warm portion of the set then the value entered into the "if Temp is Warm" control will be subtracted from the heater set value.
Fuzzy Logic Rules
Fuzzy Logic Rules are a natural progression from the way that we are beginning to think about how the code works. The idea behind the way rules are used in fuzzy logic is that the rules are specified in a literal and more natural way than they would otherwise. By this I mean that the rules within the code are expressed in an English language way rather than as pseudo code. i.e. rather than say "If the set called Heater Set has a value within the range between 41 and 50 and the set called Room Set has a value within the range 11 and 20 then reduce the heater value by 3" Alternatively to state the same thing using Fuzzy Logic Rules what we would have is "If Heater is Warm and Room is Cool then reduce the heater value by 3.
We could however refine this a little more say for example we created a Set Called Heater Control that was designed to control just how large a value was added or taken away from the heater at any particular point. This theoretical set could contain the fuzzy values Light, Medium, Large and Heavy, which means our rule could then read "If Heater is Warm and Room is Cool then Heater Control equals Medium." which to a large extent gets us away from the idea of thinking strictly about values and thinking more in real world terms about ranges of values.
The above diagram shows a theoretical fuzzy logic rule being processed. It is basically a standard if then statement but the value of C isn't known if the preconditions to the then statement are not true. Which brings us to the final point I'm going to make for now and that is that when creating any system that uses Fuzzy Logic probably the most important thing to bear in mind is not necessarily what the sets are going to contain or even what they are going to be called but that at some point you may have to translate the values you are using in the Fuzzy sets into output values. It's O.K. to be vague about the numbers while you are making your mind up in the code but at some point you will have to give a straight answer to whatever question you are trying to answer and at that point you need to be able to return something that is meaningful to the project.
There is one major problem with the code to download that is bugging the crap out of me but there seems to be nothing that I can do about it. Whenever the project is opened in Developer Studio 2003 the graphic at the top of the program gets lost by the GUI and if you try to add it the environment complains about an incorrect input value. This is pure garbage and highly annoying it means that whenever you open the project you have to remove the
FuzzyGraphic from the user controls and then add the
FuzzyGraphic to the user controls and reposition it on the form. You then have to open the form code and remove the added variable (
FuzzyGraphic1 ) and do a find and replace for
FuzzyGraphic1 replacing it with
FuzzyGraphic2. I hope this is just a problem on my system but so far I have no reason to believe it will be.
For those of you still paying attention this is not the end. There will be more as I implement more fuzzy logic into the system and we get to see some of the rules in action.
The last article in the series contains the latest code for the library. No attempt at backward compatibility will be attempted and I will change the library as I see fit.
Link To Next Article