Pages: [1]   Go Down
 Author Topic: if problems  (Read 129 times) 0 Members and 1 Guest are viewing this topic.
Offline
Newbie
Karma: 0
Posts: 16
 « on: May 07, 2013, 11:18:33 pm » Bigger Smaller Reset

hi,
i have problem with the following code, a sensor measure a distance, if the distance between 0 and 30 rule 1 should be executed, if distance is between 31 and 60 rule 2 should be executed, but here when the arduino mega enter a rule, he don't go out from it even when distance is changed.
this is the code:

Code:
#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>

//fwd, bwd, left, right
int pin1 = 53;
int pin2 = 52;
int pin3 = 51;
int pin4 = 50;
//S1
int trig = 46;
int echo = 22;
float pertinence;
int distance;
Fuzzy* fuzzy = new Fuzzy();

//Creating fuzzy sets-input
FuzzySet* near = new FuzzySet(0, 10, 20, 30);
FuzzySet* far = new FuzzySet(31, 40, 50, 60);

//Creating fuzzy sets-output
FuzzySet* slow = new FuzzySet(0, 1, 2, 4);
FuzzySet* fast = new FuzzySet(5, 6, 7, 8);

void setup()
{
Serial.begin(9600);
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pin3, OUTPUT);
pinMode(pin4, OUTPUT);

FuzzyInput* distance = new FuzzyInput(1);

FuzzyOutput* speedSS = new FuzzyOutput(1);

//Fuzzy rules
//if distance = near then speedSS = slow
FuzzyRuleAntecedent* ifDistanceNear = new FuzzyRuleAntecedent();
ifDistanceNear->joinSingle(near);
FuzzyRuleConsequent* thenspeedSSslow = new FuzzyRuleConsequent();

FuzzyRule* fuzzyRule01 = new FuzzyRule(1, ifDistanceNear, thenspeedSSslow);

//if distance = far then speedSS = fast
FuzzyRuleAntecedent* ifDistanceFar = new FuzzyRuleAntecedent();
ifDistanceFar->joinSingle(far);
FuzzyRuleConsequent* thenspeedSSfast= new FuzzyRuleConsequent();

FuzzyRule* fuzzyRule02 = new FuzzyRule(2, ifDistanceFar, thenspeedSSfast);

}

void loop()
{
distance = getDistance(trig, echo);
Serial.print(distance);
Serial.print("\n");
fuzzy->setInput(1, distance);
fuzzy->fuzzify();
float output = fuzzy->defuzzify(1);
//Serial.print(output);
Serial.print("\n");
if(fuzzy->isFiredRule(1) == true){
Serial.print("Rule 1, turn left!");
turnLeft();

}  else if(fuzzy->isFiredRule(2) == true){
Serial.print("Rule 2, turn right!");
turnRight();

}
//float output = fuzzy->defuzzify(1);
//Serial.print(output);
//delay(1000);

}
int turnRight()
{
Serial.print("turning right!");
digitalWrite(pin1, HIGH);
digitalWrite(pin2, LOW);
digitalWrite(pin3, LOW);
digitalWrite(pin4, HIGH);
delay(2000);
}
int turnLeft()
{
Serial.print("turning left!");
digitalWrite(pin1, HIGH);
digitalWrite(pin2, LOW);
digitalWrite(pin3, HIGH);
digitalWrite(pin4, LOW);
delay(2000);
}

int getDistance(int pin1, int pin2)
{
long duration, cm;

pinMode(pin1, OUTPUT);
digitalWrite(pin1, LOW);
delayMicroseconds(2);
digitalWrite(pin1, HIGH);
delayMicroseconds(5);
digitalWrite(pin1, LOW);

pinMode(pin2, INPUT);
duration = pulseIn(pin2, HIGH);

return duration / 29 / 2;

delay(100);
//  Serial.print(" cm");
//  Serial.println();
//  delay(1000);
}
 Logged

Offline
Sr. Member
Karma: 8
Posts: 251
 « Reply #1 on: May 08, 2013, 02:25:18 am » Bigger Smaller Reset

What do you get when you remove comment for the line:
Code:
Serial.print(output);

What do you get if you remove the else, i.e.
Code:
if(rule1){

}
if(rule2){

}
As I believe in fuzzy logic you can have both states being triggered to different degrees at the same time.

(Also if you want to print something on a line on its own use println rather than adding a print('\n'))
 Logged

Offline
Newbie
Karma: 0
Posts: 16
 « Reply #2 on: May 08, 2013, 03:35:39 am » Bigger Smaller Reset

ok i will make the test and reply to you
 Logged

Offline
Newbie
Karma: 0
Posts: 16
 « Reply #3 on: May 08, 2013, 05:10:23 am » Bigger Smaller Reset

if we remove else and replace it with
Code:
if(rule1)
{
{
if(rule2)
{
}

i have the same problem
 Logged

Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35500
Seattle, WA USA
 « Reply #4 on: May 08, 2013, 05:31:09 am » Bigger Smaller Reset

It would help if you identified stuff sent to the Serial Monitor.
Code:
Serial.print("distance: ");
Serial.println(distance);
is much better than:
Code:
Serial.print(distance);
Serial.print("\n");

Do this for everything you print to the Serial Monitor, and perhaps the problem will become more obvious.
 Logged

Offline
Newbie
Karma: 0
Posts: 16
 « Reply #5 on: May 08, 2013, 07:40:40 am » Bigger Smaller Reset

ok i will and i will put the output in here
thank you
 Logged

Offline
Newbie
Karma: 0
Posts: 16
 « Reply #6 on: May 08, 2013, 08:32:00 am » Bigger Smaller Reset

ok thats what happened, sensor give the distance and we go directly to the specific rule, but when the distance change, 2 rules are executed, and it loops in those 2 conditions only (see attachment)
 Logged

Offline
Newbie
Karma: 0
Posts: 16
 « Reply #7 on: May 08, 2013, 10:20:10 am » Bigger Smaller Reset

any help
 Logged

Offline
Sr. Member
Karma: 8
Posts: 251
 « Reply #8 on: May 08, 2013, 10:42:17 am » Bigger Smaller Reset

That's the problem I had alluded to above, fuzzy logic does not give you A or B, far or close, it gives you: it's a bit of A and a bit of B. If you are just using fuzzy logic as a method of smoothing out the movement then use a proper filter method, either a LP filter or a moving average.

I suggest you have a read of http://www.zerokol.com/2012/09/arduinofuzzy-fuzzy-library-for-arduino.html it's the documentation for the fuzzy logic library you are using.
 « Last Edit: May 08, 2013, 10:56:42 am by tobyb121 » Logged

Offline
Newbie
Karma: 0
Posts: 16
 « Reply #9 on: May 08, 2013, 11:14:00 am » Bigger Smaller Reset

that's mean their is no error in the code ?
thank you anyway for your help.
i am obliged to use fuzzy logic in this project i can't implement LP filter.
 Logged

 Pages: [1]   Go Up