View Single Post
  #1   Spotlight this post!  
Unread 30-03-2011, 16:16
Ben_R_R's Avatar
Ben_R_R Ben_R_R is offline
Assistant Programing Mentor
FRC #2194 (Fondy Fire)
Team Role: Mentor
 
Join Date: Jan 2008
Rookie Year: 2007
Location: WI
Posts: 21
Ben_R_R is an unknown quantity at this point
Autonomous State Machine: Abstract Inner Classes?

Hello all.

The season is over for my team, and though next year is quite a ways off, I'm already looking ahead to next season. One question that has been weighing on my mind is the best way to actually go about implementing the state machine for autonomous in Java.

The most common way, based on the code I've seen posted here, seems to be some kind of large if-else if structure, or a switch block. We took this route for the code at our first regional. I personally have always found this method difficult to read and maintain.

The way we did it at our second regional was to create an inner abstract class with one abstract method, getNextState(), then in the body of the method we put the actions for that state. We then put the states into a hashtable with the name of the state as the key. Here is an example (not from our final code, and with the boring repetitive bits removed for brevity and ease of reading):

PHP Code:
public class StateTestAutonomousFF implements AutonomousFF {
    
    
// snip...
    
    /** Autonomous state, put actions in the getNextState() method. */
    
private abstract class State{
        public abstract 
State getNextState();  
    };
    
    
/** String-keyed table of all the states */
    
private Hashtable states;
    
    
/** Stores the current Autonomous state */
    
private State currState;
    
    
// snip...
    
    /**
     * The basic autonomous routine: Raise the arm, drive straight to the wall 
     * then hang the tube.
     * 
     * @return The first state in the basic autonomous routine. calling method
     *  should set currState equal to the returned state.
     */
    
private State loadBasicSM(){
        
states = new Hashtable();

        
// snip... Example State:
        
states.put("raiseArm", new State(){ public State getNextState() {
            
// return next state when the arm is raised
            
if(arm.raiseArm(RobotArmFF.TOP)){
                return (
State)states.get("driveToWall");
            } 
            return 
this;
        }});

        
// snip...
        
        
return (State)states.get("firstState");
    }
    
// snip...
    
    /** Call once per autonomous loop */
    
public void periodicUpdate(){
        if(
currState != null){
            
currState currState.getNextState();
        } else {
            
stopEverything();
        }
    }
    
    
// snip...

}// End class 
To me this code is much more readable and self documenting, and adding a new state or even a whole new state machine is relatively easy. I am curious what the other Java programmers on Chief Delphi think. Do you find this method easier/harder to read? Do you have other criticisms? Has anyone done anything similar? Has anyone done anything better?
__________________
2194 Alumni and Mentor

Last edited by Ben_R_R : 30-03-2011 at 17:03.
Reply With Quote