[31] | 1 | package vnsim.vehicular.routePlan.cityRouting; |
---|
| 2 | |
---|
| 3 | import java.util.ArrayList; |
---|
| 4 | |
---|
| 5 | import vnsim.applications.adaptiveTL.IntersectionPath; |
---|
| 6 | import vnsim.applications.adaptiveTL.WirelessTrafficLight; |
---|
| 7 | import vnsim.map.object.Globals; |
---|
| 8 | import vnsim.vehicular.simulator.intersections.DirectedRoadSegment; |
---|
| 9 | import vnsim.vehicular.simulator.intersections.TrafficLightInfo; |
---|
| 10 | |
---|
| 11 | public class CityTrafficLight extends WirelessTrafficLight { |
---|
| 12 | //private static final long serialVersionUID = 8583006734559336974L; |
---|
| 13 | |
---|
| 14 | /** <code>serialVersionUID</code> */ |
---|
| 15 | private static final long serialVersionUID = -5883719321862303634L; |
---|
| 16 | |
---|
| 17 | private boolean initialized = false; |
---|
| 18 | |
---|
| 19 | private ArrayList<Integer> lastRedTime; // time of the last red phase for |
---|
| 20 | |
---|
| 21 | // each segment |
---|
| 22 | |
---|
| 23 | public CityTrafficLight() { |
---|
| 24 | super(); |
---|
| 25 | lastRedTime = new ArrayList<Integer>(); |
---|
| 26 | //adaptive = false; |
---|
| 27 | } |
---|
| 28 | |
---|
| 29 | public void init() { |
---|
| 30 | super.init(); |
---|
| 31 | for (int i = 0; i < segments.size(); i++) { |
---|
| 32 | lastRedTime.add(0); |
---|
| 33 | } |
---|
| 34 | } |
---|
| 35 | |
---|
| 36 | // time of the last red phase on the segment segmentNb |
---|
| 37 | public Integer lastRed(int segmentNb) { |
---|
| 38 | if (initialized && segmentNb < segments.size()) |
---|
| 39 | return lastRedTime.get(segmentNb); |
---|
| 40 | return new Integer(0); |
---|
| 41 | } |
---|
| 42 | |
---|
| 43 | public void step(int crtTime) { |
---|
| 44 | if (!initialized) { |
---|
| 45 | initialized = true; |
---|
| 46 | init(); |
---|
| 47 | } |
---|
| 48 | |
---|
| 49 | if (crtTime % (10 * Globals.SECOND) == 0) { |
---|
| 50 | for (int k = 0; k < this.segments.size(); k++) { |
---|
| 51 | DirectedRoadSegment seg = segments.get(k); |
---|
| 52 | seg.recordQueueSize(); |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | } |
---|
| 56 | if (crtTime % Globals.SECOND == 0) { |
---|
| 57 | // broadcast feedback |
---|
| 58 | scheduleSingleSendEvent(0, Globals.PROT_TL_FEEDBACK); |
---|
| 59 | } |
---|
| 60 | // compute the next cycle signal plan with 2 seconds before switching |
---|
| 61 | if (crtTime == lastCycleStartTime + cycleLength * Globals.SECOND - 2 |
---|
| 62 | * Globals.SECOND) { |
---|
| 63 | |
---|
| 64 | if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)) { |
---|
| 65 | Globals.pw.println("\n" + crtTime / Globals.SECOND + "s ) WTL"); |
---|
| 66 | } |
---|
| 67 | int dem = 0, vol = 0; |
---|
| 68 | for (int k = 0; k < this.segments.size(); k++) { |
---|
| 69 | DirectedRoadSegment seg = segments.get(k); |
---|
| 70 | |
---|
| 71 | dem = seg.computeDemand(Globals.ANALYSIS_PERIOD); |
---|
| 72 | vol = seg.computeVolume(Globals.ANALYSIS_PERIOD); |
---|
| 73 | int analysisPeriod = Globals.ANALYSIS_PERIOD; |
---|
| 74 | if (Globals.ANALYSIS_PERIOD < crtTime) { |
---|
| 75 | analysisPeriod = crtTime; |
---|
| 76 | } |
---|
| 77 | seg.carryOver += (int) ((double) (dem - vol) |
---|
| 78 | * (double) (cycleLength * Globals.SECOND) / analysisPeriod); |
---|
| 79 | if (seg.carryOver < 0) |
---|
| 80 | seg.carryOver = 0; |
---|
| 81 | |
---|
| 82 | double qs = seg.get95thQueueSize(); |
---|
| 83 | if (Globals.monitorWTL != null |
---|
| 84 | && this.equals(Globals.monitorWTL)) { |
---|
| 85 | Globals.pw.println(" " + seg.segmentIndex + "" + " dem: " |
---|
| 86 | + seg.demand + " carry: " + seg.carryOver |
---|
| 87 | + " vol: " + seg.totalVolume + " stops: " |
---|
| 88 | + seg.noOfStops + " avgQueue: " + qs); |
---|
| 89 | Globals.pw.flush(); |
---|
| 90 | } |
---|
| 91 | } |
---|
| 92 | computeNextSignalPlan(crtTime); |
---|
| 93 | } |
---|
| 94 | |
---|
| 95 | if (crtTime == lastCycleStartTime + cycleLength * Globals.SECOND) { |
---|
| 96 | lastCycleStartTime = crtTime; |
---|
| 97 | cycleLength = newCycleLength; |
---|
| 98 | for (int j = 0; j < segments.size(); j++) { |
---|
| 99 | segments.get(j).setLightInfo(segments.get(j).getNewLightInfo()); |
---|
| 100 | } |
---|
| 101 | } |
---|
| 102 | int thisSec = (int) (crtTime / (Globals.executionFPS)); |
---|
| 103 | int aux = thisSec - (lastCycleStartTime / Globals.SECOND); |
---|
| 104 | |
---|
| 105 | synchronized (this) { |
---|
| 106 | if (Globals.engine.startedWithGUI |
---|
| 107 | && Globals.demo.mv.currentIntersection != null |
---|
| 108 | && Globals.demo.mv.currentIntersection.equals(this)) { |
---|
| 109 | Globals.demo.st.cycle.setText("Cycle: " + cycleLength + " s"); |
---|
| 110 | |
---|
| 111 | } |
---|
| 112 | for (int k = 0; k < this.segments.size(); k++) { |
---|
| 113 | TrafficLightInfo info = segments.get(k).getLightInfo(); |
---|
| 114 | int color = info.getColor(aux); |
---|
| 115 | if (color != currentColor.get(k)) { |
---|
| 116 | currentColor.set(k, color); |
---|
| 117 | if (color == 1) { |
---|
| 118 | lastRedTime.set(k, crtTime); |
---|
| 119 | } |
---|
| 120 | if (segments.get(k).pair != null |
---|
| 121 | && segments.get(k).pair.getLightInfo().getColor( |
---|
| 122 | aux - 1) == Globals.GREEN && adaptive) { |
---|
| 123 | int i = segments.get(k).paths |
---|
| 124 | .indexOf(new IntersectionPath(segments.get(k), |
---|
| 125 | segments.get(k).pair)); |
---|
| 126 | if (i != -1 && color == Globals.YELLOW) { |
---|
| 127 | int secsEx = segments.get(k).leftSignalExtension(); |
---|
| 128 | if (secsEx > 0) { |
---|
| 129 | System.out.println("Extension"); |
---|
| 130 | extendGreen(aux, secsEx, segments.get(k)); |
---|
| 131 | continue; |
---|
| 132 | } |
---|
| 133 | } |
---|
| 134 | } |
---|
| 135 | segments.get(k).changePhase(null, crtTime, color); |
---|
| 136 | } |
---|
| 137 | if (Globals.engine.startedWithGUI |
---|
| 138 | && Globals.demo.mv.currentIntersection != null |
---|
| 139 | && Globals.demo.mv.currentIntersection.equals(this)) { |
---|
| 140 | int x; |
---|
| 141 | x = info.greenEnd - aux; |
---|
| 142 | if (x < 0) |
---|
| 143 | x = 0; |
---|
| 144 | if (aux < info.greenStart) |
---|
| 145 | x = info.greenEnd - info.greenStart; |
---|
| 146 | } |
---|
| 147 | } |
---|
| 148 | if (Globals.engine.startedWithGUI |
---|
| 149 | && Globals.demo.mv.currentIntersection != null |
---|
| 150 | && Globals.demo.mv.currentIntersection.equals(this)) { |
---|
| 151 | Globals.demo.st.repaint(); |
---|
| 152 | } |
---|
| 153 | |
---|
| 154 | } |
---|
| 155 | |
---|
| 156 | } |
---|
| 157 | |
---|
| 158 | public static void upgradeToCityTL() { |
---|
| 159 | for (int i = 0; i < Globals.map.allIntersections.size(); i++) { |
---|
| 160 | if (Globals.map.allIntersections.get(i).segments.size() <= 2) { |
---|
| 161 | continue; |
---|
| 162 | } |
---|
| 163 | if (Globals.map.roads.size() > 1) { |
---|
| 164 | // change it into a traffic lights intersection |
---|
| 165 | CityTrafficLight newInters = new CityTrafficLight(); |
---|
| 166 | WirelessTrafficLight oldInters = (WirelessTrafficLight) Globals.map.allIntersections |
---|
| 167 | .get(i); |
---|
| 168 | for (int j = 0; j < oldInters.segments.size(); j++) { |
---|
| 169 | newInters.addCrossingSegment(oldInters.segments.get(j)); |
---|
| 170 | } |
---|
| 171 | for (int j = 0; j < oldInters.segments.size(); j++) { |
---|
| 172 | DirectedRoadSegment seg1 = (DirectedRoadSegment) oldInters.segments |
---|
| 173 | .get(j); |
---|
| 174 | for (int k = 0; k < oldInters.segments.size(); k++) { |
---|
| 175 | DirectedRoadSegment seg2 = (DirectedRoadSegment) oldInters.segments |
---|
| 176 | .get(k); |
---|
| 177 | if (k != j) { |
---|
| 178 | double angle = seg1.angle - seg2.angle; |
---|
| 179 | if (angle < 0) |
---|
| 180 | angle = 360 + angle; |
---|
| 181 | if (angle < 190 && angle > 170) |
---|
| 182 | seg1.front = seg2; |
---|
| 183 | if (angle >= 190) |
---|
| 184 | seg1.right = seg2; |
---|
| 185 | if (angle <= 170) |
---|
| 186 | seg1.left = seg2; |
---|
| 187 | } |
---|
| 188 | } |
---|
| 189 | } |
---|
| 190 | int green = 30; |
---|
| 191 | |
---|
| 192 | int time = 0; |
---|
| 193 | int j = 2; |
---|
| 194 | newInters.segments.get(0).setLightInfo( |
---|
| 195 | new TrafficLightInfo(0, green)); |
---|
| 196 | newInters.segments.get(1).setLightInfo( |
---|
| 197 | new TrafficLightInfo(0, green)); |
---|
| 198 | time = time + green + Globals.DEFAULT_YELLOW_TIME |
---|
| 199 | + Globals.DEFAULT_ALL_RED; |
---|
| 200 | |
---|
| 201 | for (; j < oldInters.segments.size(); j++) { |
---|
| 202 | if (oldInters.segments.get(j).isExitOnly()) { |
---|
| 203 | newInters.segments.get(j).setLightInfo( |
---|
| 204 | new TrafficLightInfo(time, time)); |
---|
| 205 | if (j % 2 == 1) { |
---|
| 206 | if (!oldInters.segments.get(j - 1).isExitOnly()) |
---|
| 207 | ; |
---|
| 208 | time = time + green + Globals.DEFAULT_YELLOW_TIME |
---|
| 209 | + Globals.DEFAULT_ALL_RED; |
---|
| 210 | } |
---|
| 211 | continue; |
---|
| 212 | } |
---|
| 213 | green = 30; |
---|
| 214 | newInters.segments.get(j).setLightInfo( |
---|
| 215 | new TrafficLightInfo(time, time + green)); |
---|
| 216 | if (j % 2 == 0) |
---|
| 217 | time = time + green + Globals.DEFAULT_YELLOW_TIME |
---|
| 218 | + Globals.DEFAULT_ALL_RED; |
---|
| 219 | } |
---|
| 220 | newInters.cycleLength = time; |
---|
| 221 | Globals.map.allIntersections.set(i, newInters); |
---|
| 222 | //lightsIndices already set from Map.createTrafficLights() |
---|
| 223 | //Globals.map.lightsIndices.add(new Integer(i)); |
---|
| 224 | } |
---|
| 225 | } |
---|
| 226 | } |
---|
| 227 | } |
---|