source: proiecte/ptvs/src/vnsim/vehicular/simulator/intersections/DirectedRoadSegment.java @ 31

Last change on this file since 31 was 31, checked in by (none), 14 years ago
File size: 14.6 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.vehicular.simulator.intersections;
7
8import java.util.ArrayList;
9import java.util.Collections;
10import java.util.LinkedList;
11import java.util.ListIterator;
12
13import vnsim.applications.adaptiveTL.*;
14import vnsim.applications.trafficview.SimulatedCarInfo;
15import vnsim.map.object.*;
16import vnsim.vehicular.simulator.RouteSegment;
17
18public class DirectedRoadSegment implements java.io.Serializable {
19
20        // represents a road segment of road "roadIndex", starting
21        // from point "pointIndex" going either towards point "0" (if
22        // "direction"=false) or towards the last point on the road
23        // (if "direction"=true);
24        private static final long serialVersionUID = -5883719321862303634L;
25
26        public int roadIndex;
27        public int pointIndex;
28        public boolean direction;
29        public int segmentIndex;
30        public Intersection intersection = null;
31
32        public double angle; // degrees ( 0 - 360)
33
34        public SortedIntersectionRecordList cars = null;
35
36        public ArrayList<IntersectionPath> paths = new ArrayList<IntersectionPath>();
37        public IntersectionCarRecord[] endOfQueue = null;
38        public double[] queueDischargeRate;
39
40        public double leftProc;
41        public double pedestrianCrossingTime = 0; // seconds
42        public double noOfStops = 0;
43        public int totalLaneNo;
44        public Road road;
45
46        public int demand = 0;
47        public int totalVolume = 0;
48        public int carryOver = 0;
49
50        TrafficLightInfo lightInfo = null;
51        TrafficLightInfo newLightInfo = null;
52
53        public WirelessTrafficLight nextwtl = null;
54        public int nextwtlPointIndex = -1;
55
56        public DirectedRoadSegment left = null, right = null, front = null, pair = null;
57
58        // queue sizes measured for a speciffic analysis period
59        public LinkedList<Double> queueSizes = new LinkedList<Double>();
60        public int crossedLeft = 0;
61
62       
63        public DirectedRoadSegment(int roadIndex, int pointIndex, boolean direction)
64        {
65                this.roadIndex=roadIndex;
66                this.pointIndex=pointIndex;
67                this.direction=direction;
68                // set the angle
69
70                Road r1 = Globals.map.roads.get(roadIndex);
71                this.road = r1;
72                Point p1 = r1.points.get(pointIndex);
73                Point p2;
74                if (direction) {
75                        p2 = Globals.map.roads.get(roadIndex).points.get(pointIndex + 1);
76                } else {
77                        p2 = Globals.map.roads.get(roadIndex).points.get(pointIndex - 1);
78                }
79
80                double dy = p2.getLatitude() - p1.getLatitude();
81                double dx = p2.getLongitude() - p1.getLongitude();
82
83                if (dx == 0) {
84                        if (dy > 0)
85                                angle = 90.0;
86                        else
87                                angle = 270.0;
88                        return;
89                }
90                double rads = Math.atan(dy / dx);
91                if (rads > 0) {
92                        if (dx > 0) {
93                                // dx and dy both positive
94                                angle = Math.toDegrees(rads);
95                        } else {
96                                // both negative
97                                angle = Math.toDegrees(rads + Math.PI);
98                        }
99                } else {
100                        if (dx < 0) {
101                                // dx negative, dy positive
102                                angle = Math.toDegrees(Math.PI + rads);
103                        } else {
104                                // dy negative, dx positive
105                                angle = Math.toDegrees(2 * Math.PI + rads);
106                        }
107                }
108
109                // compute crossing time and maximum intergreen time
110                Road r = Globals.map.roads.get(roadIndex);
111                if (r.oneWay == 0) {
112                        totalLaneNo = 2 * r.laneNo;
113                } else {
114                        totalLaneNo = r.laneNo;
115                }
116                pedestrianCrossingTime = Math.ceil((double) (totalLaneNo * Globals.LANE_WIDTH) / Globals.PEDESTRIAN_SPEED);
117        }
118
119        public boolean equals(Object o) {
120                try {
121                        DirectedRoadSegment drs = (DirectedRoadSegment) o;
122                        if (drs.roadIndex == roadIndex && drs.pointIndex == pointIndex && drs.direction == direction)
123                                return true;
124                        return false;
125                } catch (Exception ex) {
126                        return false;
127                }
128        }
129
130        public boolean isSameSegment(RouteSegment s1) {
131                // should be on the same road
132                if (s1.roadIndex != this.roadIndex)
133                        return false;
134                // should have a point in common
135                if (s1.pt1 == this.pointIndex) {
136                        if (s1.pt2 < s1.pt1 && this.direction == false)
137                                return true;
138                        if (s1.pt2 > s1.pt1 && this.direction == true)
139                                return true;
140                }
141                if (s1.pt2 == this.pointIndex) {
142                        if (s1.pt1 < s1.pt2 && this.direction == false)
143                                return true;
144                        if (s1.pt1 > s1.pt2 && this.direction == true)
145                                return true;
146                }
147                return false;
148        }
149
150        public boolean isExitOnly() {
151                Road r = Globals.map.roads.get(roadIndex);
152                if (r.oneWay == 0)
153                        return false;
154                if (r.oneWay == 1) {
155                        if (direction)
156                                return true;
157                        else
158                                return false;
159                }
160                if (r.oneWay == 2) {
161                        if (direction)
162                                return false;
163                        else
164                                return true;
165                }
166                System.out.println("ERROR! isExitOnly found an unexpected value for oneWay!");
167                return false;
168        }
169
170        public boolean isEntryOnly() {
171                Road r = Globals.map.roads.get(roadIndex);
172                if (r.oneWay == 0)
173                        return false;
174                if (r.oneWay == 1) {
175                        if (direction)
176                                return false;
177                        else
178                                return true;
179                }
180                if (r.oneWay == 2) {
181                        if (direction)
182                                return true;
183                        else
184                                return false;
185                }
186                System.out.println("ERROR! isEntryOnly found an unexpected value for oneWay!");
187                return false;
188        }
189
190        public boolean carEntersIntersection(IntersectionCarRecord icr) {
191                SimulatedCarInfo sc = icr.getCar();
192                if (roadIndex == sc.getRoadIdx() && sc.getPointIdx() == pointIndex && (sc.getDirection() == 1) == !direction)
193                        return true;
194                return false;
195        }
196
197        public boolean carExitsIntersection(IntersectionCarRecord icr) {
198                SimulatedCarInfo sc = icr.getCar();
199                if (roadIndex == sc.getRoadIdx() && sc.getPointIdx() == pointIndex && (sc.getDirection() == 1) == direction)
200                        return true;
201                return false;
202        }
203
204        public boolean containsCar(IntersectionCarRecord icr) {
205                SimulatedCarInfo sc = icr.getCar();
206                if (roadIndex == sc.getRoadIdx()
207                                && ((sc.getPointIdx() > pointIndex && direction == true) || (sc.getPointIdx() < pointIndex && direction == false))) {
208                        // || (sc.getPointIdx() == pointIndex) && (sc.getDirection() == 1)
209                        // == direction))
210                        if (nextwtl != null) {
211                                if (direction == true && sc.getPointIdx() >= nextwtlPointIndex)
212                                        return false;
213                                if (direction == false && sc.getPointIdx() <= nextwtlPointIndex)
214                                        return false;
215                        }
216                        return true;
217                }
218                return false;
219        }
220
221        public boolean isCarApproaching(IntersectionCarRecord icr) {
222                SimulatedCarInfo sc = icr.getCar();
223                if (this.roadIndex == sc.getRoadIdx()) {
224                        if (sc.getPointIdx() >= this.pointIndex && this.direction == true) {
225                                if (sc.getDirection() == 1) {
226                                        return false;
227                                } else {
228                                        return true;
229                                }
230                        }
231                        if (sc.getPointIdx() <= this.pointIndex && this.direction == false) {
232                                if (sc.getDirection() == 1) {
233                                        return true;
234                                } else {
235                                        return false;
236                                }
237                        }
238                }
239                return false;
240        }
241
242        public void computeEndOfQueue(IntersectionCarRecord icr) {
243                SimulatedCarInfo car = icr.getCar();
244                endOfQueue[car.getLane()] = null;
245                ListIterator<IntersectionCarRecord> it = cars.listIterator();
246                Point px = Globals.map.roads.get(roadIndex).points.get(pointIndex);
247                IntersectionCarRecord end = new IntersectionCarRecord(null);
248                while (it.hasNext()) {
249                        IntersectionCarRecord crt = it.next();
250                        SimulatedCarInfo crtcar = crt.getCar();
251                        if (cars.getComparator().compare(crt, icr) > 0 && crtcar.getPointIdx() != car.getPointIdx())
252                                break;
253                        if (crtcar.getLane() != car.getLane())
254                                continue;
255
256                        Point p = Globals.map.roads.get(roadIndex).points.get(crtcar.getPointIdx());
257                        double dist = p.getDistance() - px.getDistance();
258                        if (dist < 0)
259                                dist = -dist;
260                        if (dist < WirelessTrafficLight.MAX_QUEUE_GAP) {
261                                end = crt;
262                        }
263                        px = p;
264                }
265                endOfQueue[car.getLane()] = end;
266        }
267
268        public boolean isCarQueuing(IntersectionCarRecord icr) {
269                SimulatedCarInfo car = icr.getCar();
270                if (car.getSpeed() < WirelessTrafficLight.LOW_SPEED) {
271                        int lane = car.getLane();
272                        Point p = Globals.map.roads.get(roadIndex).points.get(car.getPointIdx());
273                        Point px = null;
274                        if (endOfQueue[lane].getCar() == null) {
275                                // intersection point
276                                px = Globals.map.roads.get(roadIndex).points.get(pointIndex);
277
278                        } else {
279                                if (cars.getComparator().compare(endOfQueue[lane], icr) > 0)
280                                        return true;
281
282                                if (endOfQueue[lane].equals(icr)) {
283                                        // endOfQueue[lane] = icr;
284                                        // return true;
285                                        int idx = Collections.binarySearch(cars, icr, cars.getComparator());
286                                        ListIterator<IntersectionCarRecord> it = cars.listIterator(idx);
287                                        boolean first = true;
288                                        while (it.hasPrevious()) {
289                                                SimulatedCarInfo carInFront = it.previous().getCar();
290                                                if (carInFront.getLane() != car.getLane())
291                                                        continue;
292
293                                                first = false;
294                                                int pi = endOfQueue[lane].getCar().getPointIdx();
295                                                px = Globals.map.roads.get(roadIndex).points.get(pi);
296                                                double dist = p.getDistance() - px.getDistance();
297                                                if (dist < 0)
298                                                        dist = -dist;
299                                                if (dist < WirelessTrafficLight.MAX_QUEUE_GAP * 2) {
300                                                        endOfQueue[lane] = icr;
301                                                        return true;
302                                                } else {
303                                                        computeEndOfQueue(endOfQueue[lane]);
304                                                        return false;
305                                                }
306                                        }
307                                        if (first) {
308                                                endOfQueue[lane] = new IntersectionCarRecord(null);
309                                                return isCarQueuing(icr);
310                                        }
311                                } else {
312                                        int pi = endOfQueue[lane].getCar().getPointIdx();
313                                        px = Globals.map.roads.get(roadIndex).points.get(pi);
314                                }
315                        }
316
317                        double dist = p.getDistance() - px.getDistance();
318                        if (dist < 0)
319                                dist = -dist;
320                        if (dist < WirelessTrafficLight.MAX_QUEUE_GAP) {
321                                endOfQueue[lane] = icr;
322                                return true;
323                        }
324                }
325                return false;
326        }
327
328        // the number of seconds to extend the green phase, for protected left
329        public int leftSignalExtension() {
330                int leftLane = road.laneNo;
331                if (endOfQueue[leftLane].getCar() == null || this.front == null) {
332                        return 0;
333                }
334
335                ListIterator<IntersectionCarRecord> it = cars.listIterator();
336                int leftRq = 0;
337                while (it.hasNext()) {
338                        IntersectionCarRecord crt = it.next();
339                        SimulatedCarInfo crtcar = crt.getCar();
340                        if (crtcar.getLane() != leftLane) {
341                                continue;
342                        }
343                        if (cars.getComparator().compare(crt, endOfQueue[leftLane]) > 0)
344                                break;
345                        if (crtcar.getSignal() == (byte) 1) {
346                                leftRq++;
347                        }
348                }
349                if (leftRq == 0)
350                        return 0;
351                int i = paths.indexOf(new IntersectionPath(this, this.front));
352                double stops = paths.get(i).computeAvgNoOfStops(Globals.ANALYSIS_PERIOD);
353                if (stops == 0)
354                        stops = 0.5;
355                if (crossedLeft != 0 && (double) (crossedLeft + leftRq) / crossedLeft < 2 * stops)
356                        return 0;
357                int shouldPass = (int) (2 * stops * (leftRq + crossedLeft)) - crossedLeft;
358
359                if (shouldPass == 0)
360                        return 0;
361
362                leftRq = 0;
363                int k = 0;
364                it = cars.listIterator();
365                while (it.hasNext()) {
366                        IntersectionCarRecord crt = it.next();
367                        SimulatedCarInfo crtcar = crt.getCar();
368                        if (crtcar.getLane() != leftLane) {
369                                continue;
370                        }
371                        if (cars.getComparator().compare(crt, endOfQueue[leftLane]) > 0)
372                                break;
373                        k++;
374                        if (crtcar.getSignal() == (byte) 1) {
375                                leftRq++;
376                        }
377                        if (leftRq == shouldPass) {
378                                break;
379                        }
380                }
381                // 0.5 veh/s
382                return k * 2;
383        }
384
385        public int computeDemand(int period) {
386                if (paths.size() == 0)
387                        return 0;
388                IntersectionPath ip = paths.get(0);
389
390                demand = ip.computeDemand(period);
391
392                int left = ip.computeLeftDemand(period);
393                leftProc = (double) left * 100.0 / demand;
394                // if (Globals.engine.crtTime < period )
395                // demand = (int)((double) (Globals.HOUR * demand) /
396                // Globals.engine.crtTime );
397                // else
398                // demand = (int)((double) (Globals.HOUR * demand) / period);
399                demand = (int) ((double) (Globals.HOUR * demand) / ip.analysisPeriod);
400
401                return demand;
402        }
403
404        public int computeVolume(int period) {
405                totalVolume = 0;
406                noOfStops = 0;
407                int analysisPeriod = 0;
408
409                for (int i = 0; i < paths.size(); i++) {
410                        IntersectionPath ip = paths.get(i);
411                        int vol = ip.computeVolume(period);
412                        analysisPeriod += ip.analysisPeriod;
413                        totalVolume += vol;
414                        double stops = ip.computeAvgNoOfStops(period);
415                        noOfStops += (double) vol * stops;
416                }
417                try {
418                        analysisPeriod /= paths.size();
419                        noOfStops /= totalVolume;
420                        totalVolume = (int) ((double) (Globals.HOUR * totalVolume) / analysisPeriod);
421                } catch (Exception e) {
422                        totalVolume = 0;
423                        noOfStops = 0;
424                }
425                return totalVolume;
426        }
427
428        // public double computeLastCycleQueueSize(){
429        // if (paths.size() == 0)
430        // return 0;
431        // IntersectionPath ip = paths.get(0);
432        // return ip.computeLastCycleQueueSize();
433        // }
434
435        public void changePhase(DirectedRoadSegment connection, int crtTime, int color) {
436                if (color == Globals.GREEN) {
437                        crossedLeft = 0;
438                }
439                if (connection == null) {
440                        // one single color for all directions
441                        int n = 0;
442                        for (int i = 0; i < paths.size(); i++) {
443                                IntersectionPath ip = paths.get(i);
444
445                                n += ip.lastHourHistory.getLast().getCarsNo();
446
447                                ip.changePhase(crtTime, color);
448                        }
449
450                } else {
451                        int i = paths.indexOf(connection);
452                        assert (i != -1);
453                        IntersectionPath ip = paths.get(i);
454                        ip.changePhase(crtTime, color);
455                }
456        }
457
458        public void recordCar(IntersectionCarRecord icr, DirectedRoadSegment newseg) {
459                int i = paths.indexOf(new IntersectionPath(this, newseg));
460                if (this.left != null && this.left.equals(newseg)) {
461                        crossedLeft++;
462                }
463                if (i == -1)
464                        return;
465                IntersectionPath ip = paths.get(i);
466                ip.recordCar(icr);
467        }
468
469        public void recordQueueSize() {
470                double avg = 0;
471                Point px = road.points.get(pointIndex);
472                for (int i = 1; i < endOfQueue.length; i++) {
473                        if (endOfQueue[i].getCar() != null) {
474                                Point p = road.points.get(endOfQueue[i].getCar().getPointIdx());
475                                avg += Math.abs(p.getDistance() - px.getDistance());
476                        }
477                }
478                try {
479                        avg /= endOfQueue.length - 1;
480                } catch (Exception e) {
481                        avg = 0;
482                }
483
484                queueSizes.add(new Double(avg));
485                while (queueSizes.size() > Globals.ANALYSIS_PERIOD / (10 * Globals.SECOND)) {
486                        queueSizes.removeFirst();
487                }
488
489        }
490
491        public double get95thQueueSize() {
492                if (queueSizes.size() == 0) {
493                        return 0;
494                }
495                ArrayList<Double> array = new ArrayList<Double>();
496                array.addAll(queueSizes);
497                Collections.sort(array);
498                int idx = (int) (array.size() * 0.95);
499                return array.get(idx).doubleValue();
500        }
501
502        public String toString() {
503                return "(Rd=" + roadIndex + ";Pt=" + pointIndex + ";Dir=" + direction + " + ANGLE=" + angle + ") ";
504        }
505
506        public TrafficLightInfo getLightInfo() {
507                return lightInfo;
508        }
509
510        public void setLightInfo(TrafficLightInfo lightInfo) {
511                this.lightInfo = lightInfo;
512        }
513
514        public TrafficLightInfo getNewLightInfo() {
515                return newLightInfo;
516        }
517
518        public void setNewLightInfo(TrafficLightInfo newLightInfo) {
519                this.newLightInfo = newLightInfo;
520        }
521}
Note: See TracBrowser for help on using the repository browser.