Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

Fuzzy lib with GUI using mvvm light and OxyPlot

4.33/5 (4 votes)
26 Sep 2014CPOL2 min read 23.7K   2  
Fuzzy lib that have a GUI and uses Lagrange for member curve generating

Introduction

The code is a Fuzzy evaluator, that takes some Crisp values as input and evaluates a new Crisp value as output. My main gools was to create a Fuzzy evaluator with a good GUI, and easy to setup by using the C# operator overloading

Background

As I'm developing an application for my solar heating system I neede a Fuzzy logic evaluator with a good GUI and this code is a spinoff.

Using the code

The main class is SetResult that is created with name and min/max Crisp output values

C#
// create result set 
Motor = new Fuzzy.SetResult("Motor", 0, 30);

Then the waveforms are added. Waveforms are created with a Lagrange curvefitting algorithm so we only need to specify the name and zeropoints. I have predefined some often used waveforms, but its easy to create new ones.

C#
Motor += WaveForm.ParabolicLow("SLOW", -20, 0, 20); 
Motor += WaveForm.Parabolic("MEDIUM", 10, 20); 
Motor += WaveForm.ParabolicHigh("FAST", 10, 30, 40);

Then create input sets in the same manner, param 2, (0 and 1) is the index of the inputs in Evaluate described below.

C#
// create a "input" 
set Fuzzy.Set Temperature = new Fuzzy.Set("Temperature", 0, 20, 90); 
Temperature += WaveForm.ParabolicLow("LOW", 0, 20, 40); 
Temperature += WaveForm.Parabolic("MEDIUM", 30, 80); 
Temperature += WaveForm.ParabolicHigh("HIGH", 60, 90, 120); 
// create a "input" 
set Fuzzy.Set DeltaTemperature = new Fuzzy.Set("DeltaTemperature", 1, 0.0, 5.0); 
DeltaTemperature += WaveForm.ParabolicLow("LOW", -2.5, 0, 2.5); 
DeltaTemperature += WaveForm.Parabolic("MEDIUM", 2.0, 3.0); 
DeltaTemperature += WaveForm.ParabolicHigh("HIGH", 2.5, 5.0, 7.5);

As I have not yet seen any good way to define the rules in C# - I came up with this, that uses overloading, first I defined the If and THEN classes that use the lingual normaly used by the Fuzzy papers, but I feel more comfortable with the explicit way, decleare the rule with parameteres, the rule and IF logic is stored in "Motor" object by the overloading. I have overloads for ==, !=, & , | .

C#
// create rules 
// explicit 
new Fuzzy.Rule("Rule FAST", Temperature == "LOW" & DeltaTemperature == "LOW", Motor == "FAST"); 
new Fuzzy.Rule("Rule MEDIUM", Temperature != "MEDIUM" & DeltaTemperature == "LOW", Motor == "MEDIUM"); 
new Fuzzy.Rule("Rule MEDIUM", Temperature == "HIGH" | DeltaTemperature == "LOW", Motor == "MEDIUM"); 
// or implicit 
new IF(Temperature == "HIGH" & DeltaTemperature == "HIGH", new THEN(Motor == "SLOW")); 
// etc

It's posible to alter the curves(Zeropoints) by the GUI(right click and select member function).
So not to lose the new settings I have added a XML generator of the zeropoints, that can be saved and reloaded.

C#
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
{ 
	// store settings 
	String xmlStore = Motor.GetXml(); 
	// Debug.WriteLine(xmlStore); 
	Settings.Default.SetResultXML = xmlStore; 
	Settings.Default.Save(); 
}

And load at program initialization.

C#
// load setting if exist 
if (!String.IsNullOrEmpty(Settings.Default.SetResultXML) && 
Settings.Default.SetResultXML.Contains("SetResult")) 
{ 
	Motor.LoadXml(Settings.Default.SetResultXML); 
}

The its time to connect the GUI and the Fuzzy logic.

The GUI is defined in code because we do not know how many sets we are using at design time! Actualiy we do but I like the GUI to alter with code, not having to alter both code and WPF by hand. 

C#
// Create/Connect UI, only neede if you want UI feedback. 
ucFuzzySet set = new ucFuzzySet(Motor); 
set.Height = 100; 
wpfFuzzySet.Children.Add(set); 
Motor.UpdateUI(); 
foreach (Fuzzy.Set S in Motor.Sets) 
{ 
	set = new ucFuzzySet(S); 
	set.Height = 100; 
	wpfFuzzySet.Children.Add(set); 
	S.UpdateUI(); 
}

The execution of the Fuzzy logic is done by caling Motor.COG, I have implmented the Center Of Gravity methode that are often used. The params are indexed as param 2 in the Set declation.

C#
public void Evaluate() 
{ 
	Double result = Motor.COG(wpfTemp.Value, wpfDelta.Value); 
}

I have not yet found a briliant way to get rid of the Set in the call to ucFuzzySet(Motor); as this must break the MVVM pattern!!. Mybe some use of MVVM messageing can do the trick.

Points of Interest

The most wierd thing is the use of lagrange to make the curves used for member functions. The code also demostrate some use of the MVVM light toolkit and the OxyPlot lib.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)