Navigating a 2D Asteroid Field
Com S 476 FINAL PROJECT - Spring 2000

Joel Varney and Nicholas Lovell



The Problem

The universe that we used is a two dimension surface of a torus with a group of obstacles in the shape of convex polygons.  The objects are capable of translation and rotation, but only at a single fixed speed for each dimension, meaning that their motion is completely predictable in O(1) time.  The "robot" is a point-sized ship that is attempting to go from its current location to a small goal region (on the screen, the robot is shown as a circle to make it easier to see).  At any point in time, the ship can either drift or fire its engines in any direction, which is represented by a vector consisting of a bool (fire?) and a float (angle).  Because of the ship's acceleration the robot's motion is nonholonomic, and the configuration space is five dimension (position(2), velocity(2), time(1)).  Also because the robots motion in time is fixed, care must be taken not to go "back in time" while traversing the RRT.  Whenever the goal is reached a new one is chosen at random.

First the ast class was created to represent a single asteroid and provide functions to calculate it's current position and detect for collisions with a point.  Obs was then added that contains a list of asteroids and some functions to simplify things (i.e. to see if a point is in Cfree, only one function call has to be made).  Ship keeps information about position, velocity and time together and provides a function to move the robot to its next position after a given input vector and timespan.  Then planner uses an RRT to search for a useable path, using ships as nodes and vectors as edges.  It then returns a list of firing vectors in a list that the ship is to follow.  Main simply creates a window, instantiates the obs class and other variables, adds some asteroids, and runs a loop that moves the ship iterively and calls for a new path to be made on occasion.  After 1000 iterations, the RRT class "gives up", and goes as close as it can to the goal, but stops 10 steps short so that it will not come into an impossible situation nosed up against an asteroid.  The main function will execute those steps and call the planner again.

The obvious component to improve is the metric that determines which node in the RRT is to be extended from.  Our original metric was based on distance only, and had three major shortcomings, we called the orbital, reversal, and goal in asteroid problems.  The orbital problem occurs if a branch of the RRT got close to the goal, but had a high velocity to the side.  The result was that the ship is accelerating perpendicularly to its velocity, leading to a circle like a satellite in orbit.  The reversal problem was that when the ship reached a goal and had a speed in one direction, and the next goal appeared in the opposite direction, the root of the RRT was always closest.  Having the goal in an asteroid is still almost always solvable, because the asteroid will move out of the way, given some time, but if the RRT get very close to the goal and hits an asteroid, it will monopolize the adding of new edges, and gets nowhere.  We fixed the first two by setting it up so that ships that are traveling toward the goal are given a slightly shorter metric than distance alone.  We had two ideas about how to fix the last one, either including a random time to the quasi-random point and using the time difference in the metric, or when the RRT hits an asteroid deleting that branch of the RRT up to the previous fork.  We didn't have time to fully explore either possibility.

Only the function prototypes from some of the functions were used from the given code from the framework directory.  Otherwise the code was written from scratch.  Our code is reasonably efficient, the only obvious improvement being a modification to the collision detection that says that if the asteroid-point distance is greater than a certain radius, the can't be in collision.


Examples
Implementation Files

Source Code: