root/applications/doprava/traffic_agent.h @ 1139

Revision 1137, 14.4 kB (checked in by jabu, 14 years ago)

Funkce pro TrafficAgentCycleTime?

Line 
1/*!
2\file
3\brief Traffic Light Agents
4\author Vaclav Smidl.
5*/
6
7#ifndef TRAGE_H
8#define TRAGE_H
9
10
11#include <base/participants.h>
12
13using namespace bdm;
14
15class BaseTrafficAgent;
16
17//! detector of traffic variables
18class Lane{
19public:
20        Array<string> inputs;
21        Array<string> outputs;
22        vec input_distances;
23        vec output_distances;
24        vec alpha; //size of outputs
25        //! percent of queue lenght (for "multiline queues")
26        double beta;
27        string queue;
28        string sg;
29
30        //! function loading info from Setting
31        void from_setting(const Setting &set){
32                UI::get(inputs,set,"inputs",UI::compulsory);
33                UI::get(outputs,set,"outputs",UI::compulsory);
34                UI::get(input_distances,set,"input_distances",UI::compulsory);
35                UI::get(output_distances,set,"output_distances",UI::compulsory);
36                UI::get(alpha,set,"alpha",UI::compulsory);
37                UI::get(queue,set,"queue",UI::compulsory);
38                UI::get(sg,set,"sg",UI::compulsory);
39                UI::get(beta, set, "beta");
40        }
41};
42
43//! class that operates on a signal group
44class LaneHandler {
45protected:
46        //! pointer to physical lane
47        const Lane &lane;
48        //! agent pointer
49        BaseTrafficAgent *agent;
50
51public:
52        //! actual data from the relevant signal group
53        vec inputs;
54        //! queue length
55        double queue; 
56        //! description of det_data
57        RV rv_inputs;
58        //! description of det_data
59        RV rv_outputs;
60        //! description of det_data
61        RV rv_queue;
62        //! link from global measured data
63        datalink agentin2input;
64        //!
65        datalink output2agentout;
66        //!
67        int queue_index;
68
69public:
70        LaneHandler(const Lane &lane0): lane(lane0){
71                for (int i=0;i<lane0.inputs.length();i++){
72                        rv_inputs.add(RV(lane.inputs(i), 2));
73                }
74                for (int i=0;i<lane0.outputs.length();i++){
75                        rv_outputs.add(RV(lane.outputs(i), 2)); 
76                }
77                rv_queue.add(RV(lane.queue, 1)); 
78                inputs.set_size(rv_inputs._dsize());
79                // KOD PRO TrafficAgentCycleTime
80                init();
81        }
82
83
84        void connect_data(BaseTrafficAgent &agent0);
85
86        //! computes expected density in cars/s
87        double expected_density();
88
89        //! arbitrary function that computes the need of the signal group for green light in common units (number of waiting cars?)
90        double expected_output(double green_time);
91
92       
93
94/********************************
95* KOD PRO TrafficAgentCycleTime *
96*********************************/
97        double last_queue;
98        double sum_queue_length;
99        double last_sum_queue_length;
100        double queue_diff_sum;
101        double queue_variance_sum;
102        int n_of_queues_in_length;
103        int last_n_of_queues_in_length;
104        double last_variance;
105        double green_time_ratio;
106        double Tc;
107        double last_Tc;
108        double saturated_stream;
109        double delta; // ztratovy cas pri prechodu na zelenou
110        // udaje opro kalmana
111        double queue_avg; //  pruner
112        double queue_w;   //  vaha
113        double queue_d;   //  rozptyl
114        double queue_dd;  //  snizeni verohodnosti odhadu
115        double queue_r;   //  neduveryhodnost mereni = 1
116
117        double Ro_avg;  //  prumer
118        double Ro_w;    //  vaha K
119        double Ro_d;            //  rozptyl P
120        double Ro_dd;           //  snizeni verohodnosti odhadu Q
121        double Ro_r;            //  neduveryhodnost mereni = 1 R
122
123        double last_queue_avg;
124
125// pomocne funkce
126
127       
128
129        void init () {
130                last_Tc = 0;
131                saturated_stream = 0.5;
132                queue = 0;
133                sum_queue_length = 0;
134                last_sum_queue_length = 0;
135                n_of_queues_in_length = 0;
136                last_n_of_queues_in_length = 0;
137                queue_diff_sum = 0;
138                queue_variance_sum = 0;
139                last_variance = 0;
140                delta = 5;
141                // KALMAN
142                queue_avg = 0;  //  prumer
143                queue_w = 1;    //  vaha K
144                queue_d = 0.9;          //  rozptyl P
145                queue_dd =0.1;          //  snizeni verohodnosti odhadu Q
146                queue_r = 9;            //  neduveryhodnost mereni = 1 R
147
148                Ro_avg = 0;     //  prumer
149                Ro_w = 1;       //  vaha K
150                Ro_d = 0.9;             //  rozptyl P
151                Ro_dd =0.1;             //  snizeni verohodnosti odhadu Q
152                Ro_r = 9;               //  neduveryhodnost mereni = 1 R
153
154                last_queue_avg = 0;
155        }
156
157        /*double abs ( double x ) {
158                if ( x > 0 ) return x;
159                else return -x;
160        }*/
161
162        void echo () {
163                //cout << "n:" << n_of_queues_in_length << " " << getQueueName() << " q:" << getQueue() << " aq:" << getAverageQueueLength() << " diff:" << getAverageQueueGrow() << " D:" << getQueueVariance() << endl;
164                /*cout << "n:" << n_of_queues_in_length
165                     << " " << getQueueName()
166                         << "LAST aq:" << last_sum_queue_length/last_n_of_queues_in_length
167                         << " aq:" << getAverageQueueLength()
168                         << " diff" <<  getAverageQueueLength() - last_sum_queue_length/last_n_of_queues_in_length
169                         << endl;*/
170                cout << getQueueName();
171                /*if ( last_n_of_queues_in_length> 0 && n_of_queues_in_length > 0 )
172                        cout << " DIFF: " << getAverageQueueLength() - last_sum_queue_length/last_n_of_queues_in_length;
173                else
174                        cout << " no diff available";*/
175                //cout << "\tn " << n_of_queues_in_length;
176                //cout << " prijizdejicich aut za 90: " << getRo()*90;
177                cout << "\tgtr: " << green_time_ratio;
178                cout << "\tRo: " << getRo();
179                cout << "\tC: " << green_time_ratio*Tc*saturated_stream - getRo()*Tc << endl; 
180                //cout << "\tWT:";
181                for ( int i = -2; i <= 2; i++ ) {
182                        double tc = Tc + i*8;
183                        cout << tc << "\t";
184                }
185                cout << endl;
186                for ( int i = -2; i <= 2; i++ ) {
187                        double tc = Tc + i*8;
188                        cout << (int)(100*getWT(tc)) << "\t";
189                }
190                //cout << " diff: " << getRo()*Tc - saturated_stream*getGreenTime();
191                /*if ( saturated_stream*getGreenTime() >= getAverageQueueLength() )
192                        cout << " projede vsechno ";
193                else
194                        cout << " zustanou auta ";*/
195                cout << endl << endl;
196        }
197       
198
199        Lane getLane () {
200                return lane;
201        }
202
203        string getSG () {
204                return lane.sg;
205        }
206
207        string getQueueName () {
208                return lane.queue;
209        }
210
211        double getQueue() {
212                return queue_avg;
213        }
214
215        void addQueueLength ( int ql ) {
216                // pricita pouze namerene udaje
217                if ( ql >= 0 ) {
218                        last_queue = queue;
219                        queue = ql;
220                        queue_diff_sum += queue - last_queue;
221                        //queue_variance_sum += abs(queue - last_queue);
222               
223                        sum_queue_length += ql;
224                        n_of_queues_in_length ++;
225                        // KALMAN                       
226                        cout << endl << "pridani fronty\t" << queue_avg << "\t" << ql << endl;
227                        queue_avg += queue_w*( ql - queue_avg );
228                        queue_d += queue_dd;
229                        queue_w = queue_d/(queue_d+1);
230                        queue_d = (1-queue_w)*queue_d;
231       
232                        double Ro = getActualRo();
233                        Ro_avg += Ro_w*( Ro - Ro_avg );
234                        Ro_d += Ro_dd;
235                        Ro_w = Ro_d/(Ro_d+1);
236                        Ro_d = (1-Ro_w)*Ro_d;
237                }
238        }
239
240        void resetQueue () {
241                last_Tc = Tc;
242                //last_variance = getQueueVariance();
243                last_n_of_queues_in_length = n_of_queues_in_length;
244                last_sum_queue_length = sum_queue_length;
245                n_of_queues_in_length = 0;
246                sum_queue_length = 0;
247                queue_variance_sum = 0;
248                queue_diff_sum = 0;
249                // kalman
250                last_queue_avg = getAverageQueueLength();
251        }
252
253        double getAverageQueueLength () {
254                // kalmam
255                return queue_avg;
256
257                if( n_of_queues_in_length > 0 )
258                        return sum_queue_length / n_of_queues_in_length;
259                else
260                        return 0.0;
261        }
262
263        double getLastAverageQueueLength () {
264                if( last_n_of_queues_in_length > 0 )
265                        return last_sum_queue_length / last_n_of_queues_in_length;
266                else
267                        return 0.0;
268        }
269
270        /*double getAverageQueueGrow () {
271                return queue_diff_sum / n_of_queues_in_length;
272        }*/
273       
274        /*double getQueueVariance () {
275                return queue_variance_sum / n_of_queues_in_length;
276        }*/
277
278        double getGreenTime ( double tc ) { return green_time_ratio * tc - delta; }     
279        double getGreenTime () { return getGreenTime( Tc ); }   
280       
281        double getRedTime ( double tc ) { return (1-green_time_ratio) * tc;     }
282        double getRedTime () { return getRedTime( Tc ); }       
283
284        double getRelativeQueueDiff () {
285                if ( last_n_of_queues_in_length > 0 && n_of_queues_in_length > 0 ) {
286                       
287                        return getAverageQueueLength()/(Tc*(1-green_time_ratio)) - (last_sum_queue_length/last_n_of_queues_in_length)/(last_Tc*(1-green_time_ratio));
288                }
289                else
290                        return 0;
291        }
292
293        // hodnotici funkce - suma cekaciho casu aut za 10h
294        double getWT ( double  Tc ) {
295          double T = 36000; // celkovy cas 10h
296          double Ro = getRo();
297          double Gr = green_time_ratio;
298          double ss = saturated_stream;
299          double WT = 0;
300          double q = 0;  // zacina s nulovou frontou ?
301          double ti = 0;
302          double sumq = q;
303          while ( ti < T ) {
304                // ve fronte stoji vic aut nez je schopno odjet za zelenou
305                if ( q > 0.5*ss*Tc ) {
306                  WT += 0.5*ss*(Tc*Gr - delta)*(Tc*Gr - delta);
307                }
308                else {
309
310                  WT += 0.5*q*(Tc*Gr - delta);
311                }
312
313                if ( (Tc*Gr - delta)*ss < q )
314                  q -= (Tc*Gr - delta)*ss;
315                else
316                  q = 0;
317
318                WT += q * Tc; // zbytek fronty ceka cely cyklus
319                // cekani vozidel, ktera prijela za pocitany cyklus
320                if ( q > 0 ) {
321                  //pokud je fronta > 0, auta cekaji prumerne polovinu delky cyklu
322                  WT += Ro*Tc*0.5*Tc;
323                }
324                else {
325                  // pokud je fronta = 0 cekaji pouze auta, ktera prijela na cervenou (p=(1-Gr)) 0.5Tc(1-Gr)
326                  WT += Ro*(1-Gr)*Tc*0.5*(1-Gr)*Tc;
327                }
328                // fronta se zvetsi o Ro*Tc
329                q += Ro*Tc;
330                sumq += Ro*Tc;
331                ti += Tc;
332          }
333
334          //return WT;
335          if ( sumq > 0 )
336                return 100*(WT/(0.5*T*sumq));
337          else
338          return 0;
339        }
340
341        //double getWT ( double  tc ) {
342        //      double T = ;
343        //      double WT = 0;
344        //      double cWT = 0;
345        //      double q = 0;
346        //      double cq = 0;
347        //      double sum_t;
348        //      double car_part = 0.1;
349        //      double Ro = getRo();
350        //      double dt = car_part/Ro;
351        //      while ( sum_t < T ) {
352        //              if ( q < 0 )
353        //                      q = 0;
354        //              WT += q * dt;
355        //              // prirustek fronty za dt
356        //              q += car_part;
357        //              // zelena - auta projedou
358        //              if ( (sum_t - tc*(int)(sum_t/tc)) > delta && )
359        //                      q -= saturated_stream*dt;
360        //              sum_t += dt;
361        //      }
362        //}
363        // Odhad hustoty ( auto/sec )
364        double getActualRo () {
365                // pokud delka fronty mensi nez pocet aut ktere odjedou za zelenou
366                if ( saturated_stream*getGreenTime() >= getAverageQueueLength() ) {
367                        // pocet aut, ktera prijela pri cervene
368                        return getAverageQueueLength()/getRedTime();
369                }
370                else {
371                        //fronta se nevynuluje
372                        // pocet aut = to co stihlo projet na zelenou + o co narostla fronta
373                        // doba pocet_cyklu*90
374                        //double T = n_of_queues_in_length*90;
375                        //double cars_per_green = T*(getGreenTime()/Tc)*saturated_stream;
376                        //return (cars_per_green + queue_diff_sum)/T;
377                        double T = 90;
378                        double cars_per_green = T*(getGreenTime()/Tc)*saturated_stream;
379                        return (cars_per_green + (getLastAverageQueueLength()-getAverageQueueLength()))/T;
380                }
381        }
382
383        double getRo() {
384                return Ro_avg;
385        }
386       
387       
388
389        /***************************************
390        * KONEC KODU PRO TrafficAgentCycleTime *
391        ****************************************/
392};
393
394/*!
395\brief  Basic Traffic Agent
396
397*/
398class BaseTrafficAgent : public Participant {
399
400LOG_LEVEL(BaseTrafficAgent,logdata);
401public:
402        //! Signal Groups
403        Array<Lane> lanes;
404
405        Array<LaneHandler*> lanehs;
406
407        //!data from messages
408        vec inputs;
409
410        //! decription of msg_data
411        RV rv_inputs;
412
413        //! data to broadcast
414        vec outputs;
415
416        //! description of broadcast dataind
417        RV rv_outputs;
418
419        vec queues;
420
421        //! description of queues
422        RV rv_queues;
423
424        //!
425        vec green_starts;
426
427        //!
428        vec green_times;
429
430        //!
431        Array<string> green_names;
432
433        //!
434        Array<string> stage_names;
435
436        //!
437        vec stage_times;
438
439
440
441
442
443        //! datalink from DS to input variables
444        datalink ds2inputs;
445
446        //! datalink from DS to output variables
447        datalink ds2queues;
448
449        //! action description
450        RV rv_action;
451
452        datalink_part action2ds;
453
454        Array<string> neighbours;
455
456        Array<RV> rv_neighbours_out;
457
458        Array<datalink> output2neighbour;
459
460        //! simulator's step length in seconds
461        static const int step_length=90;
462
463        //! lenght of cycle in seconds
464        static const int cycle_length=80;
465
466
467
468public:
469        void validate(){
470
471                lanehs.set_length(lanes.length());
472                for (int l=0; l<lanes.length(); l++){
473                        lanehs(l) = new LaneHandler(lanes(l));
474
475                        rv_inputs.add(lanehs(l)->rv_inputs);
476                        rv_outputs.add(lanehs(l)->rv_outputs);
477                        rv_queues.add(lanehs(l)->rv_queue);
478                }
479                inputs.set_size(rv_inputs._dsize());
480                outputs.set_size(rv_outputs._dsize());
481                queues.set_size(rv_queues._dsize());
482
483                for (int l=0; l<lanes.length(); l++){
484                        lanehs(l)->connect_data(*this);
485                }
486
487                //for -- rv_outputs --
488                // TODO vybrat rv pro sousedy
489                rv_neighbours_out.set_length(neighbours.length());
490                output2neighbour.set_length(neighbours.length());
491
492                for (int i=0; i<neighbours.length(); i++){
493                        for (int r=0; r<rv_outputs.length(); r++){
494                                int str_pos = rv_outputs.name(r).compare(neighbours(i));
495                                if (str_pos>(int)neighbours(i).length()){
496                                        rv_neighbours_out(i).add(rv_outputs.subselect(vec_1(r)));
497                                }
498                        }
499                        // connect datasource
500                        output2neighbour(i).set_connection(rv_neighbours_out(i), rv_outputs);
501                }
502
503                // lanehs knows RVS
504                // write internal checks if all was loaded OK
505
506        }
507        void receive(const Setting &msg){
508                string what;
509                UI::get(what, msg, "what", UI::compulsory);
510
511                if (what=="new_stable_state"){ //
512                        // field data
513                        // extract decription of teh received datavector
514                        shared_ptr<RV> rv=UI::build<RV>(msg,"rv",UI::compulsory);
515                        // find if it is needed
516                        ivec ind=rv->dataind(rv_inputs); // position of rv in in_rv;
517                        if (ind.length()>0){ //data are interesting
518                                vec dt;
519                                UI::get(dt, msg, "value",UI::compulsory); // get data
520                                set_subvector(inputs, ind,  dt); //check size?
521                        }                               
522                } else {
523                        Participant::receive(msg);
524                }
525        }
526        void log_register(logger &L, const string &prefix){
527                root::log_register ( L, prefix );
528                if ( log_level[logdata]){
529                        L.add_vector ( log_level, logdata, RV ( 1 ), prefix ); 
530                }
531        }
532        void log_write() const {
533                if (log_level[logdata]){
534                        log_level.store(logdata, inputs);
535                }
536        }
537
538        void broadcast(Setting& set){
539                // broadcast data to all neighbours
540                for (int i=0; i<neighbours.length(); i++){
541                        Setting &msg =set.add(Setting::TypeGroup);
542
543                        // if...
544                        // copy from create message
545                        // create msg with fields {to=..., what=data, rv=..., value = ...}
546                        UI::save ( neighbours(i), msg, "to");
547                        UI::save ( (string)"new_stable_state", msg, "what");
548                        UI::save ( &(rv_neighbours_out(i)), msg, "rv");
549                        UI::save( output2neighbour(i).pushdown(outputs), msg, "value");
550                }
551
552        }
553        void adapt(const vec &glob_dt){
554                // copy data from global vector to sSGHandlers
555                ds2inputs.filldown(glob_dt, inputs);
556                //copy data from neighbours
557                ds2queues.filldown(glob_dt, queues);
558                // copy sg_length ... and others...
559        }
560        void act(vec &glob_ut){
561                vec action; // trivial stuff
562                action2ds.filldown(action,glob_ut);
563        }
564
565        void ds_register(const DS &ds){
566                //register ds2output
567                ds2inputs.set_connection(rv_inputs, ds._drv());
568                ds2queues.set_connection(rv_queues, ds._drv());
569
570                inputs.set_size(rv_inputs._dsize());
571                action2ds.set_connection( ds._urv(), rv_action);
572
573        }
574
575        void from_setting(const Setting &set);
576};
577UIREGISTER(BaseTrafficAgent);
578
579#endif //TRAGE_H
Note: See TracBrowser for help on using the browser.