root/applications/doprava/traffic_agent_offset.h @ 1132

Revision 1127, 16.5 kB (checked in by ondrak, 14 years ago)

very small code cleaning

+texty

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