Search Lab

Fall 2008

Purpose:

The purpose of this lab is as follows: The first part of this lab will be accomplished in an environment similar to the Capture the Flag environment used for the class project.  This environment will help you visualize how the searches occur.  The second part of this lab will have you use your search code in the BZFlag environment.  Write good modular code so that you can transfer your search structures between applications.

What you should learn:

When you complete this lab, you should be an expert in the following search methods: You'll also gain some experience in using a technique called probabilistic roadmaps.   We'll use the probabilistic roadmaps to create a "good enough" discretization of the world, plan a path through this discretization, and then use potential fields to follow the path.

For each of these search methods, you should be able to talk and write intelligently about the following:
For the probabilistic roadmaps, you should be able to talk and write intelligently about how you should sample the world to create a good path.

Description of the Programs used to Test and Visualize the Search Algorithms:

In previous semesters, various TAs and students worked to create a simple graphics world with trees, hills, agents, and flags. The objective is to have your agent search, from some arbitrary starting position, through the world until it finds the flag.  I know that you've programmed some search methods before, but to help increase your understanding and build your intuition about search, we have included simple animation that allows you to visualize the evolution of a search method and to see the path returned by a particular search method.  The animation is built around a two dimensional grid with agent and flag positions specified by (x,y) coordinates

The graphics world is made up of two packages: a World class, which does the animation and which calls your search routines, and a Search file, which contains "main" and simply initializes and calls the animation function.  (FYI, the animation is performed using OpenGL routines.)  You will fill out two classes that we have framed for you: an Agent class, that performs the search (and performs maintenance routines like managing search queues and requesting user input), and a Node class, that defines the domain of the search.  The World and Search classes as well as templates for the Agent and Node classes are available in zipped form here.  Please do not change what is pre-included in the Agent and Node classes as this is important for the graphics to work correctly.

From within the World  class, a call to agent->Search is made which will return a pointer to the path from the flag to your agent's starting position (this path is actually a linked list from the flag's node to the agent's node) and NULL if it fails.  In addition to finding a path, your program should also update the variable "totalnodes"; this variable is the total number of nodes that your search tries. A public function GetTotalNodes() should be part of your agent class; this function returns the value of the totalnodes variable, and is called by the World to determine the efficiency of your search. Your program will prompt the user to input a search method using something like the following:

Choose a search method from the following list:
[1]=DFS [2]=BFS [3]=UCS [4]=GS [5]=A*
For each search method, the World class will draw a yellow path from the agent to the flag and will report the number of nodes expanded, the amount of memory used, the path cost, the path length, and the amount of elapsed time used for your search (note that elapsed time will vary as a function of OS behavior and CPU workload --- remember this stuff from CS380?).

There are some functions defined in World.cpp and declared in World.h that you will probably find useful.  Note that these functions are not part of the World class, but are instead provided to act as an interface between your Agent code and the World code.  The functions include:

Make sure you build this with opengl32.lib and glut32.lib (glaux.lib can be excluded).  There are several .txt files included in the zip file.  These files represent different types of world that you can use to test your code.  When you begin the program, you will be asked to select which world you will use.

How to Apply Search in the BZFlag Environment:

Search can be used as a tool to find paths through a world.  Using search to develop a path is a form of a classic AI problem known as planning.  A full treatment of planning is beyond the scope of the class, so instead you'll use a very simple approach to planning known as probabilistic road maps.  These maps are described briefly in Section 25.4.  The basic idea is that you randomly choose points in the world, connect the nodes in some sort of reasonable way to form a graph, and then search this graph to find a good path from point A to point B.  This part of the lab is new for this semester and it should significantly improve results in the final lab, but we could have some problems.  Please report your problems early so that we can try to solve them together as a class.

For this part of the lab, you will apply probabilistic road maps to the BZFlag environment.  Do this by randomly choosing a number of points in the world.  If a point touches an obstacle, delete it and start over.  Start with a small number of points to get the hang of things, and then increase this to many more as your code evolves.

Next, start connecting nodes together by creating edges.  We're not trying to create a sophisticated way of connecting them together, just something to keep from creating a fully connected graphs.  As a first rule for culling edges, if an edge intersects an obstacle then do not add it to the list of edges; I do not want everyone to invent a way to do this, so please post solutions to this problem on the lab wiki.  As a second step, if the Euclidean distance between two nodes exceeds a threshold, then do not add it to the list of edges; you'll choose this threshold empirically, but note that it should be a function of the number of nodes you create.  The pseudo-code looks something like the following:
V = {nodes}
E = {edges}, initially empty
for each node i in V
    for each node j in V
       create an edge e(i,j) between i and j
       if (i=j) continue;
       if e(i,j) intersects an obstacle, continue;
       if the length of e(i,j) > threshold, continue;
       else add e(i,j) to E.
    end
end

You'll have to write code to detect the intersection and to compute the length of the edge given the (x,y) coordinates of each node.

Given the resulting graph G=(V,E), perform your favorite search from a starting point to the enemy's flag.  Return the list of nodes as the path that your agent should follow from the starting point to the ending point.

Follow those points using either a PD controller or potential fields.  This can be done by having the next node in the path act as a target point. When the agent is within a threshold distance of the target point, conclude that this node has been reached and set the next node in the path serve as the target point.

What you should turn in:

When you are done, you should schedule a time to pass off the lab with the TAs.  They will post a sign up sheet outside of their offices.  After passing off the lab, send the lab write-up to cs470ta@cs.byu.edu.  During passoff, we will run your code on a world you have never seen (plus some of the worlds that you have seen), and give you a grade.  Please be assured that the unknown world will be big, so be careful using magic numbers to define search queue sizes, etc.  We will be grading on accuracy of path costs, correctness of number of nodes expanded, amount of time to complete search, and memory use.

The lab write-up should include

  1. the amount of time you and your partner each spent on the lab,
  2. a summary of what you learned,
  3. a discussion of the heuristics you tried on your informed search,
  4. a discussion of what happens when a non-admissible heuristic is used, and
  5. a discussion of how you applied probabilistic roadmaps in the Capture the Flag world including
This write-up can be either an email attachment or just regular ol' text in the body of your email.  Do, however, check for spelling, grammar, and readability.

Make it work with VC++ 2005:

The project should compile fine in VC++ 2003. If you plan to do your work with VC++ 2005, some extra work is required:

  1. You might need some additional header files. You can find them here and here.
  2. To get rid of the warnings, put in "#define _CRT_SECURE_NO_DEPRECATE 1" at the top of the World.cpp file.
  3. To fix the errors in "error C2668: 'pow' : ambiguous call to overloaded function," simply change "pow (something, 2)" to "pow (something, 2.0)."

Lab 2 Passoff Sheet Posted:

You can download it here.