All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nz.ac.waikato.modeljunit.timing.examples.TrafficLight Maven / Gradle / Ivy

Go to download

Java library and GUI for supporting Model-Based Testing. The models are extended finite state machines (EFSM) that are written in Java.

The newest version!

package nz.ac.waikato.modeljunit.timing.examples;

import java.util.Random;

import nz.ac.waikato.modeljunit.Action;
import nz.ac.waikato.modeljunit.GraphListener;
import nz.ac.waikato.modeljunit.GreedyTester;
import nz.ac.waikato.modeljunit.RandomTester;
import nz.ac.waikato.modeljunit.Tester;
import nz.ac.waikato.modeljunit.timing.Time;
import nz.ac.waikato.modeljunit.timing.TimedFsmModel;
import nz.ac.waikato.modeljunit.timing.TimedModel;
import nz.ac.waikato.modeljunit.timing.Timeout;

public class TrafficLight implements TimedFsmModel
{

  /**Whether the pedestrian button has been pressed*/
  private boolean buttonPressed;

  private STATE state;

  /**
   * The length of time that both lights are red in between changing
   * who can use the crossing
   */
  private static final int SAFETY_PERIOD = 5;

  /**
   * The minimum time that the light must stay green for cars. 
   *  This ensures that traffic can flow freely through the 
   *  intersection without constantly being interrupted by pedestrians.
   */
  private static final int MINIMUM_TRAFFIC_PERIOD = 20;

  /**
   * The length of time that the light stays green for pedestrians
   * while they cross.
   */
  private static final int CROSSING_TIME = 10;

  /**
   * This timer controls the minimum 20 second period in which
   * the light must be green for cars.When the timer expires
   * the minimumWaitElapsed action will be called
   */
  @Timeout("minimumWaitElapsed")
  public int trafficFlowTimer;

  /**
   * This timer controls the period in which the light is green for
   * pedestrians to cross.
   */
  @Timeout("finishPedestrianPeriod")
  public int crossingTimer;

  /**
   * Timer to control the saftey period where both lights are red
   * because the lights are changing from allowing cars through
   * to allowing predestrians to cross
   */
  @Timeout("allowPedestrians")
  public int allowPedestriansTimer;

  /**
   * Timer to control the safety period where both lights are red
   * because the lights are changing from allowing pedestrians to cross 
   * to allowing cars through
   */
  @Timeout("allowCars")
  public int allowCarsTimer;

  /**
   * The current time of the model
   */
  @Time
  public int now = 0;


  public enum STATE {
    CARS_HOLD, //The period while the light is held green even if the button gets pressed
    CARS, //Regular state for allowing cars to move through
    WAIT_CARS, //safety period after cars have been crossing
    PEDESTRIANS, //period where pedestrians cross
    WAIT_PEDS
    //safety period after pedestrians cross
  }

  @Override
  public Object getState()
  {
    return state;
  }

  @Override
  public void reset(boolean testing)
  {
    buttonPressed = false;
    state = STATE.CARS_HOLD;
    trafficFlowTimer = now + MINIMUM_TRAFFIC_PERIOD;
  }

  /**
   * Action for pedestrians arriving at the crossing. This can
   * happen at any time so no guard is needed because it would
   * always return true
   */
  @Action
  public void pedestrianArrive()
  {
    if (state == STATE.PEDESTRIANS) {
      //they can walk right through
      return;
    }
    //In all other states they must press the button and wait
    buttonPressed = true;

    if (state == STATE.CARS) {
      state = STATE.WAIT_CARS;
      allowPedestriansTimer = now + SAFETY_PERIOD;
    }
  }

  /**
   * Guard for the safetyPeriodEnd action. We only want this
   * action to occur when the safetyTimer expires so the guard 
   * is set up to do this.
   * @return true when the allowPedestrians action is enabled.
   */
  public boolean allowPedestriansGuard()
  {
    return now == allowPedestriansTimer;
  }

  @Action
  public void allowPedestrians()
  {
    //we now move to the state where pedestrians can cross
    state = STATE.PEDESTRIANS;
    //set the timer for when the light should finish
    crossingTimer = now + CROSSING_TIME;

    buttonPressed = false;
  }

  public boolean allowCarsGuard()
  {
    return now == allowCarsTimer;
  }

  @Action
  public void allowCars()
  {
    //move to the state where the light must remain green for cars
    state = STATE.CARS_HOLD;
    //set the timer for when this period ends
    trafficFlowTimer = now + MINIMUM_TRAFFIC_PERIOD;
  }

  public boolean minimumWaitElapsedGuard()
  {
    return now == trafficFlowTimer;
  }

  @Action
  public void minimumWaitElapsed()
  {
    if (buttonPressed) {
      //the pedestrian button has been pressed.
      //go to the safety period so we can let the pedestrians cross
      //in a moment
      state = STATE.WAIT_CARS;
      allowPedestriansTimer = now + SAFETY_PERIOD;
    }
    else {
      state = STATE.CARS;
    }
  }

  public boolean finishPedestrianPeriodGuard()
  {
    return now == crossingTimer;
  }

  @Action
  public void finishPedestrianPeriod()
  {
    state = STATE.WAIT_PEDS;
    allowCarsTimer = now + SAFETY_PERIOD;
  }

  public static void main(String[] args)
  {
    TimedModel model = new TimedModel(new TrafficLight());
    Tester tester = new RandomTester(model);
    //tester.addListener("verbose");
    //GraphListener graphListener = tester.buildGraph();
    
    try {
      for (int count = 0; count < 1000000; count += 1000) {
        tester.generate(1000);
        System.out.println(count);
      }
      //graphListener.printGraphDot("TrafficLight.dot");
    }
    catch (Exception ex) {
      System.out.println(ex.getMessage());
    }
  }

  /**
   * Take random steps of between 1 and 10 time units (inclusive)
   */
  @Override
  public int getNextTimeIncrement(Random ran)
  {
    return 1 + ran.nextInt(10);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy