#include "traffic_agent.h" #include #include class GreenWaveTrafficAgent : public BaseTrafficAgent { LOG_LEVEL(GreenWaveTrafficAgent,logoffset); protected: double rating_change; int negot_offset; int negot_limit; int actual_time; RV rv_outputs; vec outputs; RV rv_change_request; vec change_request; RV rv_recieved_exps; vec recieved_exps; RV rv_next_exps; vec next_exps; RV rv_recieved_changes; vec recieved_changes; //! name of agent, whose change we have accepted string accepted_from; //TODO currently useless list of neighbours asking for expectations list seznam; double car_leaving; //s; how long is 1 car leaving queue // some state variables bool need_exps; bool new_stable_state; bool send_requests; bool final_state; //bool reset_negot_offset; int passive; //! sum of final planned_offset values since last reach of cycle_count int total_offset; //! number of finished cycles since last reach of cycle_count int negot_cycle; //! after cycle_count cycles, we count avarege planned_offseta send it to Aimsun int cycle_count; //! counts all expected cars going from each lane, saves to outputs and rv_outputs void expected_cars() { double start_time; ivec ind; RV rv_exp; datalink exp2outputs; vec exp; for (int i=0;iexpected_output(green_time)*lanes(i).alpha(j); start_time = green_starts(group_index(name+"_"+lanes(i).sg)) + lanes(i).output_distances(j)/VP + planned_offset; //first car arrive time exp(1)=start_time; //last car arrive time exp(2)=start_time + green_time; //TODO pushup az na konec exp2outputs.pushup(outputs,exp); } } } }; //! counts planned rating using offset and recieved_exps double count_rating(const int offset) { double virtual_queue; double t_green_begin; double t_green_end; vec cars_count; vec t_cars_begin; vec t_cars_end; bool found; double rating=0.0; RV rv_vector; vec vector; for (int i=0;i=0) { t_cars_begin.set_size(l+1,true); t_cars_end.set_size(l+1,true); cars_count.set_size(l+1,true); rv_vector = RV(rv_recieved_exps.name(j),3); ivec ind = rv_vector.dataind(rv_recieved_exps); cars_count(l)=recieved_exps(ind(0)); t_cars_begin(l)=recieved_exps(ind(1)); t_cars_end(l)=recieved_exps(ind(2)); l++; found=true; } } } if (found) { //counting rating string group = name+"_"+lanes(i).sg; //e.g. 495_VA int index=group_index(group); t_green_begin=green_starts(index) + offset; double green_time=green_times(index)*cycle_length; t_green_end=t_green_begin+green_time; /************** counting with all exps ****************/ int k; double t_act=t_green_begin; virtual_queue=lanehs(i)->queue; //cycle goes through all "stopping" points and counts queue lenght at these points do { k=min_i(t_cars_begin); if (k!=-1) { //in case there are cars comming before t_green begin if (t_cars_begin(k)=t_green_end else { virtual_queue+=cars_count(k)-(t_green_end-t_act)/car_leaving; t_act=t_green_end; } //more cars than cars_count(k) couldn't pass without stopping if (virtual_queue < -cars_count(k)) { virtual_queue = -cars_count(k); } cars_count.del(k); t_cars_begin.del(k); t_cars_end.del(k); } //if t_cars_begin(k)>=t_act else { if (t_cars_begin(k)2) { interval/=2; new_center=find_best_offset(new_center,interval); } return new_center; } //! finds if changing neighbour's offset could have positive effect, returns found offset change int find_best_exps(const int offset_change, const string neighbour, double &rating_change) { //! expectations recieved from neighbour vec original_exps; //! expactations after positve change of neighbour's offset vec positive_exps; //! expactations after negative change of neighbour's offset vec negative_exps; //! rating if offset is rised double rating_p; //! rating if offset is unchaged double rating_c; //! rating if offset is lowered double rating_n; original_exps.set_size(recieved_exps.length()); original_exps=recieved_exps; positive_exps=recieved_exps; negative_exps=recieved_exps; for (int j=0;j0) { ivec ind = RV(rv_recieved_exps.name(j),3).dataind(rv_recieved_exps); rating_n=count_rating(planned_offset); positive_exps(ind(1))+=offset_change; positive_exps(ind(2))+=offset_change; negative_exps(ind(1))-=offset_change; negative_exps(ind(2))-=offset_change; } } rating_c=count_rating(planned_offset); recieved_exps=positive_exps; rating_p=count_rating(planned_offset); recieved_exps=negative_exps; rating_n=count_rating(planned_offset); recieved_exps=original_exps; int max_index=max_i_of_three(rating_p,rating_c,rating_n); switch (max_index) { case 0: rating_change=rating_p-rating_c; return offset_change; break; case 1: rating_change=0; return 0; break; case 2: rating_change=rating_n-rating_c; return -offset_change; break; } rating_change=NULL; return NULL; } // pravdepodobne s chybou, momentalne se nepouziva void split_exps() { ivec ind; RV rv_exp; datalink recieved2next; rv_next_exps=RV(); for (int i=0;inext_cycle_end) { rv_next_exps.add(rv_exp); next_exps.set_size(rv_next_exps._dsize()); if (actual_time==630) { cout << "rv_next_exps " << rv_next_exps.to_string() << endl; cout << "rv_recived_exps " << rv_recieved_exps.to_string() << endl; } recieved2next.set_connection(rv_next_exps,rv_recieved_exps); recieved2next.filldown(recieved_exps,next_exps); rv_recieved_exps=rv_recieved_exps.subt(rv_exp); } else if (recieved_exps(ind(2))>next_cycle_end) { rv_next_exps.add(rv_exp); next_exps.set_size(rv_next_exps._dsize()); ivec ind2=rv_exp.dataind(rv_next_exps); next_exps(ind2(0))=recieved_exps(ind(0)); //TODO to neni spravne next_exps(ind2(1))=next_cycle_end; next_exps(ind2(2))=recieved_exps(ind(2)); recieved_exps(ind(2))=next_cycle_end; } } } } //! returns index of signal group group int group_index(const string group) { for (int i=0;i or (when second parameter is false)) <0;cycle_length> */ int normalize_offset(int offset, bool zero=true) { if (zero) { while ((offset<(-cycle_length/2)) || (offset>(cycle_length/2))) { if (offset<0) { offset+=cycle_length; } else { offset-=cycle_length; } } return offset; } else { while (offset<0 || offset>cycle_length) { if (offset<0) { offset+=cycle_length; } else { offset-=cycle_length; } } return offset; } } //! returns value shifted to fit interval <0;cycle_length> //currently not in use template T normalize(T time) { while (time<0 && time inline string to_string (const T& t) { std::stringstream ss; ss << t; return ss.str(); } //! returns index of maximum of entered values int max_i_of_three(const double a, const double b, const double c) { int index = a > b ? 0 : 1; if (index == 0) { index = a > c ? 0 : 2; } else { index = b > c ? 1 : 2; } return index; } //! returns index of smallest element in vector int min_i(vec vector) { if (vector.length()>0) { double min=vector(0); int index=0; for (int i=1;iqueue_index=index(0); } } void adapt(const vec &glob_dt) { BaseTrafficAgent::adapt(glob_dt); for (int i=0;iqueue=queues(lanehs(i)->queue_index); } planned_offset=last_offset; //set state variables to default values final_state=false; new_stable_state=false; send_requests=false; need_exps=true; negot_offset=4; } void broadcast(Setting& set){ //ask neighbours for exptected arrive times if (need_exps) { for (int i=0; inegot_limit) { negot_offset/=2; send_requests=true; } else { final_state=true; } } else { final_state=true; } } else if (what=="offset_change_request") { double final_rating_diff; rv_recieved_changes=*rv; recieved_changes=value; for (int i=0;i=0) { planned_offset+=(int)recieved_changes(ind(0)); planned_offset=normalize_offset(planned_offset); planned_rating+=final_rating_diff; accepted_from=from; } } //need_exps=true;s new_stable_state=true; } /*else if (what=="reset_negot_offset") { negot_offset=8; }*/ else { BaseTrafficAgent::receive(msg); } } void ds_register(const DS &ds) { BaseTrafficAgent::ds_register(ds); action2ds.set_connection( ds._urv(), rv_action); } void from_setting(const Setting &set) { BaseTrafficAgent::from_setting(set); RV rv_exp; car_leaving=2; VP=45; actual_time=0; negot_cycle=1; cycle_count=5; total_offset=0; negot_offset=4; negot_limit=1; passive=0; // load from file //UI::get(sgs, set, "sgs", UI::compulsory); //UI::get(green_starts, set, "green_starts", UI::compulsory); UI::get(last_offset, set, "offset", UI::compulsory); UI::get(passive, set, "passive", UI::optional); for (int i=0;i