root/applications/doprava/traffic_agent_offset.h @ 1054

Revision 1026, 13.1 kB (checked in by ondrak, 14 years ago)

zlicin.cfg now compatible with BaseTrafficAgent?.
main_loop shows warning, if reaches max number of negotiation cycles
step_time and cycle_time renamed to step_length and cycle_length
GreenWaveTrafficAgent? works, but queues are not from Aimsun yet.

Line 
1#include "traffic_agent.h"
2#include <list>
3
4class GreenWaveTrafficAgent : public BaseTrafficAgent {
5protected:
6        double rating_change;
7        int negot_offset;
8
9        RV rv_change_request;
10        vec change_request;
11
12        RV rv_recieved_exps;
13        vec recieved_exps;
14
15        RV rv_recieved_changes;
16        vec recieved_changes;
17
18        //! name of agent, whose change we have accepted
19        string accepted_from;
20
21        list<string> seznam;
22       
23        double car_leaving; //s; how long is 1 car leaving queue
24
25        bool need_exps;
26        bool new_stable_state;
27        bool send_requests;
28        bool final_state;
29        //bool reset_negot_offset;
30
31        //! counts all expected cars going from each lane, saves to outputs and rv_outputs
32        void expected_cars(/*const string dest*/) {
33                double start_time;
34
35                for (int i=0;i<lanes.length();i++) {
36                        for (int j=0;j<lanes(i).outputs.length();j++) {
37                                string group = name+"_"+lanes(i).sg;            //e.g. 495_VA
38                                ivec index=rv_inputs.dataind(RV(group,1));
39                                vec green_time=inputs(index);
40
41                                rv_outputs.add(RV(lanes(i).outputs(j)+"-"+group,3));
42                                outputs.set_size(rv_outputs._dsize());
43
44                                ivec ind = rv_outputs.dataind(RV(lanes(i).outputs(j)+"-"+group,3));
45
46                                //Number of cars
47                                outputs(ind(0))=lanehs(i)->expected_output(green_time(0));     
48
49                                start_time = green_starts(sg_index(lanes(i).sg)) + lanes(i).output_distances(j)/VP + planned_offset;
50                                //first car arrive time
51                                outputs(ind(1))=start_time;                                                                     
52                                //last car arrive time
53                                outputs(ind(2))= start_time + green_time(0);
54                        }
55                }
56        };
57
58        //! counts planned rating using offset and recieved_exps
59        double count_rating(const int offset) {
60                double virtual_queue;
61                double t_emptiyng;
62                double t_green_begin;
63                double t_green_end;
64                double t_cars_begin;
65                double t_cars_end;
66//              vec t_cars_begin;
67//              vec t_cars_end;
68                double t_mixing;
69                bool found;
70
71                double rating=0.0;
72
73                for (int i=0;i<lanes.length();i++) {
74
75                        //Finding, if we have some expectations
76                        found=false;
77                        for (int k=0;k<lanes(i).inputs.length();k++) { 
78//                              t_cars_begin.set_size(lanes(i).inputs.length());
79//                              t_cars_end.set_size(lanes(i).inputs.length());
80
81                                for (int j=0;j<rv_recieved_exps.length();j++) {
82                                        int result=rv_recieved_exps.name(j).find(lanes(i).inputs(k)+"-");
83                                        if (result>=0) {
84                                                ivec ind = rv_recieved_exps.dataind(RV(rv_recieved_exps.name(j),3));
85
86                                                t_cars_begin=recieved_exps(ind(1));             //TODO now using only last found exp.
87                                                t_cars_end=recieved_exps(ind(2));
88                                                found=true;
89                                        }
90                                }
91                        }
92
93                        if (!found) {
94                                t_cars_begin=0;
95                                t_cars_end=cycle_length;
96                        }
97                        //counting rating
98                        t_green_begin=green_starts(sg_index(lanes(i).sg)) + offset;
99                        ivec ind = rv_inputs.dataind(RV(name+"_"+lanes(i).sg,1));
100                        t_green_end=t_green_begin+inputs(ind(0));
101
102                        //TODO use real queues lenghts
103                        if (t_green_begin<t_cars_begin) {
104                                //virtual_queue=lanehs(i)->queue-(t_cars_begin-t_green_begin)/car_leaving;
105                                //virtual_queue=(rand()%8)-(t_cars_begin-t_green_begin)/car_leaving;
106                                virtual_queue=5-(t_cars_begin-t_green_begin)/car_leaving;
107                        } 
108                        else if (t_green_begin>t_cars_begin) {
109                                //virtual_queue=lanehs(i)->queue+(t_green_begin-t_cars_begin)*lanehs(i)->expected_density();
110                                //virtual_queue=(rand()%9)+(t_green_begin-t_cars_begin)*lanehs(i)->expected_density();
111                                virtual_queue=4+(t_green_begin-t_cars_begin)*lanehs(i)->expected_density();
112                        }
113
114                        t_emptiyng=virtual_queue/(1/car_leaving - lanehs(i)->expected_density());
115                        t_mixing=min(t_green_end,t_cars_end)-max(t_green_begin,t_cars_begin);
116
117                        rating+=max((t_mixing-t_emptiyng)*lanehs(i)->expected_density(),0.0); 
118                }
119                return rating;
120        }
121
122        //! finds best offset using recieved_exps. Returns found offset
123        int find_best_offset(const int center, int interval) {
124                //! rating if offset is rised
125                double rating_p;
126                //! rating if offset is unchaged (=center)
127                double rating_c;
128                //! rating if offset is lowered
129                double rating_n;
130
131                int new_center;
132
133                rating_p=count_rating(center+interval);
134                rating_c=count_rating(center);
135                rating_n=count_rating(center-interval);
136
137                new_center=center;
138                int max_index=max_of_three(rating_p,rating_c,rating_n);
139                switch (max_index) {
140                        case 0:
141                                new_center+=interval;
142                                break;
143                        case 1:
144                                break;
145                        case 2:
146                                new_center-=interval;
147                                break;
148                }
149
150                if (interval>2) {
151                        interval/=2;
152                        new_center=find_best_offset(new_center,interval);
153                }
154
155                return new_center;
156        }
157
158        //! finds if changing neighbour's offset could have positive effect, returns found offset change
159        int find_best_exps(const int offset_change, const string neighbour, double &rating_change) {
160                //! expectations recieved from neighbour
161                vec original_exps;
162                //! expactations after positve change of neighbour's offset
163                vec positive_exps;
164                //! expactations after negative change of neighbour's offset
165                vec negative_exps;
166                //! rating if offset is rised
167                double rating_p;
168                //! rating if offset is unchaged
169                double rating_c;
170                //! rating if offset is lowered
171                double rating_n;               
172                original_exps.set_size(recieved_exps.length());
173               
174                original_exps=recieved_exps;
175                positive_exps=recieved_exps;
176                negative_exps=recieved_exps;
177
178                for (int j=0;j<rv_recieved_exps.length();j++) {
179                        int res = rv_recieved_exps.name(j).find("-"+neighbour);
180                        if (res>0) {
181                                ivec ind = rv_recieved_exps.dataind(RV(rv_recieved_exps.name(j),3));
182                                rating_n=count_rating(planned_offset);
183
184                                positive_exps(ind(1))+=offset_change;
185                                positive_exps(ind(2))+=offset_change;
186
187                                negative_exps(ind(1))-=offset_change;
188                                negative_exps(ind(2))-=offset_change;
189                        }
190                }
191
192                rating_c=count_rating(planned_offset);
193
194                recieved_exps=positive_exps;
195                rating_p=count_rating(planned_offset);
196
197                recieved_exps=negative_exps;
198                rating_n=count_rating(planned_offset);
199
200                recieved_exps=original_exps;
201
202                int max_index=max_of_three(rating_p,rating_c,rating_n);
203                switch (max_index) {
204                        case 0:
205                                rating_change=rating_p-rating_c;
206                                return offset_change;
207                                break;
208                        case 1:
209                                rating_change=0;
210                                return 0;
211                                break;
212                        case 2:
213                                rating_change=rating_n-rating_c;
214                                return -offset_change;
215                                break;
216                }
217                rating_change=NULL;
218                return NULL;
219        }
220
221        //! returns index of signal group sg
222        int sg_index(const string sg) {
223                for (int i=0;i<sgs.length();i++) {
224                        if (sgs(i)==sg) {
225                                return i;
226                        }
227                }
228                return -1;
229        }
230       
231        //! returns offset value shifted to fit interval <0;cycle_length>
232        int normalize_offset(int offset) {
233                while (offset<0 && offset<cycle_length) {
234                        if (offset<0) {
235                                offset+=cycle_length;
236                        }
237                        else {
238                                offset-=cycle_length;
239                        }
240                }
241                return offset;
242        }
243
244
245        //! returns index of maximum of entered values
246        int max_of_three(const double a, const double b, const double c) {
247                int index = a > b ? 0 : 1;
248
249                if (index == 0) {
250                        index = a > c ? 0 : 2;
251                } 
252                else {
253                        index = b > c ? 1 : 2;
254                }
255                return index;
256        }
257
258public:
259        //! offset set in last simulation step
260        int last_offset;
261        //! actual planned offset to set for next simulation step
262        int planned_offset;
263        //! rating of actual planned offset
264        double planned_rating;
265       
266        //! array of existing signal groups
267        Array<string> sgs;
268        //! relative starts of green for signal groups
269        ivec green_starts;
270
271        //! avarage speed of cars
272        int VP;
273
274        void validate() {
275                rv_action = RV(name+"_offset", 1); // <======= example
276
277                for (int i=0; i<sgs.length();i++) {
278                        rv_inputs.add(RV(name+"_"+sgs(i),1));
279                }
280                inputs.set_size(rv_inputs._dsize());
281               
282                BaseTrafficAgent::validate();
283
284                for (int i=0;i<lanehs.length();i++) {
285                        ivec index = rv_queues.dataind(RV(lanes(i).queue,1));
286                        lanehs(i)->queue_index=index(0);
287                }
288
289
290        }
291
292        void adapt(const vec &glob_dt) {
293                BaseTrafficAgent::adapt(glob_dt);
294                       
295                for (int i=0;i<lanehs.length();i++) {
296                        lanehs(i)->queue=queues(lanehs(i)->queue_index);               
297                }
298
299                planned_offset=last_offset;
300               
301                //set state variables to default values
302                final_state=false;
303                new_stable_state=false;
304                send_requests=false;
305                need_exps=true;
306                negot_offset=8;
307        }
308
309        void broadcast(Setting& set){
310
311                //ask neighbours for exptected arrive times
312                if (need_exps) {
313                        for (int i=0; i<neighbours.length(); i++){
314                                Setting &msg =set.add(Setting::TypeGroup);
315
316                                UI::save ( neighbours(i), msg, "to");
317                                UI::save (name,msg,"from");
318                                UI::save ( (string)"expected_times_request", msg, "what");
319                        }
320                        need_exps=false;
321                }
322
323                // broadcast expected cars
324                if (!seznam.empty()) {
325                        expected_cars();
326                        do {
327                                Setting &msg =set.add(Setting::TypeGroup);
328                                UI::save ( seznam.back(), msg, "to");
329                                UI::save ( name, msg, "from");
330                                UI::save ( (string)"new_expected_cars", msg, "what");
331                                UI::save ( &(rv_outputs), msg, "rv");
332                                UI::save ( outputs, msg, "value");
333                                seznam.pop_back();
334                        } while (!seznam.empty());                     
335                }
336
337                // broadcast new stable state (new stable expectations)
338                if (new_stable_state) {
339                        expected_cars();
340                        for (int i=0;i<neighbours.length();i++) {
341                                Setting &msg = set.add(Setting::TypeGroup);
342                                UI::save ( neighbours(i), msg, "to");
343                                UI::save ( name, msg, "from");
344                                UI::save ( (string)"new_stable_state2", msg, "what");
345                                UI::save ( &(rv_outputs), msg, "rv");
346                                UI::save ( outputs, msg, "value");
347                        }
348                        new_stable_state=false;
349                }
350
351                // broadcast requests to change offset(s)
352                if (send_requests) {
353                        for (int i=0;i<neighbours.length();i++) {
354                                Setting &msg = set.add(Setting::TypeGroup);
355                                UI::save ( neighbours(i), msg, "to");
356                                UI::save ( name, msg, "from");
357                                UI::save ( (string)"offset_change_request", msg, "what");
358                                UI::save ( &(rv_change_request), msg, "rv");
359                                UI::save ( change_request, msg, "value");
360                        }
361                        send_requests=false;
362                }
363
364                /*if (reset_negot_offset) {
365                        for (int i=0;i<neighbours.length();i++) {
366                                Setting &msg = set.add(Setting::TypeGroup);
367                                UI::save ( neighbours(i), msg, "to");
368                                UI::save ( name, msg, "from");
369                                UI::save ( (string)"reset_negot_offset", msg, "what");
370                        }
371                }*/
372
373
374               
375                // reached final offset. Log value?
376                if (final_state) {
377                       
378                        //cout << "Jmenuji se "<<name<< " a skoncil jsem na offsetu " << planned_offset << " s hodnocenim " << planned_rating <<endl;
379                        final_state=false;
380                }
381        }
382
383        void receive(const Setting &msg){
384                string what;
385                string to;
386
387                string from;
388                vec value;
389                RV *rv;
390               
391                UI::get(what, msg, "what", UI::compulsory);
392                UI::get(to, msg, "to", UI::compulsory);
393                UI::get(from, msg, "from");
394                UI::get(rv, msg, "rv");
395                UI::get(value, msg, "value");
396               
397                if (what=="expected_times_request"){ 
398                        seznam.push_back(from);
399                } 
400                else if (what=="new_expected_cars") {
401                        rv_recieved_exps=*rv;
402                        recieved_exps=value;
403                       
404                        last_offset=planned_offset;
405
406                        planned_offset=find_best_offset(planned_offset,8);
407                        planned_offset=normalize_offset(planned_offset);
408                       
409
410                        /*if (planned_offset!=last_offset) {
411                                reset_negot_offset=true;
412                        }*/
413                        planned_rating=count_rating(planned_offset);
414                        // we have new stable state to broadcast
415                        new_stable_state=true;
416                }
417                else if (what=="new_stable_state2") {
418                        rv_recieved_exps=*rv;
419                        recieved_exps=value;
420                        planned_rating=count_rating(planned_offset);
421
422                        for (int i=0;i<neighbours.length();i++) {
423                                rv_change_request.add(RV(neighbours(i)+"_change",2));
424                                change_request.set_size(rv_change_request._dsize()); 
425                                ivec ind=rv_change_request.dataind(RV(neighbours(i)+"_change",2));
426                                // offset change
427                                change_request(ind(0))=find_best_exps(negot_offset,neighbours(i),rating_change);
428                                // rating change
429                                change_request(ind(1))=rating_change;
430                        }
431
432                        if (negot_offset>2) { 
433                                negot_offset/=2;
434                                        send_requests=true;
435                        }
436                        else {
437                                final_state=true;
438                        }
439                }
440                else if (what=="offset_change_request") {
441                        double final_rating_diff;
442
443                        rv_recieved_changes=*rv;
444                        recieved_changes=value;
445
446                        for (int i=0;i<rv_recieved_changes.length();i++) {
447
448                                ivec ind=rv_recieved_changes.dataind(RV(rv_recieved_changes.name(i),2));
449
450                                final_rating_diff=-planned_rating+count_rating(planned_offset+(int)recieved_changes(ind(0)))-recieved_changes(ind(0));
451                                if (final_rating_diff>0) {
452                                        planned_offset+=(int)recieved_changes(ind(0));
453                                        planned_rating+=final_rating_diff;
454                                        accepted_from=from;
455                                }
456                        }
457                        //need_exps=true;s
458                        new_stable_state=true;
459                }
460                /*else if (what=="reset_negot_offset") {
461                        negot_offset=8;
462                }*/
463                else {
464                        BaseTrafficAgent::receive(msg);
465                }
466        }
467       
468        void ds_register(const DS &ds) {
469                BaseTrafficAgent::ds_register(ds);
470                action2ds.set_connection( ds._urv(), rv_action);
471        }
472
473        void from_setting(const Setting &set) {
474                BaseTrafficAgent::from_setting(set);
475               
476                srand(time(NULL));
477
478                car_leaving=2;
479                VP=45;
480
481                negot_offset=8;
482               
483                // load from file
484                UI::get(sgs, set, "sgs", UI::compulsory);       
485                UI::get(green_starts, set, "green_starts", UI::compulsory);
486                UI::get(last_offset, set, "offset", UI::compulsory);
487       
488        }
489        void act(vec &glob_ut){
490                vec action;
491                action.set_size(rv_action._dsize());
492
493                ivec index = rv_action.dataind(RV(name+"_offset",1));
494                action(index(0))=planned_offset;
495                last_offset=planned_offset;
496
497                action2ds.filldown(action,glob_ut);
498        }
499
500};
501UIREGISTER(GreenWaveTrafficAgent);
Note: See TracBrowser for help on using the browser.