Arduino Recursive Backtracking Implementation, for the Micromouse Portuguese Contest c
Sergio e´ rgio Silva∗ , Diogo Duarte† , Rolando Barradas‡ , Salviano Soares§ , Ant´ Antonio o´ nio Valente∗ , and Manuel J. C. S. Reis§ ∗
School of Sciences and Technology, UTAD, Vila-Real Portugal and INESC TEC, Porto, Portugal
ORCID:0000-0003-4410-3071,
[email protected] and ORCID:0000-0002-5798-1298,
[email protected] † University
of Aveiro, Aveiro, Portugal
ORCID:0000-0001-6307-8989,
[email protected] ‡
University of Minho, Braga, Portugal
ORCID:0000-0001-9399-9981,
[email protected] §
School of Sciences and Technology, UTAD, Vila-Real Portugal and IEETA, UA Campus, Aveiro ORCID:0000-0001-5862-5706,
[email protected] and ORCID:0000-0002-8872-5721,
[email protected]
c Portugues Portuguesee Micromouse Micromouse Contest Contest is a inno inno-vated robotic robotic contest contest that addresses addresses the need to enhance enhance student interest interest and performan performance ce in science, science, technolog technology, y, engineer engineering, ing, and mathematics (STEM) courses, while fostering skills that are important important prereq prerequisi uisites tes for IT careers. careers. To facilitate facilitate the access access to younge youngerr studen students ts a robot robot kit and an Arduin Arduino o libra library ry were were developed developed and made available available on GitHub. GitHub. Some of the library examples examples include include the common common algorithms algorithms used to solve solve mazes, mazes, like the Flood Fill, Right or Left Wall Following to name a few. Recursiv Recursivee Backtrack Backtracking ing algorithm is often used to solve mazes especially if there is a lot of computer power “under the hood”. This is not the case of the Arduino platform that only has 2.5 KB of SRAM and a clock speed of 16 MHz, so implementing Recursiv Recursivee Backtrack Backtracking ing becomes becomes quite difficult. difficult. In this work, work, we show show how to implem implement ent Recursi Recursive ve Backtr Backtrack acking ing to find if there are better solutions for solving the maze. We also show the memory measurements for three Arduino common platforms the Leonardo, the UNO and the DUE. Index Terms—Arduino, STEM, Backtracking, Micromouse.
Abstract—The
I. I NTRODUCTION Recursiv Recursivee Backtrack Backtracking ing is a general general algorith algorithm m for finding some some (or all) all) of the soluti solutions ons to comput computati ationa onall proble problems ms like like findi finding ng a path path in an Maze Maze.. In the the part partic icul ular ar case case of the Microm Micromous ousee the maze maze is 16 × 16 cells cells and the start start is the bottom bottom left left and that is the only cell cell the Robot knows. knows. Recursiv Recursivee Backtracki Backtracking ng (RB) is a particula particularr case of Graph and tree tree search search algorith algorithm m and its a partic particula ularr case case of brute brute force. In fact we can look at it like a 5” Hammer to hang a picture on the wall; you probably are going to break the wall instead of hanging the picture. Therefore, and because, its so computer demanding we havent found any examples of RB implemen implementati tation on in the large large Arduino Arduino communit community y. Recursion Recursion is generally speaking a problem that call itself, backtracking on other hand means trying all the possibilities and if we get stuck then we try another solution. So to keep things simple we can state that we backtrack a path because we may have to try a different choice and we use recursion because later versions of the problem are just slightly simpler versions of the original.
I I . I MPLEMENTATION P ROCEDURE Althou Although gh first first introd introduce uced d by Trem Tremaux aux,, the Depth Depth First First Algori Algorithm thm (DFA), (DFA), as a maze-s maze-sear earchi ching ng method method,, was only only imple implemen mented ted by Robert Robert A. Tarjan arjan in june june 1972[1 1972[1]. ]. Tarjan arjan implementation explain how DFA can be used to solve graph problems. Backtrack algorithm is a widely used algorithm on artificial intelligence[2]. There are many different approaches to pathfinding and for our purposes it is not necessary to detail each one. Pathfinding can be divided into two main categories, undirected and directed[3]. The undirected approach is analogous to a rat in a maze running around blindly trying to find a way out. The rat spends no time planning a way out and puts puts all its energ energy y into into movin moving g around around.. Thus Thus the rat might might neve neverr find find a way way out out and and so uses uses most most of the the time time going going down dead ends. There are two main undirected approaches that improve improve efficien efficiency cy.. These are BreadthBreadth-first first search search and Depth-firs Depth-firstt search search respecti respectivel vely; y; they they are well known search search algorithms as detailed for example in[4]. Breadth-first search treats the virtual world as a large connected graph of nodes. It expands all nodes that are connected to the current node and then in turn expands all the nodes connected to these new nodes. Therefore, if there is a path, the breadth-first approach will find it. In addition, if there are several paths it will return the shallowest shallowest solution solution first. first. The depth-firs depth-firstt approach approach is the opposite of breadth-first searching in that it looks at all the children of each node before it looks at the rest, thus creating a linear path to the goal. Only when the search hits a dead end does it go back and expand nodes at shallower levels. For problems that have many solutions the depth-first method is usually better as it has a good chance of finding a solution after exploring only a small portion of the search space. So, we need to formalize the problem in the Micromouse space. Lets look at the Micromouse Maze of figure 1. The start of the maze is marked with the letter S and the end with an X, and the Micromouse only knows the walls that are in black. Therefore, as the Micromouse passes to the second cell (must be Cell(14,0)) there will be two possible paths. It can go front or turn right (if of course there is no wall at is right).
Fig. 1. Micromouse view of maze.
Cell(15,0)
Fig. 3. Micromouse implementation of RB in a “no walls” maze. The chars # indicates walls, the O visited cells, and * the micromouse robot path.
Cell(14,0)
Cell(13,0) Cell(14,1)
Cell(13,1)
Cell(14,2) Cell(15,1)
Fig. 2. Graph approach to recursive backtracking.
If it goes right to Cell(14,1) there will be 3 more possibilities and so one. Each new cell will introduce 3 more possibilities to find the correct path. Figure 2 graphs the micromouse robot path. Its easy to see that the possibilities will grow exponentially specially in the case that there are no walls between Cell(14,0) and the center of the maze. For this particular case there will be 47175 possible solutions, although for the shortest paths there are only fourteen solutions as can be seen in figure 3 where RB implementation is used to solve the “no walls Micromouse Maze”. Obviously, we cannot use this implementation on a Leonardo or UNO because of the amount of use memory 7692 bytes in the horse case. So, how can we implement the algorithm in these platforms with so limited memory? The answer is to limit the solutions to the shortest ones. But how
Fig. 4. New approach for selective RB. The chars # indicates walls, the O visited cells, and * the micromouse robot path.
can we do that? The solution is to constrain the best solution size. We start with the possibility that the best possible solution is fourteen, therefore the variable best solution start equal to 15. After we start graphing the maze each (??) of course will lead to paths with a value greater than 14. We then discharge this path because it will lead to a non-best solution. With this new approach in practice we have obtain the results of figure 4. As we can see from figure 4, not only, the time needed to find all the 1716 best solutions was only 469 milliseconds, but it only used 780 bytes of the SRAM, making it possible to run on a Leonardo or a UNO. Of course, now the question is - if there are walls that make the shortest solution to be greater than 14? To account to these factor, we applied a do
Fig. 6. Graphical representation of performance versus chosen best solution value.
(a)
best possible solution was 64. From the above graphic, we see that the cost of using an underestimated best solution is horse than the overestimated best solution. III. A LGORITHM E XPLAMATION The Arduino code used can be divided in four parts. The first part is the function solve. This function is used to recursively try to find a solution for the Maze, we also use this function to place the S in the start position. void solve(int x, int y, int MAX_VALUE) { Best_Solution = MAX_VALUE; if (Backtracking(x, y, 0) != MAX_VALUE) { output_maze[x][y] = ’ S’ ; } else { output_maze[x][y] = ’ S’ ; Serial.println("NO PATH FOUND"); } }
For each time the Solve solution is called we perform the Backtracking method that is the second part of our code. (b) Fig. 5. Performance differences for best solution. (a) Best solution equal to 28, and (b) for best solution equal to 64.
while statement in which if no solution is found with the best
solution equal to 14 then best solution will be incremented. That saying the algorithm will try to find a solution that fits the selective condition of 14 and if he finds at least one solution it ends, else it passes the selective condition to 15 and tries again to find a solution that fits the condition. In fact, the algorithm takes some time because we are always repeating some part of the steps as can be seen in figure5. Where for best solution equal to 28 and best solution equal to 64 we get different performances. The analysis of the results shows that the Selective technique loses performance if we dont choose the best solution correctly. The next table shows the performance decrease versus the chosen best solution for the given maze where the
// Backtracking method int Backtracking (int x, int y, int count) { / ** Accept case - we found a solution**/ if (maze[x][y] == ’X’ ) { Best_Solution = count; counter++; cloneMaze(); return count; } / ** Reject path - we are hit a wall or our path **/ if (maze[x][y] == ’#’ || maze[x][y] = = ’*’) { return _Max_Value; } / ** Reject the path - we already have a better solution! **/ if (count == Best_Solution) { return _Max_Value; } / ** Backtracking Step **/ // Mark this location as part of our path
if (output_maze[x][y] ! = ’ S ’) maze[x][y] = ’*’; int result = _Max_Value; int new_result = _Max_Value;
// Try to go Right new_result = Backtracking(x, y + 1, count + 1); if (new_result < result) { result = new_result; } // Try to go Up new_result = Backtracking(x - 1, y, count + 1); if (new_result < result) { result = new_result; }
Fig. 7. Micromouse Portuguese Contest final B maze and results.
// Try to go Left new_result = Backtracking(x, y - 1, count + 1); if (new_result < result) { result = new_result; } // Try to go Down new_result = Backtracking(x + 1, y, count + 1); if (new_result < result) { result = new_result; }
Fig. 8. Micromouse Portuguese Contest final A maze and results.
Serial.begin(9600); start = micros(); pinMode(13, OUTPUT); Serial.println("Starting bactracking! " ); Best_Solution = 8 8; do { solve(31, 1, _Max_Value); _Max_Value = _Max_Value + 1; if ( _Max_Value == 97) break; finishtime = micros(); printTime(); } while (output_maze[0][0] != ’#’);
// Unmark this location maze[x][y] = ’ o’ ; if (result < _Max_Value) { return result; } / ** Deadend - this location isn’t part of the solution **/ // Go back if(96000-freeMemory()>SRAM)SRAM=96000freeMemory(); //To measure the amount memory remove for better times return _Max_Value;
finishtime = micros(); printMaze(); printTime(); Serial.print("SRAM: "); Serial.println(SRAM);
}
The third part is a function to clone the maze call cloneMaze : void cloneMaze() { for (int x = 0; x < 3 3; x+ +) { for (int y = 0; y < 33; y+ +) { output_maze[y][x] = maze[y][ x]; } } }
This function just passes all the cells of the original maze and copies then to the output maze. The last part is the do while function that allows us to test if there is a solution for a particular _Max_Value and if it doesnt find the solution it increases the _Max_Value by one and tries again. Although this process is slower than a top down solution it ensures that we always get the best solution. unsigned long start; unsigned long finishtime; void setup() {
} void loop() { }
The rest of the code allows us to measure the performance, and to print the amount of equivalent solutions to the best. IV. R ESULTS The method was tested using the Micromouse Portuguese Contest final mazes (final A and final B). The Micromouse Portugusese Contest is a annual international Micromouse robotic contest and also a STEM project[5]. The 2016 event ´ was in Agueda, Portugal, with 11 teams, and with the paticipation of Ng Beng Kiat (World Best Time), and Peter Harrison (European Best Time). At the finals there was two classes: final A (figure), for those o acheived to reach the center of the maze in trials, and final B (figure), for the rest. The figure 9, shows the results using the maze of final A and with _Max_Value=86 . The method found the same winner
Fig. 9.
Micromouse Portuguese Contest final A maze results with
_Max_Value=86. The chars # indicates walls, the O visited cells, and * the micromouse robot path. As mentioned before, S and X indicates the START
Fig. 11.
Micromouse Portuguese Contest final B maze results with
_Max_Value=36. The chars # indicates walls, the O visited cells, and *
the micromouse robot path.
and END cells respectively.
Fig. 10. Micromouse Portuguese Contest final A maze results with an increase _Max_Value to 90. The chars # indicates walls, the O visited cells, and *
the micromouse robot path.
Fig. 12. Micromouse Portuguese Contest final B maze results with an increase _Max_Value to 40. The chars # indicates walls, the O visited cells, and *
the micromouse robot path.
solution of Demicus 4E form Peter Harrison as showned on figure 7 If the _Max_Value is increased (figure) the found solution is acheived with less visited cells and an increse in SRAM used. The method was also tested in final B maze with _Max_Value=36, figure 11, and _Max_Value=40 , figure 12. V. C ONCLUSION In conclusion, we developed a Recursion Backtracking program to solve the Micromouse Maze. The implemented
program ensures that if there is a solution to the Maze the solution will always be found. It also ensures that this solution is the best solution possible. The program can be used together with a flood fill that first tries to find a path to the center of the Maze and after finding this path, the program can be used to check if the rest of the unknown paths can have a better solution. The solution implemented looks in results much like the Breath first meaning that it will not only find a path between Start and End (if one exists!) but it will find the shortest path.
ACKNOWLEDGMENT The authors would like to thank... R EFERENCES [1] R. Tarjan, “Depth-first search and linear graph algorithms,” SIAM Journal on Computing, vol. 1, no. 2, pp. 146–160, 1972. [Online]. Available: http://dx.doi.org/10.1137/0201010 [2] P. van Beek, “Chapter 4 - backtracking search algorithms,” in Handbook of Constraint Programming, ser. Foundations of Artificial Intelligence, P. v. B. Francesca Rossi and T. Walsh, Eds. Elsevier, 2006, vol. 2, pp. 85 – 134. [Online]. Available: //www.sciencedirect.com/science/article/ pii/S1574652606800088 [3] R. Graham, H. McCabe, and S. Sheridan, “Pathfinding in computer games,” The ITB Journal, vol. Vol. 4, no. Iss. 2, p. Article 6, 2003. [Online]. Available: http://arrow.dit.ie/itbj/vol4/iss2/6 [4] S. J. Russell and P. Norvig, Artificial Intelligence: A Modern Approach , 2nd ed. Pearson Education, 2003. [5] S. Silva, S. Soares, A. Valente, R. Barradas, and P. Bartolomeu, A Iniciativa micromouseutad.pt e o Est ´ ımulo ao Saber Tecnolgico no Ensino Pr´ e- universit´ ario , ser. (Captulo Espaol de la Sociedad de Educacin del IEEE). IEEE, 2016, ch. 8, pp. 59–68.