source: proiecte/ptvs/src/vnsim/vehicular/routePlan/cityRouting/IntersectionNode.java @ 31

Last change on this file since 31 was 31, checked in by (none), 14 years ago
File size: 9.0 KB
Line 
1package vnsim.vehicular.routePlan.cityRouting;
2
3import java.io.Serializable;
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.HashMap;
7import java.util.Iterator;
8import java.util.StringTokenizer;
9
10import vnsim.applications.trafficview.SimulatedCarInfo;
11import vnsim.applications.vitp.CarRunningVITP;
12import vnsim.core.Communicator;
13import vnsim.core.Engine;
14import vnsim.core.events.SendEvent;
15import vnsim.map.object.Globals;
16import vnsim.vehicular.generator.Mobility;
17import vnsim.vehicular.simulator.CarInstance;
18import vnsim.vehicular.simulator.NotMovingPersonality;
19import vnsim.vehicular.simulator.RouteSegment;
20import vnsim.vehicular.simulator.intersections.DirectedRoadSegment;
21import vnsim.vehicular.simulator.intersections.Intersection;
22import vnsim.vehicular.simulator.intersections.TrafficLightInfo;
23
24public class IntersectionNode extends CarRunningVITP {
25        // time interval at which route metrics are sent to cars
26        private static final int kRouteMetricsInterval = Globals.SECOND / 1;
27        private static final double kTrafficLightFlow = 0.5; // cars per second
28        private static final double kDistanceBetweenCars = 5; // meters
29        private static final int kDefaultGreenTime = 30; // seconds
30        private static final double kMaxAllowedSpeed = 70; // km/h
31
32        private CityTrafficLight correspondingIntersection = null;
33        // mediated costs for each segment
34        private ArrayList<RoadSegmentCost> correspondingSegmentsCost;
35        // incoming cost list for each segment
36        private ArrayList<HashMap<Integer, Double>> incomingCost;
37        // the time when the mediated costs were sent to server
38        private ArrayList<Integer> lastUpdateTime;
39        // distance of the segments
40        private ArrayList<Double> segmentsLength;
41
42        private Server server;
43        // from server
44        private int crossIndex;
45
46        // list of segments with their actual congestion
47        // updated from server
48        private ArrayList<RoadSegmentCongestion> updatedCongestion;
49
50        public IntersectionNode(int vehicleId, short roadIdx, short pointIdx,
51                        CityTrafficLight p, Server s) {
52                super(vehicleId, (byte) 0, 0.0, roadIdx, pointIdx, (byte) 0, 0.0);
53                correspondingIntersection = p;
54                correspondingSegmentsCost = new ArrayList<RoadSegmentCost>();
55                incomingCost = new ArrayList<HashMap<Integer, Double>>();
56                lastUpdateTime = new ArrayList<Integer>();
57                segmentsLength = new ArrayList<Double>();
58                for (int i = 0; i < correspondingIntersection.segments.size(); i++) {
59                        for (int j = 0; j < Globals.routePlanConstants.segmentsCost.size(); j++) {
60                                if (Globals.routePlanConstants.segmentsCost.get(j).equals(
61                                                correspondingIntersection.segments.get(i))) {
62                                        this.correspondingSegmentsCost
63                                                        .add(Globals.routePlanConstants.segmentsCost.get(j));
64                                        break;
65                                }
66                        }
67                        incomingCost.add(new HashMap<Integer, Double>());
68                        lastUpdateTime.add(0);
69                        DirectedRoadSegment drs = correspondingIntersection.segments.get(i);
70                        segmentsLength.add(CityRouteComputingUtlis.getRoadSegmentDistance(drs));
71                }
72                if (this.correspondingIntersection.segments.size() != this.correspondingSegmentsCost
73                                .size()) {
74                        System.out
75                                        .println("Err: segmentsCost are not properly initialized");
76                        System.exit(0);
77                }
78                server = s;
79                crossIndex = server.addIntersectionNode(this);
80                updatedCongestion = new ArrayList<RoadSegmentCongestion>();
81        }
82
83        public static void createIntersectionNodes(Server s) {
84                for (int i = 0; i < Globals.map.allIntersections.size(); i++) {
85                        Intersection it = Globals.map.allIntersections.get(i);
86                        if (!(it instanceof CityTrafficLight)) {
87                                continue;
88                        }
89                        DirectedRoadSegment dr = it.segments.get(0);
90                        CarInstance car = null;
91
92                        car = Mobility
93                                        .createNewInvisibleCar(dr.roadIndex, dr.pointIndex, 0, 0,
94                                                        0.0, new NotMovingPersonality(), 0.0,
95                                                        Engine.lastCarID, dr.roadIndex, dr.pointIndex + 1,
96                                                        new RouteSegment((short) dr.roadIndex,
97                                                                        (short) dr.pointIndex,
98                                                                        (short) (dr.pointIndex + 1)), 5);
99                        if (car != null) {
100                                Engine.lastCarID++;
101                                System.out.println("Created invisible carReceivingMsg id="
102                                                + (Engine.lastCarID - 1) + " at road " + dr.roadIndex
103                                                + " point " + dr.pointIndex);
104                                addIntersectionNode(car, (CityTrafficLight) it, s);
105                        } else {
106                                System.out.println("Err: could not create IntersectionNode");
107                        }
108                }
109        }
110
111        public static void addIntersectionNode(CarInstance car,
112                        CityTrafficLight pos, Server s) {
113                if (car == null)
114                        return;
115
116                synchronized (Globals.engine.cars) {
117                        IntersectionNode in;
118                        if (car.routingType == 5) {
119                                if (Globals.engine.crtTime == 0) {
120                                        in = new IntersectionNode(car.ID, car.getRoadIdx(), car
121                                                        .getPointIdx(), pos, s);
122                                        in.setTimestamp(Globals.engine.crtTime);
123                                        in.setRealPos(car);
124                                        Globals.engine.cars.add(in);
125                                        Globals.engine.infrastructure.add(in);
126                                        in.init();
127                                } else {
128                                        int poz = Globals.engine.cars.indexOf(new SimulatedCarInfo(
129                                                        car.ID));
130                                        if (poz == -1) {
131                                                in = new IntersectionNode(car.ID, car.getRoadIdx(), car
132                                                                .getPointIdx(), pos, s);
133                                                in.setTimestamp(Globals.engine.crtTime);
134                                                in.setRealPos(car);
135                                                Globals.engine.schedEvent(new SendEvent(
136                                                                Globals.engine.crtTime + 1, in,
137                                                                SimulatedCarInfo.STANDARD_MESSAGE_ID));
138                                                Globals.engine.cars.add(in);
139                                                Globals.engine.infrastructure.add(in);
140                                                in.init();
141                                        } else {
142                                                ((SimulatedCarInfo) Globals.engine.cars.get(poz))
143                                                                .setRealPos(car);
144                                        }
145                                }
146                        }
147                }
148        }
149
150        public void onReceive(byte[] bytesReceived, Serializable m, Communicator sender) {
151                if (!isEquipped || bytesReceived == null)
152                        return;
153                // is it a VITP packet?
154                byte header = bytesReceived[0];
155                byte[] message = null;
156
157                switch (header) {
158                case Globals.PROT_NEIGHBOR_DISCOVERY:
159                        super.onReceive(bytesReceived, m, sender);
160                        break;
161                case Globals.VITP_PROT:
162                        super.onReceive(bytesReceived, m, sender);
163                        break;
164                case Globals.ROAD_METRICS_PROT:
165                        message = new byte[bytesReceived.length - 1];
166                        for (int i = 0; i < message.length; i++) {
167                                message[i] = bytesReceived[i + 1];
168                        }
169                        parseMetrics(message);
170                        break;
171                }
172        }
173
174        // calculate the congestion from a road metric packet
175        private void parseMetrics(byte[] metrics) {
176                String metricsStr = new String(metrics);
177                StringTokenizer st = new StringTokenizer(metricsStr);
178                String type = st.nextToken();
179                if (type == null || !type.equals("RM")) {
180                        return;
181                }
182                int carID = Integer.parseInt(st.nextToken());
183                double avgSpeed = Double.parseDouble(st.nextToken());
184                int nTLCycles = Integer.parseInt(st.nextToken());
185                int segmentIndex = Integer.parseInt(st.nextToken());
186
187                HashMap<Integer, Double> data = incomingCost.get(segmentIndex);
188                if (data.containsKey(carID)) { // data from this car exists
189                        return;
190                }
191                TrafficLightInfo tlInfo = correspondingIntersection.segments.get(
192                                segmentIndex).getNewLightInfo();
193                int greenTime;
194                if (tlInfo == null) {
195                        greenTime = kDefaultGreenTime;
196                } else {
197                        greenTime = tlInfo.greenEnd - tlInfo.greenStart;
198                }
199                int nTLMax = (int) Math.ceil(segmentsLength.get(segmentIndex)
200                                / (kTrafficLightFlow * greenTime * kDistanceBetweenCars));
201
202                avgSpeed = avgSpeed * (1 - (double) nTLCycles / nTLMax);
203                double congestion;
204                if (avgSpeed > kMaxAllowedSpeed) {
205                        congestion = 0;
206                } else {
207                        congestion = 255 * (1 - avgSpeed / kMaxAllowedSpeed);
208                }
209                data.put(carID, congestion);
210                // System.out.println("intersection received routemetrics from "+carID);
211        }
212
213        private Double mediateCosts(int segmentNo) {
214                Double m = new Double(0);
215                HashMap<Integer, Double> data = incomingCost.get(segmentNo);
216                if (data.size() == 0) {
217                        return m;
218                }
219                Collection<Double> values = data.values();
220                Iterator<Double> valuesIt = values.iterator();
221                while (valuesIt.hasNext()) {
222                        m = m + valuesIt.next();
223                }
224                m = m / data.size();
225                return m;
226        }
227
228        public void step(int crtTime) {
229                if (crtTime % Globals.SECOND == 0) {
230                        sendCostsToServer(crtTime);
231                }
232                if (crtTime % kRouteMetricsInterval == 0) {
233                        sendCostsToCars();
234                }
235        }
236
237        // if traffic light is on red send the segment cost to server
238        private void sendCostsToServer(int crtTime) {
239                for (int i = 0; i < correspondingIntersection.segments.size(); i++) {
240                        Integer lastRed = correspondingIntersection.lastRed(i);
241                        if (!(lastUpdateTime.get(i).equals(lastRed))) {
242                                lastUpdateTime.set(i, lastRed);
243                                Double newCost = mediateCosts(i);
244                                if (newCost != 0)
245                                        server.setCongestion(crossIndex, i, crtTime, newCost);
246                                correspondingSegmentsCost.get(i).setCost(newCost);
247                                // clear hashmap
248                                incomingCost.get(i).clear();
249                        }
250                }
251        }
252
253        private void sendCostsToCars() {
254                String toSend = "RMR ";
255                for (int i = 0; i < updatedCongestion.size(); i++) {
256                        toSend = toSend + "C " + updatedCongestion.get(i).toString();
257                }
258                broadcastRoadPacket(toSend);
259        }
260
261        public void updateCongestions(ArrayList<RoadSegmentCongestion> congestions) {
262                updatedCongestion = congestions;
263        }
264
265        public int getSegmentsNb() {
266                return correspondingIntersection.segments.size();
267        }
268}
Note: See TracBrowser for help on using the repository browser.