package vnsim.vehicular.routePlan.cityRouting;
import java.util.ArrayList;
import vnsim.applications.adaptiveTL.IntersectionPath;
import vnsim.applications.adaptiveTL.WirelessTrafficLight;
import vnsim.map.object.Globals;
import vnsim.vehicular.simulator.intersections.DirectedRoadSegment;
import vnsim.vehicular.simulator.intersections.TrafficLightInfo;
public class CityTrafficLight extends WirelessTrafficLight {
//private static final long serialVersionUID = 8583006734559336974L;
/** serialVersionUID
*/
private static final long serialVersionUID = -5883719321862303634L;
private boolean initialized = false;
private ArrayList lastRedTime; // time of the last red phase for
// each segment
public CityTrafficLight() {
super();
lastRedTime = new ArrayList();
//adaptive = false;
}
public void init() {
super.init();
for (int i = 0; i < segments.size(); i++) {
lastRedTime.add(0);
}
}
// time of the last red phase on the segment segmentNb
public Integer lastRed(int segmentNb) {
if (initialized && segmentNb < segments.size())
return lastRedTime.get(segmentNb);
return new Integer(0);
}
public void step(int crtTime) {
if (!initialized) {
initialized = true;
init();
}
if (crtTime % (10 * Globals.SECOND) == 0) {
for (int k = 0; k < this.segments.size(); k++) {
DirectedRoadSegment seg = segments.get(k);
seg.recordQueueSize();
}
}
if (crtTime % Globals.SECOND == 0) {
// broadcast feedback
scheduleSingleSendEvent(0, Globals.PROT_TL_FEEDBACK);
}
// compute the next cycle signal plan with 2 seconds before switching
if (crtTime == lastCycleStartTime + cycleLength * Globals.SECOND - 2
* Globals.SECOND) {
if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)) {
Globals.pw.println("\n" + crtTime / Globals.SECOND + "s ) WTL");
}
int dem = 0, vol = 0;
for (int k = 0; k < this.segments.size(); k++) {
DirectedRoadSegment seg = segments.get(k);
dem = seg.computeDemand(Globals.ANALYSIS_PERIOD);
vol = seg.computeVolume(Globals.ANALYSIS_PERIOD);
int analysisPeriod = Globals.ANALYSIS_PERIOD;
if (Globals.ANALYSIS_PERIOD < crtTime) {
analysisPeriod = crtTime;
}
seg.carryOver += (int) ((double) (dem - vol)
* (double) (cycleLength * Globals.SECOND) / analysisPeriod);
if (seg.carryOver < 0)
seg.carryOver = 0;
double qs = seg.get95thQueueSize();
if (Globals.monitorWTL != null
&& this.equals(Globals.monitorWTL)) {
Globals.pw.println(" " + seg.segmentIndex + "" + " dem: "
+ seg.demand + " carry: " + seg.carryOver
+ " vol: " + seg.totalVolume + " stops: "
+ seg.noOfStops + " avgQueue: " + qs);
Globals.pw.flush();
}
}
computeNextSignalPlan(crtTime);
}
if (crtTime == lastCycleStartTime + cycleLength * Globals.SECOND) {
lastCycleStartTime = crtTime;
cycleLength = newCycleLength;
for (int j = 0; j < segments.size(); j++) {
segments.get(j).setLightInfo(segments.get(j).getNewLightInfo());
}
}
int thisSec = (int) (crtTime / (Globals.executionFPS));
int aux = thisSec - (lastCycleStartTime / Globals.SECOND);
synchronized (this) {
if (Globals.engine.startedWithGUI
&& Globals.demo.mv.currentIntersection != null
&& Globals.demo.mv.currentIntersection.equals(this)) {
Globals.demo.st.cycle.setText("Cycle: " + cycleLength + " s");
}
for (int k = 0; k < this.segments.size(); k++) {
TrafficLightInfo info = segments.get(k).getLightInfo();
int color = info.getColor(aux);
if (color != currentColor.get(k)) {
currentColor.set(k, color);
if (color == 1) {
lastRedTime.set(k, crtTime);
}
if (segments.get(k).pair != null
&& segments.get(k).pair.getLightInfo().getColor(
aux - 1) == Globals.GREEN && adaptive) {
int i = segments.get(k).paths
.indexOf(new IntersectionPath(segments.get(k),
segments.get(k).pair));
if (i != -1 && color == Globals.YELLOW) {
int secsEx = segments.get(k).leftSignalExtension();
if (secsEx > 0) {
System.out.println("Extension");
extendGreen(aux, secsEx, segments.get(k));
continue;
}
}
}
segments.get(k).changePhase(null, crtTime, color);
}
if (Globals.engine.startedWithGUI
&& Globals.demo.mv.currentIntersection != null
&& Globals.demo.mv.currentIntersection.equals(this)) {
int x;
x = info.greenEnd - aux;
if (x < 0)
x = 0;
if (aux < info.greenStart)
x = info.greenEnd - info.greenStart;
}
}
if (Globals.engine.startedWithGUI
&& Globals.demo.mv.currentIntersection != null
&& Globals.demo.mv.currentIntersection.equals(this)) {
Globals.demo.st.repaint();
}
}
}
public static void upgradeToCityTL() {
for (int i = 0; i < Globals.map.allIntersections.size(); i++) {
if (Globals.map.allIntersections.get(i).segments.size() <= 2) {
continue;
}
if (Globals.map.roads.size() > 1) {
// change it into a traffic lights intersection
CityTrafficLight newInters = new CityTrafficLight();
WirelessTrafficLight oldInters = (WirelessTrafficLight) Globals.map.allIntersections
.get(i);
for (int j = 0; j < oldInters.segments.size(); j++) {
newInters.addCrossingSegment(oldInters.segments.get(j));
}
for (int j = 0; j < oldInters.segments.size(); j++) {
DirectedRoadSegment seg1 = (DirectedRoadSegment) oldInters.segments
.get(j);
for (int k = 0; k < oldInters.segments.size(); k++) {
DirectedRoadSegment seg2 = (DirectedRoadSegment) oldInters.segments
.get(k);
if (k != j) {
double angle = seg1.angle - seg2.angle;
if (angle < 0)
angle = 360 + angle;
if (angle < 190 && angle > 170)
seg1.front = seg2;
if (angle >= 190)
seg1.right = seg2;
if (angle <= 170)
seg1.left = seg2;
}
}
}
int green = 30;
int time = 0;
int j = 2;
newInters.segments.get(0).setLightInfo(
new TrafficLightInfo(0, green));
newInters.segments.get(1).setLightInfo(
new TrafficLightInfo(0, green));
time = time + green + Globals.DEFAULT_YELLOW_TIME
+ Globals.DEFAULT_ALL_RED;
for (; j < oldInters.segments.size(); j++) {
if (oldInters.segments.get(j).isExitOnly()) {
newInters.segments.get(j).setLightInfo(
new TrafficLightInfo(time, time));
if (j % 2 == 1) {
if (!oldInters.segments.get(j - 1).isExitOnly())
;
time = time + green + Globals.DEFAULT_YELLOW_TIME
+ Globals.DEFAULT_ALL_RED;
}
continue;
}
green = 30;
newInters.segments.get(j).setLightInfo(
new TrafficLightInfo(time, time + green));
if (j % 2 == 0)
time = time + green + Globals.DEFAULT_YELLOW_TIME
+ Globals.DEFAULT_ALL_RED;
}
newInters.cycleLength = time;
Globals.map.allIntersections.set(i, newInters);
//lightsIndices already set from Map.createTrafficLights()
//Globals.map.lightsIndices.add(new Integer(i));
}
}
}
}