source: proiecte/ptvs/src/vnsim/network/scft/CarRunningSCFT.java @ 31

Last change on this file since 31 was 31, checked in by (none), 14 years ago
File size: 15.9 KB
Line 
1package vnsim.network.scft;
2
3import java.io.ByteArrayOutputStream;
4import java.io.File;
5import java.io.IOException;
6import java.io.PrintWriter;
7import java.io.Serializable;
8import java.nio.ByteBuffer;
9import java.util.ArrayList;
10import java.util.HashMap;
11import java.util.Iterator;
12import java.util.Map;
13
14import vnsim.applications.trafficview.SimulatedCarInfo;
15import vnsim.core.CarInfo;
16import vnsim.core.Communicator;
17import vnsim.core.Engine;
18import vnsim.map.object.Globals;
19import vnsim.map.object.Point;
20import vnsim.map.object.Road;
21import vnsim.map.utils.GPSutil;
22import vnsim.network.dsrc.Application;
23import vnsim.network.dsrc.CarRunningDSRC;
24import vnsim.vehicular.scenarios.Route;
25import vnsim.vehicular.simulator.CarInstance;
26import vnsim.vehicular.simulator.RouteSegment;
27
28/**
29 * Implements the functionality of a car that uses the SCFT algorithm to route messages (store-and-forward and based on the car's trajectory),
30 * as well as DSRC as transporting protocol.
31 * @author Serban George-Cristian
32 */
33public class CarRunningSCFT extends CarRunningDSRC {
34
35        public Map<Integer, MesageSCFT> msgQueue = new HashMap<Integer, MesageSCFT>();
36
37        /**
38         * Number of nodes the message can traverse until it discarding - used to avoid continuous loops
39         */
40        public int ttl = 5;
41       
42        /**
43         * Numarul de mesaje transmise
44         */
45        public static int nrPleaca = 0;
46        /**
47         * Numarul de mesaje receptionate (livrate destinatarului)
48         */
49        public static int nrLivrate = 0;
50        public static Object lock = new Object();
51        public static PrintWriter out = null;
52       
53        /**
54         * rezultatele se depun intr-un fisier text
55         */
56        static {
57                try {
58                        out= new PrintWriter(new File("outputSCFT.txt"));
59                } catch (Exception e) { }
60        }
61
62        /**
63         * Atribute coada de mesaje
64         * @param insertKey - cheia de insertie
65         * @param removeKey - cheia de stergere numarul
66         * @param maxNrOfMessages- numarul maxim de mesaje ce pot fi stocate
67         * @param nrMsgToRemove - numarul de mesaje ce vor fi sterse in caz de coada plina
68         * @param secBeforeDeleteMsg - timpul de store al mesajelor
69         */
70
71        /** Insertion key */
72        public int insertKey = 1;
73
74        /** Removal key (number) */
75        public int removeKey = 1;
76
77        /**
78         * numarul maxim de mesaje ce va fi pastrat in coada
79         */
80        public int maxNrOfMessages      = 20;
81        /**
82         * numarul de mesaje ce vor fi sterse in cazul in care coada de mesaje este plina
83         */
84        public int nrMsgToRemove        = 3;
85        /**
86         * timpul dupa care un mesaj aflat in coada de mesaje va fi sters
87         */
88        public int timeBeforeDeleteMsg = 30000;
89
90        /**
91         * tipul de mesaj ce va fi stocat
92         */
93        public MesageSCFT mesage;
94
95               
96        /**
97         * constructorul clasei
98         * @param vehicleId
99         * @param lane
100         * @param speed
101         * @param roadIdx
102         * @param pointIdx
103         * @param direction
104         * @param offset
105         */
106        public CarRunningSCFT(int vehicleId, byte lane, double speed, short roadIdx, short pointIdx, byte direction,
107                        double offset) {
108                super(vehicleId, lane, speed, roadIdx, pointIdx, direction, offset);
109                System.out.println("CarRunningSCFT");
110        }
111
112        /**
113         * calculeaza distanta intre vehicule aflate pe aceeasi strada
114         * @return
115         */
116        public double getDistance() {
117
118                return this.getRealPos().getDistanceToCarInFront();
119
120        }
121
122
123        /**
124         * calculeaza distanta reala intre doua puncte
125         * @param x1 - sursa
126         * @param y1 - sursa
127         * @param x2 - destinatie
128         * @param y2 - destinatie
129         * @return
130         */
131        public double getRealDistance(double x1, double y1,double x2,double y2){
132
133                return Math.sqrt( Math.pow((x1-x2) ,2 ) + Math.pow((y1-y2) ,2 ));
134
135        }
136
137
138        /**
139         * functia de fitness a traiectoriei
140         * Fitnesul se calculeaza pe baza segmentelor comune si daca vehiculele
141         * se vor afla pe acel segment la un acelasi moment de timp sau
142         * la un moment de timp apropiat
143         * Ca si un sistem real de GPS se estimeaza timpul in care vehiculul sursa si vehiculul destinatie vor ajunge
144         * si pe baza acestor parametrii se calculeaza fitness-ul
145         * @return
146         */
147        public double getTrajectoryFitness(int vId){
148
149                int nrSegComune =0;
150
151
152                SimulatedCarInfo sciTr = (SimulatedCarInfo)Globals.engine.getCarIdx(vId);
153
154                if (sciTr != null ) {
155
156                        CarInstance destCar = sciTr.getRealPos();
157
158
159                        /**
160                         * preluam coordonatele punctului destinatie
161                         *
162                         */
163                        Road currentRoadsDestI = (Road) Globals.map.roads.get(sciTr.getRoadIdx());
164                        short ptd = sciTr.getPointIdx();
165                        Point pd = (Point) currentRoadsDestI.points.get(ptd);
166                        float yd = (float) GPSutil.getMetersLatitude(Globals.minPoint, pd);
167                        float xd = (float) GPSutil.getMetersLongitude(Globals.minPoint, pd);
168
169
170                        /**
171                         * preluam datele initiale de la sursa
172                         */
173
174                        Road currentRoadSourceI = (Road) Globals.map.roads.get(getRoadIdx());
175                        short pts = getPointIdx();
176                        Point ps = (Point) currentRoadSourceI.points.get(pts);
177                        float ys = (float) GPSutil.getMetersLatitude(Globals.minPoint, ps);
178                        float xs = (float) GPSutil.getMetersLongitude(Globals.minPoint, ps);
179
180                        CarInstance sourceCar = getRealPos();
181
182                        if (destCar.routeIndex == destCar.route.length - 1) {
183                                return 0.1;
184                        }
185
186                        if (sourceCar.routeIndex == sourceCar.route.length - 1) {
187                                return 0.1;
188                        }
189
190                        /**
191                         * cautam segmentele comune
192                         */
193                        for (int i=destCar.routeIndex; i<destCar.route.length; i++) {
194                                RouteSegment destSeg = destCar.route[i];
195                                for (int j=sourceCar.routeIndex; j<sourceCar.route.length; j++) {
196                                        RouteSegment sourceSeg = sourceCar.route[j];
197                                        /**
198                                         * testam segmentele pentru a gasi segmentele comune
199                                         */
200                                        if (destSeg.equals(sourceSeg)) {
201
202                                                /**
203                                                 * preluam segmentele curente pentru a
204                                                 * calcula diferenta de timp
205                                                 */
206                                                Road currentRoadsSourceC = (Road) Globals.map.roads.get(sourceSeg.roadIndex);
207                                                Road currentRoadsDestC = (Road) Globals.map.roads.get(destSeg.roadIndex);
208
209                                                /**
210                                                 * preluam datele de pe segmentele comune
211                                                 * pentru a estima timpul in care vehiculele vor ajunge
212                                                 */
213                                                float xdc =     (float) currentRoadsDestC.points.get(0).getLatitude();
214                                                float ydc = (float) currentRoadsDestC.points.get(0).getLongitude();
215
216                                                float xsc =     (float) currentRoadsSourceC.points.get(0).getLatitude();
217                                                float ysc = (float) currentRoadsSourceC.points.get(0).getLongitude();                                           
218
219                                                double timpSource = getRealDistance(xsc, ysc, xs, ys) / speed;
220                                                double timpDest = getRealDistance(xdc, ydc, xd, yd) / sciTr.getSpeed();
221
222                                                if ( Math.abs(timpDest - timpSource) < 20  )
223                                                        return -0.1;
224
225
226                                        }
227                                }
228                        }
229
230
231
232                }
233
234                return 0.1;
235       
236        }
237
238
239        /**
240         * functia de fitness pentru viteza
241         * @return - valoare pozitiva daca viteza este mai mare decat un anumit prag
242         */
243        public double getSpeed(int vId){
244
245                double result;
246
247                SimulatedCarInfo sciSpeed = (SimulatedCarInfo)Globals.engine.getCarIdx(vId);
248
249                if (sciSpeed != null){
250                        if( direction == sciSpeed.getDirection() )
251                                result = Math.abs(speed - sciSpeed.getSpeed());
252                        else
253                                result = speed + sciSpeed.getSpeed();
254                }
255                else
256                        result = speed;
257
258                if( result > 40)
259                        return 0.1;
260                else
261                        return -0.1;
262        }
263
264
265        /**
266         * functia de fitness - ia in calcul distanta,viteza si traiectoria
267         * vehicului si in urma acestor factori calculeaza o valoare
268         * @return - valoarea care duce la memorarea mesajului sau la transmiterea acestuia direct
269         */
270        public double getFitness(int vId) {
271
272                return Math.log(this.getDistance())/10 + this.getSpeed(vId) + this.getTrajectoryFitness(vId);
273
274        }
275
276
277
278        /**
279         * functia care intoarce probabilitatea ca mesajul sa ajunga la destinatie
280         * @return 1 - se poate transmite direct
281         *                -1 - se face store-carry     
282         */
283        public int getDecision(int vId) {
284
285                if (getFitness(vId) < 0.45)
286                        return 1;
287                else
288                        return -1;
289        }
290
291        /**
292         *  functia de receptie a unui mesaj
293         */
294
295        public void onReceive(byte[] bytesReceived,Serializable m, Communicator sender)
296        {
297
298                int vehicleIdSource;
299                int vehicleIdDest;
300                long carIdSourceH;
301                long carIdSourceV;
302                long carlIdDestH;
303                long carlIdDestV;
304                long timeStamp;
305                int ttl;
306
307
308                MesageSCFT msg;
309
310                if (!isEquipped || bytesReceived == null)
311                        return;
312                //System.out.println("on receive:"+bytesReceived[0]);
313
314                int tip;
315
316                byte[] message = null;
317
318                ByteBuffer bb = ByteBuffer.wrap(bytesReceived);
319                bb.rewind();
320
321                final int header =bb.getInt();
322
323                switch(header)
324                {
325                case 1:
326                        //preiau informatiile si creez mesajul
327                        /**
328                         * se preiau informatiile transmise
329                         */
330                       
331                        vehicleIdSource = bb.getInt();
332                        vehicleIdDest = bb.getInt();
333                        carIdSourceH = bb.getLong();
334                        carIdSourceV = bb.getLong();
335                        carlIdDestH = bb.getLong();
336                        carlIdDestV = bb.getLong();
337                        timeStamp = bb.getLong();
338                        ttl = bb.getInt() - 1;//decrementam la primire ttl-ul
339
340                        /**
341                         * daca id-ul destinatie este chiar cel al masinii curente
342                         * inseamna livrarea unui mesaj
343                         */
344                        if(vehicleId == vehicleIdDest){
345                                synchronized (lock) {
346                                        nrLivrate++;
347                                        if ((float)nrLivrate/ nrPleaca <=1)
348                                        {
349                                                out.println((long)((float)Globals.engine.crtTime / Globals.SECOND * 1000L)+" "+(float)nrLivrate/nrPleaca * 100+" "+Math.abs(nrPleaca-nrLivrate));
350                                                out.flush();
351                                        }       
352                                        else
353                                        {
354                                                out.println((long)((float)Globals.engine.crtTime / Globals.SECOND * 1000L)+" "+ 100+" "+Math.abs(nrPleaca-nrLivrate));
355                                                out.flush();
356                                        }
357                                }
358                                return;
359                        }
360                       
361                        /**
362                         * daca id-ul curent nu este acelasi cu id-ul destinatie
363                         * si daca ttl >0 se introduce in coada de mesaje
364                         */
365                        if (ttl > 0)
366                        {
367                                msg = new MesageSCFT(vehicleIdSource,vehicleIdDest,carIdSourceH,carIdSourceV,carlIdDestH,carlIdDestV, timeStamp,ttl);
368                                insertKey++;
369                                msgQueue.put(insertKey, msg);
370                        }
371                        break;
372
373                default:super.onReceive(bytesReceived,m,sender);
374                }
375        }
376
377
378       
379       
380        /**
381         * funtia de transmitere a mesajelor
382         */
383        public byte[] prepareMessage(int messageType)
384        {
385                ByteBuffer bb = ByteBuffer.allocate(56);
386                byte[] bytesToSend=null;
387
388                System.out.println("CarRunningSCFT - prepareMessage called");
389
390                if (!isEquipped)
391                        return null;
392
393
394                if(messageType==1)
395                {
396                        byte[] localinfo = null;
397
398                        System.out.println("CarRunningSCFT - storeCarryForward called");
399
400                        /**
401                         * stergem primele nrMsgToRemove mesaje in caz de coada plina
402                         */
403
404                        if (insertKey - removeKey + 1 > maxNrOfMessages)
405                                for (int i = 0; i < nrMsgToRemove; i++) {
406                                        removeKey++;
407                                        msgQueue.remove(removeKey);
408                                }
409                        /**
410                         * daca mesajul a expirat - a stat iPn coada mai mult de timeBeforeDeleteMsg secunde
411                         * aici sunt eliminate in ordine daca mesajele sunt ordonate
412                         */
413                        for(int i=removeKey;i< insertKey;i++)
414                                if(msgQueue.containsKey(i))
415                                {
416                                        long timeMsg = msgQueue.get(i).getTimeStamp() ;
417                                        long timeGlobal = Globals.engine.getCrtTime() ;
418
419                                        if ( timeGlobal - timeMsg > timeBeforeDeleteMsg ){
420                                                msgQueue.remove(i);
421
422
423                                        }
424                                }
425
426                        /**
427                         * store, carry sau forward
428                         * incercam sa scoatem mesajele si sa le transmitem daca nu se reuseste
429                         * si timpul de store nu a fost depasit pastram mesajul daca nu se
430                         * reuseste dupa un timpul de stocare mesajele se sterg din coada
431                         */
432
433                        /**
434                         * daca exista mesaje in coada de mesaje
435                         * acestea se transmit 
436                         */
437                        for (int i=removeKey;i<insertKey;i++)
438                                if(msgQueue.containsKey(i))
439                                        if (getDecision(msgQueue.get(i).vehicleIdDest) > 0)
440                                        {
441                                               
442                                                bb.clear();
443                                                bb.putInt(1);
444                                                bb.putInt(msgQueue.get(i).vehicleIdSource);
445                                                bb.putInt(msgQueue.get(i).vehicleIdDest);
446                                                bb.putLong(msgQueue.get(i).carIdSourceH);
447                                                bb.putLong(msgQueue.get(i).carIdSourceV);
448                                                bb.putLong(msgQueue.get(i).carIdDestH);
449                                                bb.putLong(msgQueue.get(i).carIdDestV);
450                                                bb.putLong(msgQueue.get(i).timeStamp);
451                                                bb.putInt(msgQueue.get(i).ttl);
452
453                                               
454                                        }
455
456                        /**
457                         * cautam un posibil vehicul destinatie
458                         * se alege un index random si se cauta daca a fost creat un vehicul cu acel index
459                         * daca nu exista un astfel de vehicul, cautarea continua dupa pasii prezentati mai sus
460                         * daca este gasit, cautarea inceteaza
461                         */
462                        int nextCar = 0;
463                        SimulatedCarInfo sci = null;
464                        while (true) {
465                                nextCar =(int)(Math.random()*Engine.lastCarID);
466                                sci = (SimulatedCarInfo)Globals.engine.getCarIdx(nextCar);
467                                if (sci != null) break;
468                        }
469
470                        /**
471                         * preiau coordonatele vehiculului sursa, date necesare in vederea stabilirii distantei reale
472                         * intre vehiculul sursa si vehiculul destinatie
473                         * datele preluate - coordonatele vehiculului
474                         */
475                       
476                        Road currentRoads = (Road) Globals.map.roads.get(getRoadIdx());
477                        short pts = getPointIdx();
478                        Point ps = (Point) currentRoads.points.get(pts);
479                        float ys = (float) GPSutil.getMetersLatitude(Globals.minPoint, ps);
480                        float xs = (float) GPSutil.getMetersLongitude(Globals.minPoint, ps);
481
482
483
484                        /**
485                         * preiau coordonatele vehiculului destinatie, date necesare in vederea stabilirii distantei reale
486                         * intre vehiculul sursa si vehiculul destinatie
487                         * datele preluate - coordonatele vehiculului
488                         */
489                        Road currentRoad = (Road) Globals.map.roads.get(sci.getRoadIdx());
490                        short pt = sci.getPointIdx();
491                        Point pd = (Point) currentRoad.points.get(pt);
492                        float y = (float) GPSutil.getMetersLatitude(Globals.minPoint, pd);
493                        float x = (float) GPSutil.getMetersLongitude(Globals.minPoint, pd);
494
495               
496
497                        /**
498                         * daca mesajul nu poate fi transmis se va stoca in coada
499                         * si se va incerca transmiterea lui de fiecare data cand vehiculul se afla
500                         *  in apropierea altor vehicule ce ar putea prelua mesajul si ar putea
501                         *  sa il livreze vehiculului destinatie
502                         */
503                        if (getDecision(nextCar) < 0) {
504
505                                /**
506                                 *
507                                 * se creaza un mesaj de tip MesageSCFT ce va contine
508                                 *            - id vehicul sursa
509                                 *            - id vehicul destinatie
510                                 *            - pozitia orizontala a vehicului sursa
511                                 *            - pozitia verticala a vehicului sursa
512                                 *            - pozitia orizontala a vehicului destinatie
513                                 *            - pozitia verticala a vehicului destinatie
514                                 *            - timpul de sosire a mesajului - secunde
515                                 *            - TTL definit
516                                 */
517
518                                mesage = new MesageSCFT(vehicleId,nextCar, (long)xs, (long)ys, (long)x,  (long)y, Globals.engine.getCrtTime(),ttl);
519                                insertKey++;
520                                msgQueue.put(insertKey, mesage);
521
522                                /*System.out.println();
523                                System.out.println("afisarea cozii");
524                                System.out.println("distanta "+getDistance()+" fitnesul "+getFitness(nextCar)+" decizia " +getDecision(nextCar));
525                                System.out.println("afisam vehicle id :"+ vehicleId +" "+nextCar+" id "+" "+x+" "+y);
526                                System.out.println("viteza destinatie "+sci.getSpeed()+" "+ sci.getDirection()+" " +" viteza sursa " + speed +" "+direction);
527                                System.out.println("introducem in coada "+ Globals.engine.getCrtTime());
528                                System.out.println();*/
529
530
531                        } else{
532                                /**
533                                 * daca decizia de transmitere a mesajelor este pozitiva
534                                 * mesajul se va transmite direct fara a mai fi stocat in coada de mesaje
535                                 * pentru fiecare eveniment send se creeaza un eveniment receive
536                                 */
537
538                                bb.clear();
539                                bb.putInt(1);
540                                bb.putInt(vehicleId);
541                                bb.putInt(nextCar);
542                                bb.putLong((long)xs);
543                                bb.putLong((long)ys);
544                                bb.putLong((long)x);
545                                bb.putLong((long)y);
546                                bb.putLong(Globals.engine.getCrtTime());
547                                bb.putInt(ttl);
548                               
549                                /**
550                                 * la fiecare mesaj nou transmis se creste numarul de mesaje
551                                 * care au fost transmise
552                                 */
553                                synchronized (lock) {
554                                        nrPleaca++;
555                                        if ((float)nrLivrate/ nrPleaca <=1)
556                                        {
557                                                out.println((long)((float)Globals.engine.crtTime / Globals.SECOND * 1000L)+" "+(float)nrLivrate/nrPleaca * 100+" "+Math.abs(nrPleaca-nrLivrate));
558                                                out.flush();
559                                        }       
560                                        else
561                                        {
562                                                out.println((long)((float)Globals.engine.crtTime / Globals.SECOND * 1000L)+" "+ 100+" "+Math.abs(nrPleaca-nrLivrate));
563                                                out.flush();
564                                        }
565                                }
566
567                                /*System.out.println();
568                                System.out.println("distanta "+getDistance()+" fitnesul "+getFitness(nextCar)+" decizia " +getDecision(nextCar));       
569                                System.out.println(" roadidx  "+ this.roadIdx +xs+" "+ys);
570                                System.out.println("afisam vehicle id :"+vehicleId+" "+nextCar +" "+x+" "+y);
571                                System.out.println("viteza destinatie "+sci.getSpeed() +" "+ sci.getDirection()+" " +" viteza sursa " + speed +" "+direction );
572                                System.out.println("trimitem mesajul - raza de actiune directa");
573                                System.out.println();*/
574
575
576                        }
577
578                        localinfo = bb.array();
579
580                        return localinfo;
581
582
583                }
584                else
585                {
586                        return super.prepareMessage(messageType);
587                }
588        }
589
590
591
592
593
594
595}
Note: See TracBrowser for help on using the repository browser.