In fact, using ‘waf’ based ns-3 compile, we can easily add an external library and use it in our ns-3 simulations. Doing the same under CMake is a little bit different thing. This article shows a simple ‘waf ‘based compile and an easy unique way of doing that in CMake based ns-3 compile process that uses an external fuzzy logic library along with ns-3-dev.
Fuzzylite
Fuzzylite[1] is an excellent, rich library that contains almost all the concepts of fuzzy logic that you may see in a text book.
As presented in [1], the FuzzyLite library have the following features:
Controllers: Mamdani, Takagi-Sugeno, Larsen, Tsukamoto, Inverse Tsukamoto, Hybrids
Linguistic terms:
Basic: triangle, trapezoid, rectangle, discrete.
Extended: bell, cosine, gaussian, gaussian product, pi-shape, sigmoid difference, sigmoid product, spike.
Edges: binary, concave, ramp, sigmoid, s-shape, z-shape.
Functions: constant, linear, function.
Activation methods: general, proportional, threshold, first, last, lowest, highest.
Conjunction and Implication (T-Norms): minimum, algebraic product, bounded difference, drastic product, einstein product, hamacher product, nilpotent minimum, function.
Disjunction and Aggregation (S-Norms): maximum, algebraic sum, bounded sum, drastic sum, einstein sum, hamacher sum, nilpotent maximum, normalized sum, unbounded sum, function.
Defuzzifiers:
Integral: centroid, bisector, smallest of maximum, largest of maximum, mean of maximum.
Weighted: weighted average, weighted sum.
Hedges: any, not, extremely, seldom, somewhat, very, function.
Importers: FuzzyLite Language fll, Fuzzy Inference System fis, Fuzzy Control Language fcl.
Exporters: C++, Java, FuzzyLite Language fll, FuzzyLite Dataset fld, R script, Fuzzy Inference System fis, Fuzzy Control Language fcl.
Examples: for Mamdani, Takagi-Sugeno, Tsukamoto, and Hybrid controllers from fuzzylite, Octave, and Matlab, each included in the following formats: C++, Java, fll, fld, R, fis, and fcl.
In addition, we can easily:
- Create your own classes inheriting from fuzzylite, register them in the factories, and incorporate them to operate in fuzzylite.
- Utilize multiple rule blocks within a single engine, each containing any number of (possibly weighted) rule, and different conjunction, disjunction and activation operators.
- Write inference rules just naturally, e.g., “if obstacle is left then steer is right”.
- Return a default output value, lock the output values to be within specific ranges, lock the previous valid output value when no rules are activated.
- Explore the function space of your controller.
- Utilize the entire library across multiple threads as it is thread-safe.
- Download the sources, documentation, and binaries for the major platforms in the Downloads tab.
Using an External Library under the earlier ‘waf’ based ns-3 systems
If you search the internet, then you may find different ways of compiling ns-3 with an external library.
So, the above additions to a typical “wscript” of a particular module or an ns-3 simulation will add fuzzylite functionality in that module or simulation. We are ignoring that procedure here because we are going to use only cmake based compile process of ns-3.
Using an External Library under the old and new ‘CMake’ based ns-3 systems
As far as search the internet, there is no such simple way to do the same under the latest CMake based ns-3 or ns-3-dev versions which will not contain ‘waf’ script.
The author and maintainer of ns-3 CMake system have explained the way of using an external library under CMake at the ns-3 user group[3]. But I could not understand that. So I tried to do the same in another easy way.
Installing Fuzzylite
Step 1: Downloading Fuzzylite
One may download source and binary versions of Fuzzylite from [4] or download the source version from [5].
In this procedure, I used the Fuzzylite version from [5].
$ git clone https://github.com/fuzzylite/fuzzylite
Step 2: Compiling Fuzzylite
After downloading the latest version of Fuzzylite from [5], we may compile it as follows:
You will see the following screen at the successful end of the compile process.
The next step shows the simplest way of accessing this library
Step 4: Testing the good working of Fuzzylite
After installing Fuzzylite, before trying to use it with ns-3, we have to test the good working status of the library installation by using it in a simple CPP program.
The following “ObstacleAvoidance.cpp” is one such sample program provided at [1]. If we run this program, the for loop will generate 50 locations and will make fuzzy decisions using fuzzy logic.
//File: ObstacleAvoidance.cpp
#include “fl/Headers.h”
int main(int argc, char* argv[]){
using namespace fl;
Engine* engine = new Engine;
engine->setName(“ObstacleAvoidance”);
engine->setDescription(“”);
InputVariable* obstacle = new InputVariable;
obstacle->setName(“obstacle”);
obstacle->setDescription(“”);
obstacle->setEnabled(true);
obstacle->setRange(0.000, 1.000);
obstacle->setLockValueInRange(false);
obstacle->addTerm(new Ramp(“left”, 1.000, 0.000));
obstacle->addTerm(new Ramp(“right”, 0.000, 1.000));
engine->addInputVariable(obstacle);
OutputVariable* mSteer = new OutputVariable;
mSteer->setName(“mSteer”);
mSteer->setDescription(“”);
mSteer->setEnabled(true);
mSteer->setRange(0.000, 1.000);
mSteer->setLockValueInRange(false);
mSteer->setAggregation(new Maximum);
mSteer->setDefuzzifier(new Centroid(100));
mSteer->setDefaultValue(fl::nan);
mSteer->setLockPreviousValue(false);
mSteer->addTerm(new Ramp(“left”, 1.000, 0.000));
mSteer->addTerm(new Ramp(“right”, 0.000, 1.000));
engine->addOutputVariable(mSteer);
RuleBlock* mamdani = new RuleBlock;
mamdani->setName(“mamdani”);
mamdani->setDescription(“”);
mamdani->setEnabled(true);
mamdani->setConjunction(fl::null);
mamdani->setDisjunction(fl::null);
mamdani->setImplication(new AlgebraicProduct);
mamdani->setActivation(new General);
mamdani->addRule(Rule::parse(“if obstacle is left then mSteer is right”, engine));
mamdani->addRule(Rule::parse(“if obstacle is right then mSteer is left”, engine));
engine->addRuleBlock(mamdani);
std::string status;
if (not engine->isReady(&status))
throw Exception(“[engine error] engine is not ready:\n” + status, FL_AT);
for (int i = 0; i <= 50; ++i){
scalar location = obstacle->getMinimum() + i * (obstacle->range() / 50);
obstacle->setValue(location);
engine->process();
FL_LOG(“obstacle.input = ” << Op::str(location) <<
” => ” << “steer.output = ” << Op::str(mSteer->getValue()));
}
}
If you compile the code using gcc or g++, then you may end up with an error like the following one:
To successfully run the code, you have to do the following two things:
The above command will successfully compile the code, and we will have the binary as “a.out”.
So now we can run this example as follows:
$ cd /home/your_home/
$ ./a.out
Installing ns-3-dev version
Using Fuzzylite in a ns-3 Project
#include “fl/Headers.h”
using namespace fl;
Engine* engine = new Engine;
//Now configure fuzzy sets (inputs and outpus), rules
. . . . .
. . . . .
// check whether the engine is ready after the above settings
std::string status;
if (not engine->isReady(&status))
throw Exception(“[engine error] engine is not ready:\n” + status, FL_AT);
//Give a crisp input andget a crisp output
AAAA->setValue(aaa);
engine->process();
. . . . .
. . . . .
//Make use of the output values
Now we can implement fuzzylogic inside any ns-3 project by following the above steps.
The following is the output of one such example programme based on the inputs and outputs of “ObstacleAvoidance.cpp” – but it is implemented inside a network protocol of ns-3.
In the above output, each line is created at a packet receive function of a typical protocol layer and every line corresponds to one received packet.