#include "traffic_agent.h" #include class GreenWaveTrafficAgent : public BaseTrafficAgent { protected: double rating_change; int negot_offset; RV rv_change_request; vec change_request; RV rv_recieved_exps; vec recieved_exps; RV rv_recieved_changes; vec recieved_changes; //! name of agent, whose change we have accepted string accepted_from; list seznam; double car_leaving; //s; how long is 1 car leaving queue bool need_exps; bool new_stable_state; bool send_requests; bool final_state; //bool reset_negot_offset; //! counts all expected cars going from each lane, saves to outputs and rv_outputs void expected_cars(/*const string dest*/) { double start_time; for (int i=0;iexpected_output(green_time(0)); start_time = green_starts(sg_index(lanes(i).sg)) + lanes(i).output_distances(j)/VP + planned_offset; //first car arrive time outputs(ind(1))=start_time; //last car arrive time outputs(ind(2))= start_time + green_time(0); } } }; //! counts planned rating using offset and recieved_exps double count_rating(const int offset) { double virtual_queue; double t_emptiyng; double t_green_begin; double t_green_end; double t_cars_begin; double t_cars_end; // vec t_cars_begin; // vec t_cars_end; double t_mixing; bool found; double rating=0.0; for (int i=0;i=0) { ivec ind = rv_recieved_exps.dataind(RV(rv_recieved_exps.name(j),3)); t_cars_begin=recieved_exps(ind(1)); //TODO now using only last found exp. t_cars_end=recieved_exps(ind(2)); found=true; } } } if (!found) { t_cars_begin=0; t_cars_end=cycle_length; } //counting rating t_green_begin=green_starts(sg_index(lanes(i).sg)) + offset; ivec ind = rv_inputs.dataind(RV(name+"_"+lanes(i).sg,1)); t_green_end=t_green_begin+inputs(ind(0)); //TODO use real queues lenghts if (t_green_beginqueue-(t_cars_begin-t_green_begin)/car_leaving; //virtual_queue=(rand()%8)-(t_cars_begin-t_green_begin)/car_leaving; virtual_queue=5-(t_cars_begin-t_green_begin)/car_leaving; } else if (t_green_begin>t_cars_begin) { //virtual_queue=lanehs(i)->queue+(t_green_begin-t_cars_begin)*lanehs(i)->expected_density(); //virtual_queue=(rand()%9)+(t_green_begin-t_cars_begin)*lanehs(i)->expected_density(); virtual_queue=4+(t_green_begin-t_cars_begin)*lanehs(i)->expected_density(); } t_emptiyng=virtual_queue/(1/car_leaving - lanehs(i)->expected_density()); t_mixing=min(t_green_end,t_cars_end)-max(t_green_begin,t_cars_begin); rating+=max((t_mixing-t_emptiyng)*lanehs(i)->expected_density(),0.0); } return rating; } //! finds best offset using recieved_exps. Returns found offset int find_best_offset(const int center, int interval) { //! rating if offset is rised double rating_p; //! rating if offset is unchaged (=center) double rating_c; //! rating if offset is lowered double rating_n; int new_center; rating_p=count_rating(center+interval); rating_c=count_rating(center); rating_n=count_rating(center-interval); new_center=center; int max_index=max_of_three(rating_p,rating_c,rating_n); switch (max_index) { case 0: new_center+=interval; break; case 1: break; case 2: new_center-=interval; break; } if (interval>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_recieved_exps.dataind(RV(rv_recieved_exps.name(j),3)); 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_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; } //! returns index of signal group sg int sg_index(const string sg) { for (int i=0;i int normalize_offset(int offset) { while (offset<0 && offset b ? 0 : 1; if (index == 0) { index = a > c ? 0 : 2; } else { index = b > c ? 1 : 2; } return index; } public: //! offset set in last simulation step int last_offset; //! actual planned offset to set for next simulation step int planned_offset; //! rating of actual planned offset double planned_rating; //! array of existing signal groups Array sgs; //! relative starts of green for signal groups ivec green_starts; //! avarage speed of cars int VP; void validate() { rv_action = RV(name+"_offset", 1); // <======= example for (int i=0; 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=8; } void broadcast(Setting& set){ //ask neighbours for exptected arrive times if (need_exps) { for (int i=0; i2) { negot_offset/=2; send_requests=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;i0) { planned_offset+=(int)recieved_changes(ind(0)); 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); srand(time(NULL)); car_leaving=2; VP=45; negot_offset=8; // 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); } void act(vec &glob_ut){ vec action; action.set_size(rv_action._dsize()); ivec index = rv_action.dataind(RV(name+"_offset",1)); action(index(0))=planned_offset; last_offset=planned_offset; action2ds.filldown(action,glob_ut); } }; UIREGISTER(GreenWaveTrafficAgent);