Maze Solving Algorithms.pdf

Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
Final Report
Module: 8096 BSc Computing Project
School of Technology
Design, implementation and testing of a maze
solving LEGO robot
Student: Jean-Luc Pasquier 10077923
Supervisor: Mr. Ken Brownsey
1
Jean-Luc Pasquier: 10077923
I.
Oxford Brookes University
U08096
Table of Contents
II.
Introduction ..................................................................................................................................... 4
A.
Background.................................................................................................................................. 4
B.
Objective...................................................................................................................................... 4
C.
Assumptions ................................................................................................................................ 4
III.
Literature Review of technologies............................................................................................... 5
A.
LEGO Mindstorms[1] ................................................................................................................... 5
B.
Coding platform[2] ...................................................................................................................... 6
1.
LEGOS NXT-G : ......................................................................................................................... 6
2.
LEJOS, Java for Lego Mindstorms ............................................................................................ 6
3.
C based programming platforms ............................................................................................. 6
4.
Others ...................................................................................................................................... 6
C.
Maze algorithms .......................................................................................................................... 7
1.
Wall follower (right-hand or left-hand) ................................................................................... 7
2.
Tremaux Algorithm .................................................................................................................. 7
3.
Recursive backtracker ............................................................................................................. 8
IV.
Specifications ............................................................................................................................... 9
A.
Objectives .................................................................................................................................... 9
B.
Requirements .............................................................................................................................. 9
C.
Choice of technologies ................................................................................................................ 9
1.
Maze solving algorithm ........................................................................................................... 9
2.
Coding platform..................................................................................................................... 10
D.
Robot specifications .................................................................................................................. 10
E.
Algorithm specification ............................................................................................................. 11
F.
Robot movement specification ................................................................................................. 12
V.
Design and Implementation .......................................................................................................... 13
A.
Design ........................................................................................................................................ 13
1.
Robot design .......................................................................................................................... 13
2.
Maze solving algorithm ......................................................................................................... 13
3.
Robot movement and navigation design .............................................................................. 14
4.
Wall finder ............................................................................................................................. 14
5.
Exit ......................................................................................................................................... 14
B.
Implementation ......................................................................................................................... 14
1.
Robot ..................................................................................................................................... 14
2
Jean-Luc Pasquier: 10077923
VI.
Oxford Brookes University
U08096
2.
Movement and Navigation .................................................................................................... 15
3.
Tremaux algorithm in Java .................................................................................................... 16
Testing ....................................................................................................................................... 20
A.
Testing protocol......................................................................................................................... 20
B.
Algorithm test ............................................................................................................................ 21
C.
Navigational test........................................................................................................................ 21
VII.
Results ....................................................................................................................................... 22
A.
Algorithm test ............................................................................................................................ 22
B.
Navigational test........................................................................................................................ 22
VIII.
Conclusion ................................................................................................................................. 23
IX.
References ................................................................................................................................. 23
X.
Appendices .................................................................................................................................... 24
A.
Program Code ............................................................................................................................ 24
B.
Algorithm test Code .................................................................................................................. 30
C.
Interim Report ........................................................................................................................... 37
3
Jean-Luc Pasquier: 10077923
II.
Oxford Brookes University
U08096
Introduction
A.
Background
“Robot: any machine or mechanical device that operates automatically with humanlike
skill.”(dictionary.com).
Robots were created to reduce the need of human manpower for repetitive and hard
jobs. At first, they were simple, heavy and very expensive, so they weren’t widely used to
replace human labour, but after the invention of electronics and the reduction of size and cost
they became smaller, cheaper and more complex. That made them perfect to replace people in
the factories because they can reproduce the same identical movement over and over again.
Now, the field of robotics has evolved from its initial use and has expanded out of the
factories and helped humankind doing jobs that humans don’t want or cannot do. Robots like
Honda’s ASIMO (world.honda.com/ASIMO) or Tosy’s TOPIO (www.tosy.com) have shown
the capabilities of robots and in that context, maze-solving robots have a huge amount of
possible uses in the real world. For example, it can be used to create automated robots for
search and rescue operations in disaster zones or in deep water automated submarines, which
are really difficult and dangerous task for humans to do.
B.
Objective
There is a good number of maze solving robots out there but they tend to use external
help, like having the layout of the map in their memory to get through the maze or using a
simple algorithm, like following only the left walls or randomly going through the maze,
which cannot solve every kind of maze available or are very time and resources consuming.
Those flaws make the robot less useful and not very practical in the real world. This project
intends to try and solve those problems with a simple robot, a robot built with a LEGO
Mindstorms set.
The overall objective of the project is to create a robot that can solve a maze without
any external help, using only its sensors to get around the maze and be able to retain the path
to the exit so it can go again directly to the exit for example. The robotics should be designed
carefully to get a balanced robot. In addition, the robot may not go straight or be parallel to
the walls, so a good control system should be built to overcome the problem.
C.
Assumptions
We assume that the maze is composed of fixed length and composed of “cells” which
are squares, so the turns are 90 degrees to the left or to the right. That means that the maze has
well defined passages. The exit is indicated by a red square in the floor and the maze has a
maximum of around 80*80 cells because of memory limitations.
4
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
III. Literature Review of technologies
A.
LEGO Mindstorms[1]
The Mindstorms set is a robotic set build around the famous Lego bricks, in this case
the LEGO technic (technic.lego.com). That allows the user to create almost any kind of robot,
from eight legged animals that crawl or jump to humanoid exoskeletons capable of walking.
That makes the Mindstorms set a very practical, flexible and simple way to enter in the world
of robotics.
The set comes with a range of sensors, motors and a brain to control the robot:
-The “brain” of the robot is a mini-computer called the “NXT brick”. It is built around
an ARM7 micro-controller and has 3 motor ports, 4 sensor ports, a loud speaker, buttons and
a USB port for the connection to the computer.
Figure 1 NXT brick
-In the set there’s also 3 servo motors so the robot can move, or to rotate something.
One of the main features of the servo motor is that is comes with a built-in rotation sensor, so
we can accurately rotate the motor with a precision of +/- 1 degree.
Figure 2 Mindstorms servo motor
-In this project, there are 2 types of sensors that will be used. The ultrasonic sensor can
see objects and gives us the distance between the sensor and the object with a precision of
around 3 centimetres and a maximum distance of around 170 centimetres. The touch sensor’s
main purpose is to detect the exit of the maze because it can detect when the sensor is
touched.
5
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
Figure 3 Ultrasonic sensor and touch sensor
B.
Coding platform[2]
There are a lot of different platforms in different languages, some are open source,
some are made for beginners and others are for more experienced programmers. Here we will
look at some of them:
1.
LEGOS NXT-G :
Is the base interface that comes with the Mindstorms set. It only includes the basic
programming elements that include controlling motors, different sensors inputs, simple math
calculations, etc… But only in version 2.1 arrays and integer support were added. So it’s
limited in complexity but does the job very good for simple programs. It works on Microsoft
Windows and Apple OS X.
2.
LEJOS, Java for Lego Mindstorms
“LeJOS (pronounced like the Spanish word "lejos" for "far") is a tiny Java Virtual
Machine.”(www.lejos.sourceforge.net). Lejos is a Java virtual machine mounted in the NXT
brick to run Java programs using the Lejos API [1]. The API consists of a series of functions
made to simplify the creation and use of the sensors and motors from the robot. It gives the
programmer more control and simpler use of the motors and sensor to be able to create very
powerful programs that the standard software bundle wouldn’t allow because it is made for
people that might not know how to code in Java, Pascal or C.
3.
C based programming platforms
They come in very different forms. For example, the Bricx Command
Center(http://bricxcc.sourceforge.net/) is a IDE[2] originally created to create programs for the
RCX, which is the older version of the NXT, and now has been ported to the NXT brick. “Not
eXactly C” is an open-source programming language, very close to C language. It is one of
the most popular alternatives to NXT-G.
4.
Others
Besides these more important and supported programming platforms, there are at least
10 other different programming platforms including Ada, Lua and Ruby. These platforms are
not interesting for this project.
6
Jean-Luc Pasquier: 10077923
C.
Oxford Brookes University
U08096
Maze algorithms
1.
Wall follower (right-hand or left-hand)
a)
Principle
The Wall follower method solves a big number off mazes, but not all of them. It
consists in a simple rule to apply. It states that, when possible, if you follow the left (or right)
and turn left (or right) whenever possible, you will find the exit.[3]
b)
c)
-
d)
-
2.
Advantages
You are very likely to find the exit
It’s really simple to apply, only one rule
There is no need to know about position and orientation
It only needs to follow a line, or a wall and recognize the exit
Disadvantages
It doesn’t work for every maze, especially those containing
loops and when the exit or the entrance aren’t in the external
walls
Implementation
It is really simple to implement because there is no need to
know any position or track where you’ve been. It’s simply
follow a line or a wall and being able to recognize the exit.
Tremaux Algorithm
a)
Principle
The Tremaux algorithm consists on storing the path we follow in the maze. In our
case, we can consider dividing the maze in cells. Each square is unvisited, marked once or
marked twice. Every time we advance in one direction we mark it. On arriving at a junction
that has not been visited before, we pick a random direction and mark the path. When arriving
at a marked junction and if our current path is marked only once we then turn around and
walk back and mark the path again. If this is not the case, pick the direction with the fewest
marks. When you finally reach the solution, paths marked exactly once will indicate a direct
way back to the start.[3]
b)
-
Advantages
We will always find the exit
We have stored a direct path to the exit
-
Disadvantages
It’s more complicated to implement
-
Implementation
The robot will need to know it’s relative position
The robot will need “memory” to store the maze
May be limited by the quantity of ram available on big mazes
c)
d)
7
Jean-Luc Pasquier: 10077923
3.
Oxford Brookes University
U08096
Recursive backtracker
a)
Principle
The Recursive backtracker is essentially a depth-first search. It tries to move in the
four directions. When we hit a wall, we return false, else if, we are at the exit, we return true.
We mark the spot when we try a new position and erase when we return false. That way, we
will get a single solution when we get to the exit.[3]
b)
-
Advantages
It is a fairly simply code, because it calls himself
We will always find the exit
-
Disadvantages
We don’t get necessarily the shortest solution
It’s more complicated to implement
c)
d)
-
Implementation
The implementation is more complicated since we have a 3D
maze, not 2D.
We are more likely to encounter a lot of collision problems.
We need to divide the maze into squares to be able to well
define the path.
8
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
IV. Specifications
A.
Objectives
The main objective of the robot is to exit the maze using only the information from the
sensors it’s connected to. It should not find the exit randomly; it has to follow an algorithm
suited for maze solving. It also needs to save the path followed for later use.
The other part of this project is the maze. The maze should be consisted of a series of
cells, which have a predefined length that is in proportion with the length of the robot, made
out of cardboard or any other material, as long as the floor is smooth, not like carpet for
example.
B.
Requirements
Using only 2 servo motors and 1 sensor someone could make a robot that full fills the
objectives but it would make the coding of the program hard and not very easy to understand.
To most elegant and simple way of creating the robot would be with 3 sensors to detect the
walls and a sensor to detect the exit, but due to lack of hardware in this project, only one
sensor to detect the walls will be used and another to detect the exit.
The other requirement is the saving of the path. Having assumed that the maze is
composed of “cells” the resulting path should be instructions to direct the robot to the exit.
For example, an array which contains numbers for which direction to go next so that we can
put the robot at the start and using that array it can safely arrive to the exit.
C.
Choice of technologies
1.
Maze solving algorithm
After carefully examination of the 3 different maze solving algorithms I think that the
best suited algorithm to implement is the Tremaux algorithm. The reasons behind this
decision are that I cannot use the wall follower because it cannot solve all the mazes. In fact,
if the exit of the maze is inside the maze, it will not find the exit. As for the Recursive
backtracker, the representation of the “hitting a wall” not suited for the objectives of the
project. I chose the Tremaux algorithm because it is designed to be able to be used by a
human in a maze. I find it very interesting because it represents our process to find the exit
with a maze. Even if, when asked by someone, we cannot give the details of how we try to
find the exit of a maze, this algorithm actually does what our brain does. It simply goes
through the maze, and when we hit a dead-end, we go back and go where we haven’t been
already.
9
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
2.
Coding platform
The decision to use the Lejos virtual machine and API was made before I even got the
set of legos. The set I got for this project was already mounted in the NXT brick but I still did
a bit of research of the possible ways to code programs for the NXT brick. The software
bundle that comes with the set lego set is the NXT-G, which is not adequate for this project
because it needs a fair amount of complexity, to maintain the robot parallel to the walls for
example. I’m used to work with object oriented languages like Java or C++ even if I didn’t
know how to code in Java at the start of this project. That’s why I’ve decided to stay with the
Lejos system, it made me learn a new programming language but I’m still familiarised with
the philosophy of the language.
D.
Robot specifications
The robot needs to fulfil a series of tasks in order to achieve the objectives. It must be
a robot capable of moving in 360 degrees. It also has to be able to detect walls and the exit. It
also should be as compact as possible with the pieces in our disposal.
To be able to rotate the robot precisely it will need to have 2 motors and they will
work just like a tank’s caterpillar tracks. They will rotate in the same direction to go forward
or backward. To rotate, the will rotate in different direction. That allows the robot to turn in
place with a good precision.
To mount the wall detector, which is the ultrasonic sensor, 2 choices are possible. One
possibility is that the sensor could be rotated in the directions needed with the help of a third
servo motor and the use of some gears. The other possibility is to leave the sensor facing in
front of the robot and make the whole robot rotate to the right and left to detect the walls.
The other sensor is the touch sensor; its position will depend on the choice of location
for the ultrasonic sensor and the remaining space in the robot. An obstacle will be put in the
exit of the maze that will touch the sensor and the program will know that it has arrived to the
exit.
In order to create a robot that can accomplish the objectives, it will need some
mandatory pieces. The resulting robot should contain all the hardware but still trying to be as
compact as possible because the size of the robot will directly impact the minimum size of a
cell.
The final specification requirements are:
- 1 NXT brick to control the robot
- 2 servo motors to power the wheels and be able to move and rotate the robot.
- 1 ultrasonic sensors, which will be mounted with a third servo motor to rotate or
just looking in front.
- 1 light sensor that should be mounted looking down, but the final decision will
depend on the choices made for the other parts of the robot.
10
Jean-Luc Pasquier: 10077923
E.
Oxford Brookes University
U08096
Algorithm specification
The algorithm used in this project is the Tremaux algorithm. Basically, it is a depthfirst search algorithm. It starts at the root, the entrance of the maze, and then explores the tree
as long as it doesn’t find a dead-end. When it finds one, it backtracks until the first unexplored
path, and takes that path until it finds the exit or another cul-de-sac. To be able to do this, the
program needs to mark the path already visited and also mark the junctions encountered.
Firstly, the program needs to be able to mark the path followed by the robot. To be
able to do that, it will need some kind of map that represents the maze. That map will need to
remember where the robot has been, the intersections it’s crossed, how many path of those
intersections have already been visited and the cells it hasn’t visited yet.
Secondly, to allow the algorithm to work properly, a position control system is needed.
Indeed, to be able mark the map correctly, the robot needs to know its relative position. A
simple 4 way direction system will be used, like the four winds. It doesn’t have to really
represent the 4 winds, just give us the 4 different directions the robot can go.
The program will also need a way to surely identify the presence of walls around the
robot.
Figure 4 Tremaux algorithm flowchart
11
Jean-Luc Pasquier: 10077923
F.
Oxford Brookes University
U08096
Robot movement specification
The robot needs to be able to move. To do that, it has 2 servo motors mounted in
parallel and can rotate clockwise and counter-clockwise. To move forward in a straight line,
both motors should rotate at the same time and at the same speed. When it comes to turn the
robot, the motors need to rotate in different directions. To rotate right, the left motor needs to
turn forward and the right motor needs to rotate backward and vice versa to turn left. Another
important part of this project is the wall finder. The ultrasonic sensor will give us the distance
between the robot and the nearest object, in this case, the nearest wall. The exit detector will
be a simple touch sensor that when pressed, the exit has been found. That means that if it
finds an obstacle in the maze, the robot will simply stop because the algorithm will think it
found the exit, so it’s a good fail-safe system.
12
Jean-Luc Pasquier: 10077923
V.
Oxford Brookes University
U08096
Design and Implementation
A.
Design
1.
Robot design
The building of the robot was not simple. The mounting of the 2 servo motors used to
steer the robot is not complicated, but to integrate the sensors is more complicated. The first
try with the ultrasonic sensor was to mount a third servo motor to rotate the sensor. The idea
was to use some gears to transform the vertical circular movement to a horizontal circular
movement. The problem with that solution was that the gears and the Lego bricks in my
disposal don’t allow me to create a strong enough system to be able to precisely rotate the
sensor 90 degrees to the sides and the back. The main problem is the cable connecting the
sensor to the brick. The cable, a RJ 11, is quite tick and doesn’t allow the sensor to rotate
correctly. The only solution left is to mount the ultrasonic sensor in the front of the robot and
facing the front. That way, the robot needs to rotate to the right and left to be able to identify
the walls around the robot. That solution makes the robot a lot simpler and allows the other
sensor, the touch sensor, to be mounted in the same support as the ultrasonic sensor and be
facing down. Also, that way, the NXT brick can be easily mounted on top of the servo motors
and doesn’t bother the other sensors and makes the robot more compact. The main problem
with that solution is that the robot will have to rotate much more.
2.
Maze solving algorithm
As said earlier the Tremaux algorithm is the algorithm that will be used to control the
robot. The algorithm will use a right-hand priority. That means that the algorithm will always
try to go right, if it cannot go right it will try to go forward and finally if that’s not possible it
will try to take the left route. In order to follow the good route and not to hit the walls of the
maze it will need to know what is around the maze. That means that the robot will have to
give him information about the space around it and be able to store it.
To make the coding simpler and easier to understand we will use 2 different maps.
One that represents the map and that will be filled with the information of the maze, where the
walls are and the value of each cell. That map will tell us the path followed to reach the exit
and it will be needed to know the unexplored paths.
To be able to backtrack, the robot will have to have in memory the path followed until
that cell. That way, it just has to follow its own path and checking each cell for an open
intersection. Using this algorithm will even allow us to go back to the entrance if there is no
exit to the maze for example. But the first map is not suited for that part of the algorithm. To
tackle that problem the program will need another map, but this time, it will track the actual
path followed by the robot. It features a simple 3-way direction system. For each cell it visits
a value will be attributed to the cell, it may be right, left or forward. That way, when it comes
to get back to an unexplored path, it just needs to read the map of the path followed by the
robot used to get there in the first place.
13
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
3.
Robot movement and navigation design
In order to let the robot move around the maze the program a few functions will be
needed. It needs to be able to go forward, turn right, turn left and be able to turn 180 degrees.
The problem about the movements of the robot is that the movements might not be extremely
precise. That makes the coding of a special function that will keep the robot on track and
parallel to the walls. It should take the information available and be able to make the right
corrections so that the robot keeps on track.
4.
Wall finder
The ultrasonic sensor is capable to detect the distance between the robot and the first
object it encounters. Using that information and according to the size of the maze a value will
be fixed to decide whether there is a wall in front of the robot or not. It will be a fixed value
and the function should return a Boolean value.
5.
Exit
To find the exit, the robot will simply look each time the robot advances if it is at the
exit of the maze or not. A simple obstacle should tell the robot when it reached the exit of the
maze.
B.
Implementation
1.
Robot
Having decided which sensors to mount and how to mount them, the final result was
quite satisfactory. The base is composed by the 2 servo motors mounted parallel to each other.
A stable 2 wheel robot is quite hard to make, so the robot features a small wheel at the back so
the robot is more stable and the weight is distributed more evenly. Once the base is done, the
sensors could be mounted in the positions required and on top of the robot is the NXT brick.
As the final result we obtain a stable and compact robot.
Figure 5 The final robot
14
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
2.
Movement and Navigation
The Lejos API has some very useful features when it comes to movement of the robot.
The class TachoPilot lets us use a 2 motor system to make the robot move. It needs to know
which motors are used and some information about the size of the robot. Java being an objectoriented programming language we need to instantiate an object which will be the TachoPilot.
Its constructor needs 4 arguments. The diameter of the wheels, the wheelbase between the two
motors and the sensor ports for the 2 motors. A precise value is needed for the parameters
because a slight variation and the robot will not move precisely. The values can be of any type
(centimetres, inches, etc…) but they have to be the same type for the 2 arguments. In this
case, centimetres are used.
“traveler.robot = new TachoPilot(5.6f,14.8f,Motor.A,Motor.C);”
Once the object is instantiated, we are able to make a few useful functions that will
help us move the robot around. The robot needs to be able to move around, to turn and to able
to turn 180 degrees. So, 4 simple functions are made called: forward(), rotateRight(),
rotateLeft() and backward(). The final robot is around 18 centimetres long so when we move
forward to another cell, the distance travelled should be aroung 18 centimetres, so the forward
function will make the robot travel 18 cm:
“ public void forward() { //The Robot advances one cell
robot.travel(18);
}”
The rotateRight and rotateLeft are simple rotations of the robot 90 degrees to the left
or the right:
“ public void rotateRight(){ //The Robot rotates to the right
robot.rotate(90);
pause(500);
}”
Finally, the backward() function makes the robot travel backward of 1 cell.
“public void backward() { //The Robot travels 18 cm back.
robot.travel(-18);
}”
The big problem with this kind of robot is the lack of precision. Each robot is different
and to be able to create an API that takes in count every single type of robot is not simple. To
try and resolve the possible problem of not going in a straight line or not being parallel to the
walls another functions is needed.
To use the ultrasonic sensor, we need to instantiate the ultrasonic sensor class, it only
needs one argument, the number of the sensor port:
“UltrasonicSensor sensor = new UltrasonicSensor (SensorPort.S1);”
Knowing that each cell has fixed values and that the precision of the rotations is good
we can assume that when the robot is at the entrance it will be put at an X distance from the
right wall and a Y distance from the left. The program will store those distances to compare
them with the new distances each time it advances one cell. If the distance is lower than the
15
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
reference distance, then the robot is not parallel to the walls and a simple rotation to counter
that effect should be enough. That way, even if the robot may not go in a straight line,
hopefully it won’t collide with the walls and be able to find the exit. The rotation needs to be
small to avoid adding more precision errors when turning. This function needs to be called
only if we know there is wall present to the right or to the left. So we obtain two different
functions, one for the right wall and another for the left wall.
“public void testParallelRight(int refdistance){
int Distance;
Distance= sensor.getDistance();
pause(30);
Distance = sensor.getDistance();
if( refdistance > Distance) {
robot.rotate(-5);
}
}”
The code is the same for the left side, only the negative rotation becomes a positive
one. There is a bug in the Lejos system concerning the Ultrasonic sensor which seems to be
affecting only in a few users. If our code contains only one “Distance = sensor.getDistance();”
it won’t return a true result, it will only return 255, which is the distance of not finding
anything. The solution is to leave a pause in the thread, in this case 30 ms, and then call the
method again so we get a satisfactory result.
3.
Tremaux algorithm in Java
The Tremaux algorithm needs a few components to work properly. Before starting the
actual algorithm we’ll look at all the components needed for the algorithm to work.
First of all, we need the maps. The first map is simply to map each cell visited by the
robot. In Java, we will use a simple 2 dimension array. For this method, we suppose that the
maze is no bigger than a 20*20 cell maze. We don’t want to go outside this map so we will
put the outer boundaries to the value of an already visited cell. So, to be able to obtain a
20*20 maze we will need to create a 22*22 array. Once the array is created we need to define
the values to be put in the maze. For this project we will use the following values:
- 0 = not visited
- 1 = all possibilities visited
- 2 = there’s still a path left unvisited
- 3 = there’s still two paths left unvisited
These units will be used to let the robot know which path has been visited and where
to go next after backtracking from a cul-de-sac.
The other map is the one actually recording the path followed by the robot and has 3
possible values:
- 1 = left
- 2 = forward
- 3 = right
The size of that map must be the exact quantity of the possible cells, so that means
20*20. After creating the maps, we obtain:
“int maze_X = 22; int maze_Y = 22;
int maze[][] = new int[maze_X][maze_Y];
int myPath[] = new int[maze_X*maze_Y];”
16
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
Once we have the maps, we will need some methods to know what cells are around us.
For that matter we will create a method that gives the maze coordinates of the cells around the
robot. To simplify the code, only two methods for the one in front and the one behind will be
implemented. To get the ones on the side, we will implement a directions system. The relative
position of the robot will always be saved so we know where the left and the right of the robot
are. We will call those directions North, East, South and West. These directions don’t
correspond to the actual cardinal points and we will suppose that at the entrance of the maze
the robot is facing North. There is a problem however, having decided to show the finished
map once the robot has found the exit we will not follow the orthonormal basis because the
LCD screen in the NXT uses one as follows :
Figure 6 The program basis
With that decision, we can now code the methods to get the cells. The first one is the
cell in front. To simplify even more the coding, we will code 2 different methods to get the
coordinates of the cell. We then get InFrontX() and InFrontY():
“public int InFrontX(int Direction) {
int result;
if (Direction == 0){
result = 1;
}
else if (Direction == 2) {
result = -1;
}
else result = 0;
return result;
}”
The same type of method is coded for the other coordinates methods. The result gives
us the relative coordinates of the cell needed but there is a little problem. We need the left and
right directions of the actual direction of the robot to be able to get those coordinates. That’s
why we need a couple of methods that return the directions of the left and right of the
direction passed as argument. We then get:
“public int RightOf(int Direction){
int newDir;
if (Direction != 3){
newDir = Direction +1;
}
else {
newDir = 0;
}
return newDir;
}”
17
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
Another very important function is the function that allows us to know if there is a
wall near the robot. The wallFinder() will use the ultrasonic sensor to find the distance
between the robot and the nearest wall. Once we’ve got the distance, we need to compare it to
what we consider is the distance between the robot and a wall in that cell. That value will
depend of what on the size of a maze cell and the size of the robot. The value doesn’t have to
be very precise, because of the distance between a wall in the cell next to the robot and the
one 2 cells away is quite big. As a result we obtain:
“public int wallFinder(){
int Distance;
int wallPresence;
sensor.getDistance();
pause(30);
Distance= sensor.getDistance();
LCD.drawInt(Distance, 5, 5);
if (Distance > 12)
{
wallPresence = 0;
}
else
{
wallPresence = 1;
}
return wallPresence;
}”
The last method needed before starting the Tremaux algorithm is the
DecreasedVisited(). That method will decrease the value of the cell. If the value of the cell is
already at 1 it will return the same value. We obtain :
“public int DecreaseVisited(int maze) {
maze = maze -1;
if (maze < 1) {
return 1;
}
else {
return maze;
}
}”
We know have all the methods needed to begin the coding of the main method itself.
This algorithm works in two stages, when it can advance and when it can’t.
The first part is pretty straight-forward. We robot will move through the maze using a
right-hand-priority. Each time the robot moves, the values of the cells will be updated. But
first, we need to know if we are at the exit, because if we are, then there is no need to
continue. Once we are sure that we are not at the exit, we can check if there is any wall in the
right, the left and in front of the robot. Using the methods created earlier we can easily rotate
the robot into position and see if there is a wall near.
while (traveler.exit() == false) { //loop while we haven't found the exit
traveler.rotateLeft();
18
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
pause(500);
walls[0] = traveler.wallFinder();
traveler.rotateRight();
pause(500);
walls[1] = traveler.wallFinder();
traveler.rotateRight();
pause(500);
walls[2] = traveler.wallFinder();
traveler.rotateLeft();”
Once we have the actual information we can put the value in the current cell:
“maze[cellX][cellY] = 3 - walls[2] - walls[1] - walls[0];
if (maze[cellX][cellY] == 0) {
maze[cellX][cellY] = 1;
}”
Now we need to decide which route to take. For that matter we will assume that the
next move is to backtrack. If we change that value, it means that we can move either forward,
left or right. To be able to give the priority to the right, we will first try to go left if we can,
then in front, and finally to the right. That way, if the right path is open the robot will go that
way because it is the last modification done to the cells and the nextMove variable. If we
don’t then it will be the front path and lastly the left path. To be able to go anywhere not only
there must be no wall but the value of the case in front of that path must be 0. That way, when
we come back in an intersection we have already been, in other words backtracking from a
cul-de-sac, it won’t go a path that has already been visited. If there is no wall in front of the
robot and the cell in front of us not available then we need to decrease the value of the current
cell and the cell in front of the robot to keep the map coherent. This is the result for the turn
left, the same principle applies for the right and front moves:
“ if (walls[0] == 0){
RelX = traveler.InFrontX(traveler.LeftOf(Direction));
RelY = traveler.InFrontY(traveler.LeftOf(Direction));
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 1;
}
else {
maze[cellX][cellY] = traveler.DecreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.DecreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}”
At this point, we have all the information to actually do the next move, so the robot
will turn if it needs to, update the direction and then move forward. Once the robot has
moved, the actual cell value will be updated and we obtain the following code:
“switch(nextMove) {
case 1:
traveler.rotateLeft();
Direction = traveler.LeftOf(Direction);
break;
case 3:
traveler.rotateRight();
19
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
Direction = traveler.RightOf(Direction);
break;
}
if(nextMove != -1) {
traveler.forward();
myPath[moves++] = nextMove;
cellX = cellX + traveler.InFrontX(Direction);
cellY = cellY + traveler.InFrontY(Direction);
continue;
}”
If the nextMove value hasn’t changed, that means that the robot is surrounded by walls
and we’ve reached the famous cul-de-sac. In that case we need to use the path followed by the
robot to get here so that the robot return to an intersection with an unexplored path. The robot
will go backward until it either reaches a cell with a value superior to 1 or the entrance of the
maze, which means there is no exit. Also, each time it backtracks we need to check if it needs
to turn left or right but, since it is backtracking, when myPath[moves] says it needs to go right
or left, it actually needs to turn the other way. Finally, once the robot has moved, the actual
cell of the robot needs to be updated. The final piece of code looks like this:
“while ((maze[cellX][cellY] < 2) && (moves-- > 0)){
if (myPath[moves] == 1) {
traveler.rotateLeft();
Direction = traveler.RightOf(Direction);
}
else if (myPath[moves] == 3) {
traveler.rotateRight();
Direction = traveler.LeftOf(Direction);
}
traveler.backward();
cellX =cellX + traveler.BehindX(Direction);
cellY =cellY + traveler.BehindY(Direction);
}
}”
Once we put all the pieces together we obtain a fully functional program that achieves
all the objectives set by this project. Next, we will actually test this program to look at its
performance and efficiency.
VI. Testing
A.
Testing protocol
To test this program two different tests are made. First, we will test the algorithm and
the map created by the path followed by the robot. This test is to test only the algorithm so the
robot it’s actually not needed. Another map will be created to represent a maze. Using a value
that is not used to represent the values of the visited cells is necessary to represent the walls.
Once the maze is created we change the wallFinder method to search the maze and not use the
ultrasonic sensor. We will also modify the main program to show the current cell and the path
followed as we go through the maze. The second test is to test the movement and navigation
of the robot. In this case it needs to have a maze and go through it without hitting the walls
and test all the methods used to control the robot.
20
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
B.
Algorithm test
This test is simple, it requires a maze that represents all or almost all possibilities that
the algorithm could face in the real world. In this test, the algorithm should find the exit and
put the good values in each cell. For this test, we will use the following maze, which includes
turns, intersections, cul-de-sac, etc…
5
Entrance
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
exit
5
5
5
5
5
Figure 7 The algorithm test
C.
Navigational test
This test is to test the navigational ability of the robot; it is not about a complicated maze, is
about being able to turn, move forward and being able to stay parallel to the walls. The maze
is made out of cardboard with 18*25 cm cells. The walls are 15 cm high. We will use this
maze for this test:
Figure 8 Navigational test
21
5
5
5
5
5
5
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
VII. Results
A.
Algorithm test
For this test, the results were perfect. It simply went to the exit and accurately mapped
the maze. The depth-first search is an efficient mathematical algorithm to search through a
tree, that’s why it works very well with a maze. It doesn’t try to search the shortest path to the
exit, but it will always find the exit in this kind of maze.
5
Entrance
5
5
5
5
5
5
5
1
1
1
1
1
1
5
5
5
5
5
5
5
1
5
5
5
5
1
1
1
1
1
1
5
1
5
5
5
5
5
5
5
1
5
5
5
5
5
5
1
5
5
5
1
5
5
5
1
1
1
1
1
1
1
2
1
1
1
3
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
exit
5
5
5
5
5
Figure 9 The algorithm test partial result
B.
Navigational test
The second test wasn’t completely satisfactory. It worked well but there is a big
problem, the hardware itself. In this case, with only an ultrasonic sensor and a touch sensor, it
is not possible to have a very precise system and it’s even harder to have an absolute
positioning system. In this project, the robot keeps in track but requires a very fine tweaking
of the variables in the TachoPilot, the rotations and the parallel tests. The resulting robot is a
robot that can go straight at first but it will eventually start going from wall to wall, which is
the whole purpose of the parallel test methods.
In this case, the error was to make a small maze, and because the ultrasonic sensor has
a precision of around 3 centimetres it means that sometimes the parallel test doesn’t work
properly. One possible solution is to make everything bigger because when things get bigger,
the precision needed for that system to work gets smaller.
Another solution, which I believe is the best solution for a navigational system, is an
internal compass. An internal compass would be perfect to get an absolute positioning system
and be able to get through a maze without following a line on the floor or touching a wall.
22
5
5
5
5
5
5
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
VIII. Conclusion
For this project, the objective was to create a functional robot that is able to exit a
maze and retain the path followed. I do believe that both of the objectives were met. The
resulting robot is able to enter the maze and find the exit while retaining the path it used. I
also believe that there is room for improvement but it would need the use of more hardware
and finer tuning of the robot.
I’ve definitely learned a lot during this project. First of all, I’ve been introduced to the
world of robotics, which is an expanding domain of the computer science, along with
electronics and mechanics. Robotics is a very interesting domain and there’s still a lot of room
for innovation.
With this project, I’ve also learned a new programming language, Java, which is one
of the most widely used programming language in the world. It’s a very flexible and powerful
language. I would not use it in every situation but it is a very good replacement for languages
like COBOL or FORTRAN.
Finally, doing this project has let me improve my way of managing my time to work
on this project. One big problem with big project is time management. When you are a
student and don’t have any classes for this project it becomes really important to manage your
time working on the project very well. It is quite easy to forget that there is a project in which
you have to spend some time every single week and that can become very stressful. Having
been through that experience a couple of time, I put a strict schedule to work in the project
and I can definitely say that it pays off.
IX. References
1. http://mindstorms.lego.com/en-us/whatisnxt/default.aspx
2. http://en.wikipedia.org/wiki/Lego_Mindstorms_NXT
3. http://www.astrolog.org/labyrnth/algrithm.htm
23
Jean-Luc Pasquier: 10077923
X.
Oxford Brookes University
U08096
Appendices
A.
Program Code
import java.lang.Math.*;
import lejos.nxt.*;
import lejos.robotics.navigation.*;
/*Lego Robot that exits mazes using the Tremaux Algorithm*/
public class TravelTest {
//All the variables and instanciations of the motors, sensors, etc...
TachoPilot robot; // The Class that will deal with the movement of the robot
UltrasonicSensor sensor = new UltrasonicSensor (SensorPort.S1);// The sensor
TouchSensor exitdetector = new TouchSensor(SensorPort.S4);
// *END*
// Extra functions needed
public static void pause(int time) {
try{ Thread.sleep(time);
}
catch(InterruptedException e){}
}
public int getDistance(){
int Distance= sensor.getDistance();
pause(30);
return sensor.getDistance();
}
void fill_map(int maze[][], int maze_X, int maze_Y) {//fill the outer boundaries of the maze
to 1
int a=0;
int b=0;
for ( a=0; a<maze_X; a++) {
for ( b=0; b<maze_Y;b++) {
maze[a][b] = 1;
}
}
for (int c=1; c<maze_X-1; c++) {
for (int d=1; d<maze_Y-1;d++) {
maze[c][d] = 0;
}
}
}
void show_map(int maze[][], int maze_X, int maze_Y) {//show the result
for (int a=1; a<maze_X; a++) {
for (int b=1; b<maze_Y;b++) {
LCD.drawInt(maze[a][b], a, b);
}
24
Jean-Luc Pasquier: 10077923
Oxford Brookes University
}
}
public boolean exit() {
if ( exitdetector.isPressed()== true) {
return true;
}
return false;
}
// *END*
//All the functions needed to get informations and get around the maze
public int RightOf(int Direction){ //Gives the Right direction of the actual direction
int newDir;
if (Direction != 3){
newDir = Direction +1;
}
else {
newDir = 0;
}
return newDir;
}
public int LeftOf(int Direction){ //Gives the Left direction of the actual direction
int newDir;
if (Direction != 0){
newDir = Direction -1;
}
else {
newDir = 3;
}
return newDir;
}
public int BehindX(int Direction) {
int result;
if(Direction == 0){
result = -1;
}
else if (Direction == 2){
result = 1;
}
else result = 0;
return result;
}
public int BehindY(int Direction) {
int result;
if(Direction == 3){
result = 1;
}
else if (Direction == 1){
result = -1;
}
25
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
else result = 0;
return result;
}
public int InFrontX(int Direction) {//the cell in front of the robot
int result;
if (Direction == 0){
result = 1;
}
else if (Direction == 2) {
result = -1;
}
else result = 0;
return result;
}
public int InFrontY(int Direction) {
int result;
if (Direction == 3){
result = -1;
}
else if (Direction == 1) {
result = 1;
}
else result = 0;
return result;
}
public int DecreaseVisited(int maze) {
maze = maze -1;
if (maze < 1) {
return 1;
}
else {
return maze;
}
}
public int wallFinder(){ //the ultrasonic sensors gets the distance to the wall.
int Distance;
int wallPresence;
sensor.getDistance();
pause(30);
Distance= sensor.getDistance();
LCD.drawInt(Distance, 5, 5);
if (Distance > 12)
{
wallPresence = 0;
}
else
{
wallPresence = 1;
}
return wallPresence;
26
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
}
// *END*
//Functions to move the robot
public void forward() { //The Robot advances one cell
robot.travel(19);
}
public void backward() { //The Robot advances one cell
robot.travel(-19);
}
public void backturn() { //The Robot makes a 180 degrees turn
robot.rotate(-180);
}
public void rotateRight(){ //The Robot rotates to the right
robot.rotate(90);
pause(500);
}
public void rotateLeft(){
robot.rotate(-90);
pause(500);
}
public void testParallelRight1(int refdistance){
int Distance;
Distance= sensor.getDistance();
pause(30);
Distance = sensor.getDistance();
if( refdistance > Distance) {
robot.rotate(-5);
}
}
public void testParallelLeft1(int refdistance){
int Distance;
Distance= sensor.getDistance();
pause(30);
Distance = sensor.getDistance();
if( refdistance > Distance) {
robot.rotate(5);
}
}
// *END*
public static void main(String[] args ){
TravelTest traveler = new TravelTest();
traveler.robot = new TachoPilot(5.6f,13.7f,Motor.A,Motor.C);
int walls[] = new int[3];
int cellX;//The current cell we are on.
int cellY;//The current cell we are on.
27
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
int maze_X = 22;// We can solve a 20 by 20 cell maze
int maze_Y = 22;// So that the robots doesn't want to go outside the maze, we set the outer
cells to 1
int maze[][] = new int[maze_X][maze_Y]; //Identifies each cell of the maze. We can solve
a 20 by 20 cell maze
int myPath[] = new int[maze_X*maze_Y];
int Direction = 0;//we suppose that the robot faces north when it gets in;
int nextMove = 0;
int moves = 0;
int exit = 0;
int RelX;
int RelY;
int oldDistanceL = 0;
int oldDistanceR = 0;
// North = 0; West =1; South = 2; East =3;
//notvisited = 0; we haven't visited that map position.
//visited = 1; we have already visited all the posibles paths of that cell
//onepathleft = 2; we still have one path to go
//twopathsleft = 3;we still have 2 two paths to go
traveler.fill_map(maze,maze_X,maze_Y);
cellX = 4; //we suppose the robots starts at cell 4 2;
cellY = 2;
while (traveler.exit() == false) { //loop while we haven't found the exit
traveler.rotateLeft();
pause(500);
walls[0] = traveler.wallFinder();
if (moves == 0) {
oldDistanceL = traveler.getDistance();
}
else if (walls[0] == 1){
pause(100);
traveler.testParallelLeft1(oldDistanceL);
pause(200);
}
traveler.rotateRight();
pause(500);
walls[1] = traveler.wallFinder();
traveler.rotateRight();
pause(500);
walls[2] = traveler.wallFinder();
if (moves == 0) {
oldDistanceR = traveler.getDistance();
}
else if( walls[2]== 1){
28
Jean-Luc Pasquier: 10077923
Oxford Brookes University
pause(100);
traveler.testParallelRight1(oldDistanceR);
pause(200);
}
traveler.rotateLeft();
//we assume all the paths unvisited
maze[cellX][cellY] = 3 - walls[2] - walls[1] - walls[0];
if (maze[cellX][cellY] == 0) {
maze[cellX][cellY] = 1;
}
nextMove=-1;
if (walls[0] == 0){
RelX = traveler.InFrontX(traveler.LeftOf(Direction));
RelY = traveler.InFrontY(traveler.LeftOf(Direction));
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 1;
}
else {
maze[cellX][cellY] = traveler.DecreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.DecreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}
if (walls[1] == 0){
RelX = traveler.InFrontX(Direction);
RelY = traveler.InFrontY(Direction);
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 2;
}
else {
maze[cellX][cellY] = traveler.DecreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.DecreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}
if (walls[2] == 0){
RelX = traveler.InFrontX(traveler.RightOf(Direction));
RelY = traveler.InFrontY(traveler.RightOf(Direction));
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 3;
}
else {
maze[cellX][cellY] = traveler.DecreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.DecreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}
switch(nextMove) {
29
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
case 1:
traveler.rotateLeft();
Direction = traveler.LeftOf(Direction);
break;
case 3:
traveler.rotateRight();
Direction = traveler.RightOf(Direction);
break;
}
if(nextMove != -1) {
traveler.forward();
myPath[moves++] = nextMove;
cellX = cellX + traveler.InFrontX(Direction);
cellY = cellY + traveler.InFrontY(Direction);
continue;
}
//cul-de-sac
while ((maze[cellX][cellY] < 2) && (moves-- > 0)){
if (myPath[moves] == 1) {
traveler.rotateLeft();
Direction = traveler.RightOf(Direction);
}
else if (myPath[moves] == 3) {
traveler.rotateRight();
Direction = traveler.LeftOf(Direction);
}
traveler.backward();
cellX =cellX + traveler.BehindX(Direction);
cellY =cellY + traveler.BehindY(Direction);
}
}
traveler.show_map(maze, maze_X, maze_Y);
Button.waitForPress();
}
}
B.
Algorithm test Code
import lejos.nxt.*;
/**
*
* @author WandereR
*/
public class Test {
// Extra functions needed
public static void pause(int time) {
try{ Thread.sleep(time);
}
30
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
catch(InterruptedException e){}
}
void fill_map(int maze[][], int maze_X, int maze_Y) {
int a=0;
int b=0;
for ( a=0; a<maze_X; a++) {
for ( b=0; b<maze_Y;b++) {
maze[a][b] = 1;
}
}
for (int c=1; c<maze_X-1; c++) {
for (int d=1; d<maze_Y-1;d++) {
maze[c][d] = 0;
}
}
}
void fill_maze(int maze[][], int maze_X, int maze_Y) {
int a=0;
int b=0;
for ( a=0; a<maze_X; a++) {
for ( b=0; b<maze_Y;b++) {
maze[a][b] = 1;
}
}
for (int c=1; c<maze_X-1; c++) {
for (int d=1; d<maze_Y-1;d++) {
maze[c][d] = 0;
}
}
maze[1][1] = 5;
maze[2][1] = 5;
maze[3][1] = 5;
maze[4][1] = 5;
maze[5][1] = 5;
maze[3][2] = 5;
maze[3][3] = 5;
maze[5][3] = 5;
maze[5][4] = 5;
maze[5][5] = 5;
maze[4][5] = 5;
maze[3][5] = 5;
maze[2][5] = 5;
maze[1][5] = 5;
maze[1][3] = 5;
maze[1][4] = 5;
maze[6][1] = 5;
maze[7][1] = 5;
maze[7][2] = 5;
maze[7][3] = 5;
maze[7][4] = 5;
31
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
maze[7][5] = 5;
maze[4][6] = 5;
maze[4][7] = 5;
maze[5][7] = 5;
maze[6][7] = 5;
maze[7][7] = 5;
maze[8][7] = 5;
maze[9][7] = 5;
maze[9][6] = 5;
maze[9][5] = 5;
maze[8][5] = 5;
}
void show_map(int maze[][], int maze_X, int maze_Y) {
for (int a=1; a<maze_X; a++) {
for (int b=1; b<maze_Y;b++) {
LCD.drawInt(maze[a][b], a, b);
}
}
}
public int decreaseVisited(int maze){
if(maze == 1){
return maze;
}
else {
maze = maze -1;
return maze;
}
}
// *END*
//All the functions needed to get informations and get around the maze
public int RightOf(int Direction){ //Gives the Right direction of the actual direction
int newDir;
if (Direction != 3){
newDir = Direction +1;
}
else {
newDir = 0;
}
return newDir;
}
public int LeftOf(int Direction){ //Gives the Left direction of the actual direction
int newDir;
if (Direction != 0){
newDir = Direction -1;
}
else {
newDir = 3;
32
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
}
return newDir;
}
public int RelPosX(int Direction) {
int result;
if (Direction == 0){
result = 1;
}
else if (Direction == 2) {
result = -1;
}
else result = 0;
return result;
}
public int RelPosY(int Direction) {
int result;
if (Direction == 3){
result = -1;
}
else if (Direction == 1) {
result = 1;
}
else result = 0;
return result;
}
// *END*
//Functions to move the robot
public int wallFinder(int filledMaze[][],int direction,int cellX,int cellY){
if (direction == 3) {
if (filledMaze[cellX][cellY-1] == 5){
return 1;
}
}
else if (direction == 1) {
if (filledMaze[cellX][cellY+1] == 5) {
return 1;
}
}
else if (direction == 0) {
if(filledMaze[cellX+1][cellY] == 5) {
return 1;
}
}
else if (direction == 2) {
if(filledMaze[cellX-1][cellY] == 5) {
return 1;
}
}
33
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
return 0;
}
// *END*
public static void main(String[] args ){
TravelTest traveler = new TravelTest();
int walls[] = new int[3];
int cellX;//The current cell we are on.
int cellY;//The current cell we are on.
int maze_X = 22;// We can solve a 20 by 20 cell maze
int maze_Y = 22;// So that the robots doesn't want to go outside the maze, we set the outer
cells to 1
int filledMaze[][] = new int[maze_X][maze_Y];
int maze[][] = new int[maze_X][maze_Y]; //Identifies each cell of the maze. We can solve
a 20 by 20 cell maze
int myPath[] = new int[maze_X*maze_Y];
int Direction = 0;//we suppose that the robot faces north when it gets in;
int nextMove;
int moves = 0;
int exit = 0;
int RelX;
int RelY;
// North = 0; West =1; South = 2; East =3;
//notvisited = 0; we haven't visited that map position.
//visited = 1; we have already visited all the posibles paths of that cell
//onepathleft = 2; we still have one path to go
//twopathsleft = 3;we still have 2 two paths to go
traveler.fill_maze(filledMaze, maze_X, maze_Y);
traveler.show_map(filledMaze, maze_X, maze_Y);
Button.waitForPress();
traveler.fill_map(maze,maze_X,maze_Y);
cellX = 1; //we suppose the robots starts at cell 1 2;
cellY = 2;
LCD.drawInt(1, cellX, cellY);
while (exit != 1) { //loop while we haven't found the exit
Button.waitForPress();
LCD.drawInt(Direction, 15, 1);
if((cellX == 7)&&(cellY==6) ){
exit = 1;
}
Direction = traveler.LeftOf(Direction);
walls[0] = traveler.wallFinder(filledMaze,Direction,cellX,cellY);
Direction = traveler.RightOf(Direction);
walls[1] = traveler.wallFinder(filledMaze,Direction,cellX,cellY);
34
Jean-Luc Pasquier: 10077923
Oxford Brookes University
Direction = traveler.RightOf(Direction);
walls[2] = traveler.wallFinder(filledMaze,Direction,cellX,cellY);
Direction = traveler.LeftOf(Direction);
//we assume all the paths unvisited
maze[cellX][cellY] = 3 - walls[2] - walls[1] - walls[0];
if (maze[cellX][cellY] == 0){
maze[cellX][cellY] = 1;
}
nextMove=-1;
//left
if (walls[0] != 1){
RelX = traveler.RelPosX(traveler.LeftOf(Direction));
RelY = traveler.RelPosY(traveler.LeftOf(Direction));
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 1;
}
else {
maze[cellX][cellY] = traveler.decreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.decreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}
if (walls[1] != 1){
RelX = traveler.RelPosX(Direction);
RelY = traveler.RelPosY(Direction);
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 2;
}
else {
maze[cellX][cellY] = traveler.decreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.decreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}
if (walls[2] != 1){
RelX = traveler.RelPosX(traveler.RightOf(Direction));
RelY = traveler.RelPosY(traveler.RightOf(Direction));
if (maze[cellX+RelX][cellY+RelY] == 0) {
nextMove = 3;
}
else {
maze[cellX][cellY] = traveler.decreaseVisited(maze[cellX][cellY]);
maze[cellX+RelX][cellY+RelY] =
traveler.decreaseVisited(maze[cellX+RelX][cellY+RelY]);
}
}
switch(nextMove) {
case 1:
35
U08096
Jean-Luc Pasquier: 10077923
Oxford Brookes University
Direction = traveler.LeftOf(Direction);
break;
case 3:
Direction = traveler.RightOf(Direction);
break;
}
if(nextMove != -1) {
myPath[moves] = nextMove;
moves++;
LCD.drawInt(maze[cellX][cellY], cellX, cellY);
cellX =cellX + traveler.RelPosX(Direction);
cellY =cellY + traveler.RelPosY(Direction);
LCD.drawInt(cellX, 12, 5);
LCD.drawInt(cellY, 12, 6);
continue;
}
LCD.drawInt(4, cellX, cellY);
LCD.drawInt(7, 15, 6);
Direction = traveler.RightOf(traveler.RightOf(Direction));
LCD.drawInt(Direction, 15, 5);
Button.waitForPress();
while ((maze[cellX][cellY] < 2) && (moves > 0)){
if (myPath[moves] == 1) {
Direction = traveler.RightOf(Direction);
}
else if (myPath[moves] == 3) {
Direction = traveler.LeftOf(Direction);
}
cellX = cellX + traveler.RelPosX(Direction);
cellY = cellY + traveler.RelPosY(Direction);
moves--;
LCD.drawInt(Direction, 15, 5);
LCD.drawInt(cellX, 12, 5);
LCD.drawInt(cellY, 12, 6);
Button.waitForPress();
}
}
LCD.drawString("YOU WON", 10, 10);
Button.waitForPress();
}
}
36
U08096
Jean-Luc Pasquier: 10077923
C.
Oxford Brookes University
U08096
Interim Report
Jean-Luc Pasquier
29/11/10
Interim report
Module: 8096 BSc Computing Project
School of Technology
Design, implementation and testing of a maze
solving LEGO robot
Student: Jean-Luc Pasquier 10077923
Supervisor: Mr. Ken Brownsey
37
Jean-Luc Pasquier: 10077923
I)
Oxford Brookes University
U08096
Introduction
While I was doing the proposal I came across various decisions
to be made that because I didn’t fully understand the environment of
the project and the major challenges it raises. That’s why in this
interim report I tried to explain those challenges, the advantages and
disadvantages of each decisions and my general progress to date.
Firstly, I will describe the different maze solving algorithms,
their advantages and disadvantages followed by my final decision.
After that, I will talk about my choice more in detail. I will explain the
keys issues on applying that algorithm to the constraints of the robot
and the implementation of the code. Finally, I will explain how the
robot will deal with the real world problems such as following a line
or getting back on track after a dead end.
38
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
I) Maze solving Algorithms
I’ve made quite a long research on how robots solve mazes. And
there are quite a few techniques out there. I’ve selected the most
interesting ones that can be coded and used by the robot with the
hardware at my disposal.
1) Wall follower (right-hand or left-hand)
a. Principle
i. The Wall follower method solves a big number
off mazes, but not all of them. It consists in a
simple rule to apply. It states that, when
possible, if you follow the left (or right) and
turn left (or right) whenever possible, you will
find the exit.
b. Advantages
i. You are very likely to find the exit
ii. It’s really simple to apply, only one rule
iii. There is no need to know about position and
orientation
iv. It only needs to follow a line, or a wall and
recognize the exit
c. Disadvantages
i. It doesn’t work for every maze, especially those
containing loops and when the exit or the
entrance aren’t in the external walls
d. Implementation
39
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
i. It is really simple to implement because there
is no need to know any position or track where
you’ve been. It’s simply follow a line or a wall
and being able to recognize the exit.
2) Tremaux Algorithm
a. Principle
i. The Tremaux algorithm consists on storing the
path we follow in the maze. In our case, we can
consider dividing the maze in cells. Each square
is unvisited, marked once or marked twice.
Every time we advance in one direction we
mark it. On arriving at a junction that has not
been visited before, we pick a random
direction and mark the path. When arriving at a
marked junction and if our current path is
marked only once we then turn around and
walk back and mark the path again. If this is
not the case, pick the direction with the fewest
marks. When you finally reach the solution,
paths marked exactly once will indicate a direct
way back to the start.
b. Advantages
i. We will always find the exit
ii. We have stored a direct path to the exit
c. Disadvantages
i. It’s more complicated to implement
d. Implementation
i. The robot will need to know it’s relative
position
40
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
ii. The robot will need “memory” to store the
maze
iii. May be limited by the quantity of ram available
on big mazes
3) Recursive backtracker
a. Principle
i. The Recursive backtracker is essentially a
depth-first search. It tries to move in the four
directions. When we hit a wall, we return false,
else if, we are at the exit, we return true. We
mark the spot when we try a new position and
erase when we return false. That way, we will
get a single solution when we get to the exit.
b. Advantages
i. It is a fairly simply code, because it calls himself
ii. We will always find the exit
c. Disadvantages
i. We don’t get necessarily the shortest solution
ii. It’s more complicated to implement
d. Implementation
i. The implementation is more complicated since
we have a 3D maze, not 2D. We are more likely
to encounter a lot of collision problems.
ii. We need to divide the maze into squares to be
able to well define the path.
41
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
After carefully examination of the 3 different maze solving
algorithms I think that the best suited algorithm to implement is the
Tremaux algorithm.
I cannot use the wall follower because it cannot solve all the
mazes. As for the Recursive backtracker, I find the representation of
the “hitting a wall” not very suited for my project. Finally, the
Tremaux algorithm is designed to be able to be used by a human in a
maze. I find it very interesting because it represents our process to
find the exit with a maze. Even if we cannot give the details of how
we resolve a maze to someone, this algorithms actually does what
our brain does. It goes through the maze, and when we hit a deadend, we go back and go where we haven’t been already.
II) The Tremaux Algorithm
1) Algorithm Implementation
To implement this algorithm in the robot, there are a few things
that are needed. For instance, we need to divide the maze in cells.
We need to have directions. We also need to have memory to
memorize each cell’s marking.
a) Directions
We will follow the usual convention, using north, west, south
and east; these coincide with the north of the maze. For each
42
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
direction we need to assign a number to define it. For example:
North=0, West=1, South=2, East=3.
b) Cell marking
Each cell will have a value that represents the state of that
cell. We need to know if we haven’t been to that cell, if we
passed once, twice or three times. We need them for the “T”
shaped intersections and the four-way intersections. An
example of the cell markings are:
0: It means we haven’t been in that cell
1: This corresponds to a position which we’ve passed
already
2: This corresponds to a cell that we have already visited,
but that we still have one path that we haven’t visited. It usually
to a “T” shaped intersection or when we have visited 2 paths of
a four-way intersection.
3: This represents a path in which two routes have been
left unexplored. It’s is mainly used in four-way intersections.
Apart from the state of each cell, we need to find the
possible paths for each cell, so we need to store which path we
can take.
2) Technical constraints
The NXT brick comes with a limited amount of memory, but in
our case, the maze will not be big enough to use the full amount of
memory, but the problem may arise in very big mazes.
43
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
Having only one ultrasonic sensor, so that means that the robot
will have to do 90 degrees in both directions to get the information
for each cell.
The maze will have to be formatted to correspond to the cells;
otherwise the algorithm won’t work, given that it goes x centimetres
and then it makes its measurements.
III) General Progress
For the most part, I’ve been doing research on the subject and
experimenting with the hardware. I made a prototype of the robot
with all 3 sensors, which I think I won’t use 2 of them. It has 2 servo
motors that work in harmony to go straight and in reverse between
each other to be able to turn, like a tank.
I’ve been experimenting with the ultrasonic sensor, which will
be used to detect the walls and the lack of wall (the path). It works
pretty well with hard white paper. That’s why I think I’ll build a maze
out of white hard paper because it is pretty cheap and easy to get.
The maze will have only straight angle turns. A coloured square will
be drawn in the ground to detect the exit of the maze.
After doing some research, I found that the motors have a
Synchronized Motors feature, so the robot can go in a straight line
without too much problem because earlier versions of the LEJOS NXT
API didn’t have that feature, which made synchronising the two
motors much harder, so the robots actually went zigzagging instead
of straight.
44
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
The maze will have to be quite large so that the robot can turn
properly, but I’ll make the robot as little as possible to avoid those
kinds of problems.
With my current prototype I have a problem with turning
because I use 2 wheels at the back; I take those out and put a free
spinning wheel so that it can turn properly.
IV) References
-
Building with LEGO Mindstorms NXT by Dave Astolfo
http://www.astrolog.org/labyrnth/algrithm.htm
http://en.wikipedia.org/wiki/Maze_solving_algorithm
http://www.enseignement.polytechnique.fr/profs/informatiqu
e/Jean-Jacques.Levy/poly/main5/node9.html
45
Jean-Luc Pasquier: 10077923
Oxford Brookes University
U08096
A maze-solving robot using Lego Mindstorms
This project involved the specification, design and implementation of a maze-solving
robot, coded in Java and using the Lejos API. The program is used to control a robot capable
of finding the exit of a maze using only its sensors and trying to keep the robot on track. The
text first introduces the Lego Mindstorms set, followed by the coding platforms that can be
used with the NXT brick and the maze-solving algorithm. After setting the objectives of the
project, this document sets the specifications and requirements for the robot and the maze.
Having defined the specifications of the robot, the design analyses all the functions
needed to allow the program to work. Once the design is done, the document moves into the
implementation of the movement and navigational systems for the robot and the coding of the
Tremaux algorithm in a java and robotic environment.
With design and implementation done, the testing and results are discussed with
emphasis of the problems encountered and the possible solutions to those problems.
46