Commit e8efcb45 authored by Ulrich Kemloh's avatar Ulrich Kemloh

New information are now accepted with a probability in events

parent 0a05650f
......@@ -557,7 +557,6 @@ void TrajectoriesJPSV06::WriteFrame(int frameNr, Building* building)
char tmp1[CLENGTH] = "";
int color=ped->GetColor();
double a = ped->GetLargerAxis();
double b = ped->GetSmallerAxis();
......
......@@ -498,29 +498,29 @@ int Simulation::RunBody(double maxSimTime)
while ( (_nPeds || !_agentSrcManager.IsCompleted() ) && t < maxSimTime)
{
t = 0 + (frameNr - 1) * _deltaT;
//process the queue for incoming pedestrians
ProcessAgentsQueue();
if(t>Pedestrian::GetMinPremovementTime())
{
//update the linked cells
_building->UpdateGrid();
//update the linked cells
_building->UpdateGrid();
// update the positions
_operationalModel->ComputeNextTimeStep(t, _deltaT, _building.get());
// update the positions
_operationalModel->ComputeNextTimeStep(t, _deltaT, _building.get());
//update the routes and locations
UpdateRoutesAndLocations();
//update the events
_em->ProcessEvent();
//update the events
//_em->Update_Events(t);
_em->ProcessEvent();
//update the routes and locations
UpdateRoutesAndLocations();
//other updates
//someone might have left the building
_nPeds = _building->GetAllPedestrians().size();
}
//other updates
//someone might have left the building
_nPeds = _building->GetAllPedestrians().size();
}
// update the global time
Pedestrian::SetGlobalTime(t);
......@@ -528,7 +528,8 @@ int Simulation::RunBody(double maxSimTime)
if (0 == frameNr % writeInterval) {
_iod->WriteFrame(frameNr / writeInterval, _building.get());
}
Log->ProgressBar(initialnPeds, initialnPeds - _building->GetAllPedestrians().size() , t);
Log->ProgressBar(initialnPeds, initialnPeds - _nPeds , t);
// needed to control the execution time PART 2
// time(&endtime);
// double timeToWait=t-difftime(endtime, starttime);
......@@ -571,5 +572,5 @@ AgentsSourcesManager& Simulation::GetAgentSrcManager()
Building* Simulation::GetBuilding()
{
return _building.get();
return _building.get();
}
......@@ -82,11 +82,16 @@ EventManager::EventManager(Building *_b)
//generate random number between 0 and 1 uniformly distributed
_rdDistribution = std::uniform_real_distribution<double> (0,1);
std::random_device rd;
_rdGenerator=std::mt19937(rd());
//std::random_device rd;
//_rdGenerator=std::mt19937(rd());
_rdGenerator=std::mt19937(23);
//save the first graph
CreateRoutingEngine(_b, true);
//create and
CreateSomeEngine();
}
EventManager::~EventManager()
......@@ -202,9 +207,9 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
//actualize the information about the newly closed door
if(door.second->IsOpen()==false)
{
ped->AddKnownClosedDoor(door.first, Pedestrian::GetGlobalTime());
//1.0 because the information is sure
ped->AddKnownClosedDoor(door.first, Pedestrian::GetGlobalTime(), !door.second->IsOpen(),_updateFrequency,1.0);
ped->SetNewEventFlag(true);
}
}
}
......@@ -214,8 +219,14 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
vector<Pedestrian*> informant;
for(auto&& ped:_b->GetAllPedestrians())
{
if (ped->GetNewEventFlag())
//if (ped->GetNewEventFlag())
informant.push_back(ped);
for(auto&& info: ped->GetKnownledge())
{
info.second.DecreaseLatency(_updateFrequency);
}
}
......@@ -231,7 +242,8 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
vector<SubRoom*> empty;
if(_b->IsVisible(ped1->GetPos(),ped2->GetPos(),empty))
{
//SynchronizeKnowledge(ped1, ped2); //ped1->SetSpotlight(true);
//if(SynchronizeKnowledge(ped1, ped2)) //ped1->SetSpotlight(true);
//if(MergeKnowledgeUsingProbability(ped1, ped2))
if(MergeKnowledge(ped1, ped2))
{
//p2 is now an informant
......@@ -246,6 +258,7 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
if(informant.size()==_b->GetAllPedestrians().size())
{
//Log->Write("INFO:\t all pedestrians are now propagating information");
for(auto&& ped:_b->GetAllPedestrians())
ped->SetNewEventFlag(false);
}
......@@ -275,7 +288,8 @@ bool EventManager::UpdateAgentKnowledge(Building* _b)
//Clear the memory and attempt to reroute
//this can happen if all doors are known to be closed
ped->ClearKnowledge();
//Log->Write("ERROR: \t clearing ped knowledge");
Log->Write("ERROR: \t clearing ped knowledge");
//ped->Dump(ped->GetID());
if(UpdateRoute(ped)==false)
{
Log->Write("ERROR: \t cannot reroute the pedestrian. unknown problem");
......@@ -353,63 +367,139 @@ bool EventManager::SynchronizeKnowledge(Pedestrian* p1, Pedestrian* p2)
p2->ClearKnowledge();
for (auto&& info : merge_info)
{
p1->AddKnownClosedDoor(info.first, info.second.GetTime());
p2->AddKnownClosedDoor(info.first, info.second.GetTime());
p1->AddKnownClosedDoor(info.first, info.second.GetTime(),
info.second.GetState(), info.second.GetQuality(),_updateFrequency);
p2->AddKnownClosedDoor(info.first, info.second.GetTime(),
info.second.GetState(), info.second.GetQuality(),_updateFrequency);
}
return true;
}
bool EventManager::MergeKnowledgeUsingProbability(Pedestrian* p1, Pedestrian* p2)
{
auto const & old_info1 = p1->GetKnownledge();
auto const & old_info2 = p2->GetKnownledge();
map<int, Knowledge> merge_info;
//collect the most recent knowledge
//only the knowledge that has been accepted
for (auto&& info1 : old_info1)
{
merge_info[info1.first] = info1.second;
}
for (auto&& info2 : old_info2)
{
//update infos according to a newest time
if (merge_info.count(info2.first) > 0)
{
if (info2.second.GetTime() > merge_info[info2.first].GetTime())
// and the quality
// only if I never refused that information
{
merge_info[info2.first] = info2.second;
}
}
else //the info was not present, just add
{
merge_info[info2.first] = info2.second;
}
}
//synchronize the knowledge
//accept the information with a certain probability
if(_rdDistribution(_rdGenerator)< (1-p1->GetRiskTolerance()))
{
//p1->ClearKnowledge();
p2->ClearKnowledge();
for (auto&& info : merge_info)
{
p2->AddKnownClosedDoor(info.first, info.second.GetTime(),info.second.GetState(),_updateFrequency,1.0);
}
//p2->SetSpotlight(false);
return true;
}
else
{
cout<<"refusing the information:"<<p2->GetID()<<endl;
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
//p2->SetSpotlight(true);
//exit(0);
return false;
}
}
bool EventManager::MergeKnowledge(Pedestrian* p1, Pedestrian* p2)
{
auto const & old_info1 = p1->GetKnownledge();
auto const & old_info2 = p2->GetKnownledge();
map<int, Knowledge> merge_info;
//collect the most recent knowledge
for (auto&& info1 : old_info1)
{
merge_info[info1.first] = info1.second;
}
for (auto&& info2 : old_info2)
{
//update infos according to a newest time
if (merge_info.count(info2.first) > 0)
{
if (info2.second.GetTime() > merge_info[info2.first].GetTime())
{
merge_info[info2.first] = info2.second;
}
}
else //the info was not present, just add
{
merge_info[info2.first] = info2.second;
}
}
//synchronize the knowledge
//accept the information with a certain probability
//cout<<_rdDistribution(_rdGenerator)<<endl;
if(_rdDistribution(_rdGenerator)< (1-p1->GetRiskTolerance()))
{
//p1->ClearKnowledge();
p2->ClearKnowledge();
for (auto&& info : merge_info)
{
//p1->AddKnownClosedDoor(info.first, info.second.GetTime());
p2->AddKnownClosedDoor(info.first, info.second.GetTime());
}
//p2->SetSpotlight(false);
return true;
}
else
{
cout<<"refusing the information:"<<p2->GetID()<<endl;
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
//p2->SetSpotlight(true);
//exit(0);
return false;
}
auto & old_info2 = p2->GetKnownledge();
//accept the new information
if(_rdDistribution(_rdGenerator)< (1-p1->GetRiskTolerance()))
{
for (const auto& info1 : old_info1)
{
//I dont forward information that I refused already
if(info1.second.HasBeenRefused()) continue;
// Is the latency ok ?
if(!info1.second.CanBeForwarded()) continue;
//do I already have that information ?
if (old_info2.count(info1.first) > 0)
{
//only accept if it is newer
if (info1.second.GetTime() > old_info2[info1.first].GetTime())
{
//maybe I already refused that information earlier. Keep refusing
if(old_info2[info1.first].HasBeenRefused()==false)
{
old_info2[info1.first]=info1.second;
//alter the quality of the info
old_info2[info1.first].SetQuality(0.5);
old_info2[info1.first].SetLatency(_updateFrequency);
}
}
}
else
{
//new piece of information
old_info2[info1.first]=info1.second;
//alter the quality of the info
old_info2[info1.first].SetQuality(0.5);
old_info2[info1.first].SetLatency(_updateFrequency);
}
}
return true;
}
//refuse the new information
else
{
for (const auto& info1 : old_info1)
{
if (old_info2.count(info1.first) > 0)
{
old_info2[info1.first].Refuse(true);
old_info2[info1.first].SetLatency(_updateFrequency);
//cout<<"refusing present: "<<p2->GetID()<<endl;
}
else
{//refuse the information and set a bad quality
old_info2[info1.first]=info1.second;
//alter the quality of the info
old_info2[info1.first].SetQuality(0.0);
old_info2[info1.first].Refuse(true);
old_info2[info1.first].SetLatency(_updateFrequency);
//cout<<"refusing: "<<p2->GetID()<<endl;
}
}
//p2->SetSpotlight(true);
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
cout<<"refusing..."<<p2->GetID()<<endl;
return false;
}
}
void EventManager::ProcessEvent()
......@@ -426,7 +516,7 @@ void EventManager::ProcessEvent()
UpdateAgentKnowledge(_building);
//actualize based on the new knowledge
_lastUpdateTime = current_time;
//cout<<"updating..."<<current_time<<endl<<endl;
//cout<<"update: "<<current_time<<endl;
}
//update the building state
......@@ -561,9 +651,6 @@ bool EventManager::CreateRoutingEngine(Building* _b, int first_engine)
// create a new one with the actual configuration
if (_eventEngineStorage.count(key)==0)
{
//std::shared_ptr<RoutingEngine> engine = std::shared_ptr<RoutingEngine>(new RoutingEngine());
//engine.get()->Init(_b);
//_eventEngineStorage[key]=engine.get();
//populate the engine with the routers defined in the ini file
//and initialize
......@@ -631,4 +718,49 @@ Router * EventManager::CreateRouter(const RoutingStrategy& strategy)
return rout;
}
void EventManager::CreateSomeEngine()
{
Log->Write("INFO: \tpopulating routers");
std::map<int, bool> doors_states;
//save the doors states
for(auto&& t:_building->GetAllTransitions())
{
doors_states[t.second->GetID()]= t.second->IsOpen();
}
//open all doors
for(auto&& t:_building->GetAllTransitions())
{
t.second->Open();
}
//close the doors one by one and create engines
for(auto&& t1:_building->GetAllTransitions())
{
for(auto&& t2:_building->GetAllTransitions())
{
t2.second->Open();
}
t1.second->Close();
//create the engine;
CreateRoutingEngine(_building, false);
}
//restore the door states
for(auto&& t:_building->GetAllTransitions())
{
if (doors_states[t.second->GetID()])
{
t.second->Open();
}
else
{
t.second->Close();
}
}
Log->Write("INFO: \tdone");
}
......@@ -120,6 +120,9 @@ private:
*/
bool MergeKnowledge(Pedestrian* p1, Pedestrian* p2);
bool MergeKnowledgeUsingProbability(Pedestrian* p1, Pedestrian* p2);
/**
* Update the pedestrian route based on the new information
* @param p1
......@@ -127,6 +130,7 @@ private:
*/
bool UpdateRoute(Pedestrian* p1);
void CreateSomeEngine();
private:
......
......@@ -1257,16 +1257,19 @@ void Building::DeletePedestrian(Pedestrian* &ped)
}
}
_allPedestians.erase(it);
}
//update the stats before deleting
Transition* trans =GetTransitionByUID(ped->GetExitIndex());
if(trans)
{
trans->IncreaseDoorUsage(1, ped->GetGlobalTime());
//this can happen if the pedesrians is pushed too hard
// or cant stop due to high velocity
// he will remain in the simulation in that case
if(trans->IsOpen()==false) return;
}
_allPedestians.erase(it);
delete ped;
//ped=nullptr;
}
const vector<Pedestrian*>& Building::GetAllPedestrians() const
......
......@@ -27,8 +27,6 @@
#include "Knowledge.h"
#include "../IO/OutputHandler.h"
extern OutputHandler* Log;
Knowledge::Knowledge()
{
......@@ -36,22 +34,29 @@ Knowledge::Knowledge()
_time = 0;
_quality=1;
_id=-1;
_hasBeenRefusedOnce=false;
_latency=0.0;
}
Knowledge::~Knowledge()
{
}
void Knowledge::Dump()
std::string Knowledge::Dump()
{
Log->Write("INFO: \tdoor [%d] state [%d] since [%f]\n",_id,_isClosed,_time);
char tmp[2048];
sprintf(tmp,"door [%d] state [%d] since [%.2f] sec. Refused= %d, Quality=%.2f, latency=%.2f",_id,_isClosed,_time,_hasBeenRefusedOnce,_quality,_latency);
return std::string(tmp);
}
void Knowledge::SetState(int id, bool is_closed, double time)
void Knowledge::SetState(int id, bool is_closed, double time, double quality, double latency, bool refuse)
{
_isClosed=is_closed;
_time=time;
_id=id;
_quality=quality;
_hasBeenRefusedOnce=refuse;
_latency=latency;
}
bool Knowledge::GetState() const
......@@ -64,7 +69,44 @@ double Knowledge::GetQuality() const
return _quality;
}
void Knowledge::SetQuality(double quality)
{
_quality=quality;
}
double Knowledge::GetTime() const
{
return _time;
}
bool Knowledge::HasBeenRefused() const
{
return _hasBeenRefusedOnce;
}
void Knowledge::Refuse(bool state)
{
_hasBeenRefusedOnce=state;
}
bool Knowledge::CanBeForwarded() const
{
return (_latency<=0);
}
void Knowledge::SetLatency(double latency)
{
_latency=latency;
}
double Knowledge::GetLatency() const
{
return _latency;
}
void Knowledge::DecreaseLatency(double minus)
{
_latency = _latency - minus;
if (_latency <= 0)
_latency = 0.0;
}
......@@ -43,12 +43,76 @@ public:
*/
~Knowledge();
void Dump();
void SetState(int id, bool is_closed, double time);
/**
* Initialize the knowledge
* @param id
* @param is_closed
* @param time
* @param quality
* @param refuse
*/
void SetState(int id, bool is_closed, double time, double quality, double latency, bool refuse=false);
/**
* @return the state of the object. close or open
*/
bool GetState() const;
/**
* transmitted knowledge have a lower quality than those gathered by oneself.
* @return the quality of the knowledge
*/
double GetQuality() const;
/**
* transmitted knowledge have a lower quality than those gathered by oneself.
* @return the quality of the knowledge
*/
void SetQuality(double quality);
/**
* When was the event recorded
*/
double GetTime() const;
/**
* @return whether this knowledge has been refused before
*/
bool HasBeenRefused() const;
/**
* store but refuse the knowledge.
* @param state
*/
void Refuse(bool state);
/**
* print the content of the knowledge as string
*/
std::string Dump();
/**
* @return true, if the information can be forwarded
*/
bool CanBeForwarded() const;
/**
* Set/Get the latency time before forwarding the information
*/
void SetLatency(double latency);
/**
* Set/Get the latency time before forwarding the information
*/
double GetLatency() const;
/**
* Update the latency by reducing the specified time.
* The latency will eventually be 0 and the information will be forwarded.
* @param minus
*/
void DecreaseLatency(double minus);
private:
/// information quality in [0..1]. 1 is very reliable information
double _quality; //
......@@ -59,7 +123,9 @@ private:
/// id of the door
int _id;
/// whether I already accepted or refused that information
bool _refusedOnce;
bool _hasBeenRefusedOnce;
/// time to retain this information before forwarding
double _latency;
};
#endif /* KNOWLEDGE_H_ */
......
......@@ -329,10 +329,10 @@ void Pedestrian::ClearMentalMap()
_exitIndex = -1;
}
void Pedestrian::AddKnownClosedDoor(int door, double time)
void Pedestrian::AddKnownClosedDoor(int door, double ttime, bool state, double quality, double latency)
{
if(time==0) time=_globalTime;
_knownDoors[door].SetState(door,true,time);
if(ttime==0) ttime=_globalTime;
_knownDoors[door].SetState(door,state,ttime,quality, latency);
}
void Pedestrian::ClearKnowledge()
......@@ -340,7 +340,7 @@ void Pedestrian::ClearKnowledge()
_knownDoors.clear();
}
const map<int, Knowledge>& Pedestrian::GetKnownledge() const
map<int, Knowledge>& Pedestrian::GetKnownledge()
{
return _knownDoors;
}
......@@ -350,6 +350,9 @@ const std::string Pedestrian::GetKnowledgeAsString() const
string key="";
for(auto&& knowledge:_knownDoors)
{
//skip low quality information
if(knowledge.second.GetQuality()<0.2) continue;
int door=knowledge.first;
if(key.empty())
key.append(std::to_string(door));
......@@ -765,6 +768,10 @@ void Pedestrian::Dump(int ID, int pa)
printf(">> mental map");