root/applications/doprava/traffic_agent.h

Revision 1141, 13.3 kB (checked in by jabu, 14 years ago)
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 queue_last;     
98        double queue_avg_last;
99        double green_time_ratio;
100        double Tc;
101        double last_Tc;
102        double saturated_stream;
103        double delta; // ztratovy cas pri prechodu na zelenou
104        double delta_w;
105        // udaje opro filtr
106        double queue_avg; //  pruner
107        double queue_w;   //  vaha
108
109        double Ro_avg;  //  prumer
110        double Ro_w;    //  vaha K
111
112        double cars_in_avg;
113        double cars_in_w;
114       
115
116        double last_queue_avg;
117
118// pomocne funkce
119
120       
121
122        void init () {
123                last_Tc = 0;
124                saturated_stream = 0.5;
125                queue = 0;
126                queue_last = 0;
127                // filtr
128                delta = 0;
129                delta_w = 0.2;
130               
131                queue_avg = 0;  //  prumer
132                queue_w = 0.4;  //  vaha               
133
134                Ro_avg = 0;     //  prumer
135                Ro_w = 0.1;     //  vaha
136
137                cars_in_avg = 0;
138                cars_in_w = 0.4;
139               
140                last_queue_avg = 0;
141        }
142
143        /*double abs ( double x ) {
144                if ( x > 0 ) return x;
145                else return -x;
146        }*/
147
148        void echo () {
149               
150                cout << getQueueName();
151               
152                cout << "\tgtr: " << green_time_ratio;
153                cout << "\tRo: " << getRo();
154                cout << "\tC: " << green_time_ratio*Tc*saturated_stream - getRo()*Tc << endl; 
155                //cout << "\tWT:";
156                for ( int i = -2; i <= 2; i++ ) {
157                        double tc = Tc + i*8;
158                        cout << tc << "\t";
159                }
160                cout << endl;
161                for ( int i = -2; i <= 2; i++ ) {
162                        double tc = Tc + i*8;
163                        cout << (int)(100*getWT(tc)) << "\t";
164                }
165               
166                cout << endl << endl;
167        }
168       
169
170        Lane getLane () {
171                return lane;
172        }
173
174        string getSG () {
175                return lane.sg;
176        }
177
178        string getQueueName () {
179                return lane.queue;
180        }
181
182        double getQueue() {
183                return queue_avg;
184        }
185
186        void addQueueLength ( int ql ) {
187                // pricita pouze namerene udaje
188                if ( ql >= 0 ) {
189                        queue_last = queue;
190                        queue = ql;
191                        queue_avg_last = queue_avg;
192                       
193                        // KALMAN                       
194                        //cout << endl << "pridani fronty\t" << queue_avg << "\t" << ql << endl;
195                        queue_avg += queue_w*( ql - queue_avg );                       
196                        /*cout << getQueueName() << " inputs";
197                        int k = 0;
198                        for ( int i = 0; i < rv_inputs.length(); i ++ ) {
199                        cout <<"\t"<< rv_inputs.name(i) << ": ";
200                        for ( int j = 0; j < rv_inputs.size(i); j ++ ) {                               
201                                cout << inputs(k) << " ";
202                                k ++;
203                        }
204                        cout << endl;*/
205                }
206                if ( inputs(0) >= 0 ) {
207                        cars_in_avg += cars_in_w*( inputs(0) - cars_in_avg );
208               
209                }
210                if ( cars_in_avg > 0 && queue_avg_last > saturated_stream*last_Tc*green_time_ratio ) {
211                        //double delta_d = queue_avg - queue_avg_last + last_Tc * saturated_stream - cars_in_avg*(double)last_Tc/90;                   
212                        double delta_d = ( last_Tc/(90*saturated_stream)) * (cars_in_avg - queue_avg + queue_avg_last) - green_time_ratio;
213                        delta += delta_w * ( delta_d - delta );
214                        if ( delta < 0 )
215                                delta = 0;
216                }
217
218                cout << getQueueName() << " cars in: " << inputs(0) << " " << cars_in_avg <<
219                        " q_avd: " << queue_avg <<
220                        " delta: " << delta <<
221                        endl;
222        }
223
224
225       
226
227        double getAverageQueueLength () {
228                // kalmam
229                return queue_avg;
230        }
231
232        double getLastAverageQueueLength () {
233                return queue_avg_last;
234        }
235
236        /*double getAverageQueueGrow () {
237                return queue_diff_sum / n_of_queues_in_length;
238        }*/
239       
240        /*double getQueueVariance () {
241                return queue_variance_sum / n_of_queues_in_length;
242        }*/
243
244        double getGreenTime ( double tc ) { return green_time_ratio * tc - delta; }     
245        double getGreenTime () { return getGreenTime( Tc ); }   
246       
247        double getRedTime ( double tc ) { return (1-green_time_ratio) * tc;     }
248        double getRedTime () { return getRedTime( Tc ); }       
249
250       
251
252        // hodnotici funkce - suma cekaciho casu aut za 10h
253        //double getWT_old ( double  Tc ) {
254        //  double T = 36000; // celkovy cas 10h
255        //  double Ro = getRo();
256        //  double Gr = green_time_ratio;
257        //  double ss = saturated_stream;
258        //  double WT = 0;
259        //  double q = 0;  // zacina s nulovou frontou ?
260        //  double ti = 0;
261        //  double sumq = q;
262        //  while ( ti < T ) {
263        //      // ve fronte stoji vic aut nez je schopno odjet za zelenou
264        //      if ( q > 0.5*ss*Tc ) {
265        //        WT += 0.5*ss*(Tc*Gr - delta)*(Tc*Gr - delta);
266        //      }
267        //      else {
268
269        //        WT += 0.5*q*(Tc*Gr - delta);
270        //      }
271
272        //      if ( (Tc*Gr - delta)*ss < q )
273        //        q -= (Tc*Gr - delta)*ss;
274        //      else
275        //        q = 0;
276
277        //      WT += q * Tc; // zbytek fronty ceka cely cyklus
278        //      // cekani vozidel, ktera prijela za pocitany cyklus
279        //      if ( q > 0 ) {
280        //        //pokud je fronta > 0, auta cekaji prumerne polovinu delky cyklu
281        //        WT += Ro*Tc*0.5*Tc;
282        //      }
283        //      else {
284        //        // pokud je fronta = 0 cekaji pouze auta, ktera prijela na cervenou (p=(1-Gr)) 0.5Tc(1-Gr)
285        //        WT += Ro*(1-Gr)*Tc*0.5*(1-Gr)*Tc;
286        //      }
287        //      // fronta se zvetsi o Ro*Tc
288        //      q += Ro*Tc;
289        //      sumq += Ro*Tc;
290        //      ti += Tc;
291        //  }
292
293        //  //return WT;
294        //  if ( sumq > 0 )
295        //      return 100*(WT/(0.5*T*sumq));
296        //  else
297        //  return 0;
298        //}
299        // stredni doba prujezdu n-teho auta ve fronte
300        double getEcarWT ( const double tc, const int n ) {
301                double cpg = (tc * green_time_ratio - delta) * saturated_stream; // cars per green time
302                double wc = floor( n / cpg ); // number of waiting cycles               
303                double ET_last_cycle = ( 1/ (2*tc) ) * ( tc*(1-green_time_ratio) + (n-wc*cpg)/saturated_stream )*( tc*(1-green_time_ratio) + (n-wc*cpg)/saturated_stream );
304                double ET = wc*tc + ET_last_cycle;
305                return ET;
306        }
307
308        // suma strednich hodnot cekacich casu pres auta ve fronte
309        double getWT ( const double tc ) {
310                double sumEWT = 0;
311                //int n = round(getAverageQueueLength());
312                int n = round(cars_in_avg + getAverageQueueLength());
313                for ( int i = 0; i <= n; i ++ ) {
314                        sumEWT += getEcarWT( tc, i );
315                }
316                return sumEWT;
317        }
318
319
320        //double getWT ( double  tc ) {
321        //      double T = ;
322        //      double WT = 0;
323        //      double cWT = 0;
324        //      double q = 0;
325        //      double cq = 0;
326        //      double sum_t;
327        //      double car_part = 0.1;
328        //      double Ro = getRo();
329        //      double dt = car_part/Ro;
330        //      while ( sum_t < T ) {
331        //              if ( q < 0 )
332        //                      q = 0;
333        //              WT += q * dt;
334        //              // prirustek fronty za dt
335        //              q += car_part;
336        //              // zelena - auta projedou
337        //              if ( (sum_t - tc*(int)(sum_t/tc)) > delta && )
338        //                      q -= saturated_stream*dt;
339        //              sum_t += dt;
340        //      }
341        //}
342        // Odhad hustoty ( auto/sec )
343        double getActualRo () {
344                // pokud delka fronty mensi nez pocet aut ktere odjedou za zelenou
345                if ( saturated_stream*getGreenTime() >= getAverageQueueLength() ) {
346                        // pocet aut, ktera prijela pri cervene
347                        return getAverageQueueLength()/getRedTime();
348                }
349                else {
350                        //fronta se nevynuluje
351                        // pocet aut = to co stihlo projet na zelenou + o co narostla fronta
352                        // doba pocet_cyklu*90
353                        //double T = n_of_queues_in_length*90;
354                        //double cars_per_green = T*(getGreenTime()/Tc)*saturated_stream;
355                        //return (cars_per_green + queue_diff_sum)/T;
356                        double T = 90;
357                        double cars_per_green = T*(getGreenTime()/Tc)*saturated_stream;
358                        return (cars_per_green + (getLastAverageQueueLength()-getAverageQueueLength()))/T;
359                }
360        }
361
362        double getRo() {
363                return Ro_avg;
364        }
365       
366       
367
368        /***************************************
369        * KONEC KODU PRO TrafficAgentCycleTime *
370        ****************************************/
371};
372
373/*!
374\brief  Basic Traffic Agent
375
376*/
377class BaseTrafficAgent : public Participant {
378
379LOG_LEVEL(BaseTrafficAgent,logdata);
380public:
381        //! Signal Groups
382        Array<Lane> lanes;
383
384        Array<LaneHandler*> lanehs;
385
386        //!data from messages
387        vec inputs;
388
389        //! decription of msg_data
390        RV rv_inputs;
391
392        //! data to broadcast
393        vec outputs;
394
395        //! description of broadcast dataind
396        RV rv_outputs;
397
398        vec queues;
399
400        //! description of queues
401        RV rv_queues;
402
403        //!
404        vec green_starts;
405
406        //!
407        vec green_times;
408
409        //!
410        Array<string> green_names;
411
412        //!
413        Array<string> stage_names;
414
415        //!
416        vec stage_times;
417
418
419
420
421
422        //! datalink from DS to input variables
423        datalink ds2inputs;
424
425        //! datalink from DS to output variables
426        datalink ds2queues;
427
428        //! action description
429        RV rv_action;
430
431        datalink_part action2ds;
432
433        Array<string> neighbours;
434
435        Array<RV> rv_neighbours_out;
436
437        Array<datalink> output2neighbour;
438
439        //! simulator's step length in seconds
440        static const int step_length=90;
441
442        //! lenght of cycle in seconds
443        static const int cycle_length=80;
444
445
446
447public:
448        void validate(){
449
450                lanehs.set_length(lanes.length());
451                for (int l=0; l<lanes.length(); l++){
452                        lanehs(l) = new LaneHandler(lanes(l));
453
454                        rv_inputs.add(lanehs(l)->rv_inputs);
455                        rv_outputs.add(lanehs(l)->rv_outputs);
456                        rv_queues.add(lanehs(l)->rv_queue);
457                }
458                inputs.set_size(rv_inputs._dsize());
459                outputs.set_size(rv_outputs._dsize());
460                queues.set_size(rv_queues._dsize());
461
462                for (int l=0; l<lanes.length(); l++){
463                        lanehs(l)->connect_data(*this);
464                }
465
466                //for -- rv_outputs --
467                // TODO vybrat rv pro sousedy
468                rv_neighbours_out.set_length(neighbours.length());
469                output2neighbour.set_length(neighbours.length());
470
471                for (int i=0; i<neighbours.length(); i++){
472                        for (int r=0; r<rv_outputs.length(); r++){
473                                int str_pos = rv_outputs.name(r).compare(neighbours(i));
474                                if (str_pos>(int)neighbours(i).length()){
475                                        rv_neighbours_out(i).add(rv_outputs.subselect(vec_1(r)));
476                                }
477                        }
478                        // connect datasource
479                        output2neighbour(i).set_connection(rv_neighbours_out(i), rv_outputs);
480                }
481
482                // lanehs knows RVS
483                // write internal checks if all was loaded OK
484
485        }
486        void receive(const Setting &msg){
487                string what;
488                UI::get(what, msg, "what", UI::compulsory);
489
490                if (what=="new_stable_state"){ //
491                        // field data
492                        // extract decription of teh received datavector
493                        shared_ptr<RV> rv=UI::build<RV>(msg,"rv",UI::compulsory);
494                        // find if it is needed
495                        ivec ind=rv->dataind(rv_inputs); // position of rv in in_rv;
496                        if (ind.length()>0){ //data are interesting
497                                vec dt;
498                                UI::get(dt, msg, "value",UI::compulsory); // get data
499                                set_subvector(inputs, ind,  dt); //check size?
500                        }                               
501                } else {
502                        Participant::receive(msg);
503                }
504        }
505        void log_register(logger &L, const string &prefix){
506                root::log_register ( L, prefix );
507                if ( log_level[logdata]){
508                        L.add_vector ( log_level, logdata, RV ( 1 ), prefix ); 
509                }
510        }
511        void log_write() const {
512                if (log_level[logdata]){
513                        log_level.store(logdata, inputs);
514                }
515        }
516
517        void broadcast(Setting& set){
518                // broadcast data to all neighbours
519                for (int i=0; i<neighbours.length(); i++){
520                        Setting &msg =set.add(Setting::TypeGroup);
521
522                        // if...
523                        // copy from create message
524                        // create msg with fields {to=..., what=data, rv=..., value = ...}
525                        UI::save ( neighbours(i), msg, "to");
526                        UI::save ( (string)"new_stable_state", msg, "what");
527                        UI::save ( &(rv_neighbours_out(i)), msg, "rv");
528                        UI::save( output2neighbour(i).pushdown(outputs), msg, "value");
529                }
530
531        }
532        void adapt(const vec &glob_dt){
533                // copy data from global vector to sSGHandlers
534                ds2inputs.filldown(glob_dt, inputs);
535                //copy data from neighbours
536                ds2queues.filldown(glob_dt, queues);
537                // copy sg_length ... and others...
538        }
539        void act(vec &glob_ut){
540                vec action; // trivial stuff
541                action2ds.filldown(action,glob_ut);
542        }
543
544        void ds_register(const DS &ds){
545                //register ds2output
546                ds2inputs.set_connection(rv_inputs, ds._drv());
547                ds2queues.set_connection(rv_queues, ds._drv());
548
549                inputs.set_size(rv_inputs._dsize());
550                action2ds.set_connection( ds._urv(), rv_action);
551
552        }
553
554        void from_setting(const Setting &set);
555};
556UIREGISTER(BaseTrafficAgent);
557
558#endif //TRAGE_H
Note: See TracBrowser for help on using the browser.