Go Down

Topic: Maze solver robot help (Read 795 times) previous topic - next topic

CharlesCarron

Hello everyone,
I've been trying to program my robot so it could solve a maze but I failed time after time, I'm desperate and hoping to find an answer here. (My experiences with arduino are minimal.)
Basically my robot is a little car and it has 2 distance sensors (1 front, 1 back) and I want it to:
- drive forward
- if there's an obstacle turn 90°
- detect what side has a wall
- drive away from that wall till you cross another wall
This looked quite simple in my head but I'm not able to get this into code. If you have any ideas on what functions I should use please let me know!


extra code info
Code: [Select]
#define ENABLE_A 0
#define ENABLE_B 1
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5
#define trigpin 6
#define echopin 7
#define trigpin2 8
#define echopin2 9
#define MAX_DISTANCE 154

void setup() {
   Serial.begin(115200);
    pinMode(trigpin, OUTPUT);
    pinMode(echopin, INPUT);
    pinMode(trigpin2, OUTPUT);
    pinMode(echopin2, INPUT);
    pinMode(ENABLE_A, OUTPUT);
    pinMode(ENABLE_B, OUTPUT);
    pinMode(IN1,OUTPUT);
    pinMode(IN2,OUTPUT);
    pinMode(IN3,OUTPUT);
    pinMode(IN4,OUTPUT);


moving in direction of sensor 1:
Code: [Select]
    digitalWrite(ENABLE_A, HIGH);
    digitalWrite(ENABLE_B, HIGH);
    digitalWrite(IN1, LOW);
    analogWrite(IN2, 150);
    digitalWrite(IN3, LOW);
    analogWrite(IN4, 150);


moving in direction of sensor 2:
Code: [Select]
    digitalWrite(ENABLE_A, HIGH);
    digitalWrite(ENABLE_B, HIGH);
    analogWrite(IN1, 150);
    digitalWrite(IN2, LOW);
    analogWrite(IN3, 150);
    digitalWrite(IN4, LOW);


moving 90°
Code: [Select]
    digitalWrite(ENABLE_A, HIGH);
    digitalWrite(ENABLE_B, HIGH);
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(1000);




Thanks for your help in advance!
Cheers

PaulS

#1
Nov 07, 2015, 11:30 pm Last Edit: Nov 07, 2015, 11:31 pm by PaulS
Quote
- if there's an obstacle turn 90°
Without feedback, you are just guessing how much you have turned. You aren't planning to just guess, are you?

Quote
- detect what side has a wall
The walls will be on the left and right, after the turn, won't they? Forward and aft sensors won't be much use then.

Quote
This looked quite simple in my head
Draw some pictures of various situations - wall ahead, can turn left or right; wall ahead, can turn left; wall ahead, can turn right; wall ahead, can't turn either direction.

Decide what to do in each case.

A maze solving robot needs to keep track of how far it traveled, and where it turned and how much, so that it can back up to a point where there was an alternate path, when it finds itself blocked.

How are you going to know how far you have traveled, or how far you have turned? How are you going to keep track of that information?

These are all things to be considered before you fire up the IDE at all.
The art of getting good answers lies in asking good questions.

GoForSmoke

#2
Nov 08, 2015, 03:46 am Last Edit: Nov 08, 2015, 03:50 am by GoForSmoke
I didn't see anything in your code to map where it has been. Backtracking may have to be done many times before the path out of a good maze is found. A good map will save time as long as the robot can retrace past steps. It can save searching the same places twice, but you have to be able to locate the robot on the map hopefully for sure and not should be located.

What sensor(s)? Can you put the sensor(s) on a turret to perform sweep scans?
What scale is all of this? Small robot? Tabletop maze?


Inside loop()

Make code for the sensors that runs as often as you need, maybe 10/sec, and have it put the result into a variable that other sections of code may use. As long as no code in the sketch blocks execution longer than the time to the next sensor read, the read will happen on time.

The same with your motor code. Have it read variables or put it in a function that gets args but make it only motor(s) operation. And for the turret if you have one. And any other input or output.

Does the robot have a way to know its position? If so, code for that, update the variable with the result often when position changes.

Make one code that reads the sensor(s) value(s) and decides what to do based on collected data and commands those actions/outputs. This is where the map goes if you have one.

Try just making a robot that can follow a pre-planned course through a maze. Otherwise how do you know when you're back at a certain spot?
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

PaulMurrayCbr

I find it extremely off that he's attempting to analog write and also digital write to the same pin.

Notice that his post doesn't actually state the problem, aside from "it doesn't go". I'd bet that the issue is not that he can't solve a maze - it's that his robot doesn't move at all.

http://paulmurraycbr.github.io/ArduinoTheOOWay.html

Groove

I find it extremely off that he's attempting to analog write and also digital write to the same pin.
And yet that's precisely what analogWrite for the AVR itself does.  ;)
Per Arduino ad Astra

PaulMurrayCbr

And yet that's precisely what analogWrite for the AVR itself does.  ;)
Duh! I was confusing analog write and analog read.

Carry on.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

CharlesCarron

I find it extremely off that he's attempting to analog write and also digital write to the same pin.

Notice that his post doesn't actually state the problem, aside from "it doesn't go". I'd bet that the issue is not that he can't solve a maze - it's that his robot doesn't move at all.


The robot does move, but gets often stuck in the same loop in a certain situation. Like it keeps turning in circles and so on...

CharlesCarron

Without feedback, you are just guessing how much you have turned. You aren't planning to just guess, are you?
The walls will be on the left and right, after the turn, won't they? Forward and aft sensors won't be much use then.
Draw some pictures of various situations - wall ahead, can turn left or right; wall ahead, can turn left; wall ahead, can turn right; wall ahead, can't turn either direction.

Decide what to do in each case.

A maze solving robot needs to keep track of how far it traveled, and where it turned and how much, so that it can back up to a point where there was an alternate path, when it finds itself blocked.

How are you going to know how far you have traveled, or how far you have turned? How are you going to keep track of that information?

These are all things to be considered before you fire up the IDE at all.
I didn't see anything in your code to map where it has been. Backtracking may have to be done many times before the path out of a good maze is found. A good map will save time as long as the robot can retrace past steps. It can save searching the same places twice, but you have to be able to locate the robot on the map hopefully for sure and not should be located.

What sensor(s)? Can you put the sensor(s) on a turret to perform sweep scans?
What scale is all of this? Small robot? Tabletop maze?


Inside loop()

Make code for the sensors that runs as often as you need, maybe 10/sec, and have it put the result into a variable that other sections of code may use. As long as no code in the sketch blocks execution longer than the time to the next sensor read, the read will happen on time.

The same with your motor code. Have it read variables or put it in a function that gets args but make it only motor(s) operation. And for the turret if you have one. And any other input or output.

Does the robot have a way to know its position? If so, code for that, update the variable with the result often when position changes.

Make one code that reads the sensor(s) value(s) and decides what to do based on collected data and commands those actions/outputs. This is where the map goes if you have one.

Try just making a robot that can follow a pre-planned course through a maze. Otherwise how do you know when you're back at a certain spot?
Thanks for your info but this is my first arduino project and I was thinking of something easier to begin with. You are talking about the possibility of going the wrong way. But the 'maze' I'll make for now will only have 1 way and corners of 90°. I just need the robot to avoid walls and following the path without crushing anything. The problem is I only have 2 sensors (1 on the back and 1 on the front). I tried writing a code something like this:
Code: [Select]

void loop()
{
calculate distance
if (distance1 < ...)
{
go forward
}
else
{
turn 1/4
  if distance1 < ...)
  {
  go forward
  }
  else
  {
  go backward untill distance2 < ...
  }
}
}


I know this code doesn't work (by testing it out and reading it now), but I simply don't know the commands I should use. If you don't understand what I'm trying to accomplish here please ask your question and if you do I'ld be very glad to hear what you think I should try.

Thanks again!

OldSteve

#8
Nov 08, 2015, 09:00 pm Last Edit: Nov 08, 2015, 09:03 pm by OldSteve
Charles, to achieve a similar thing on my robot, I mounted an ultrasonic sensor on an inverted servo. The servo horn is attached to the robot car's base plate. (There's a pic of the servo/sensor setup attached.)

The servo swings side to side, so the US sensor can take distance measurements at 5 points - left, mid-left, centre, mid-right and right. Then when it encounters an object directly ahead, it turns 90 degrees to the side that has the longest clear path. It alos uses side measurements to keep more than a set distance from side obstacles.

It's not a maze robot, just obstacle-avoiding, but it's a similar situation.
(And I'm just guessing 90 degrees of turn using timing too. That's plenty good enough for mine.)

Perhaps you could do similar, but with a servo/sensor assembly at each end of your robot?
Please do not PM me for help. I am not a personal consultant.
And others will benefit as well if you post your question publicly on the forums.

CharlesCarron

Charles, to achieve a similar thing on my robot, I mounted an ultrasonic sensor on an inverted servo. The servo horn is attached to the robot car's base plate. (There's a pic of the servo/sensor setup attached.)

The servo swings side to side, so the US sensor can take distance measurements at 5 points - left, mid-left, centre, mid-right and right. Then when it encounters an object directly ahead, it turns 90 degrees to the side that has the longest clear path. It alos uses side measurements to keep more than a set distance from side obstacles.

It's not a maze robot, just obstacle-avoiding, but it's a similar situation.
(And I'm just guessing 90 degrees of turn using timing too. That's plenty good enough for mine.)

Perhaps you could do similar, but with a servo/sensor assembly at each end of your robot?
As it happens I recently ordered 2 servos to upgrade a claw on my robot. I think I could use one of those to simulate your robot. I'll try it out, thanks!

OldSteve

As it happens I recently ordered 2 servos to upgrade a claw on my robot. I think I could use one of those to simulate your robot. I'll try it out, thanks!
No problem. It works well on my little car, and it rarely runs into anything now. Still happens occasionally though, with narrow chair legs etc, but with solid maze walls you should have no issues.

I just have the servo stop momentarily at each of the 5 positions I want to measure at. Just for a few milliseconds, and barely noticeable to the eye when watching it. I haven't tried it without stopping at each position, but it might not be necessary. I chose to err on the side of caution.
Please do not PM me for help. I am not a personal consultant.
And others will benefit as well if you post your question publicly on the forums.

GoForSmoke

Thanks for your info but this is my first arduino project and I was thinking of something easier to begin with. You are talking about the possibility of going the wrong way. But the 'maze' I'll make for now will only have 1 way and corners of 90°. I just need the robot to avoid walls and following the path without crushing anything.
That means a simpler processing task. It is still simpler and easier to have independent code modules run the sensors and motors, small and debugged, and do what your code below does in a processing module that reads sensor output, makes decisions and signals motors to change behavior when the motor code module runs.
This puts the function of each element outside of the workings of any other. They interact through variables like a sensor module updating a variable the other modules use when it reads X times per second. It's like blinking a led but you read the sensor instead. There need be no coordination between the sensor module and whatever uses the sensor data, it simply reads and updates every so many millis (without using delay) and the processing module gets whatever's in the variable when it runs.

Do this right and loop() will run well over 10,000x/second, everything will appear to work simultaneous because it just about will.

Quote
The problem is I only have 2 sensors (1 on the back and 1 on the front). I tried writing a code something like this:
Code: [Select]

void loop()
{
calculate distance
if (distance1 < ...)
{
go forward
}
else
{
turn 1/4
  if distance1 < ...)
  {
  go forward
  }
  else
  {
  go backward untill distance2 < ...
  }
}
}


I know this code doesn't work (by testing it out and reading it now), but I simply don't know the commands I should use. If you don't understand what I'm trying to accomplish here please ask your question and if you do I'ld be very glad to hear what you think I should try.

Thanks again!
You have an Arduino with unused pins? How about adding reflective IR sensing with leds and detectors? At least it will know which turns are blocked.



 
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up