source: proiecte/ptvs/src/vnsim/applications/adaptiveTL/WirelessTrafficLight.java @ 46

Last change on this file since 46 was 46, checked in by (none), 14 years ago
File size: 31.7 KB
Line 
1/************************************************************************************
2 * Copyright (C) 2008 by Politehnica University of Bucharest and Rutgers University
3 * All rights reserved.
4 * Refer to LICENSE for terms and conditions of use.
5 ***********************************************************************************/
6package vnsim.applications.adaptiveTL;
7
8
9import java.io.ByteArrayInputStream;
10import java.io.Serializable;
11import java.nio.ByteBuffer;
12import java.util.ArrayList;
13import java.util.LinkedList;
14import java.util.TreeMap;
15
16import vnsim.applications.trafficview.SimulatedCarInfo;
17import vnsim.core.*;
18import vnsim.core.events.ReceiveEvent;
19import vnsim.core.events.SendEvent;
20import vnsim.map.object.*;
21import vnsim.network.RadioDev;
22import vnsim.vehicular.simulator.intersections.*;
23
24public class WirelessTrafficLight 
25        extends IntersectionWithTrafficLights implements Communicator{ 
26
27        private static final long serialVersionUID = 8724226247069906455L;
28       
29        public final static byte PROT_RESERVED = 0;
30       
31        public static final double LOW_SPEED = 5.0; // km/h
32        public static final double MAX_QUEUE_GAP = 0.02; // km
33       
34        public ArrayList <IntersectionCarRecord> trafficDB = new ArrayList<IntersectionCarRecord>();
35       
36        public ArrayList <IntersectionCarRecord> intersectionCars = new ArrayList<IntersectionCarRecord>();
37       
38        public Integer DBmutex = new Integer(0); 
39
40//      public ArrayList<TrafficLightInfo> newLightInfos;
41        public int newCycleLength;
42
43        public int phases;
44       
45        int lastMediumTransmission;
46
47        public LinkedList<ReceiveEvent> receiveEvents = new LinkedList<ReceiveEvent>(); 
48       
49        public TreeMap<Integer,Integer> messagePeriods = new TreeMap<Integer,Integer>(); 
50
51        boolean promiscuousMode;
52       
53        public static boolean adaptive = true;
54//      public LinkedList lastHourHistory = new LinkedList();
55       
56        protected boolean initialized = false; 
57
58        final static int CRTDIR = 0;   
59        final static int OPPDIR = 1;
60       
61        private final RadioDev radio = new RadioDev(this);
62       
63        public void init(){
64               
65                for (int i = 0; i < segments.size(); i++){
66                        DirectedRoadSegment seg = segments.get(i);
67                        seg.segmentIndex = i;
68                        seg.intersection = this;
69                        Road r1 = Globals.map.roads.get(seg.roadIndex);
70                        seg.endOfQueue = new IntersectionCarRecord[r1.laneNo + 1];//new ArrayList<IntersectionCarRecord>(r1.laneNo);
71                        seg.queueDischargeRate = new double[r1.laneNo+1];
72                       
73                        for (int j = 0; j <= r1.laneNo; j++){
74                                seg.endOfQueue[j] = new IntersectionCarRecord(null);
75                                seg.queueDischargeRate[j] = -1;
76                        }
77                        if (seg.isExitOnly())
78                                continue;
79                        for (int j = 0; j < segments.size(); j++){
80                                if (i != j && !segments.get(j).isEntryOnly()){
81                                        seg.paths.add(new IntersectionPath(this, seg, segments.get(j)));
82                                }
83                        }
84                       
85                        Intersection intersection = null;
86                        if(seg.direction) {
87                                for(int k=0; k < r1.crosses.size();k++) {
88                                        if(r1.crosses.get(k).getPointIndex() > seg.pointIndex) {
89                                                //that's the next cross
90                                                intersection=Globals.map.allIntersections.get(r1.crosses.get(k).intersectionIndex);
91                                                seg.nextwtlPointIndex = r1.crosses.get(k).getPointIndex();
92                                                break;
93                                        }
94                                }
95                        } else {
96                                for(int k = r1.crosses.size()-1; k >= 0; k--) {
97                                        if(r1.crosses.get(k).getPointIndex() < seg.pointIndex) {
98                                                //that's the next cross
99                                                intersection=Globals.map.allIntersections.get(r1.crosses.get(k).intersectionIndex);
100                                                seg.nextwtlPointIndex = r1.crosses.get(k).getPointIndex();
101                                                break;
102                                        }
103                                }
104                        }
105                        if (intersection == null){
106                                seg.nextwtl = null;
107                        }
108                        if (intersection instanceof WirelessTrafficLight){
109                                seg.nextwtl = (WirelessTrafficLight)intersection;
110                        }
111                }
112        }
113       
114       
115        public void computeNextSignalPlan(int crtTime){
116               
117                if (crtTime < 3 * Globals.MINUTE){
118                        newCycleLength = cycleLength;
119                        for( int j = 0; j < segments.size(); j++ ) {
120                                segments.get(j).setNewLightInfo(segments.get(j).getLightInfo());
121                        }
122                        return;
123                }
124                if (adaptive){
125                        int interGreenTime = 0;
126                        interGreenTime = Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED;
127                       
128                        int green=30;
129                        int time=0, j, lostTime = 0;
130                        double Y = 0, ycr = 0;
131                        int[] v = new int[segments.size()];
132                        double[] yc = new double[segments.size()];
133                       
134                        for( j = 0; j < segments.size(); j++ )
135                                v[j] = 0;
136
137// CALCULATE SUM OF CRITICAL FLOW RATIOS
138                        if (Globals.map.allIntersections.size() >= 2)
139                                if(this.equals(Globals.map.allIntersections.get(1))){
140                                v[0] = 0;
141                        }
142                       
143//                      System.out.println("%%%%%%%%%% The intersections");
144//                      System.out.println(Globals.map.allIntersections.toString());
145                       
146                        phases = 0;
147                        for( j = 0; j < segments.size(); j++ ) {
148                                DirectedRoadSegment seg1 = segments.get(j);
149                                if (v[j] == 1)
150                                        continue;
151                                phases ++;
152                                if (!seg1.isExitOnly()){
153                                        double satflow = Globals.SATURATION_FLOW * seg1.road.laneNo;
154        //                              if (segments.get(j).road.laneNo > 1)
155        //                              satflow -= 300;
156                                        double correction = 0;
157                                        if (seg1.demand > seg1.totalVolume)
158                                                correction = (double)(seg1.demand - seg1.totalVolume);
159                                        yc[j] = (double)(seg1.demand + seg1.carryOver) / satflow;
160                                }else{
161                                        yc[j] = 0;
162                                }
163                                v[seg1.segmentIndex] = 1;
164
165                                /*if (Globals.map.roads.get(0).getName().startsWith("Iuliu")){
166                                        if (j < 2)
167                                                seg1.pair = seg1.front;
168                                        else{
169                                                seg1.pair = null;
170                                        }
171                                }else*/{
172                                        seg1.pair = seg1.front;
173                                        if (seg1.front != null)
174                                                seg1.front.pair = seg1;
175                                }
176                               
177                                DirectedRoadSegment seg2 = seg1.pair;
178                                if (seg2 == null){
179                                        Y += yc[j];
180                                        continue;
181                                }else{
182                                        if (!seg2.isExitOnly()){
183                                                double satflow = Globals.SATURATION_FLOW * seg2.road.laneNo;
184                //                              if (segments.get(j).road.laneNo > 1)
185                //                              satflow -= 300;
186                                                double correction = 0;
187                                                if (seg2.demand > seg2.totalVolume)
188                                                        correction = (double)(seg2.demand - seg2.totalVolume);
189                                                yc[seg2.segmentIndex] = (double)(seg2.demand + seg2.carryOver) / satflow;
190                                        }else{
191                                                yc[seg2.segmentIndex] = 0;
192                                        }
193                                }
194                               
195                                ycr = yc[j];
196                                if (ycr < yc[seg2.segmentIndex]){
197                                        ycr = yc[seg2.segmentIndex];
198                                        yc[j] = ycr;
199                                }else{
200                                        yc[seg2.segmentIndex] = ycr;
201                                }
202                                Y += ycr;
203                                v[seg2.segmentIndex] = 1;
204                        }
205
206// CALCULATE CYCLE LENGTH WITH WEBSTER EQUATION
207                        if (Y >= 1){
208                                newCycleLength = Globals.MAXIMUM_CYCLE_LENGTH;
209                        }else{
210                                lostTime = (int)Math.ceil((double)segments.size() / 2) * interGreenTime;
211                                //Webster's equation
212                                newCycleLength = (int)((double)(1.5 * lostTime + 5) / (1 - Globals.Xc * Y));
213//                              newCycleLength = (int)(2.0 * newCycleLength);
214                                if (newCycleLength > Globals.MAXIMUM_CYCLE_LENGTH || newCycleLength < 0)
215                                        newCycleLength = Globals.MAXIMUM_CYCLE_LENGTH;
216                        }
217
218                        if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)){ 
219                                Globals.pw.print(crtTime/Globals.SECOND + "     ");
220                        }
221//COMPUTE GREEN SPLITS
222                       
223//                      newLightInfos = new ArrayList<TrafficLightInfo>();
224                        double extra = 0, grprop;
225                        double maxIncreaseProp = 1;
226                        int[] greens = new int[segments.size()];
227                        double[] increaseProp = new double[segments.size()];
228                        int count = 0, sum = 0, dec = 0;
229                       
230                        for(j=0;j<segments.size();j++) {
231                                DirectedRoadSegment seg = segments.get(j);
232                               
233                                grprop = (double)(newCycleLength - lostTime) * yc[j] / Y;
234                                green = (int) Math.ceil(grprop);
235                                greens[j] = green;
236                                if (greens[j] == 0){
237                                        greens[j] = 1;
238                                }
239//                              System.out.println("Greens [ "+j+" ] " + greens[j]);
240//                              get the perpendicular segments with green for pedestrians
241                                int maxPedestrianTime = 0;
242                                if (seg.left != null && seg.left.pedestrianCrossingTime > maxPedestrianTime){
243                                        maxPedestrianTime = (int)seg.left.pedestrianCrossingTime;
244                                }
245                                if (seg.right != null && seg.right.pedestrianCrossingTime > maxPedestrianTime){
246                                        maxPedestrianTime = (int)seg.right.pedestrianCrossingTime;
247                                }
248//                              compare to minimum accepted green
249                                int mingreen = (int)(maxPedestrianTime + (double)Globals.MIN_WALK_LIGHT_TIME/Globals.SECOND);
250//                              System.out.println("MaxPedestrianTime [ "+j+" ] " + mingreen);
251                                increaseProp[j] = 0;
252                                if (green + interGreenTime < mingreen){
253                                        increaseProp[j] = (double)(mingreen - interGreenTime) / greens[j];
254//                                      System.out.println("Increase [ "+j+" ] " + increaseProp[j]);
255                                        if (maxIncreaseProp < increaseProp[j])
256                                                maxIncreaseProp = increaseProp[j];
257                                }
258                        }
259
260                        for( j = 0; j < segments.size(); j++ )
261                                v[j] = 0;
262                       
263                        for(j=0;j<segments.size();j ++) {
264                                DirectedRoadSegment seg1 = segments.get(j);
265                                if (v[j] == 1)
266                                        continue;
267                                if (maxIncreaseProp > 0){
268                                        greens[j] = (int)Math.round(maxIncreaseProp * greens[j]); 
269                                }
270                                if ( increaseProp[j] == 0){
271                                        count ++;
272                                }
273                                sum += greens[j] + interGreenTime;
274                                v[seg1.segmentIndex] = 1;
275                                DirectedRoadSegment seg2 = seg1.pair;
276                                if (seg2 != null){
277                                        if (maxIncreaseProp > 0){
278                                                greens[seg2.segmentIndex] = (int)Math.round(maxIncreaseProp * greens[j]); 
279                                        }
280                                        v[seg2.segmentIndex] = 1;
281                                }
282//                              System.out.println("NewGreens [ "+j+" ] " + greens[j]);
283                        }
284                        if (sum > Globals.MAXIMUM_CYCLE_LENGTH){
285                                dec = (int)Math.ceil((double)(sum - Globals.MAXIMUM_CYCLE_LENGTH)/count);
286                        }
287                       
288                       
289                        for( j = 0; j < segments.size(); j++ )
290                                v[j] = 0;
291
292//SET FINAL TIMING PLANS
293                        for( j = 0; j < segments.size(); j++ ) {
294                                DirectedRoadSegment seg1 = segments.get(j);
295                                if (v[j] == 1)
296                                        continue;
297                               
298                                if ( increaseProp[j] == 0 && dec > 0)
299                                        greens[j] -= dec;
300                                if (!seg1.isExitOnly()){
301                                        seg1.setNewLightInfo(new TrafficLightInfo(time, time + greens[j]));
302                                }else{
303                                        seg1.setNewLightInfo(new TrafficLightInfo(time, time));
304                                }
305                                v[seg1.segmentIndex] = 1;
306                                DirectedRoadSegment seg2 = seg1.pair;
307                                if (seg2 != null){
308                                        v[seg2.segmentIndex] = 1;
309                                        greens[seg2.segmentIndex] = greens[j];
310                                        if (!seg2.isExitOnly()){
311                                                seg2.setNewLightInfo(new TrafficLightInfo(time, time + greens[j]));
312                                        }else{
313                                                seg2.setNewLightInfo(new TrafficLightInfo(time, time));
314                                        }
315                                }
316                                if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)){ 
317                                        Globals.pw.print("    " +time +" " + (time + greens[j]) +" ");
318                                }
319                                time = time + greens[j] + interGreenTime;
320                        }
321                       
322                        newCycleLength = time;//Math.ceil(extra);
323                        if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)){ 
324                                Globals.pw.print(" "+newCycleLength + " s ");
325                                Globals.pw.print("  MaxInc " + maxIncreaseProp+"; \n");
326                                Globals.pw.flush();
327                        }
328                }else{
329                        newCycleLength = cycleLength;
330                        for( int j = 0; j < segments.size(); j++ ) {
331                                segments.get(j).setNewLightInfo(segments.get(j).getLightInfo());
332                        }
333                }
334        }
335       
336        public void extendGreen(int t, int secs, DirectedRoadSegment segment){
337                Globals.pw.print("Green Extension\t");
338               
339                TrafficLightInfo tli = segment.getLightInfo();
340                if (secs > (tli.greenEnd - tli.greenStart)/2)
341                        secs = (tli.greenEnd - tli.greenStart)/2;
342               
343                for(int j = 0; j < segments.size(); j++ ) {
344                        DirectedRoadSegment seg = segments.get(j);
345                        tli = seg.getLightInfo();
346                        if (t < tli.yellowStart)
347                                seg.setLightInfo(new TrafficLightInfo(tli.greenStart + secs, tli.greenEnd + secs));
348                        if (seg.equals(segment))
349                                seg.setLightInfo(new TrafficLightInfo(tli.greenStart, tli.greenEnd + secs));
350                        tli = seg.getLightInfo();
351                        Globals.pw.print("    " +tli.greenStart +" " + tli.greenEnd +" ");
352                }
353                cycleLength += secs;
354                Globals.pw.println(" "+cycleLength + " s");
355                Globals.pw.flush();
356        }
357       
358       
359        int changeTime = -1;
360        public void step(int crtTime){
361                if (!initialized){
362                        initialized = true;
363                        init();
364                }
365               
366                //recommend speeds to cars
367//              scheduleSingleSendEvent(1, Globals.PROT_TL_FEEDBACK);
368               
369                if (crtTime % (10 * Globals.SECOND) == 0){
370                        for (int k = 0; k < this.segments.size(); k++) {
371                                DirectedRoadSegment seg = segments.get(k);
372                                seg.recordQueueSize();
373                        }
374                        /*//broadcast feedback
375                        if (Engine.simulationType == RoutingConstants.DYNAMIC_CITY_ROUTE) {
376                                scheduleSingleSendEvent(0, Globals.PROT_TL_FEEDBACK);
377                        }*/
378                }
379                // compute the next cycle signal plan with 2 seconds before switching
380                if (crtTime == lastCycleStartTime + cycleLength * Globals.SECOND - 2 * Globals.SECOND){
381                       
382                        if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)){ 
383                                Globals.pw.println("\n"+crtTime/Globals.SECOND + "s ) WTL");
384                        }
385                        int dem = 0, vol = 0;
386                        double stops = 0;
387                        for (int k = 0; k < this.segments.size(); k++) {
388                                DirectedRoadSegment seg = segments.get(k);
389                               
390                                dem = seg.computeDemand(Globals.ANALYSIS_PERIOD);
391                                vol = seg.computeVolume(Globals.ANALYSIS_PERIOD);
392                                stops = seg.noOfStops;
393                                int analysisPeriod = Globals.ANALYSIS_PERIOD;
394                                if (Globals.ANALYSIS_PERIOD < crtTime){
395                                        analysisPeriod = crtTime;
396                                }
397//                              if (dem > vol){
398                                seg.carryOver += (int)((double)(dem - vol) * (double)(cycleLength * Globals.SECOND) / analysisPeriod);
399                                if (seg.carryOver < 0)
400                                        seg.carryOver = 0;
401//                              }else{
402//                              seg.carryOver -= (int)((double)(dem - vol) * (double)(cycleLength * Globals.SECOND) / analysisPeriod);
403//                              }
404                               
405                                Point px = seg.road.points.get(seg.pointIndex);
406                                double qs = seg.get95thQueueSize();
407                                if (Globals.monitorWTL != null && this.equals(Globals.monitorWTL)){ 
408                                        Globals.pw.println("  "+ seg.segmentIndex + "" +
409                                                        " dem: "+seg.demand + " carry: "+seg.carryOver+" vol: " + seg.totalVolume + " stops: " + seg.noOfStops + " avgQueue: " + qs );
410                                        Globals.pw.flush();
411                                }
412                               
413                                if (Globals.engine.startedWithGUI && Globals.demo.mv.currentIntersection != null &&
414                                                Globals.demo.mv.currentIntersection.equals(this)){
415                                       
416                                        /*if (segments.get(2).road.getName().startsWith("Iuliu")){
417                                                if (k == 0)
418                                                        Globals.demo.st.setDemand("sw", vol, dem, true);
419                                                if (k == 2)
420                                                        Globals.demo.st.setDemand("se", vol, dem, true);
421                                                if (k == 1)
422                                                        Globals.demo.st.setDemand("ne", vol, dem, true);
423                                                if (k == 3)
424                                                        Globals.demo.st.setDemand("nw", vol, dem, true);
425                                        }
426                                        if (segments.get(1).road.getName().startsWith("Dr T")){
427                                                if (k == 0)
428                                                        Globals.demo.st.setDemand("sw", vol, dem, true);
429                                                if (k == 2)
430                                                        Globals.demo.st.setDemand("se", vol, dem, true);
431                                                if (k == 1)
432                                                        Globals.demo.st.setDemand("ne", vol, dem, true);
433                                                if (k == 3)
434                                                        Globals.demo.st.setDemand("nw", vol, dem, true);
435                                        }*/
436                                }
437
438                        }
439                       
440                        computeNextSignalPlan(crtTime);
441        }
442               
443                boolean debug = false;
444                if (crtTime == lastCycleStartTime + cycleLength * Globals.SECOND){
445                        debug = true;
446                        lastCycleStartTime = crtTime;
447                        cycleLength = newCycleLength;
448                        for( int j = 0; j < segments.size(); j++ ) {
449                                segments.get(j).setLightInfo(segments.get(j).getNewLightInfo());
450                        }
451                }
452                int thisSec = (int) (crtTime / (Globals.executionFPS));
453                int aux = thisSec - (lastCycleStartTime / Globals.SECOND);
454               
455                synchronized (this) {
456                        boolean b = false;
457                        if (Globals.engine.startedWithGUI && Globals.demo.mv.currentIntersection != null &&
458                                        Globals.demo.mv.currentIntersection.equals(this)){
459                                Globals.demo.st.cycle.setText("Cycle: " + cycleLength + " s");
460                               
461                        }
462                        for (int k = 0; k < this.segments.size(); k++) {
463                                TrafficLightInfo info = segments.get(k).getLightInfo();
464                                int color = info.getColor(aux);
465                                if (color != currentColor.get(k) ){
466                                        currentColor.set(k, color);
467                                        int dem = 0, vol = 0;
468                                        double stops = 0;
469                                        if (segments.get(k).pair != null 
470                                                        && segments.get(k).pair.getLightInfo().getColor(aux-1) == Globals.GREEN 
471                                                        && adaptive){
472                                                int i = segments.get(k).paths.indexOf(new IntersectionPath(segments.get(k), segments.get(k).pair));
473                                                if (i!= -1 && color == Globals.YELLOW){ 
474                                                        int secsEx = segments.get(k).leftSignalExtension(); 
475                                                        if (secsEx > 0){
476                                                                System.out.println("Extension");
477                                                                extendGreen(aux, secsEx, segments.get(k));
478                                                                continue;
479                                                        }
480                                                }
481                                        }
482                                        segments.get(k).changePhase(null,crtTime, color);
483                                        if (!segments.get(k).isExitOnly()){
484                                                DirectedRoadSegment seg = segments.get(k);
485                                               
486                                                dem = seg.computeDemand(Globals.ANALYSIS_PERIOD);
487                                                vol = seg.computeVolume(Globals.ANALYSIS_PERIOD);
488                                                stops = seg.noOfStops;
489                                               
490                                        }
491                                               
492                                        b = true;
493                                        if (segments.get(k).pair != null){
494                                                int i = segments.get(k).paths.indexOf(new IntersectionPath(segments.get(k), segments.get(k).pair));
495                                                if (i!= -1 && color == Globals.YELLOW){ 
496                                                        IntersectionPhaseStatistics ips= segments.get(k).paths.get(i).getLastGreenPhase();
497                                                       
498//                                                      if (ips!= null)
499//                                                      System.out.println(crtTime + ") gap ["+segments.get(k)+" "+segments.get(k).front+"] "+ ips.avgGap);
500                                                       
501                                                }
502                                        }
503                                        if (Globals.engine.startedWithGUI && Globals.demo.mv.currentIntersection != null &&
504                                                        Globals.demo.mv.currentIntersection.equals(this)){
505                                                /*if (segments.get(2).road.getName().startsWith("Iuliu")){
506                                                        if (k == 0)
507                                                                Globals.demo.st.setDemand("sw", vol, dem, true);
508                                                        if (k == 2)
509                                                                Globals.demo.st.setDemand("se", vol, dem, true);
510                                                        if (k == 1)
511                                                                Globals.demo.st.setDemand("ne", vol, dem, true);
512                                                        if (k == 3)
513                                                                Globals.demo.st.setDemand("nw", vol, dem, true);
514                                                }
515                                                if (segments.get(0).road.getName().startsWith("Dr T")){
516                                                        if (k == 0)
517                                                                Globals.demo.st.setDemand("sw", vol, dem, true);
518                                                        if (k == 2)
519                                                                Globals.demo.st.setDemand("se", vol, dem, true);
520                                                        if (k == 1)
521                                                                Globals.demo.st.setDemand("ne", vol, dem, true);
522                                                        if (k == 3)
523                                                                Globals.demo.st.setDemand("nw", vol, dem, true);
524                                                }*/
525                                        }
526                                }
527                               
528                               
529                               
530                                if (Globals.engine.startedWithGUI && Globals.demo.mv.currentIntersection != null &&
531                                                Globals.demo.mv.currentIntersection.equals(this)){
532                                        int x;
533                                        x = info.greenEnd - aux;
534                                        if (x < 0)
535                                                x = 0;
536                                        if (aux < info.greenStart)
537                                                x = info.greenEnd - info.greenStart;
538//                                     
539//                                      if (segments.get(2).road.getName().startsWith("Iuliu")){
540//                                              if (k == 0)
541//                                                      Globals.demo.st.phase2.setText("Green sw: " + x +" s");
542//                                              if (k == 2)
543//                                                      Globals.demo.st.phase1.setText("Green se: " + x +" s");
544//                                              if (k == 1)
545//                                                      Globals.demo.st.phase3.setText("Green ne: " + x +" s");
546//                                              if (k == 3)
547//                                                      Globals.demo.st.phase4.setText("Green nw: " + x +" s");
548//                                      }
549//                                      if (segments.get(0).road.getName().startsWith("Dr T")){
550//                                              if (k == 0)
551//                                                      Globals.demo.st.phase2.setText("Green sw: " + x +" s");
552//                                              if (k == 2)
553//                                                      Globals.demo.st.phase1.setText("Green se: " + x +" s");
554//                                              if (k == 1)
555//                                                      Globals.demo.st.phase3.setText("Green ne: " + x +" s");
556//                                      }
557                                }
558                               
559                        }
560                       
561                        if (b){
562                                changeTime = crtTime;
563                        }
564                        if (debug){
565                               
566                        }
567                        if (Globals.engine.startedWithGUI && Globals.demo.mv.currentIntersection != null &&
568                                        Globals.demo.mv.currentIntersection.equals(this)){
569                                Globals.demo.st.repaint();
570                               
571                        }
572
573//debug
574/*                      if (Globals.demo.mv.currentIntersection != null &&
575                                        Globals.demo.mv.currentIntersection.equals(this) &&
576                                        changeTime != -1 && crtTime == changeTime + 200){
577                                prevSec = (int) ((changeTime - 11) / (Globals.executionFPS));
578                                aux = prevSec % this.totalTime;
579                                for (int k = 0; k < this.segments.size(); k++) {
580                                        if (!segments.get(k).isExitOnly()){
581                                               
582                                                TrafficLightInfo info = this.lightInfos.get(k);
583                                                Road r = Globals.map.roads.get(segments.get(k).roadIndex);
584                                                int l = segments.get(k).pointIndex;
585                                                if (segments.get(k).direction)
586                                                        l++;
587                                                else
588                                                        l--;
589                                               
590                                                if (info.getColor(aux) == 1) System.out.print("Red ");
591                                                if (info.getColor(aux) == 2) System.out.print("Yellow ");
592                                                if (info.getColor(aux) == 3) System.out.print("Green ");
593                                               
594                                                int n = 0;
595                                                for (int i=0; i < segments.get(k).paths.size();i++){
596                                                        IntersectionPath ip = segments.get(k).paths.get(i);
597                                                       
598                                                        IntersectionPhaseStatistics ips = ip.lastHourHistory.getLast();
599                                                       
600                                                        if (changeTime <= ips.phaseStartFrame ){
601                                                                ips = ip.lastHourHistory.get(ip.lastHourHistory.size() - 2);
602                                                        }
603                                                        n += ips.getCarsNo();
604                                                }
605                                               
606                                                Road road = Globals.map.roads.get(segments.get(k).roadIndex);
607                                                Point p0 = road.points.get(segments.get(k).pointIndex);
608                                                if (segments.get(k).cars != null)
609                                                for (int i = 1; i < segments.get(k).cars.size(); i ++){
610                                                        SimulatedCarInfo sc1 = segments.get(k).cars.get(i-1).car;
611                                                        SimulatedCarInfo sc2 = segments.get(k).cars.get(i-1).car;
612                                                        Point p1 = road.points.get(sc1.getPointIdx());
613                                                        Point p2 = road.points.get(sc2.getPointIdx());
614                                                        if (Math.pow(p1.getDistance() - p0.getDistance(),2)
615                                                                        > Math.pow(p2.getDistance() - p0.getDistance(),2))
616                                                                throw new RuntimeException();
617                                                       
618                                                }
619                                               
620                                                System.out.println(segments.get(k).roadIndex+"; "+r.getName() + " [" + l +"] : " + n);
621                                        }
622                                }
623                                System.out.println(" --------- /"+ crtTime);
624                                System.out.flush();
625                        }*/
626                }
627
628        }
629       
630        public void onReceive(byte[] bytesReceived, Serializable message, Communicator sender) {
631                int j, k = 0;
632                ByteArrayInputStream byteStream = new ByteArrayInputStream(bytesReceived);
633                byte numberOfRecords, recordsRead = 0;
634                byte[] b = new byte[Globals.NONAGG_RECORD_SIZE];
635                int offset;
636               
637                byte protocol = (byte)byteStream.read();
638                switch (protocol){
639                        case Globals.PROT_NEIGHBOR_DISCOVERY: 
640                                                        numberOfRecords = 1;
641                                                        break;
642                        case Globals.PROT_SETOFCARS: 
643                                                        numberOfRecords = (byte)byteStream.read();
644                                                        break;
645                        default:
646                                                        return;
647                }
648                if (numberOfRecords == -1)
649                        return;
650               
651                int comState = (byte)byteStream.read();
652               
653               
654                DirectedRoadSegment messageSegment = null;
655                boolean sendToNeighborWTL = false;
656               
657                offset = 2;
658                while (recordsRead < numberOfRecords){
659                       
660                        int n = byteStream.read(b, 0, Globals.NONAGG_RECORD_SIZE);
661                        if (n == -1 || n < Globals.NONAGG_RECORD_SIZE){
662                                break;
663                        }
664                        offset += Globals.NONAGG_RECORD_SIZE;
665                        recordsRead ++;
666                       
667                        SimulatedCarInfo sc = new SimulatedCarInfo();
668                        sc.wrap(b);
669                       
670                        Engine e = Globals.engine;
671                       
672                        if (Globals.engine.startedWithGUI && Globals.demo.mv.currentIntersection != null &&
673                                        Globals.demo.mv.currentIntersection.equals(this)){
674                                j = 0;
675                        }
676                        IntersectionCarRecord icr = new IntersectionCarRecord(sc);
677                       
678                        int i = trafficDB.indexOf(icr);
679                       
680                        // update car
681                        if (i != -1){
682                                IntersectionCarRecord old = trafficDB.get(i);
683                                DirectedRoadSegment oldseg = null;
684                                DirectedRoadSegment seg = null;
685                               
686                                if (old.getCar().getTimestamp() >= sc.getTimestamp() )
687                                        continue;
688                                if (!(sender instanceof WirelessTrafficLight)){
689                                        old.learnedFromWTL = false;
690                                }
691                               
692                                if (old.isPassed()){
693                                        if (recordsRead == 1 && comState == CRTDIR){
694                                                for (j=0; j<segments.size();j++){
695                                                        seg = segments.get(j);
696                                                        if (seg.containsCar(icr)){
697                                                                messageSegment = seg;
698                                                                sendToNeighborWTL = true;
699                                                                break;
700                                                        }
701                                                }
702                                        }
703                                        continue;
704                                }
705                               
706                                for (j=0; j<segments.size();j++){
707                                        seg = segments.get(j);
708                                       
709                                       
710                                        if (seg.containsCar(icr) || seg.carEntersIntersection(icr) || seg.carExitsIntersection(icr)){
711                                               
712                                                synchronized(DBmutex){
713                                                        // if the old record was on the same segment
714                                                        oldseg = old.segment;
715                                                        if (oldseg.cars != null){
716                                                                oldseg.cars.remove(old);       
717                                                        }
718                                                       
719                                                        icr = new IntersectionCarRecord(old, true);
720                                                        icr.car = sc;
721                                                       
722                                                        if (seg.cars == null)
723                                                                seg.cars = new SortedIntersectionRecordList(seg);
724                                                       
725                                                        if (seg.carEntersIntersection(icr) || seg.carExitsIntersection(icr)){
726                                                                if (intersectionCars.indexOf(icr) == -1){
727                                                                        int lane = old.getCar().getLane();
728                                                                        if (oldseg.endOfQueue[lane].getCar() != null && oldseg.endOfQueue[lane].equals(icr))
729                                                                                oldseg.endOfQueue[lane] = new IntersectionCarRecord(null);
730                                                                        icr.old = old;
731                                                                        intersectionCars.add(icr);
732                                                                }
733//                                                              seg.cars.add(icr);
734                                                                trafficDB.set(i,icr);
735                                                        }else
736                                                                if (seg.isCarApproaching(icr)){
737                                                                        seg.cars.add(icr);
738                                                                        icr.setPassed(false);
739                                                                       
740                                                                        trafficDB.set(i,icr);
741                                                                        if (seg.endOfQueue[old.getCar().getLane()].getCar() != null &&
742                                                                                        seg.endOfQueue[old.getCar().getLane()].equals(old)){
743                                                                                if (old.getCar().getLane() != icr.getCar().getLane()){
744                                                                                        seg.computeEndOfQueue(old);
745                                                                                }
746                                                                        }
747                                                                        if (seg.isCarQueuing(icr)){
748                                                                                if (icr.getQueuedTime() == -1) 
749                                                                                        icr.setQueuedTime(e.crtTime);
750                                                                                if (!icr.countedForDemand){
751                                                                                        icr.increaseDemand();
752                                                                                }
753                                                                        }else{
754                                                                                if (!icr.countedForDemand
755                                                                                        && icr.distanceTillIntersection() < Globals.DEMAND_DISTANCE_ON_FREE_FLOW){
756                                                                                       
757                                                                                        icr.increaseDemand();
758                                                                                }
759                                                                        }
760//                                                                      if (recordsRead == 1 && comState == OPPDIR){
761//                                                                              //first car
762//                                                                              messageSegment = seg;
763//                                                                              sendToNeighborWTL = true;
764//                                                                      }
765                                                                }else{
766                                                                        // the car has just passed through the intersection
767                                                                        int z = intersectionCars.indexOf(icr);
768                                                                        if (z!= -1){
769                                                                                intersectionCars.remove(icr);
770                                                                                old = icr.old;
771                                                                        }
772                                                                        if (oldseg != null){
773                                                                                oldseg.recordCar(old, seg);
774                                                                                int lane = old.getCar().getLane();
775                                                                                if(z == -1) 
776                                                                                        if (oldseg.endOfQueue[lane].getCar() != null && oldseg.endOfQueue[lane].equals(icr))
777                                                                                                oldseg.endOfQueue[lane] = new IntersectionCarRecord(null);
778
779                                                                        }else{
780                                                                                System.out.println("[DEBUG - WTL] Car passed but oldseg = null");
781                                                                        }
782                                                                        if (recordsRead == 1 && comState == CRTDIR){
783                                                                                //first car
784                                                                                if (Globals.map.allIntersections.size()>=2 && Globals.map.allIntersections.get(1).equals(this)){
785                                                                                        messageSegment = seg;
786                                                                                               
787                                                                                }
788                                                                                       
789                                                                                messageSegment = seg;
790                                                                                sendToNeighborWTL = true;
791                                                                        }
792                                                                        icr.setPassed(true);
793                                                                        trafficDB.set(i,icr);
794                                                                }
795
796                                                }
797                                                break;
798                                        }
799
800                                }
801                               
802                                if (j == segments.size()){
803                                        System.out.println("WTL" + this.toString() + ": car not on my segments: " +sc);
804                                        synchronized(DBmutex){
805                                                trafficDB.remove(i);
806                                        }
807                                        return;
808                                }
809                               
810                        }
811                        // new car
812                        else{ 
813                                DirectedRoadSegment seg = null;
814                                for (j=0; j<segments.size();j++){
815                                        seg = segments.get(j);
816                                        if (seg.containsCar(icr)){
817                                               
818                                                if (seg.isCarApproaching(icr)){
819                                                        synchronized(DBmutex){
820                                                                if (seg.cars == null){
821                                                                        seg.cars = new SortedIntersectionRecordList(seg);
822                                                                }
823                                                                seg.cars.add(icr);
824                                                                trafficDB.add(icr);
825
826                                                                if (sender instanceof WirelessTrafficLight)
827                                                                        icr.init(this, seg, true);
828                                                                else
829                                                                        icr.init(this, seg, false);
830                                                                if (seg.get95thQueueSize() > 0.15){
831                                                                        icr.increaseDemand();
832                                                                }
833                                                        }
834//                                                      if (recordsRead == 1 && comState == OPPDIR){
835//                                                              //first car
836//                                                              messageSegment = seg;
837//                                                              sendToNeighborWTL = true;
838//                                                      }
839                                                }else{
840                                                        if (recordsRead == 1 && comState == CRTDIR){
841                                                                messageSegment = seg;
842                                                                sendToNeighborWTL = true;
843                                                        }
844                                                }
845                                                break;
846                                        }
847                                }
848                        }
849                }
850                // Got stack overflow when 2 traffic lights at the end of a segment
851                // route are sending messages to each other
852                //if (sendToNeighborWTL && messageSegment.nextwtl != null){
853                //      messageSegment.nextwtl.onReceive(bytesReceived, this);
854                //}
855        }
856
857        public byte[] prepareMessage(int messageType) {
858                byte[] bytesToSend = null;
859               
860                if (messageType == Globals.PROT_TL_FEEDBACK){
861                        ByteBuffer bb = ByteBuffer.allocate(Globals.TL_FEEDBACK_SIZE);
862                        bb.put(Globals.PROT_TL_FEEDBACK);
863                       
864                        bb.putShort((short)cycleLength);
865                        int thisSec = (int) (Globals.engine.crtTime / (Globals.SECOND));
866                        int aux = thisSec - (lastCycleStartTime / Globals.SECOND);
867                        bb.put((byte)segments.size());
868                        for (int k = 0; k < this.segments.size(); k++) {
869                                Road rx = Globals.map.roads.get(segments.get(k).roadIndex);
870                                Point px = rx.points.get(segments.get(k).pointIndex);
871                                bb.putShort((short)segments.get(k).roadIndex);
872                                bb.putShort((short)segments.get(k).pointIndex);
873                                if (segments.get(k).direction == true)
874                                        bb.put((byte)1);
875                                else
876                                        bb.put((byte)0);
877                               
878                                TrafficLightInfo info = segments.get(k).getLightInfo();
879                                int color = info.getColor(aux);
880                                bb.put((byte)color);
881                                int remaining = -1;
882                                if (color == Globals.GREEN){
883                                        remaining = info.greenEnd - aux;
884                                }
885                                if (color == Globals.RED){
886                                        if (aux < info.greenStart) 
887                                                remaining = info.greenStart - aux;
888                                        else{
889                                                remaining = info.greenStart + (cycleLength - aux);
890//                                              remaining = - remaining;
891                                        }
892                                }
893                                bb.putShort((short)remaining);
894                                bb.putShort((short)(cycleLength - (info.greenEnd - info.greenStart)));
895                               
896                                for (int i = 1; i < segments.get(k).endOfQueue.length;i++){
897                                        IntersectionCarRecord icr = segments.get(k).endOfQueue[i];
898                                        if (icr.car == null){
899                                                bb.putDouble(0);
900                                        }else{
901                                                Road r = Globals.map.roads.get(icr.car.getRoadIdx());
902                                                Point p = r.points.get(icr.car.getPointIdx());
903                                                double distance = p.getDistance() - px.getDistance();
904                                                if (distance < 0)
905                                                        distance = - distance;
906                                                bb.putDouble(distance);
907                                        }
908                                }
909                        }
910                        bytesToSend = bb.array();
911                }
912                return bytesToSend;
913        }
914
915        public int getLastMediumTransmition() {
916                return lastMediumTransmission;
917        }
918        public void setLastMediumTransmition(int lastMediumTransmission) {
919                this.lastMediumTransmission = lastMediumTransmission;
920        }
921       
922        public boolean mediumAvailable(int crtTime){
923                int fps = Globals.engine.fps;
924                if (crtTime - lastMediumTransmission >= Globals.WIRELESS_TRANSMISSION_FRAMES)
925                        return true;
926                return false;
927        }
928       
929        public boolean isPeriodicalMessage(int messageType){
930                return (messageType >= 0);
931        }
932
933        public int getPeriod(int messageType){
934                try{
935                        return messagePeriods.get(new Integer(messageType)).intValue();
936                }catch(Exception e){
937                        return -1;
938                }
939        }
940       
941        public boolean isPromiscuousMode() {
942                return promiscuousMode;
943        }
944        public void setPromiscuousMode(boolean promiscuousMode) {
945                this.promiscuousMode = promiscuousMode;
946        }
947
948        /**
949         * delay of the new event (in frames)
950         * @return the identifier of the new message type
951         */
952        public int scheduleSingleSendEvent(int delay, int messageType){
953                Engine engine = Globals.engine;
954                int newType = PROT_RESERVED;
955                if (messageType != -1)
956                        newType = Globals.PROT_TL_FEEDBACK;
957               
958                // if (singleMessageNo < MIN_NEG_INT) singleMessageNo = -1;
959               
960                engine.schedEvent(new SendEvent(engine.crtTime + delay, this, newType));
961                return newType;
962        }
963       
964        @Override
965        public String toString() {
966                String s = "[ ";
967                for (int i = 0; i < segments.size(); i++){
968                        if (i > 0 && segments.get(i-1).road.getName().equals(segments.get(i).road.getName())){
969                                continue;
970                        }
971                        s += segments.get(i).road.getName().trim()+" ";
972                }
973                s += "]";
974                return s;
975        }
976       
977        public short getRoadIdx(){
978                return (short)segments.get(0).roadIndex;
979        }
980       
981        public short getPointIdx(){
982                return (short)segments.get(0).pointIndex;
983        }
984       
985        public RadioDev getRadio(){
986                return radio;
987        }
988
989        public ReceiveEvent getReceiveEventForTime(int t){
990                int i = receiveEvents.indexOf(new ReceiveEvent(t, null, null, null, 0));
991                if (i == -1)
992                        return null;
993                return receiveEvents.get(i);
994        }
995
996        public void addReceiveEventForTime(ReceiveEvent re){
997                receiveEvents.add(re);
998        }
999        public void removeReceiveEventForTime(int t){
1000                int i = receiveEvents.indexOf(new ReceiveEvent(t, null, null, null, 0));
1001                if (i == -1)
1002                        return;
1003                receiveEvents.remove(i);
1004        }
1005
1006}
Note: See TracBrowser for help on using the repository browser.