Tags

, , , , , , , , , , , , ,

I’ve been drifting about space, just gazing at the glorious stars. Yeah, in my post The shapely contours of Venus I used Python code to traverse the astronomical sky, and OpenCV to detect celestial objects. Here’s me zooming past venus:

Venus_Screenshot2

The astronomical sky was provided by Microsoft’s WorldWide Telescope HTML5 web application. Adjusting the url parameters of the web application, I was able to zoom through space. I took screenshots of each step in my journey, checking for rocks and dust.

‘But what you need is a spaceship,’ Arkwood said, licking a lollipop.

He’s right! If I have a spaceship with the logic to zoom through space, I can just sit back and watch it collect tons of data.

But what logic should I code into my spaceship? Let’s try AForge.NET Fuzzy Logic. AForge.NET is an open source C# framework for computer vision and artificial intelligence. In my post Getting started with AForge.NET I downloaded and installed AForge.NET on my PC, along with Visual Studio Express 2013 for Windows Desktop.

But why fuzzy logic? Well, as we’ll see, fuzzy logic allows us to express in plain English how we want our spaceship to zoom about space. As we add more rules to govern how the spaceship should behave, using words instead of real numbers will make the logic much easier to understand. Of course, if we need precise logic for, say, landing the spaceship on a planet then perhaps fuzzy logic wouldn’t be suitable. But for navigating through space it’s perfect!

If you want a bit of background on AForge.NET Fuzzy Logic, read the article Fuzzy Computing: Basic Concepts by Fábio Lopes Caversan. The Code Project article Fuzzy Framework by Václav Slavíček is also helpful. AForge.NET also has some sample apps.

Okay, so here’s how it goes. First we create a new C# Console application and reference the AForge.Fuzzy dll.

using System;
using AForge.Fuzzy;

namespace Spaceship
{
    class Program
    {
        static void Main(string[] args)
        {

        }
    }
}

Next we add a Linguistic Variable to our Main method, to define the average distance of the stars in the night sky. We have three fuzzy sets attached to this variable, which will tell us whether the stars are near, medium or far away.

// Distance of stars
FuzzySet fsNear = new FuzzySet("Near", new TrapezoidalFunction(15, 50, TrapezoidalFunction.EdgeType.Right));
FuzzySet fsMedium = new FuzzySet("Medium", new TrapezoidalFunction(15, 50, 60, 100));
FuzzySet fsFar = new FuzzySet("Far", new TrapezoidalFunction(60, 100, TrapezoidalFunction.EdgeType.Left));

LinguisticVariable lvDistance = new LinguisticVariable("Distance", 0, 120);
lvDistance.AddLabel(fsNear);
lvDistance.AddLabel(fsMedium);
lvDistance.AddLabel(fsFar);

We have a Linguistic Variable to define the number of stars in the night sky. Two fuzzy sets tell us whether the stars are many or few.

// Number of stars
FuzzySet fsFew = new FuzzySet("Few", new TrapezoidalFunction(30, 40, TrapezoidalFunction.EdgeType.Right));
FuzzySet fsMany = new FuzzySet("Many", new TrapezoidalFunction(30, 40, TrapezoidalFunction.EdgeType.Left));

LinguisticVariable lvNumber = new LinguisticVariable("Number", 0, 80);
lvNumber.AddLabel(fsFew);
lvNumber.AddLabel(fsMany);

Also, we have a Linguistic Variable to define the speed of the spaceship. Three fuzzy sets allow us to set it to low, mid or high.

// Speed of spaceship
FuzzySet fsLow = new FuzzySet("Low", new TrapezoidalFunction(10, 45, TrapezoidalFunction.EdgeType.Right));
FuzzySet fsMid = new FuzzySet("Mid", new TrapezoidalFunction(10, 45, 55, 90));
FuzzySet fsHigh = new FuzzySet("High", new TrapezoidalFunction(55, 90, TrapezoidalFunction.EdgeType.Left));

LinguisticVariable lvSpeed = new LinguisticVariable("Speed", 0, 100);
lvSpeed.AddLabel(fsLow);
lvSpeed.AddLabel(fsMid);
lvSpeed.AddLabel(fsHigh);

Great. Now we add our variables to a database, and in turn add it to the overall fuzzy inference system.

// The database
Database fuzzyDB = new Database();
fuzzyDB.AddVariable(lvDistance);
fuzzyDB.AddVariable(lvNumber);
fuzzyDB.AddVariable(lvSpeed);

// Creating the inference system
InferenceSystem IS = new InferenceSystem(fuzzyDB, new CentroidDefuzzifier(1000));

So what about these plain English rules then? Let’s start off with the following, which we add to our fuzzy system:

// Add rules
IS.NewRule("Rule 1", "IF Distance IS Far THEN Speed IS High");
IS.NewRule("Rule 2", "IF Distance IS Medium AND Number IS Few THEN Speed IS High");
IS.NewRule("Rule 3", "IF Distance IS Medium AND Number IS Many THEN Speed IS Mid");
IS.NewRule("Rule 4", "IF Distance IS Near THEN Speed IS Low");

The basic logic is thus: if the stars are far away then set the speed of the spaceship to high. If the stars are near then we better slow down and collect tons of data. If the stars are at a medium distance but there are only a few of them then full steam ahead; but if there are many of them then set the speed to mid.

Fantastic. Now we are ready to take our spaceship on a maiden voyage. Let’s input the distance and number of stars.

// Set inputs
IS.SetInput("Distance", 40);
IS.SetInput("Number", 50);

As mentioned, in a previous post I have used OpenCV computer vision to detect stars in screenshots of space. It will tell us how big the stars are, indicating the distance we must travel to inspect them. It will count the stars and yield a total number. We may wish to normalise the values that OpenCV provide, before feeding them into our fuzzy system, or just ensure that both are working on the same scale.

For now, we’ll simply test our system with a distance of “40” and a number of “50”.

Hold on to your hats, we have lift-off! Our spaceship is now in space and we are evaluating its speed:

// Get output
double currentSpeed = IS.Evaluate("Speed");

// Display speed of spaceship
Console.WriteLine("Current speed of spaceship: " + currentSpeed);

So, with the stars at an average distance of “40” and the number of stars at “50”, what has the fuzzy logic set the speed at?

FuzzyLogic_Output_SpaceshipCurrentSpeed

“43.25” puts the speed of the spaceship at mid. Given that our distance is roughly medium and the number of stars are many, then a speed of mid is correct. Note that an input value can match more than one fuzzy set (e.g. a distance of “40” means that to a certain degree it belongs to both the near and medium fuzzy sets) and more than one rule can fire, so a defuzzification method is used to provide a single numerical output.

What can we do with this output value of “43.25”? Well, we can use it to adjust the parameters of the WorldWide Telescope HTML5 web application as we continue to zoom through space. The fuzzy logic of our spaceship will let us slow down when we need more detailed screenshots of space, and speed up when there is nothing much to see.

No doubt the fuzzy logic needs some fine-tuning. With our rules in plain English, it will be easy to understand how the spaceship navigates through space, no matter how much logic is added.

‘Wow, what a fine rocket you’ve built!’ Arkwood exclaimed, putting down his copy of The Inscrutable Diaries Of Rodger Saltwash.

Yes, I suppose it is.

Ciao!

P.S.

AForge.NET uses the C# programming language. I am using Python code with OpenCV. If these two systems are to work together, I may use a C# wrapper for OpenCV instead. Or OpenCV C++ (no, not pointers!). Or pass the values between the systems in some other way. Or just do it all in AForge.NET. A world with options keeps us amused, until our dust reaches the stars!