root/applications/doprava/traffic_agent_offset.h @ 1075

Revision 1071, 17.7 kB (checked in by ondrak, 14 years ago)

compatibility with new config file, many other changes, but yet untested

Line 
1#include "traffic_agent.h"
2#include <list>
3#include <fstream>
4
5class GreenWaveTrafficAgent : public BaseTrafficAgent {
6protected:
7        double rating_change;
8        int negot_offset;
9
10        int actual_time;
11
12        RV rv_outputs;
13        vec outputs;
14
15        RV rv_change_request;
16        vec change_request;
17
18        RV rv_recieved_exps;
19        vec recieved_exps;
20
21        RV rv_next_exps;
22        vec next_exps;
23
24        RV rv_recieved_changes;
25        vec recieved_changes;
26
27        //! name of agent, whose change we have accepted
28        string accepted_from;
29
30        list<string> seznam;
31       
32        double car_leaving; //s; how long is 1 car leaving queue
33
34        bool need_exps;
35        bool new_stable_state;
36        bool send_requests;
37        bool final_state;
38        //bool reset_negot_offset;
39
40        //! counts all expected cars going from each lane, saves to outputs and rv_outputs
41        void expected_cars() {
42                double start_time;
43                ivec ind;
44                RV rv_exp;
45                datalink exp2outputs;
46                vec exp;
47
48                for (int i=0;i<lanes.length();i++) {
49                        for (int j=0;j<lanes(i).outputs.length();j++) {
50                                if (lanes(i).outputs(j)!="DUMMY_DET") {
51                                        string group = name+"_"+lanes(i).sg;            //e.g. 495_VA
52                                       
53                                        int index=group_index(group);
54                                       
55                                        double green_time=green_times(index)*cycle_length;
56
57                                        //ivec green_index=rv_inputs.dataind(RV(group,1));
58                                        //vec green_time=inputs(green_index);
59
60                                        //cout << "Green time "<<green_time<<endl;
61
62                                        rv_exp=RV(lanes(i).outputs(j)+"-"+name+"_"+to_string(i),3);
63
64                                        exp.set_size(rv_exp._dsize());
65                                        exp2outputs.set_connection(rv_exp,rv_outputs);
66
67                                        //Number of cars
68                                        exp(0)=lanehs(i)->expected_output(green_time)*lanes(i).alpha(j);       
69
70                                        start_time = green_starts(group_index(name+"_"+lanes(i).sg)) + lanes(i).output_distances(j)/VP + planned_offset;
71                                        //first car arrive time
72                                        exp(1)=start_time;
73                                        //last car arrive time
74                                        exp(2)=start_time + green_time;
75                                        //TODO pushup az na konec
76                                        exp2outputs.pushup(outputs,exp);
77
78                                }                       
79                        }
80                }
81        };
82
83        //! counts planned rating using offset and recieved_exps
84        double count_rating(const int offset) {
85                double virtual_queue;
86                double t_green_begin;
87                double t_green_end;
88                vec cars_count;
89                vec t_cars_begin;
90                vec t_cars_end;
91                bool found;
92
93                double rating=0.0;
94
95                RV rv_vector;
96                vec vector;
97                datalink exps2vector;
98
99                for (int i=0;i<lanes.length();i++) {
100
101                        //Finding, if we have some expectations
102                        found=false;
103                       
104                        for (int k=0;k<lanes(i).inputs.length();k++) { 
105                                int l=0;               
106                                for (int j=0;j<rv_recieved_exps.length();j++) {
107                                        t_cars_begin.set_size(l+1,true);
108                                        t_cars_end.set_size(l+1,true);
109                                        cars_count.set_size(l+1,true);
110                               
111                                        int result=rv_recieved_exps.name(j).find(lanes(i).inputs(k)+"-");
112                                        if (result>=0) {
113
114                                                rv_vector = RV(rv_recieved_exps.name(j),3);
115                                                ivec ind = rv_vector.dataind(rv_recieved_exps);
116
117                                                cars_count(l)=recieved_exps(ind(0));
118                                                t_cars_begin(l)=recieved_exps(ind(1));
119                                                t_cars_end(l)=recieved_exps(ind(2));
120                                                l++;
121
122                                                found=true;
123                                        }
124                                }
125                                if (found) {                   
126                                        //counting rating
127                                        string group = name+"_"+lanes(i).sg;            //e.g. 495_VA
128                                        int index=group_index(group);
129
130                                        t_green_begin=green_starts(index) + offset;
131                                        double green_time=green_times(index)*cycle_length;
132                                        t_green_end=t_green_begin+green_time;
133
134                                        /************** counting with all exps ****************/
135
136                                        int k;
137                                        double t_act=t_green_begin;
138                                        virtual_queue=lanehs(i)->queue;
139
140                                        //cycle goes through all stopping points and counts queue lenght at these points
141                                        do {
142                                                k=min_i(t_cars_begin);
143
144                                                if (k!=-1) {                                           
145                                                        double a=cars_count(k);
146                                                        double b=t_cars_begin(k);
147                                                        double c=t_cars_end(k);
148
149                                                        //in case there are cars comming before t_green begin
150                                                        if (t_cars_begin(k)<t_act) {
151                                                                if (t_cars_end(k)<=t_act) {
152                                                                        virtual_queue+=cars_count(k);
153                                                                        //jen prodlouzime, t_act zustava, odstranime k-ty predpoklad (mozna hned, mozna az na konci
154                                                                        cars_count.del(k);
155                                                                        t_cars_begin.del(k);
156                                                                        t_cars_end.del(k);
157
158                                                                }
159                                                                else {
160                                                                        //prodlouzujeme do casu t_green_begin,
161                                                                        //pak bud green_begin posuneme do t_act
162                                                                        double pomer=(t_cars_begin(k)-t_act)/(t_cars_end(k)-t_cars_begin(k));
163                                                                        virtual_queue+=cars_count(k)*pomer;
164                                                                        t_cars_begin(k)=t_act;
165                                                                }
166                                                        }
167                                                        else if (t_cars_begin(k)==t_act) {
168                                                                //mixujeme az do t_cars_end nebo t_green_end
169                                                                //posuneme t_act na jeden z tech casu
170                                                                if (t_cars_end(k)<t_green_end) {
171                                                                        virtual_queue+=cars_count(k)-(t_cars_end(k)-t_act)/car_leaving;
172                                                                        t_act=t_cars_end(k);
173
174                                                                        cars_count.del(k);
175                                                                        t_cars_begin.del(k);
176                                                                        t_cars_end.del(k);
177                                                                }
178                                                                //t_cars_end>=t_green_end
179                                                                else {
180                                                                        virtual_queue+=cars_count(k)-(t_green_end-t_act)/car_leaving;
181                                                                        t_act=t_green_end;
182
183                                                                        cars_count.del(k);
184                                                                        t_cars_begin.del(k);
185                                                                        t_cars_end.del(k);                                                     
186                                                                }
187
188
189                                                        }
190                                                        //t_cars_begin(k)>=t_act
191                                                        else {
192                                                                //zkracujeme frontu az do t_cars_end(k) nebo t_green_end a posuneme t_act
193                                                                if (t_cars_end(k)<t_green_end) {
194                                                                        virtual_queue-=(t_cars_end(k)-t_act)/car_leaving;
195                                                                        t_act=t_cars_end(k);
196                                                                }
197                                                                else {
198                                                                        virtual_queue-=(t_green_end-t_act)/car_leaving;
199                                                                        t_act=t_green_end;
200                                                                }
201                                                        }
202                                                }
203                                                else {
204                                                        virtual_queue-=(t_green_end-t_act)/car_leaving;
205                                                        t_act=t_green_end;
206                                                }
207                                                if (virtual_queue<0) {
208                                                        rating-=virtual_queue;
209                                                        virtual_queue=0;
210                                                }
211
212                                        } while (t_act<t_green_end);
213                                }
214                        }
215                }
216                return rating;
217        }
218
219        //! finds best offset using recieved_exps. Returns found offset
220        int find_best_offset(const int center, int interval) {
221                //! rating if offset is rised
222                double rating_p;
223                //! rating if offset is unchaged (=center)
224                double rating_c;
225                //! rating if offset is lowered
226                double rating_n;
227
228                int new_center;
229
230                rating_p=count_rating(center+interval);
231                rating_c=count_rating(center);
232                rating_n=count_rating(center-interval);
233
234                new_center=center;
235                int max_index=max_of_three(rating_p,rating_c,rating_n);
236                switch (max_index) {
237                        case 0:
238                                new_center+=interval;
239                                break;
240                        case 1:
241                                break;
242                        case 2:
243                                new_center-=interval;
244                                break;
245                }
246
247                if (interval>2) {
248                        interval/=2;
249                        new_center=find_best_offset(new_center,interval);
250                }
251
252                return new_center;
253        }
254
255        //! finds if changing neighbour's offset could have positive effect, returns found offset change
256        int find_best_exps(const int offset_change, const string neighbour, double &rating_change) {
257                //! expectations recieved from neighbour
258                vec original_exps;
259                //! expactations after positve change of neighbour's offset
260                vec positive_exps;
261                //! expactations after negative change of neighbour's offset
262                vec negative_exps;
263                //! rating if offset is rised
264                double rating_p;
265                //! rating if offset is unchaged
266                double rating_c;
267                //! rating if offset is lowered
268                double rating_n;               
269                original_exps.set_size(recieved_exps.length());
270               
271                original_exps=recieved_exps;
272                positive_exps=recieved_exps;
273                negative_exps=recieved_exps;
274
275                for (int j=0;j<rv_recieved_exps.length();j++) {
276                        int res = rv_recieved_exps.name(j).find("-"+neighbour);
277                        if (res>0) {
278                                ivec ind = RV(rv_recieved_exps.name(j),3).dataind(rv_recieved_exps);
279
280                                rating_n=count_rating(planned_offset);
281
282                                positive_exps(ind(1))+=offset_change;
283                                positive_exps(ind(2))+=offset_change;
284
285                                negative_exps(ind(1))-=offset_change;
286                                negative_exps(ind(2))-=offset_change;
287                        }
288                }
289
290                rating_c=count_rating(planned_offset);
291
292                recieved_exps=positive_exps;
293                rating_p=count_rating(planned_offset);
294
295                recieved_exps=negative_exps;
296                rating_n=count_rating(planned_offset);
297
298                recieved_exps=original_exps;
299
300                int max_index=max_of_three(rating_p,rating_c,rating_n);
301                switch (max_index) {
302                        case 0:
303                                rating_change=rating_p-rating_c;
304                                return offset_change;
305                                break;
306                        case 1:
307                                rating_change=0;
308                                return 0;
309                                break;
310                        case 2:
311                                rating_change=rating_n-rating_c;
312                                return -offset_change;
313                                break;
314                }
315                rating_change=NULL;
316                return NULL;
317        }
318
319        // pravdepodobne s chybou, momentalne se nepouziva
320        void split_exps() {
321                ivec ind;
322                RV rv_exp;
323                datalink recieved2next;
324
325                rv_next_exps=RV();
326                for (int i=0;i<rv_recieved_exps.length();i++) {
327                        if (rv_recieved_exps.size(i)==3) {             
328                                rv_exp=RV(rv_recieved_exps.name(i),3);
329                                ind = rv_exp.dataind(rv_recieved_exps);
330                                //cout << "ind " << ind << endl;
331
332                                int next_cycle_end=2 * cycle_length - (actual_time % cycle_length);
333                                if (recieved_exps(ind(1))>next_cycle_end) {
334                                        rv_next_exps.add(rv_exp);
335                                        next_exps.set_size(rv_next_exps._dsize());
336                                       
337                                        if (actual_time==630) {
338                                                cout << "rv_next_exps " << rv_next_exps.to_string() << endl;
339                                                cout << "rv_recived_exps " << rv_recieved_exps.to_string() << endl;
340                                        }
341
342                                        recieved2next.set_connection(rv_next_exps,rv_recieved_exps);
343                                        recieved2next.filldown(recieved_exps,next_exps);
344                                        rv_recieved_exps=rv_recieved_exps.subt(rv_exp);
345                                }
346                                else if (recieved_exps(ind(2))>next_cycle_end) {
347                                        rv_next_exps.add(rv_exp);
348                                        next_exps.set_size(rv_next_exps._dsize());
349
350                                        ivec ind2=rv_exp.dataind(rv_next_exps);
351                                        next_exps(ind2(0))=recieved_exps(ind(0)); //TODO to neni spravne
352                                        next_exps(ind2(1))=next_cycle_end; 
353                                        next_exps(ind2(2))=recieved_exps(ind(2));
354                                        recieved_exps(ind(2))=next_cycle_end;
355                                }
356                        }
357                }
358        }
359
360        //! returns index of signal group group
361        int group_index(const string group) {
362                for (int i=0;i<green_names.length();i++) {
363                        if (green_names(i)==group) {
364                                return i;
365                        }
366                }
367                return -1;
368        }
369       
370        //! returns offset value shifted to fit interval <0;cycle_length>
371        int normalize_offset(int offset) {
372                while (offset<0 || offset>cycle_length) {
373                        if (offset<0) {
374                                offset+=cycle_length;
375                        }
376                        else {
377                                offset-=cycle_length;
378                        }
379                }
380                return offset;
381        }
382       
383        //! returns value shifted to fit interval <0;cycle_length>
384        template<class T> T normalize(T time) {
385                while (time<0 && time<cycle_length) {
386                        if (time<0) {
387                                time+=cycle_length;
388                        }
389                        else {
390                                time-=cycle_length;
391                        }
392                }
393                return time;
394        }
395
396        template <class T> inline string to_string (const T& t)
397        {
398                std::stringstream ss;
399                ss << t;
400                return ss.str();
401        }
402
403        //! returns index of maximum of entered values
404        int max_of_three(const double a, const double b, const double c) {
405                int index = a > b ? 0 : 1;
406
407                if (index == 0) {
408                        index = a > c ? 0 : 2;
409                } 
410                else {
411                        index = b > c ? 1 : 2;
412                }
413                return index;
414        }
415
416        //! returns index of smallest element in vectorsx
417        int min_i(vec vector) {
418                if (vector.length()>0) {
419                        double min=vector(0);
420                        int index=0;
421                        for (int i=1;i<vector.length();i++) {
422                                if (vector(i)<min) {
423                                        min=vector(i);
424                                        index=i;
425                                }
426                        }
427                        return index;
428                }
429                return -1;
430        }
431
432public:
433        //! offset set in last simulation step
434        int last_offset;
435        //! actual planned offset to set for next simulation step
436        int planned_offset;
437        //! planned offset for cycle after next cycle
438        int planned_next_offset;
439        //! rating of actual planned offset
440        double planned_rating;
441        //! rating of planned next offset
442        double planned_next_rating;
443       
444        //! avarage speed of cars
445        int VP;
446
447        void validate() {
448                rv_action = RV(name+"_offset", 1); // <======= example
449
450                for (int i=0; i<green_names.length();i++) {
451                        rv_inputs.add(RV(green_names(i),1));
452                }
453                inputs.set_size(rv_inputs._dsize());
454               
455                BaseTrafficAgent::validate();
456
457                for (int i=0;i<lanehs.length();i++) {
458                        ivec index = RV(lanes(i).queue,1).dataind(rv_queues);
459                        lanehs(i)->queue_index=index(0);
460                }
461        }
462
463        void adapt(const vec &glob_dt) {
464                BaseTrafficAgent::adapt(glob_dt);
465                       
466                for (int i=0;i<lanehs.length();i++) {
467                        lanehs(i)->queue=queues(lanehs(i)->queue_index);               
468                }
469
470                planned_offset=last_offset;
471               
472                //set state variables to default values
473                final_state=false;
474                new_stable_state=false;
475                send_requests=false;
476                need_exps=true;
477                negot_offset=8;
478        }
479
480        void broadcast(Setting& set){
481
482                //ask neighbours for exptected arrive times
483                if (need_exps) {
484                        for (int i=0; i<neighbours.length(); i++){
485                                Setting &msg =set.add(Setting::TypeGroup);
486
487                                UI::save ( neighbours(i), msg, "to");
488                                UI::save (name,msg,"from");
489                                UI::save ( (string)"expected_times_request", msg, "what");
490                        }
491                        need_exps=false;
492                }
493
494                // broadcast expected cars
495                if (!seznam.empty()) {
496                        double a;
497                        expected_cars();
498                        do {
499                                Setting &msg =set.add(Setting::TypeGroup);
500                                UI::save ( seznam.back(), msg, "to");
501                                UI::save ( name, msg, "from");
502                                UI::save ( (string)"new_expected_cars", msg, "what");
503                                UI::save ( &(rv_outputs), msg, "rv");
504                                UI::save ( outputs, msg, "value");
505                                seznam.pop_back();
506                                a=outputs (10);
507                               
508                        } while (!seznam.empty());                     
509                }
510
511                // broadcast new stable state (new stable expectations)
512                if (new_stable_state) {
513                        expected_cars();
514                        for (int i=0;i<neighbours.length();i++) {
515                                Setting &msg = set.add(Setting::TypeGroup);
516                                UI::save ( neighbours(i), msg, "to");
517                                UI::save ( name, msg, "from");
518                                UI::save ( (string)"new_stable_state2", msg, "what");
519                                UI::save ( &(rv_outputs), msg, "rv");
520                                UI::save ( outputs, msg, "value");
521                        }
522                        new_stable_state=false;
523                }
524
525                // broadcast requests to change offset(s)
526                if (send_requests) {
527                        for (int i=0;i<neighbours.length();i++) {
528                                Setting &msg = set.add(Setting::TypeGroup);
529                                UI::save ( neighbours(i), msg, "to");
530                                UI::save ( name, msg, "from");
531                                UI::save ( (string)"offset_change_request", msg, "what");
532                                UI::save ( &(rv_change_request), msg, "rv");
533                                UI::save ( change_request, msg, "value");
534                        }
535                        send_requests=false;
536                }
537
538                /*if (reset_negot_offset) {
539                        for (int i=0;i<neighbours.length();i++) {
540                                Setting &msg = set.add(Setting::TypeGroup);
541                                UI::save ( neighbours(i), msg, "to");
542                                UI::save ( name, msg, "from");
543                                UI::save ( (string)"reset_negot_offset", msg, "what");
544                        }
545                }*/
546
547
548               
549                // reached final offset. Log value?
550                if (final_state) {
551                        cout << "Jmenuji se "<<name<< " a skoncil jsem na offsetu " << planned_offset << " s hodnocenim " << planned_rating <<endl;
552                        final_state=false;
553                }
554        }
555
556        void receive(const Setting &msg){
557                string what;
558                string to;
559
560                string from;
561                vec value;
562                RV *rv;
563               
564                UI::get(what, msg, "what", UI::compulsory);
565                UI::get(to, msg, "to", UI::compulsory);
566                UI::get(from, msg, "from");
567                UI::get(rv, msg, "rv");
568                UI::get(value, msg, "value");
569               
570                if (what=="expected_times_request"){ 
571                        seznam.push_back(from);
572                } 
573                else if (what=="new_expected_cars") {
574                        rv_recieved_exps=*rv;
575                        recieved_exps=value;
576                        //split_exps();
577                       
578                        last_offset=planned_offset;
579
580                        planned_offset=find_best_offset(planned_offset,8);
581                        planned_offset=normalize_offset(planned_offset);
582                       
583
584                        /*if (planned_offset!=last_offset) {
585                                reset_negot_offset=true;
586                        }*/
587
588                        planned_rating=count_rating(planned_offset);
589                        // we have new stable state to broadcast
590                        new_stable_state=true;
591                }
592                else if (what=="new_stable_state2") {
593                        rv_recieved_exps=*rv;
594                        recieved_exps=value;
595                        //split_exps();
596                        planned_rating=count_rating(planned_offset);
597
598                        for (int i=0;i<neighbours.length();i++) {
599                                rv_change_request.add(RV(neighbours(i)+"_change",2));
600                                change_request.set_size(rv_change_request._dsize()); 
601                                ivec ind=RV(neighbours(i)+"_change",2).dataind(rv_change_request);
602                                // offset change
603                                change_request(ind(0))=find_best_exps(negot_offset,neighbours(i),rating_change);
604                                // rating change
605                                change_request(ind(1))=rating_change;
606                        }
607
608                        if (negot_offset>2) { 
609                                negot_offset/=2;
610                                        send_requests=true;
611                        }
612                        else {
613                                final_state=true;
614                        }
615                }
616                else if (what=="offset_change_request") {
617                        double final_rating_diff;
618
619                        rv_recieved_changes=*rv;
620                        recieved_changes=value;
621
622                        for (int i=0;i<rv_recieved_changes.length();i++) {
623
624                                ivec ind=RV(rv_recieved_changes.name(i),2).dataind(rv_recieved_changes);
625
626                                final_rating_diff=-planned_rating+count_rating(planned_offset+(int)recieved_changes(ind(0)))+recieved_changes(ind(1));
627                                if (final_rating_diff>=0) {
628                                        planned_offset+=(int)recieved_changes(ind(0));
629                                        planned_offset=normalize_offset(planned_offset);
630                                        planned_rating+=final_rating_diff;
631                                        accepted_from=from;
632                                }
633                        }
634                        //need_exps=true;s
635                        new_stable_state=true;
636                }
637                /*else if (what=="reset_negot_offset") {
638                        negot_offset=8;
639                }*/
640                else {
641                        BaseTrafficAgent::receive(msg);
642                }
643        }
644       
645        void ds_register(const DS &ds) {
646                BaseTrafficAgent::ds_register(ds);
647                action2ds.set_connection( ds._urv(), rv_action);
648        }
649
650        void from_setting(const Setting &set) {
651                BaseTrafficAgent::from_setting(set);
652
653                RV rv_exp;
654
655                std::ofstream ofile;
656                ofile.open("greentimes.txt");
657                ofile.close();
658
659                car_leaving=2;
660                VP=45;
661                actual_time=0;
662
663                negot_offset=8;
664               
665                // load from file
666                //UI::get(sgs, set, "sgs", UI::compulsory);     
667
668                //UI::get(green_starts, set, "green_starts", UI::compulsory);
669                UI::get(last_offset, set, "offset", UI::compulsory);
670
671                for (int i=0;i<lanes.length();i++) {
672                        for (int j=0;j<lanes(i).outputs.length();j++) {
673                                if (lanes(i).outputs(j)!="DUMMY_DET") {
674                                        rv_exp=RV(lanes(i).outputs(j)+"-"+name+"_"+to_string(i),3);
675                                        rv_outputs.add(rv_exp);
676                                }
677                        }
678                }
679                outputs.set_size(rv_outputs._dsize()); 
680        }
681
682        void act(vec &glob_ut){
683                vec action;
684                action.set_size(rv_action._dsize());
685               
686                ivec index = rv_action.dataind(RV(name+"_offset",1));
687
688                action(index(0))=planned_offset;
689                last_offset=planned_offset;
690                action2ds.filldown(action,glob_ut);
691
692                actual_time+=step_length;
693        }
694
695};
696UIREGISTER(GreenWaveTrafficAgent);
Note: See TracBrowser for help on using the browser.