Project 4: Finite State Machines

Project Goals

At the end of this project, you should be able to:

Project Outline

The goal for the hovercraft is to navigate to a specific "corner" of a room or hallway. Define theta1 to be the initial orientation of the craft (nominally oriented with the hallway). Define theta2 to point in a direction orthogonal to theta1. If the switch is in a low logic state, then theta2 should be clockwise from theta1. Otherwise, theta2 should be counter-clockwise from theta1.

Here are the steps:

  1. Ramp up the middle fan to a level that enables the craft to leave the ground.
  2. Navigate along theta1 while avoiding oblique obstacles (obstacles such that the two distance sensors give very different values).
  3. If 15 seconds has gone by since step #2 has started, then the craft should brake long enough to stop (this time period should be represented by its own state). Then, continue with step #2.
  4. Should an obstacle appear directly in front of the craft during execution of step #2 (as indicated by the two distance sensors having similar values), then the craft should first brake and then turn toward theta2. If the new direction is also blocked by an obstacle, then the craft should power down and stop.
  5. Navigate along theta2 while avoiding oblique obstacles.
  6. If 15 seconds has gone by since step #5 has started, then the craft should brake long enough to stop. Then, continue with step #5.
  7. Should an obstacle appear directly in front of the craft while executing step #5, then the craft should first brake and then turn toward theta1. If the new direction is also blocked by an obstacle, then the craft should power down and stop.
  8. Continue with step #2


Project Components

All components are required to receive full credit for the project.

Part 1: Finite State Machine Design

Design a complete FSM in diagram form:

Part 2: Finite State Machine Implementation

Note: this part will count for two personal programming credits (and can be split between two people)

Modify your main function such that it is structured as follows (you will of course need to add other code). Here is an outline for the code:

int main(void) {
       int16_t counter = 0;
       int16_t heading, heading_last, heading_goal, heading_error;
       int16_t rotation_rate, distance_left, distance_right;

       int16_t theta1, theta2;
       uint8_t state;

       #APPROPRIATE VARIABLE DECLARATIONS HERE#

       
       #APPROPRIATE INITIALIZATIONS HERE#

       timer0_config(TIMER0_PRE_1024);   // Prescale by 1024
       timer0_enable();  // Enable the timer 0 overflow interrupt
       sei();  // Enable global interrupts

       // Initialize variables
       theta1 = heading_goal = get_orientation();

       theta2 = ## add code to set theta2

       state = STATE_START;

       distance_left = get_distance(LEFT);
       distance_right = get_distance(RIGHT);

      

       // Begin to lift off the ground
       middle_thrust_dir(HOVER);

       #RAMP UP MIDDLE THRUST TO HOVER#

       // Loop forever
       while(1) {              
       
           heading = get_orientation();
           heading_error = compute_error(heading_goal, heading);
       
           rotation_rate = get_rotation_rate();

           distance_left = get_distance(LEFT);
           distance_right = get_distance(RIGHT);

           // Display
           if(#SWITCH 0 OPEN#) {
                display_distance(distance_left);
           }else{
                display_rotation_rate(rotation_rate);
           }
           if(#SWITCH 1 OPEN#) {
                display_orient(heading_error);
           }else{
                display_orient(heading);
           }

           // Finite state machine
           switch(state) {
               case STATE_START:
                   :
                  break;
               case STATE_NAVIGATE_1:
                   :
                  break;
                :
                :
               default:
                  // this should never happen: but take safety steps
                  //   if it does
                  #Shut down craft#
                  while(1){};
           }


           // Steer away from obstacles
           status = obstacle_control(distance_left, distance_right, rotation_rate, #PICK SOME SMALL VALUE#);

           if(status == -1) {
                // No obstacles: steer to desired heading
                pd_control(heading_error, rotation_rate, #PICK THE SAME SMALL VALUE#);
           }

           // Increment time
           ++counter;

           if(flag_timing) {
               // Error condition: your code body is taking too much
               //  time.  Indicate this with an LED display of some form

           }

           // Wait for the flag to be set (happens once every ~50 ms)
           while(flag_timing == 0) {};

           // Clear the flag for next time.
           flag_timing = 0;
       }
}



References


What to Hand In

All components of the project are due by Tuesday, May 3rd at 5:00pm.


Grading

Group grade distribution:

Grades for individuals will be based on the group grade, but weighted by the assessed contributions of the group members.


fagg [[at]] cs.ou.edu

Last modified: Mon May 9 15:40:10 2011