EECS110 Course Project Option 3, Spring 2018

 

The pyRobot Project

Description: http://www.cs.hmc.edu/~cs5grad/cs5/pyRobot.png

Overview

In this project you will program a simulated robot to navigate through its environment.

The screenshot above shows the actors in this simulation. The red circle is the robot. The red line emanating from it is its laser rangefinder that can be pointed in any direction. The green circle is the goal point, which can be set by clicking with the g key held down. The walls are blue and the obstacles are black.

At each time step, the robot senses its environment, including the distance it reads from its range sensor, its global position, and its bump sensors (in case it hits a wall). With that information, your program should decide on the appropriate task (or "state") for the robot to execute. Based on the robot's task or state, in turn, it should decide what velocity it should set for itself.

Project Goal

You should design and implement an algorithm that will successfully and repeatedly enable the virtual robot to navigate from its current location to a user-specified goal. In particular, you should assume that the room will be square and there will be some number of random objects which are rectangles whose axes are parallel to the sides of the square. Your robot must be able to autonomously navigate to the goal object, no matter where it is placed in the room. You may assume that these rectangles will be separated by a "reasonable" distance from one another so that the goal object is always reachable! There are many possible algorithms for reaching the goal. Your algorithm does not need to follow the shortest possible path, but it should guarantee that it will always get the robot to the goal in a finite and reasonable amount of time. (For example, random wandering is too slow and unreliable, and thus not a satisfactory solution.)

Getting Started

If you are using a version other than Python 3.5 download and unzip the pyRobot.zip file from this link.

IMPORTANT: If you are using Python 3.5, please download pyRobot_3-5-1.zip and use it instead.

This package contains all the infrastructure that you will need. The file that you will be altering is pyRobot.py. Do not alter the other support files.

You should be able to run this program by running pyRobot.py from IDLE. In case, for some reason, the graphics do not work well from IDLE on your computer, you may wish to run the program from the command line as shown below:

Change directory in to the pyRobot folder and then run from your command line (Mac in this case):

% python pyRobot.py

or, if you're using windows and python isn't in your path, you'd type

> C:\python35\python pyRobot.py

You should see a window appear and the simulation will already be running.

Play with the program!

Start by playing with the program. When you first invoke the program, you will be prompted to enter a map number. There are three maps that we've supplied. Map 0 is an empty room, map 1 has two rectangular obstacles, and map 2 has more obstacles.

Note that there are several windows that open when you run the program. One is the robot simulation window. Another is the IDLE or command line window where all of the print statements will be displayed. You may also see a "Console" window which you can ignore.

Use the mouse to point to a location on the python robot window. Hold the "g" key down and click with the mouse button. This will set the position of the goal object. On the Macs, you may need to move the robot window around a bit before this will work correctly.

Now, drive the robot around manually. Here are the keys that have been defined:

 

Notice that the laser rangefinder is fixed relative to the orientation of the robot. So, as the robot turns, so does the rangefinder. However, the rangefinder can also be turned without turning the robot itself (as you see when you use the "r" and "R" keys).

You will also notice that, at the moment, the robot can drive right over the goal object and the program won't detect it.

In order to stop the program you can type "Q" in the robot simulation menu or Control-C or Control-D in the IDLE or command line window. Some computers may not recognize one of these but should recognize the others.

 

Manual Control

Take a look at the code in the file pyRobot.py. It has quite a few comments that you should read carefully. You will notice that the robot has a set of states that are specified by numbers, but each state number is given a name as well. The starter code that we have provided has five states. There is a variable called state that keeps track of the current state of the robot. This state is initially 1 (also called KBD) indicating that the robot begins in a state in which it is being manually driven by a human user via the keyboard.

The program enters an infinite loop (you'll see the while True statement that runs this loop). Inside that loop, the simulator obtains the robot's current x and y coordinates, its heading (thd) in degrees, and the values of its bump sensors. These sensors evaluate to True when they press up against a wall. You'll see this a bit further down in the code.

Skip down to the part of the code with the line

if state == KBD

The program begins with state equal to KBD so this condition will be True initially. The variable key is the name of the key that was just pressed by the user (if a key was, in fact, pressed). Notice that if the key was "i" then the command self.setVels(FV, 0) is invoked. This sets the robot's forward velocity to FV the maximum permitted forward velocity. Notice that FV was set earlier in the program to be the maximum forward velocity. The second argument of setVels is the rotational velocity for turning the robot. Notice that RV was defined earlier in the code to be the maximum rotational velocity. When we press "j" or "l" we turn the robot counter-clockwise or clockwise, respectively.

It is important to notice that once the robot's forward or turning velocity are set, the robot will keep moving according to these velocity values until some action is taken to change the robot's course. In other words, the self.setVels command can be viewed as setting the robot's motors and these motors will maintain their velocity settings until the settings are changed by a later self.setVels command.

In other words, the robot will continue moving according to its current velocity settings even if we were to somehow leave the while loop. The while loop is only used to decide what state to enter next based on the robot's current location, sensor inputs, and possibly keyboard input.

Finally, take a look at the other key presses that are defined for KBD state. We can turn the laser rangefinder (without turning the robot!) using "r" and "R". Experiment with all of these manual controls and take a look at the corresponding code in the program so that you understand how this all works. The "s" key does something special. More on that next!

Autonomous Control

Move the goal to some location other than it's initial default location (which is right at the origin where the robot starts). To do this, move the mouse to the desired location and press the "g" key. On a Mac, you may need to first move the robot window once or twice before this will work.

Now, press the "s" key. Notice in the code that pressing "s" changes the state of the robot from KBD to the state GO, which, you will notice, is just another name for the number 3. This is state 3, but giving it a meaningful name like GO is convenient.

Now the robot is in the GO state and NOT in the KBD state. This means that pressing keyboard keys will not control the robot. (However, pressing the space key will return the robot to the KBD state so that it is back under manual control. Do you see where in the code we made this happen?).

What happens in the GO state? Take a look a bit further up in the code in the line that begins with

if state == GO

Next time through the while loop, the robot will hit this statement and activate this piece of code. In particular, it sets the rangefinder to point 0 degrees away from the heading of the robot (in other words, in the direction of the robot's movement). It then checks to see if the robot has gotten close to a wall (the range distance is within 2 times the radius of the robot). If so, it changes state again to the TURN state. Otherwise, it sends a message to the robot to move full speed ahead.

Now for the TURN state. This state sends a message to the robot to start turning at maximum rotational velocity. It then sets a variable called pause_stop to be 3 seconds beyond the current time. It sets another variable called nextState to be the GO state. Finally, it enters state GOFOR. As we will now see, this will have the effect of forcing the robot to stop turning in 3 seconds and then enter the GO state.

GOFOR is an interesting state. Notice that its block of code simply checks to see if the current time, time.time() has exceeded the time pause_stop. If so, it sets the state to nextState which is currently GO.

What You Will Do

Notice that we have provided some very crude autonomous control through the GO, TURN, and GOFOR states. Your task is to design an algorithm for the robot to autonomously find the goal and to implement new states that implement your algorithm. Here are the requirements for your pyRobot program:

A Note on Sensor Readings

You'll notice in the simulator that we get the robot's x- and y-coordinates, its heading (thd) and, other sensor readings from the robot. You may be inclined to set these values. However, these are sensor values that the robot obtains and not values that can actually be changed by simply assigning them values. You can only change the robot's position by issuing movement commands through the setVels function, which sends information to the robot's motors.

A Note on Reducing the Number of States

You may find that you need to implement many different states, some of which do more-or-less the same thing. This is OK. However, there are a number of ways of reducing the number of different states and keeping your code quite short and simple. For example, some tasks may comprise a sequence of smaller tasks. You might have a state for each small task. Then, the big task could simply make a list of the smaller tasks that need to be performed to accomplish the big task. The first small task would be removed from the list and executed. When it is done being executed, the next state to be executed would be taken from that list! By using lists of tasks, you can save quite a bit of coding.

What to Submit for the Intermediate and Final Submissions

There are two submission deadlines. By the Intermediate Deadline on Sunday, 06/03 at 11:59 PM you should submit the following:

o   Your name (and your partner's name if this is a pair submission)

o   The project that you've chosen (pyRobot in this case)

o   A section entitled "Description of the Approach". This section will normally be 2-3 paragraphs long. This section should describe, in detail, the process or "algorithm" that the robot will use to navigate from its starting point to the goal point (wherever that might be). Your plan should be general enough to handle any room with rectangular obstacle whose edges are parallel to the walls of the room and that are spaced sufficiently far apart.

·         A file called pr3_milestone.py (renamed from pyRobot.py) that contains a working solution for maps 0 and 1. Your code might not implement your complete algorithm yet, but it should implement enough of your algorithm to handle any goal location in these two maps.

·         Submit your pr3_milestone.txt and pr3_milestone.py files at Canvas.

 

Final submissions are due by 11:59 PM on Sunday, 06/10.

For the final project submission, you should submit the following:

 

Some notes about the design, implementation and testing of your code: