/*!
\file
\brief Traffic Light Agents
\author Vaclav Smidl.
*/
#ifndef TRAGE_H
#define TRAGE_H
#include
using namespace bdm;
//! detector of traffic variables
class Detector{
public:
string name; //! detector name
int distance; //! distance from stop-line
//! function loading info from Setting
void from_setting(const Setting &set){
UI::get(name,set,"name",UI::compulsory);
UI::get(distance,set,"distance",UI::compulsory);
}
};
//! detector fo incomming flow
class DetectorIn : public Detector{
public:
Array to_sg; // to signal plans
void from_setting(const Setting &set){
Detector::from_setting(set);
UI::get(to_sg, set, "to_sg", UI::compulsory);
}
};
//! structure for output detectors
class RequestOut {
public:
string to; // agent
Array detectors; //detectors
void from_setting(const Setting &set){
UI::get(detectors,set,"detectors",UI::compulsory);
UI::get(to, set, "to", UI::compulsory);
}
};
//! class with physical information about a signal group
class SignalGroup {
public:
string name; //! names of the group
Array detectors; //! (possible) detectors
//! function that loads information from Setting
void from_setting(const Setting &set);
};
//! class that operates on a signal group
class SignalGroupHandler {
protected:
//! pointer to physical signal group
SignalGroup *sg;
public:
//! actual data from the relevant signal group
vec det_data;
//! description of det_data
RV rv_det_data;
//! link from global measured data
datalink ds2data;
public:
void connect_sg(SignalGroup &sg0, const string &agent_name){
sg=&sg0;
for (int i=0;idetectors.length();i++){
rv_det_data.add(RV(agent_name +"_"+ sg->detectors(i).name, 2)); //TODO intensity occupancy
}
}
//! arbitrary function that computes the need of the signal group for green light in common units (number of waiting cars?)
double expected_load(){
if (det_data.length()>0){
return det_data(0); // whatever
} else {
return 1.0; // mean value
}
}
};
class RequestHandler{
protected:
RequestOut *rq;
public:
RV rv;
public:
void connect_request(RequestOut &rq0, const string &agent_name){
rq=&rq0;
for (int i=0;idetectors.length();i++){
rv.add(RV(rq->detectors(i), 2)); //TODO intensity occupancy
}
}
};
/*!
\brief Basic Traffic Agent
*/
class BaseTrafficAgent : public Participant {
protected:
//! Signal Groups
Array sg;
Array sgh;
//!data from messages
vec input_data;
//! decription of msg_data
RV input_rv;
//! data to broadcast
vec output_data;
//! description of broadcast dataind
RV output_rv;
//! datalink from DS to output variables
datalink ds2output;
//! output recepient
Array requests;
Array request_handler;
//! action description
RV action_rv;
datalink_part action2ds;
public:
void validate(){
// write internal checks if all was loaded OK
// set action variable == this is a feature of the agent!
action_rv = RV(name+"_Tc", 1); // <======= example
}
void receive(const Setting &msg){
string what;
UI::get(what, msg, "what", UI::compulsory);
if (what=="data"){ //
// field data
// extract decription of teh received datavector
shared_ptr rv=UI::build(msg,"rv",UI::compulsory);
// find if it is needed
ivec ind=rv->dataind(input_rv); // position of rv in in_rv;
if (ind.length()>0){ //data are interesting
vec dt;
UI::get(dt, msg, "value",UI::compulsory); // get data
set_subvector(input_data, ind, dt); //check size?
}
} else {
bdm_warning("Unknown message of type "+what);
}
}
void log_register(logger &L, const string &prefix){
root::log_register ( L, prefix );
logrec->ids.set_size(sg.length()+2);
int i;
for (i=0;i ids(i)=logrec->L.add_vector(sgh(i).rv_det_data, "");
}
logrec->ids(i)=logrec->L.add_vector(input_rv,"in_"); i++;
logrec->ids(i)=logrec->L.add_vector(output_rv,"out_");
}
void log_write() const {
int i;
for (i=0;i L.log_vector(logrec->ids(i), sgh(i).det_data);
}
logrec->L.log_vector(logrec->ids(i),input_data); i++;
logrec->L.log_vector(logrec->ids(i),output_data); i++;
}
void broadcast(Setting& set){
// broadcast data to all neighbours
for (int i=0; i