root/applications/doprava/traffic_agent_offset.h @ 1136

Revision 1136, 18.5 kB (checked in by ondrak, 14 years ago)

bugfix again...

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