root/applications/doprava/traffic_agent.h @ 1115

Revision 1111, 6.3 kB (checked in by ondrak, 14 years ago)

One agent made passive - doesn't send offset_change_request

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        }
80
81
82        void connect_data(BaseTrafficAgent &agent0);
83
84        //! computes expected density in cars/s
85        double expected_density();
86
87        //! arbitrary function that computes the need of the signal group for green light in common units (number of waiting cars?)
88        double expected_output(double green_time);
89};
90
91/*!
92\brief  Basic Traffic Agent
93
94*/
95class BaseTrafficAgent : public Participant {
96
97LOG_LEVEL(BaseTrafficAgent,logdata);
98public:
99        //! Signal Groups
100        Array<Lane> lanes;
101
102        Array<LaneHandler*> lanehs;
103
104        //!data from messages
105        vec inputs;
106
107        //! decription of msg_data
108        RV rv_inputs;
109
110        //! data to broadcast
111        vec outputs;
112
113        //! description of broadcast dataind
114        RV rv_outputs;
115
116        vec queues;
117
118        //! description of queues
119        RV rv_queues;
120
121        //!
122        vec green_starts;
123
124        //!
125        vec green_times;
126
127        //!
128        Array<string> green_names;
129
130        //!
131        Array<string> stage_names;
132
133        //!
134        vec stage_times;
135
136
137
138
139
140        //! datalink from DS to input variables
141        datalink ds2inputs;
142
143        //! datalink from DS to output variables
144        datalink ds2queues;
145
146        //! action description
147        RV rv_action;
148
149        datalink_part action2ds;
150
151        Array<string> neighbours;
152
153        Array<RV> rv_neighbours_out;
154
155        Array<datalink> output2neighbour;
156
157        //! simulator's step length in seconds
158        static const int step_length=90;
159
160        //! lenght of cycle in seconds
161        static const int cycle_length=80;
162
163
164
165public:
166        void validate(){
167
168                lanehs.set_length(lanes.length());
169                for (int l=0; l<lanes.length(); l++){
170                        lanehs(l) = new LaneHandler(lanes(l));
171
172                        rv_inputs.add(lanehs(l)->rv_inputs);
173                        rv_outputs.add(lanehs(l)->rv_outputs);
174                        rv_queues.add(lanehs(l)->rv_queue);
175                }
176                inputs.set_size(rv_inputs._dsize());
177                outputs.set_size(rv_outputs._dsize());
178                queues.set_size(rv_queues._dsize());
179
180                for (int l=0; l<lanes.length(); l++){
181                        lanehs(l)->connect_data(*this);
182                }
183
184                //for -- rv_outputs --
185                // TODO vybrat rv pro sousedy
186                rv_neighbours_out.set_length(neighbours.length());
187                output2neighbour.set_length(neighbours.length());
188
189                for (int i=0; i<neighbours.length(); i++){
190                        for (int r=0; r<rv_outputs.length(); r++){
191                                int str_pos = rv_outputs.name(r).compare(neighbours(i));
192                                if (str_pos>(int)neighbours(i).length()){
193                                        rv_neighbours_out(i).add(rv_outputs.subselect(vec_1(r)));
194                                }
195                        }
196                        // connect datasource
197                        output2neighbour(i).set_connection(rv_neighbours_out(i), rv_outputs);
198                }
199
200                // lanehs knows RVS
201                // write internal checks if all was loaded OK
202
203        }
204        void receive(const Setting &msg){
205                string what;
206                UI::get(what, msg, "what", UI::compulsory);
207
208                if (what=="new_stable_state"){ //
209                        // field data
210                        // extract decription of teh received datavector
211                        shared_ptr<RV> rv=UI::build<RV>(msg,"rv",UI::compulsory);
212                        // find if it is needed
213                        ivec ind=rv->dataind(rv_inputs); // position of rv in in_rv;
214                        if (ind.length()>0){ //data are interesting
215                                vec dt;
216                                UI::get(dt, msg, "value",UI::compulsory); // get data
217                                set_subvector(inputs, ind,  dt); //check size?
218                        }                               
219                } else {
220                        Participant::receive(msg);
221                }
222        }
223        void log_register(logger &L, const string &prefix){
224                root::log_register ( L, prefix );
225                if ( log_level[logdata]){
226                        L.add_vector ( log_level, logdata, RV ( 1 ), prefix ); 
227                }
228        }
229        void log_write() const {
230                if (log_level[logdata]){
231                        log_level.store(logdata, inputs);
232                }
233        }
234
235        void broadcast(Setting& set){
236                // broadcast data to all neighbours
237                for (int i=0; i<neighbours.length(); i++){
238                        Setting &msg =set.add(Setting::TypeGroup);
239
240                        // if...
241                        // copy from create message
242                        // create msg with fields {to=..., what=data, rv=..., value = ...}
243                        UI::save ( neighbours(i), msg, "to");
244                        UI::save ( (string)"new_stable_state", msg, "what");
245                        UI::save ( &(rv_neighbours_out(i)), msg, "rv");
246                        UI::save( output2neighbour(i).pushdown(outputs), msg, "value");
247                }
248
249        }
250        void adapt(const vec &glob_dt){
251                // copy data from global vector to sSGHandlers
252                ds2inputs.filldown(glob_dt, inputs);
253                //copy data from neighbours
254                ds2queues.filldown(glob_dt, queues);
255                // copy sg_length ... and others...
256        }
257        void act(vec &glob_ut){
258                vec action; // trivial stuff
259                action2ds.filldown(action,glob_ut);
260        }
261
262        void ds_register(const DS &ds){
263                //register ds2output
264                ds2inputs.set_connection(rv_inputs, ds._drv());
265                ds2queues.set_connection(rv_queues, ds._drv());
266
267                inputs.set_size(rv_inputs._dsize());
268                action2ds.set_connection( ds._urv(), rv_action);
269
270        }
271
272        void from_setting(const Setting &set);
273};
274UIREGISTER(BaseTrafficAgent);
275
276#endif //TRAGE_H
Note: See TracBrowser for help on using the browser.