MSRS Code Page Home      MSRS Maze Simulator

Line Following using the Maze Simulator


Questions about Line Following in the MSRS Simulator come up from time to time in the Discussion Forum. So I decided to try setting it up using the Maze Simulator. The concept is very simple -- Make some really tiny walls (only a few millimeters high) to act as the lines! The result is shown in the screenshot below:

To set up the Line Following environment there are several steps you need to take:

Creating a Bitmap Image for Line Following

The objective of creating a bitmap image is to specify the lines that the robot must follow. It only needs to be in two colors -- the background and the lines. A sample image is shown below (at half size - the full image is 500x500):

A copy of this image is included in the ZIP file. It is called, not surprisingly, LineFollowing.bmp. You need to copy it into the Apps\QUT\MazeSimulator directory.

The starting point is in the bottom left corner, and the finishing point is the circle near the middle. Notice that there are loops and dead ends. It is not an easy map to follow.

It is difficult to draw smooth curves in a bitmap, and the Maze Simulator is not very good at handling them because it is designed to work with straight lines. Robots cannot easily turn 90-degree corners. However, this just adds to the challenge!

As with any maze, the pixel in the top-left corner specifies the background color (which is grey in this case).

Changing the Config File

The Maze Simulator configuration is saved in MazeSimulator.Config.xml. A sample config file is included in the ZIP file. You need to copy this file into the Apps\QUT\Config folder. Note that you should make a backup copy of the existing config file first!

You can edit this file using Notepad. The following instructions explain the changes to the file, but you do not have to make them if you use the supplied file.

The first thing that needs to be changed is the name of the Maze:
Notice that the file should be in the MazeSimulator source folder.

You can change the line color if you wish, but line following is usually done using black lines on a light background (or vice versa). The ground color can be changed using the texture. The plaster texture is a good light background:
This file should already exist in the store\media folder.

The color of the lines can be changed using the corresponding entry in either the WallTextures or WallColors. In the sample config, the WallTexture is specified as black for the 8th entry in the WallTextures:
(The 8th entry corresponds to White, which is the color of the lines in the bitmap image.)

The lines have to be really, really low walls. So change the Height Map so that the 8th entry is tiny:

Side note: The value for black is set to 0.005. If you change the background color in the bitmap to black, then you can get white lines on a black background. The background has to be lower than the lines. This is a special case because black has a pixel value of zero.

Notice that the 8th entry is 0.01. Normall this would be 1cm high, which is still a decent step, so you also need to modify the parameters that affect the scaling:
This reduces the height by a further factor of 10. The Grid Spacing is also reduced so that the pixels in the bitmap only correspond to about 1cm.

Lastly, position the robot so that it starts from the correct location. This is done as follows:

Modifying the Maze Simulator's Camera Orientation

When the Maze Simulator creates the simulated Pioneer 3DX robot, it places a webcam on top of the robot. By default, cameras are oriented so that they look out horizontally. In order to see the floor immediately in front of the robot, we need to make two changes: Move the camera forward to look over the front of the robot and tilt it downwards.

The changes to MazeSimulator.cs are quite minimal. Locate the CreateCamera method. Replace the existing statement that sets the Position of the camera (commented out below) with the bolded statements:

private CameraEntity CreateCamera()
    // low resolution, wide Field of View
    CameraEntity cam = new CameraEntity(320, 240, ((float)Math.PI * 0.4f));
    //CameraEntity cam = new CameraEntity(320, 240);
    // TT Dec-2006 - Remove slash for V1.0
    cam.State.Name = "robocam";
    // just on top of the bot
    //cam.State.Pose.Position = new Vector3(0.0f, 0.5f, 0.0f);
    cam.State.Pose.Position = new Vector3(0.0f, 0.5f, -0.5f);
    // Set the camera tilt angle
    // Rotate about the X axis
    AxisAngle aa = new AxisAngle(new Vector3(1, 0, 0), (float)(-85 * Math.PI / 180));
    cam.State.Pose.Orientation = Quaternion.FromAxisAngle(aa);

These changes move the camera forwards and angle it down at 85 degrees (the -85 in the AxisAngle). It would be better to expose the Pose as a parameter in the config file, but this requires a lot more changes. It will be included in a future version of the Maze Simulator. For now just make the changes above.

You might think that the camera should be angled down at 90 degrees. However, this causes some strange behavior in the simulator as the robot rotates. The image in the webcam suddenly jumps as the orientation of the robot crosses 90 degree boundaries and it gets confusing. Using 85 degrees is close enough.

Once you have made these changes, rebuild the Maze Simulator.

Requirements and Installation

This example is just an application of the Maze Simulator. Therefore you need to download and install the Maze Simulator first. Make sure that you have this working before you try to implement Line Following. Then make the minor code change above and rebuild. If you want to return to the original camera orientation, just comment out the new lines and recompile again.

Download the extra files for Line Following. Unzip the file and then copy the LineFollowing.bmp to the MazeSimulator source directory (which should be Apps\QUT\MazeSimulator) and copy the MazeSimulator.Config.xml file to the Config folder (which should be Apps\QUT\Config). You should take a copy of your existing config file before you overwrite it.

How to run Line Following

NOTE: There is no code to perform Line Following! This application just provides the simulation environment you need to do Line Following. The rest is up to you. You do NOT modify the Maze Simulator service. Instead, write a new service that connects to a Webcam and a Differential Drive as partners.

At the MSRS Command Prompt, enter the following command:
dsshost -port:50000 -tcpport:50001 -manifest:"Apps/QUT/MazeSimulator/MazeSimulator.manifest.xml"

Alternatively, you can run the Maze Simulator from Visual Studio. Regardless of how you start the Maze Simulator, you must have copied LineFollowing.bmp and MazeSimulator.Config.xml to the correct folders first.

When the Simulator window appears, select the robocam from the Camera menu. You should see something like the following screenshot:

The objects in the window at the bottom are the bumpers at the front of the Pioneer robot. If you do not want these in the picture, you will have to adjust the Z coordinate of the camera Position a little more. However, this gives you a point of reference.

The T-junction is the start of the Line Following maze. This is where your robot should begin its journey, so it needs to start out by moving forwards until it recognizes the line.

If you use the Dashboard that comes in the Maze Simulator package, you can connect to the Pioneer's Differential Drive and also the camera. Try driving the robot around and following the line yourself. It's not easy!

The Challenge

Now it is over to you. Write a service that can successfully navigate by following the lines and locate the circle at the end point. Processing the images should not be too hard because the black line is very clear. You can either handle the images yourself or use a package like RoboRealm. (Look in the Dashboard code to see how to connect to a webcam and capture images.)

Good luck and send me an e-mail when you have it working!

Legal Stuff

Thanks to Jason Summerour at RoboticsConnection for giving me a sample line following pattern.

Maze Simulator: [ Overview ] | [ Tutorial ]