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