Erlang Central

Java FSM on Erlang FSM Model

Revision as of 09:34, 2 September 2006 by Rvg (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

We were recently faced with the problem of implementing a Finite State Machine (FSM) in java. We have previously worked a lot with FSM’s in Erlang and liked the way it works. In this article I describe a simple, but very flexible Java FSM modeled on the gen_fsm in Erlang.

So what is an FSM? (Definition from wikipedia)

A finite state machine (FSM) or finite automaton is a model of behaviour composed of states, transitions and actions. A state stores information about the past, i.e. it reflects the input changes from the system start to the present moment. A transition indicates a state change and is described by a condition that would need to be fulfilled to enable the transition. An action is a description of an activity that is to be performed at a given moment.

State Description
Entry action execute the action when entering the state
Exit action execute the action when exiting the state
Input action execute the action dependant on input conditions
Transition action execute the action when performing certain transition

Let us now define a simple FSM for an Elevator Door. It can be represented by the following diagram:

This state machine has four states:

  • The doors are Closed
  • The doors are Opening
  • The doors are Open
  • The doors are Closing
  • The blue boxes indicate the events that triggers a state change

We start by defining a new FSM, called Elevator

public class ElevatorDoor extends FSM {...}

and then we declare the four states:

public static State CLOSED_STATE = new ClosedState(0);
public static State OPENING_STATE = new OpeningState(0);
public static State OPEN_STATE = new OpenState(10000);
public static State CLOSING_STATE = new ClosingState(0);

It is obvious that we have a timeout of 10s in the Open state. This is meant to allow the door to automatically close after 10s.

Each of the State objects is a simple java class based on the following template:

package javafsm.elevator.states;

import javafsm.fsm.State;

public class OpeningState extends State{
  public OpeningState(int aTimeout) {
    super(aTimeout);
  }
}

We need to declare public methods for each of the events:

public void closeButtonPressed() throws FSMHandlerException {
    try {
      processEvent(new CloseButtonEvent());
    } catch (FSMNoHandlerForCurrentStateException e) {
    }
  }

  public void openButtonPressed() throws FSMHandlerException {
    try {
      processEvent(new OpenButtonEvent());
    } catch (FSMNoHandlerForCurrentStateException e) {
    }
  }

  public void arrivedAtFloor() throws FSMHandlerException {
    try {
      processEvent(new ArrivedAtFloorEvent());
    } catch (FSMNoHandlerForCurrentStateException e) {
    }
  }

  public void doorIsFullyOpen() throws FSMHandlerException {
    try {
      processEvent(new DoorIsFullyOpenEvent());
    } catch (FSMNoHandlerForCurrentStateException e) {
    }
  }
  public void doorIsCompletelyClosed() throws FSMHandlerException {
    try {
      processEvent(new DoorIsCompletelyClosedEvent());
    } catch (FSMNoHandlerForCurrentStateException e) {
    }
  }

You will surely have noticed that I left the exception handler for the FSMNoHandlerForCurrentStateException empty for all the above events. The reason is that this exception will only occur if there is no event handler available for the applicable event in a certain state. In this case, it is not important and simply means that we are not interested in the event in the specific state. In other FSM’s the exception might mean that we have a design flaw.

Note that we create a certain event object and then call the FSM’s processEvent method to submit the event into the FSM.

There is now only two tasks left to do:

  1. Write code for each event handler and
  2. Write the state transition functions

A typical event handler will look like this:

/**
* This handler is triggered when the door is closing and it is    
* detected that the door is obstructed
*/
public State handleEvent(ClosingState aState,  DoorObstructedEvent aEvent) {
    return OPENING_STATE;
}

The event handler contains the state for which it is defined (ClosingState) and the event (DoorObstructedEvent). The return type is an instance of the next state to enter.

I leave it as an exercise to write the rest of the event handlers.
Now, the transition functions is where the work of the state machine is performed:
public void enterState(ClosedState aState) {
  stopMotors();
}

public void enterState(OpeningState aState) {
  openDoors();
}

public void enterState(OpenState aState) {
  stopMotors();
}

public void enterState(ClosingState aState) {
  closeDoors();

} It is also possible to schedule periodic events for the FSM. You must then define an event handler for the PeriodicEvent object.