Introduction:

Path planning is the task of getting from point A to point B and, in many cases, is similar to the shortest path problem. Although there are many different algorithms and approaches they share some commonalities. One common feature in path-planning algorithms is a map. Although later in the semester we will be studying how to dynamically create a map, today you will be provided with a map and we will focus on the use of it. The goal of the lab is to implement one of the path-planning algorithms we studied in lecture #4, Dijkstra’s Algorithm, A*, or RRT.

Webots Map:

The RatsLife maze is a 10 by 10 grid in which each cell has 0 to 3 walls separating it from its neighboring cells. The map representation, in the RatMap.java class, is a 2-dimensional array in which each cell is denoted by a row and column number, [row#][column#]. The bottom left cell of the grid is the cell [0][0] and the top right cell is the cell [9][9]. Each cell has associated with it a tuple of 1’s and 0’s that denote the presence or absence of a wall. This tuple is implemented in the RatMap.java class as a 1 by 4 array in which the walls are listed in the order “east”, “north”, “west”, and “south” wall. For example, consider the cell [3][5] with the tuple (1,0,1,0). This cell is 4 rows up from the bottom and 6 columns to the right (since we start counting at zero) and has a wall on its east side and on its west side and no walls on its north and south sides. The RatsLife maze also contains four chargers that will recharge your robot’s battery in the RatsLife contest. The locations of these chargers are the goals for your path-planning. Your robot starts in cell [0][0] and the chargers are located in cells [0][3], [5][3], [8][5], and [9][1].

Exercise:

1) Make a new empty directory, lab5, for this lab using the terminal.

2) Open Webots and create a New Project Directory, choosing the directory you created in step 1, and create a New Controller using the Wizard. Name your controller lab5Controller.

3) Download the lab5Files. Put the protos in the lab5 directory, merging with the one already there, put the folder csci3302lab5 in the lab5Controller folder found in the Controllers folder and put the lab5.wbt file in the Worlds folder replacing the one that is already there. The other two files RatMap.html and MapCell.html are the javadocs for the two classes that implement the map discussed above. In your controller you will need to import csci3302lab5.RatMap; and import csci3302lab5.MapCell;

4) Choose one of the shortest-path algorithms to work with and one of the chargers for your goal.

5) If you are successfully able to navigate to a single charger, then try to start at [0][0] and navigate to all chargers in turn. The RatMap.java class has a getChargers() method that may be useful.

6) Notes: In order to navigate the map, the robot needs to keep track of its position in the world. For your final project you will use the odometry that you developed last week to track position, but for this lab we have altered the E-Puck to include a GPS. The GPS functions of the Webots API allow you to get the (x, y, z) coordinates of the robot in the world. The MapCell class then has a method, getMapPosition(double [] coord) that will return the occupied cell in terms of the [row][column] coordinates when given a double array of the GPS coordinates. To initialize and use the GPS on the E-Puck, declare a GPS object, initialize it, and then call its getValues() function.

//above constructor

GPS myGPS;

//in constructor

myGPS = getGPS(“gps”);

myGPS.enable(64);

//in run()

double [] coordinates = myGPS.getValues();

You may also find it helpful to add a function for the robot to move one cell or to turn 90 degrees. The encoders are helpful for this type of functionality. The encoder resolution for the E-Puck is 159.23, which means there are 159.23 ticks per radian and the distance from one cell to the next is about $\frac{1}{9}$ of a meter. To use the encoders to move a specified distance, d, you can use the expression $\frac{159.23d}{0.0205}$ to give the encoder value needed to move d. You can then write an expression like:

if(getLeftEncoder() < resultFromAbove){

setSpeed(400,400);

}else{

setSpeed(0,0);

}