/*
* Licensed Materials - Property of Rogue Wave Software, Inc.
* © Copyright Rogue Wave Software, Inc. 2014, 2017
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
import java.util.Hashtable;
/**
* The simulator computes values for parameters that could be asked.
*/
public class Simulator {
// maxima
final double maxcars = 100;
final double maxbuses= 50;
final double maxtrucks= 50;
final double maxairquality = 50;
final double maxtemperature = 50;
// nomenclature of values for traffic and general air quality
public static final String CAR_COUNT = "car_count";
public static final String BUS_COUNT = "bus_count";
public static final String TRUCK_COUNT = "truck_count";
public static final String AIR_QUALITY = "air_quality";
// nomenclature for temperatures and air quality per section
public static final String TEMPERATURE1_LINE1 = "temperature1_line1";
public static final String TEMPERATURE2_LINE1 = "temperature2_line1";
public static final String TEMPERATURE3_LINE1 = "temperature3_line1";
public static final String TEMPERATURE1_LINE2 = "temperature1_line2";
public static final String TEMPERATURE2_LINE2 = "temperature2_line2";
public static final String TEMPERATURE3_LINE2 = "temperature3_line2";
public static final String AIR1_LINE1 = "air1_line1";
public static final String AIR2_LINE1 = "air2_line1";
public static final String AIR3_LINE1 = "air3_line1";
public static final String AIR1_LINE2 = "air1_line2";
public static final String AIR2_LINE2 = "air2_line2";
public static final String AIR3_LINE2 = "air3_line2";
//nomenclature for status of traffic lines
public static final String LINE1_1_STATUS= "line1_1_status";
public static final String LINE1_2_STATUS= "line1_2_status";
public static final String LINE2_1_STATUS= "line2_1_status";
public static final String LINE2_2_STATUS= "line2_2_status";
// work variables
private double currentNbCars = 50;
private double currentNbBuses = 25;
private double currentNbTrucks = 25;
private double airQuality = 25;
private Hashtable<String, Double> temperatures = null;
private Hashtable<String, Double> air = null;
private boolean canChangeLineStatus = true;
private int[][] lines = {{1,1},{2,2}};
/**
* Creates the simulator
*/
public Simulator() {
// create a table for the different temperatures and
// init the default values
temperatures = new Hashtable<String, Double>();
temperatures.put(TEMPERATURE1_LINE1, new Double(25));
temperatures.put(TEMPERATURE2_LINE1, new Double(25));
temperatures.put(TEMPERATURE3_LINE1, new Double(25));
temperatures.put(TEMPERATURE1_LINE2, new Double(25));
temperatures.put(TEMPERATURE2_LINE2, new Double(25));
temperatures.put(TEMPERATURE3_LINE2, new Double(25));
// create a table for the different air quality and
// init the default values
air = new Hashtable<String, Double>();
air.put(AIR1_LINE1, new Double(25));
air.put(AIR2_LINE1, new Double(25));
air.put(AIR3_LINE1, new Double(25));
air.put(AIR1_LINE2, new Double(25));
air.put(AIR2_LINE2, new Double(25));
air.put(AIR3_LINE2, new Double(25));
}
/**
*
*/
private Object simulateNbVehicles(String type){
// compute the values
if(type.equals(CAR_COUNT)){
currentNbCars = computeNb(0,maxcars,currentNbCars,0.15);
return new Integer((int)currentNbCars);
}else if(type.equals(BUS_COUNT)){
currentNbBuses = computeNb(0,50,currentNbBuses,0.1);
return new Integer((int)currentNbBuses);
}if(type.equals(TRUCK_COUNT)){
currentNbTrucks = computeNb(0,50,currentNbTrucks,0.1);
return new Integer((int)currentNbTrucks);
}
return null;
}
private double computeNb(double min,double max,double current, double amplitude){
double res;
double delta = Math.sin(System.currentTimeMillis())*(max*amplitude);
res = current + (Math.random()*delta) ;
if(res<min) res=min;
if(res>max) res=max;
return res;
}
/**
* Air quality is depending on number of vehicles in the tunnel :
*
* nb_vehicles*max_air_quality / max_vehicles
*
*/
private Object simulateAirQuality() {
airQuality = ((currentNbBuses+currentNbCars+currentNbTrucks)*maxairquality) / (maxbuses+maxcars+maxtrucks);
return new Integer((int)airQuality);
}
/**
*
*/
private Object simulateTemperature(String type) {
Double temp = (Double)temperatures.get(type);
double current = temp.doubleValue();
double delta = Math.sin(System.currentTimeMillis())*(maxtemperature*0.03);
double res = current + delta ;
if(res<0) res=0;
if(res>maxtemperature) res=maxtemperature;
temp = new Double(res);
temperatures.put(type,temp);
return temp;
}
/**
*
*/
private Object simulateAir(String type) {
Double temp = (Double)air.get(type);
double current = temp.doubleValue();
double delta = Math.sin(System.currentTimeMillis())*(maxairquality*0.03);
double res = current + delta ;
if(res<0) res=0;
if(res>maxairquality) res=maxairquality;
temp = new Double(res);
air.put(type,temp);
return temp;
}
/**
*
*/
private Object simulateLineStatus(String type) {
// compute new staus of lines
double z = Math.random();
if(canChangeLineStatus && z>0.997){
//randomize current line
int currentLine = Math.round( (float)Math.random()*1.0f );
// determine secondary line
int secondaryLine = (currentLine==0)?1:0;
// randomize current line status: 0 (no traffic),1(to-right) or 2(to-left)
int currentLineStatus = Math.round( (float)Math.random()*2.0f );
lines[currentLine][0]=currentLineStatus;
lines[currentLine][1]=currentLineStatus;
// if 0 then no traffic: then put traffic 1 and 2 on the secondary line
if(currentLineStatus==0){
lines[secondaryLine][0]=1;
lines[secondaryLine][1]=2;
}
// if 1 then traffic is 2 on secondary line
else if(currentLineStatus==1){
lines[secondaryLine][0]=2;
lines[secondaryLine][1]=2;
}
// if 2 then traffic is 1 on secondary line
else if(currentLineStatus==2){
lines[secondaryLine][0]=1;
lines[secondaryLine][1]=1;
}
canChangeLineStatus = false;
}
// return traffic according to requested line
Integer res = null;
if(type.equals(LINE1_1_STATUS)){
res = new Integer(lines[0][0]);
}
else if(type.equals(LINE1_2_STATUS)){
res = new Integer(lines[0][1]);
}
else if(type.equals(LINE2_1_STATUS)){
res = new Integer(lines[1][0]);
}
else if(type.equals(LINE2_2_STATUS)){
res = new Integer(lines[1][1]);
//status of last line is requested then allows change for the next time... maybe
canChangeLineStatus = true;
}
return res;
}
/**
* Returns a value for the specified mapped parameter
*/
public Object getValue(String name){
if(name.equals(CAR_COUNT) || name.equals(BUS_COUNT) || name.equals(TRUCK_COUNT)){
return simulateNbVehicles(name);
}
else if(name.equals(AIR_QUALITY)){
return simulateAirQuality();
}
else if(name.startsWith("temperature")){
return simulateTemperature(name);
}
else if(name.startsWith("air")){
return simulateAir(name);
}
else if(name.startsWith("line") && name.endsWith("_status")){
return simulateLineStatus(name);
}
return null;
}
}