/*!
\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{
string from; // from agent
Array to_sg; // to signal plans
void from_setting(const Setting &set){
Detector::from_setting(set);
UI::get(from,set,"from",UI::compulsory);
UI::get(to_sg, set, "to_sg", UI::compulsory);
}
};
//! structure for output detectors
class RequestOut {
public:
string to; // agent
Array from; //detectors
void from_setting(const Setting &set){
UI::get(from,set,"from",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;
//! link from data to global out_data
datalink data2out;
public:
SignalGroupHandler(SignalGroup *sg0, const string &agent_name):rv_det_data(){
sg=sg0;
for (int i=0;idetectors.length();i++){
rv_det_data.add(RV(agent_name + sg->detectors(i).name, 1)); //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;
datalink outdata2out;
public:
RequestHandler(RequestOut *rq0, const string &agent_name){
rq=rq0;
for (int i=0;ifrom.length();i++){
rv.add(RV(agent_name + rq->from(i), 1)); //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;
RV action_rv;
datalink_part action2ds;
//! output recepient
Array requests;
Array request_handler;
public:
void validate(){
// write internal checks if all was loaded OK
}
void receive(const Setting &msg){
string what;
UI::get(what, msg, "what", UI::compulsory);
if (what=="data"){ //
// field data
//! decription of detected data
shared_ptr rv=UI::build(msg,"rv",UI::compulsory);
ivec ind=rv->dataind(input_rv); // position of rv in in_rv;
if (ind.length()>0){ //data belong here
vec dt;
UI::get(dt, msg, "value",UI::compulsory);
set_subvector(input_data, ind, dt); //check size?
}
} else {
bdm_warning("Unknown message of type "+what);
}
}
void broadcast(Setting& set){
// broadcast data to all neighbours
for (int i=0; i