[1422] | 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 | }; |
---|