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)); } } } }