This project is primarily about code organization and software architecture. The end goal is to have the robot navigate a simple maze.
Since this project involves refactoring your code, it may be wise to make a new subdirectory for this project. Copy over only the code you need into the new organization.
The overall concept of the software architecture you will build this
week is that of a state machine. Your main function will be a simple
loop that has three steps.
- State update step: this should call a function that evaluates the current sensors, internal robot status, and current state, and sets the next state and goals of the robot.
- Nav step: this should call a function that takes in the current state and any other status information and determines the appropriate velocities for the robot.
- Action step: this is a simple call to vm(v, w). You should implement limits on v and w in the main loop, just before calling vm. Make sure the signals still have the same ratio after any modifications to address the limits.
One of your first tasks will be to make a robotState data structure that contains the state vector, the current task, other sensor values (virtual or the laser) and any necessary additional information, such as the current goal angle, distance, or position.
Your nav step should be a big switch statement based on the current state. Each case should call a function that calculates the proper translational and rotational velocities given the state, sensor readings, and the current goals (all stored in the robot struct).
After the case statement, the nav function should evaluate the sensors for local obstacles, and modify the velocities appropriately. In some states, such as the rotate state, this step may be optional. In other states, such as wall following, obstacle avoidance may be built into the function that calculates velocities. But you can think of this part of the nav function as the sanity check stage: if the robot is about to run into something, it should stop..
All of the tasks below should be executable from the single main function. You should specify which action the robot should execute through command line arguments. Once the robot has completed its task, you can have the robot move to a Quit state, halt, and terminate. For something like the wander function, which does not have a specific end state, we have often used a particular bump sensor or IR sensor to tell the system to quit (just find a bump sensor that works and put a piece of tape on it). You could also trigger a quit, for example, by having the robot be sensitive to something very close to its rear IR sensor.
The first task is to have your robot read in a set of x, y locations
and have it go from point to point to point until it reaches the last
point. This of this as a POINT_FOLLOW state with an index, an array
of points, and the number of points. The index indicates which point
the robot is currently trying to achieve. When it achieves the current
point, it should increment index and go to the next point, until index
is equal to the number of points, in which case it is finished and
should return to an IDLE state. It is fine for the robot to stop at
each point. You can assume there are no obstacles between points, but
the robot should be sensitive to obstacles in the environment and not
run into anything.
You may want to let the robot read the points from a data file as part of its initialization for this task. It is much easier than trying to type lots of points on the command line. Instead, give it a filename to read. To read a file in C, use fopen to open the file, fscanf to read the file, and fclose to close the file.
- The second task is to generalize your wall following so the robot can go to a wall if one is not near and turn appropriately given internal and external corners. You can treat this task as one having four states: WALL_FIND, WALL_FOLLOW, WALL_ECORNER, WALL_ICORNER. Alternatively, you build it all into a single WALL_FOLLOW state.
The final task is to get the robot to get through a small maze. You
can use the wall-following solution from the prior step to do this or
come up with your own algorithm. There will be a circular post at the
end of the maze. It will be an extension to recognize the obstacle and
stop a set distance away from it.
Next week during lab we'll build a simple maze in the lab or hallway and see if your robot can traverse it and recognize when it's done.
- Try to get smooth motion as the robot goes from point to point.
- Add other states and capabilities to your system, including ROTATE, TRANSLATE, ACHIEVE, or WANDER.
- Add some kind of feature estimation to your wall follow, trying to identify line segments or circles.
- Create some type of obstacle that could be placed at the end of the maze so the robot knows it has found the end.
- Create a real-time view of the sensors/robot position/robot orientation. You can use this skeleton file as the basis for creating an X-window and displaying information.
The report for each project should be a brief summary of what you did along with some code examples, terminal output, or screen shots, depending upon the assignment. Please organize the writeup as follows.
- Title of the project and your name(s)
- An abstract describing what you did in 200 words or less.
- A brief description of code you wrote and experiments you ran.
- A brief description of what you learned.
Make your writeup for the project a wiki page in your personal space.
Once you have written up your assignment, give the page the label:
Do not put code on your writeup page or anywhere it can be publicly accessed. To hand in code, put it into a project4 directory in the Private folder of your handin folder on Courses.