I am also working on a simple fuzzy controller, which is using distances as its input and revoultion of step motor as its output.
but unfortunately every time when i am watching my input and output on my serial monitor it is just printing revolution time =0 even when I am providing certain positive inputs.
kindly someone help me.
I am attaching my code.
// eFFL includes
#include <Fuzzy.h>
#include <FuzzyComposition.h>
#include <FuzzyInput.h>
#include <FuzzyIO.h>
#include <FuzzyOutput.h>
#include <FuzzyRule.h>
#include <FuzzyRuleAntecedent.h>
#include <FuzzyRuleConsequent.h>
#include <FuzzySet.h>
// pins
#define TRIGGER 9
#define ECHO 10
int initialdepth() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(5);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
long pulse = pulseIn(ECHO, HIGH) / 2;
return(pulse * 10 / 292);
}
const int stepPin = 5;
const int dirPin = 2;
byte b;
long i=0;
long temp=0;
// object library
Fuzzy *fuzzy = new Fuzzy();
void setup() {
// set console and pins
Serial.begin(9600);
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(TRIGGER, OUTPUT);
pinMode(ECHO, INPUT);
temp= initialdepth();
Serial.print("Enter the Depth at which You want to go=:)");
Serial.setTimeout(10);
while(Serial.available()==0)
{}
i= Serial.parseInt();
Serial.print("Distance: "); Serial.println(i);
Serial.print("Initial Depth is: "); Serial.println(temp);
// fuzzy sets
// error1
FuzzySet *NL = new FuzzySet(-10 ,-10, -10, -7);
FuzzySet *NM = new FuzzySet(-10, -7, -7, 3.5);
FuzzySet *NS = new FuzzySet(-7, -3.5, -3.5, 3);
FuzzySet *DZ = new FuzzySet(-3.5, 0, 0, 3.5);
FuzzySet *PS = new FuzzySet(3, 3.5, 3.5, 7);
FuzzySet *PM = new FuzzySet(3.5, 7, 7, 10);
FuzzySet *PL = new FuzzySet(7, 10.0, 10.0, 10.0);
// error2
FuzzySet *NVL2 = new FuzzySet(-12, -12, -12, -1);
FuzzySet *NL2 = new FuzzySet(-12,-10, -10,-6);
FuzzySet *NM2 = new FuzzySet(-10 ,-6,-6,-3);
FuzzySet *NS2 = new FuzzySet(-6, -3, -3, 0);
FuzzySet *DZ2 = new FuzzySet(-3, 0, 0, 3);
FuzzySet *PS2 = new FuzzySet(0 ,3, 3, 6);
FuzzySet *PM2 = new FuzzySet(3, 6, 6, 10);
FuzzySet *PL2 = new FuzzySet(6 ,10, 10, 12);
FuzzySet *PVL2 = new FuzzySet(10, 12, 12, 12);
// stepmotor
FuzzySet *NHigh = new FuzzySet(-1200, -1200, -1200, -1000);
FuzzySet *NMid = new FuzzySet(-1200, -1000, -1000, -300);
FuzzySet *NLow = new FuzzySet(-1000, -300, -300, 100);
FuzzySet *Neutral = new FuzzySet(-300, 100, 100, 300);
FuzzySet *PLow = new FuzzySet(100, 300, 300, 1000);
FuzzySet *PMid = new FuzzySet(300, 1000, 1000, 1200);
FuzzySet *PHigh = new FuzzySet(1000, 1200, 1200, 1200);
// variables
// variable error1 with universe 0-60 as input
FuzzyInput *error1 = new FuzzyInput(1);
error1->addFuzzySet(NL);
error1->addFuzzySet(NM);
error1->addFuzzySet(NS);
error1->addFuzzySet(DZ);
error1->addFuzzySet(PS);
error1->addFuzzySet(PM);
error1->addFuzzySet(PL);
fuzzy->addFuzzyInput(error1);
// variable error2 with universe 0-600 as input
FuzzyInput *error2 = new FuzzyInput(2);
error2->addFuzzySet(NVL2);
error2->addFuzzySet(NL2);
error2->addFuzzySet(NM2);
error2->addFuzzySet(NS2);
error2->addFuzzySet(DZ2);
error2->addFuzzySet(PS2);
error2->addFuzzySet(PM2);
error2->addFuzzySet(PL2);
error2->addFuzzySet(PVL2);
fuzzy->addFuzzyInput(error2);
// variable MOTOR with universe 0-255 as output
FuzzyOutput *MOTOR = new FuzzyOutput(1);
MOTOR->addFuzzySet(NHigh);
MOTOR->addFuzzySet(NMid);
MOTOR->addFuzzySet(NLow);
MOTOR->addFuzzySet(Neutral);
MOTOR->addFuzzySet(PHigh);
MOTOR->addFuzzySet(PMid);
MOTOR->addFuzzySet(PLow);
fuzzy->addFuzzyOutput(MOTOR);
// rules
// if error1 is NL and error2 is NVL2 then MOTOR is Nhigh
FuzzyRuleAntecedent *iferror1NLAnderror2IsNVL2 = new FuzzyRuleAntecedent();
iferror1NLAnderror2IsNVL2->joinWithAND(NL, NVL2);
FuzzyRuleConsequent *thenMOTORNHigh = new FuzzyRuleConsequent();
thenMOTORNHigh->addOutput(NHigh);
FuzzyRule *fuzzyRule1 = new FuzzyRule(1, iferror1NLAnderror2IsNVL2, thenMOTORNHigh);
fuzzy->addFuzzyRule(fuzzyRule1);
// if error1 is PL and error2 is PVL2 then MOTOR is PHigh
FuzzyRuleAntecedent *iferror1PLAnderror2IsPVL2 = new FuzzyRuleAntecedent();
iferror1PLAnderror2IsPVL2->joinWithAND(PL, PVL2);
FuzzyRuleConsequent *thenMOTORPHigh = new FuzzyRuleConsequent();
thenMOTORPHigh->addOutput(PHigh);
FuzzyRule *fuzzyRule2 = new FuzzyRule(2, iferror1PLAnderror2IsPVL2, thenMOTORPHigh);
fuzzy->addFuzzyRule(fuzzyRule2);
// if error1 is PL and error2 is PVL2 then MOTOR is PHigh
FuzzyRuleAntecedent *iferror1PSAnderror2IsPM2 = new FuzzyRuleAntecedent();
iferror1PSAnderror2IsPM2->joinWithAND(PS, PM2);
FuzzyRuleConsequent *thenMOTORPMid = new FuzzyRuleConsequent();
thenMOTORPHigh->addOutput(PHigh);
FuzzyRule fuzzyRule3 = new FuzzyRule(3, iferror1PSAnderror2IsPM2, thenMOTORPMid);
fuzzy->addFuzzyRule(fuzzyRule3);
/ // if error1 is mid then MOTOR is midb
FuzzyRuleAntecedent *iferror1Mid = new FuzzyRuleAntecedent();
iferror1Mid->joinSingle(mid);
FuzzyRuleConsequent *thenMOTORMidb = new FuzzyRuleConsequent();
thenMOTORMidb->addOutput(midb);
FuzzyRule *fuzzyRule3 = new FuzzyRule(3, iferror1Mid, thenMOTORMidb);
fuzzy->addFuzzyRule(fuzzyRule3);
// if error1 is big then MOTOR is low
FuzzyRuleAntecedent *iferror1Big = new FuzzyRuleAntecedent();
iferror1Big->joinSingle(big);
FuzzyRuleConsequent thenMOTORLow = new FuzzyRuleConsequent();
thenMOTORLow->addOutput(lowb);
FuzzyRule fuzzyRule4 = new FuzzyRule(4, iferror1Big, thenMOTORLow);
fuzzy->addFuzzyRule(fuzzyRule4);
// if error1 is verybig then MOTOR is off
FuzzyRuleAntecedent iferror1VeryBig = new FuzzyRuleAntecedent();
iferror1VeryBig->joinSingle(verybig);
FuzzyRule fuzzyRule5 = new FuzzyRule(5, iferror1VeryBig, thenMOTOROff);
fuzzy->addFuzzyRule(fuzzyRule5);
*/
}
// returns the error1 means target depth-actual distance
int error1() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(5);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
long pulse = pulseIn(ECHO, HIGH) / 2;
temp=(pulse * 10 / 292)- temp;
return( i-(pulse * 10 / 292));
}
// returns the error2
int error2() {
// return analogRead(error2);
return(temp);
}
// prints in serial monitor
void print(int err1, int err2, int output) {
Serial.print("error1: ");
Serial.print(err1);
Serial.print(" error2: ");
Serial.print(err2);
Serial.print(" => output revolution: ");
Serial.print(output);
Serial.println();
}
// main method
void loop() {
// get error1 and error2
int err2 = error2();
int err1 = error1();
// if the inputs are weird, ignore them
// if (dist < 0 || dist > 80 || light > 600) return;
// fuzzyfication
fuzzy->setInput(1, err1); // erro1 as fuzzy input 1 (error1)
fuzzy->setInput(2, err2); // error2 as fuzzy input 2 (error2)
fuzzy->fuzzify();
// defuzzyfication
int output = fuzzy->defuzzify(1); // defuzzify fuzzy output 1 (MOTOR)
if (output<=0)
{
digitalWrite(dirPin,HIGH);
digitalWrite(stepPin, HIGH);
delay(-100output);
digitalWrite(stepPin,LOW);
}
if (output>0)
{
digitalWrite(dirPin,LOW);
analogWrite(stepPin, HIGH);
delay(100output);
digitalWrite(stepPin,LOW);
}
print(err1,err2,output);
}