| 1 | #pragma once |
|---|
| 2 | #include "traffic_agent.h" |
|---|
| 3 | #include "QueueData.h" |
|---|
| 4 | |
|---|
| 5 | /** |
|---|
| 6 | * Zakladni trida agenta pro nastavovani delky cyklu |
|---|
| 7 | */ |
|---|
| 8 | class BaseTrafficAgentCt : public BaseTrafficAgent { |
|---|
| 9 | protected: |
|---|
| 10 | Array<QueueData> queueData; |
|---|
| 11 | int looper; |
|---|
| 12 | mat A, B, Q, R, I0; |
|---|
| 13 | static const int T = 90; |
|---|
| 14 | double L; |
|---|
| 15 | int nOfBroadcast; |
|---|
| 16 | |
|---|
| 17 | vec computedQueues; |
|---|
| 18 | // intendsities of inputs |
|---|
| 19 | vec inputs_i; |
|---|
| 20 | |
|---|
| 21 | double Tc_sum; // suma Tc*w |
|---|
| 22 | double Tc_w_sum; // suma vah |
|---|
| 23 | double Tc_computed; // vypoctena hodnota pro Tc |
|---|
| 24 | double Tc_avg; // prumer s exponencialnim zapominanim |
|---|
| 25 | double Tc_w; // vaha pro prumer s exponencialnim zapominanim |
|---|
| 26 | static int const Tc_min = 40; |
|---|
| 27 | static int const Tc_max = 200; |
|---|
| 28 | |
|---|
| 29 | // pomocne logovaci soubory |
|---|
| 30 | ofstream Tc_log; |
|---|
| 31 | ofstream Q_log; |
|---|
| 32 | public: |
|---|
| 33 | // FUNKCE VOLANE V main_loop NA ZACATKU |
|---|
| 34 | |
|---|
| 35 | void from_setting(const Setting& set) { |
|---|
| 36 | BaseTrafficAgent::from_setting(set); |
|---|
| 37 | UI::get(L, set, "lost_time", UI::compulsory); |
|---|
| 38 | } |
|---|
| 39 | |
|---|
| 40 | void validate (){ |
|---|
| 41 | BaseTrafficAgent::validate(); |
|---|
| 42 | |
|---|
| 43 | queueData.set_length(queues.length()); |
|---|
| 44 | looper = 0; |
|---|
| 45 | Tc_avg = 80; |
|---|
| 46 | Tc_w = 0.2; |
|---|
| 47 | rv_action = RV("Tc",1); |
|---|
| 48 | rv_action.add( RV( stage_names, ones_i(stage_names.length()) ) ); |
|---|
| 49 | |
|---|
| 50 | |
|---|
| 51 | |
|---|
| 52 | for ( int i=0; i<lanehs.length(); i ++ ) { |
|---|
| 53 | unsigned int index = find_index( green_names, name + "_" + lanehs(i)->getSG() ); |
|---|
| 54 | lanehs(i)->green_time_ratio = green_times( index ); |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | // logovaci soubory |
|---|
| 58 | stringstream Tc_log_name; |
|---|
| 59 | Tc_log_name << name << "_tc_log.dat"; |
|---|
| 60 | Tc_log.open(Tc_log_name.str().c_str()); |
|---|
| 61 | |
|---|
| 62 | stringstream Q_log_name; |
|---|
| 63 | Q_log_name << name << "_q_log.dat"; |
|---|
| 64 | Q_log.open(Q_log_name.str().c_str()); |
|---|
| 65 | } |
|---|
| 66 | |
|---|
| 67 | // FUNKCE VOLANE V main_loop V KAZDEM CYKLU |
|---|
| 68 | |
|---|
| 69 | void initQueueData() { |
|---|
| 70 | for ( int i=0; i < queues.length(); i ++ ) { |
|---|
| 71 | queueData(i).id = rv_queues.name(i); |
|---|
| 72 | queueData(i).idInput = lanehs(i)->rv_inputs.name(0); |
|---|
| 73 | if ( queues(i) > 0 ) |
|---|
| 74 | queueData(i).queue = queues(i); |
|---|
| 75 | queueData(i).green = lanehs(i)->green_time_ratio; |
|---|
| 76 | |
|---|
| 77 | queueData(i).outputs.set_length( lanehs(i)->rv_outputs.length() ); |
|---|
| 78 | for ( int j = 0; j < lanehs(i)->rv_outputs.length(); j ++ ) { |
|---|
| 79 | queueData(i).outputs(j) = lanehs(i)->rv_outputs.name(j); |
|---|
| 80 | } |
|---|
| 81 | queueData(i).alphas.set_length( lanehs(i)->getLane().alpha.length() ); |
|---|
| 82 | for ( int j = 0; j < lanehs(i)->getLane().alpha.length(); j ++ ) { |
|---|
| 83 | queueData(i).alphas(j) = lanehs(i)->getLane().alpha(j); |
|---|
| 84 | } |
|---|
| 85 | } |
|---|
| 86 | for ( int i=0; i < queueData.length(); i ++ ) { |
|---|
| 87 | for ( int j = 0; j < rv_inputs.length(); j ++ ) { |
|---|
| 88 | if ( queueData(i).idInput == rv_inputs.name(j) && inputs(2*j) > 0 ) { |
|---|
| 89 | queueData(i).input = inputs(2*j); |
|---|
| 90 | } |
|---|
| 91 | } |
|---|
| 92 | } |
|---|
| 93 | } |
|---|
| 94 | |
|---|
| 95 | void adapt (const vec &glob_dt) { |
|---|
| 96 | BaseTrafficAgent::adapt(glob_dt); |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 99 | // compute inputs intensities |
|---|
| 100 | inputs_i = zeros( queues.length() ); |
|---|
| 101 | for ( int i = 0; i < lanehs.length(); i++ ) { |
|---|
| 102 | inputs_i(i) = lanehs(i)->inputs(0); |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | Tc_sum = 0; |
|---|
| 106 | Tc_w_sum = 0; |
|---|
| 107 | nOfBroadcast = 0; |
|---|
| 108 | |
|---|
| 109 | for ( int i=0; i<queues.length(); i ++ ) { |
|---|
| 110 | // nevim jestli sedej indexy |
|---|
| 111 | lanehs(i)->inputs( 0 ) = inputs( 2*find_index(rv_inputs, lanehs(i)->rv_inputs.name(0) ) ); |
|---|
| 112 | lanehs(i)->inputs( 1 ) = inputs( 2*find_index(rv_inputs, lanehs(i)->rv_inputs.name(0) ) + 1 ); |
|---|
| 113 | lanehs(i)->queue = queues( find_index( rv_queues, lanehs(i)->getQueueName() ) ); |
|---|
| 114 | lanehs(i)->countAvgs(); |
|---|
| 115 | Q_log << lanehs(i)->queue << " "; |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | Q_log << endl; |
|---|
| 119 | computedQueues = getComputedQueues(); |
|---|
| 120 | |
|---|
| 121 | initQueueData(); |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | void act (vec &glob_ut){ |
|---|
| 125 | looper ++; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | |
|---|
| 129 | // POMOCNE FCE |
|---|
| 130 | // saturovany tok pruhu i |
|---|
| 131 | double s_flow(int i) { |
|---|
| 132 | double min_flow = 0.5; |
|---|
| 133 | double max_flow = 0.5; |
|---|
| 134 | double input = 0; |
|---|
| 135 | if ( 2*i < inputs.length() ) |
|---|
| 136 | input = inputs(2*i); |
|---|
| 137 | |
|---|
| 138 | vec q = getComputedQueues(); |
|---|
| 139 | double flow = q(i); |
|---|
| 140 | if ( input > 0 ) |
|---|
| 141 | flow += input; |
|---|
| 142 | flow = flow/T; |
|---|
| 143 | if ( flow > max_flow ) |
|---|
| 144 | return max_flow; |
|---|
| 145 | if ( flow < min_flow ) |
|---|
| 146 | return min_flow; |
|---|
| 147 | else |
|---|
| 148 | return flow; |
|---|
| 149 | } |
|---|
| 150 | |
|---|
| 151 | void setCycleTime( int Tc, vec &glob_ut ) { |
|---|
| 152 | Tc_avg += Tc_w * (Tc - Tc_avg); |
|---|
| 153 | Tc_log << Tc << "\t" << Tc_avg << endl; |
|---|
| 154 | if ( looper % 5 == 0) { |
|---|
| 155 | Tc = (int)round(Tc_avg); |
|---|
| 156 | cout << endl << endl << "Nastavuji Tc = "<< Tc << endl << endl; |
|---|
| 157 | vec action; |
|---|
| 158 | action.set_size(rv_action._dsize()); |
|---|
| 159 | action(find_index(rv_action, "Tc")) = Tc; |
|---|
| 160 | int st; |
|---|
| 161 | int stage_time_sum = 0; // soucet delky fazi |
|---|
| 162 | action(find_index(rv_action, "Tc")) = Tc; |
|---|
| 163 | for ( int i =0; i < stage_names.length(); i ++) { |
|---|
| 164 | if ( (i+1) < stage_names.length() ) { |
|---|
| 165 | st = (int)round(((double)(stage_times(i)*(double)Tc))/80.0); |
|---|
| 166 | stage_time_sum += st; |
|---|
| 167 | action(find_index(rv_action, stage_names(i))) = st; |
|---|
| 168 | } |
|---|
| 169 | else { // dopocitani posledni faze - oprava zaokrouhlovaci chyby |
|---|
| 170 | action(find_index(rv_action, stage_names(i))) = Tc - stage_time_sum; |
|---|
| 171 | } |
|---|
| 172 | } |
|---|
| 173 | action2ds.filldown(action,glob_ut); |
|---|
| 174 | } |
|---|
| 175 | } |
|---|
| 176 | |
|---|
| 177 | vec getComputedQueues() { |
|---|
| 178 | vec q = zeros( queues.length() ); |
|---|
| 179 | for ( int i = 0; i < lanehs.length(); i++ ) { |
|---|
| 180 | q(i) = lanehs(i)->queue_avg; |
|---|
| 181 | } |
|---|
| 182 | return q; |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | int findQueueDataById( string id ) { |
|---|
| 186 | for ( int i = 0; i < queueData.length(); i ++ ) { |
|---|
| 187 | if ( queueData(i).id == id ) |
|---|
| 188 | return i; |
|---|
| 189 | } |
|---|
| 190 | return -1; |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | void sendQueueData( Setting &set, QueueData data) { |
|---|
| 194 | for ( int i = 0; i < neighbours.length(); i ++ ) { |
|---|
| 195 | Setting & msg = set.add(Setting::TypeGroup); |
|---|
| 196 | UI::save( neighbours(i), msg, "to" ); |
|---|
| 197 | UI::save (name,msg,"from"); |
|---|
| 198 | string msgCode = data.getMessageCode(); |
|---|
| 199 | UI::save( msgCode, msg, "what" ); |
|---|
| 200 | vec value = data.getVec(); |
|---|
| 201 | UI::save( value, msg, "value" ); |
|---|
| 202 | } |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | template <class T> void sendToAll( Setting &set, string msgCode, T value) { |
|---|
| 206 | for ( int i = 0; i < neighbours.length(); i ++ ) { |
|---|
| 207 | Setting & msg = set.add(Setting::TypeGroup); |
|---|
| 208 | UI::save( neighbours(i), msg, "to" ); |
|---|
| 209 | UI::save (name,msg,"from"); |
|---|
| 210 | UI::save( msgCode, msg, "what" ); |
|---|
| 211 | UI::save( value, msg, "value" ); |
|---|
| 212 | } |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | void printVector ( RV rv_vector, vec vector, string description ) { |
|---|
| 216 | cout << endl << description << " " << name << endl; |
|---|
| 217 | int k = 0; |
|---|
| 218 | for ( int i = 0; i < rv_vector.length(); i ++ ) { |
|---|
| 219 | cout << rv_vector.name(i) << " : "; |
|---|
| 220 | for ( int j = 0; j < rv_vector.size(i); j ++ ) { |
|---|
| 221 | cout << vector(k) << " "; |
|---|
| 222 | k ++; |
|---|
| 223 | } |
|---|
| 224 | cout << endl; |
|---|
| 225 | } |
|---|
| 226 | cout << endl; |
|---|
| 227 | } |
|---|
| 228 | |
|---|
| 229 | unsigned int find_index ( RV rv_vector, string index_string ) { |
|---|
| 230 | for ( int i = 0; i < rv_vector.length(); i ++) { |
|---|
| 231 | if ( rv_vector.name(i) == index_string ) |
|---|
| 232 | return i; |
|---|
| 233 | } |
|---|
| 234 | return -1; |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | unsigned int find_index ( Array <string> arr, string index_string ) { |
|---|
| 238 | for ( int i = 0; i < arr.length(); i ++) { |
|---|
| 239 | if ( arr(i) == index_string ) |
|---|
| 240 | return i; |
|---|
| 241 | } |
|---|
| 242 | return -1; |
|---|
| 243 | } |
|---|
| 244 | |
|---|
| 245 | /** |
|---|
| 246 | * Destructor |
|---|
| 247 | */ |
|---|
| 248 | ~BaseTrafficAgentCt() { |
|---|
| 249 | Tc_log.close(); |
|---|
| 250 | Q_log.close(); |
|---|
| 251 | } |
|---|
| 252 | }; |
|---|