root/applications/doprava/traffic_agent_offset.h @ 1227

Revision 1146, 18.7 kB (checked in by ondrak, 14 years ago)

bugfix - average speed conversion
bugfix - negot_offset now correctly resets every cycle
now agent don't act in first cycles, before getting correct values from detectors
final version used in thesis (including cfg file)

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