Commit 7fcb7c5b authored by Mohcine Chraibi's avatar Mohcine Chraibi

Add flag to SrcManager to mark building update

Source thread updates the Queues, but the building is not updated yet.
That leads, to the same agents will be generated by the sources
and added to the Queue.
The queue will be emptied in the main thread.

Therefore, the source thread should not iterate again, unless the
main thread empties the queues and updated the building pointer
parent 686eac90
......@@ -60,6 +60,7 @@ void AgentsSourcesManager::Run()
//Generate all agents required for the complete simulation
//It might be more efficient to generate at each frequency step
//TODO this loop is exactly GenerateAgents( --> REFACTOR)
for (const auto& src : _sources)
{
src->GenerateAgentsAndAddToPool(src->GetMaxAgents(), _building);
......@@ -72,57 +73,100 @@ void AgentsSourcesManager::Run()
//it might be better to use a timer
_isCompleted = false;
bool finished = false;
SetBuildingUpdated(false);
long updateFrequency = 1; //TODO parse this from inifile
//std::cout << KMAG << "RUN Starting thread manager with _lastUpdateTime " << _lastUpdateTime<< std::endl;
do
{ //@todo: break if max simulation time is reached.
int current_time = (int)Pedestrian::GetGlobalTime();
if ((current_time != _lastUpdateTime)
&& ((current_time % updateFrequency) == 0))
&& ((current_time % updateFrequency) == 0))
{
// std::cout << ">> RUN: current_time " << current_time << " last update " << _lastUpdateTime << std::endl;
finished=ProcessAllSources();
_lastUpdateTime = current_time;
}
//wait some time
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
// wait for main thread to update building
while(! IsBuildingUpdated())
{
std::cout << " sourceManager waiting ... \n";
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
SetBuildingUpdated(false);
std::cout << " NOT waiting ... \n";
} while (!finished);
Log->Write("INFO:\tTerminating agent manager thread");
_isCompleted = true;
// std::cout << "Terminating agent manager thread" << RESET << std::endl;
Log->Write("INFO:\tTerminating agent manager thread");
_isCompleted = true;
}
bool AgentsSourcesManager::ProcessAllSources() const
{
bool empty=true;
double current_time = Pedestrian::GetGlobalTime();
for (const auto& src : _sources)
bool AgentsSourcesManager::ProcessAllSources() const
{
std::cout << "src: " << src->GetId() << " -- current time: " << current_time << " number of peds " << _building->GetAllPedestrians().size() << std::endl;
if (src->GetPoolSize() && (src->GetPlanTime() <= current_time) )// maybe diff<eps
std::cout << "\nSTART AgentsSourcesManager::ProcessAllSources()\n";
bool empty=true;
double current_time = Pedestrian::GetGlobalTime();
for(auto pp: _building->GetAllPedestrians())
std::cout<< KMAG << "BUL: agentssourcesManager: " << pp->GetPos()._x << ", " << pp->GetPos()._y << RESET << std::endl;
for (const auto& src : _sources)
{
vector<Pedestrian*> peds;
src->RemoveAgentsFromPool(peds,src->GetFrequency());
Log->Write("> INFO:\tSource %d generating %d agents (%d remaining)\n",src->GetId(),peds.size(),src->GetPoolSize());
//ComputeBestPositionRandom(src.get(), peds);
//todo: here every pedestrian needs an exitline
if( !ComputeBestPositionVoronoiBoost(src.get(), peds, _building) )
Log->Write("WARNING:\tThere was no place for some pedestrians");
AgentsQueueIn::Add(peds);
empty = false;
src->Dump();
std::cout << KRED << "\nprocessing src: " << src->GetId() << " -- current time: " << current_time << " number of peds in building " << _building->GetAllPedestrians().size() << RESET << std::endl;
// for(auto pp: _building->GetAllPedestrians()) std::cout<< KYEL << "BUL: agentssourcesManager: " << pp->GetPos()._x << ", " << pp->GetPos()._y << RESET << std::endl;
if (src->GetPoolSize() && (src->GetPlanTime() <= current_time) )// maybe diff<eps
{
vector<Pedestrian*> peds;
src->RemoveAgentsFromPool(peds, src->GetFrequency());
Log->Write("> INFO:\tSource %d generating %d agents (%d remaining)\n",src->GetId(),peds.size(),src->GetPoolSize());
//ComputeBestPositionRandom(src.get(), peds);
//todo: here every pedestrian needs an exitline
std::cout << "\tCalling ComputeBestPositionVoronoiBoost\n";
if( !ComputeBestPositionVoronoiBoost(src.get(), peds, _building) )
Log->Write("WARNING:\tThere was no place for some pedestrians");
for (auto p: peds)
std::cout<< KGRN << "PED: agentssourcesManager: " << p->GetPos()._x << ", " << p->GetPos()._y << RESET << std::endl;
for(auto pp: _building->GetAllPedestrians()) std::cout<< KBLU << "In source BUL: agentssourcesManager: " << pp->GetPos()._x << ", " << pp->GetPos()._y << RESET << std::endl;
std::cout << "ADD TO QUEUE " << peds.size() << std::endl;
AgentsQueueIn::Add(peds);
empty = false;
src->Dump();
}
if (src->GetPlanTime() > current_time) // for the case we still expect
// agents coming
empty = false;
//src->Dump();//exit(0);
}
if (src->GetPlanTime() > current_time) // for the case we still expect
// agents coming
empty = false;
//src->Dump();//exit(0);
std::cout << "LEAVE AgentsSourcesManager::ProcessAllSources()\n";
std::cout << " Source building: "<< _building << " size " << _building->GetAllPedestrians().size()<< std::endl;
for(auto pp: _building->GetAllPedestrians())
std::cout<< KBLU << "BUL: agentssourcesManager: " << pp->GetPos()._x << ", " << pp->GetPos()._y << RESET << std::endl;
std::cout << "========================\n";
//
return empty;
}
return empty;
}
//4 agents frequency, just for an example
void AgentsSourcesManager::ComputeBestPositionDummy(AgentsSource* src,
vector<Pedestrian*>& peds)const
vector<Pedestrian*>& peds)const
{
UNUSED(src);
peds[0]->SetPos( Point(10,5.5) );
......@@ -131,8 +175,8 @@ void AgentsSourcesManager::ComputeBestPositionDummy(AgentsSource* src,
peds[3]->SetPos( Point(10,3.7) );
/*peds[0]->SetPos( Point(10,5.4) );
peds[1]->SetPos( Point(10,4.6) );
peds[2]->SetPos( Point(10,3.8) );*/
peds[1]->SetPos( Point(10,4.6) );
peds[2]->SetPos( Point(10,3.8) );*/
for(auto&& ped : peds)
{
......@@ -144,12 +188,12 @@ void AgentsSourcesManager::ComputeBestPositionDummy(AgentsSource* src,
}
void AgentsSourcesManager::ComputeBestPositionCompleteRandom(AgentsSource* src,
vector<Pedestrian*>& peds)const
vector<Pedestrian*>& peds)const
{
auto dist = src->GetStartDistribution();
auto subroom = _building->GetRoom(dist->GetRoomId())->GetSubRoom(dist->GetSubroomID());
vector<Point> positions = PedDistributor::PossiblePositions(*subroom);
double seed = time(NULL);
double seed = time(0);
//TODO: get the seed from the simulation
std:: cout << "seed: "<< seed << std::endl;
......@@ -177,134 +221,134 @@ void AgentsSourcesManager::ComputeBestPositionCompleteRandom(AgentsSource* src,
}
/*
void AgentsSourcesManager::ComputeBestPositionVoronoi(AgentsSource* src,
Pedestrian* agent) const
{
auto dist = src->GetStartDistribution();
double bounds[4];
dist->Getbounds(bounds);
int roomID = dist->GetRoomId();
int subroomID = dist->GetSubroomID();
//Get all pedestrians in that location
vector<Pedestrian*> peds;
_building->GetPedestrians(roomID, subroomID, peds);
//filter the points that are not within the boundaries
for (auto&& iter = peds.begin(); iter != peds.end();)
{
const Point& pos = (*iter)->GetPos();
if ((bounds[0] <= pos._x && pos._x <= bounds[1])
&& (bounds[1] <= pos._y && pos._y <= bounds[2]))
{
iter = peds.erase(iter);
cout << "removing (testing only)..." << endl;
exit(0);
} else
{
++iter;
}
}
//special case with 1, 2 or only three pedestrians in the area
if (peds.size() < 3)
{
//TODO/random position in the area
return;
}
// compute the cells and cut with the bounds
const int count = peds.size();
float* xValues = new float[count];
float* yValues = new float[count];
//float xValues[count];
//float yValues[count];
for (int i = 0; i < count; i++)
{
xValues[i] = peds[i]->GetPos()._x;
yValues[i] = peds[i]->GetPos()._y;
}
VoronoiDiagramGenerator vdg;
vdg.generateVoronoi(xValues, yValues, count, bounds[0], bounds[1],
bounds[2], bounds[3], 3);
vdg.resetIterator();
vdg.resetVerticesIterator();
printf("\n------vertices---------\n");
//collect the positions
vector<Point> positions;
float x1, y1;
while (vdg.getNextVertex(x1, y1))
{
printf("GOT Point (%f,%f)\n", x1, y1);
positions.push_back(Point(x1, y1));
}
//look for the biggest spot
map<double, Point> map_dist_to_position;
for (auto&& pos : positions)
{
double min_dist = FLT_MAX;
for (auto&& ped : peds)
{
double dist = (pos - ped->GetPos()).NormSquare();
if (dist < min_dist)
{
min_dist = dist;
}
}
map_dist_to_position[min_dist] = pos;
}
//list the result
for (auto&& mp : map_dist_to_position)
{
cout << "dist: " << mp.first << " pos: " << mp.second.toString()
<< endl;
//agent->SetPos(mp.second, true);
}
//the elements are ordered.
// so the last one has the largest distance
if (!map_dist_to_position.empty())
{
agent->SetPos(map_dist_to_position.rbegin()->second, true);
cout << "position:" << agent->GetPos().toString() << endl;
//exit(0);
} else
{
cout << "position not set:" << endl;
cout << "size: " << map_dist_to_position.size() << endl;
cout << " for " << peds.size() << " pedestrians" << endl;
exit(0);
}
//exit(0);
// float x1,y1,x2,y2;
//while(vdg.getNext(x1,y1,x2,y2))
//{
// printf("GOT Line (%f,%f)->(%f,%f)\n",x1,y1,x2, y2);
//
//}
//compute the best position
//exit(0);
}
*/
void AgentsSourcesManager::ComputeBestPositionVoronoi(AgentsSource* src,
Pedestrian* agent) const
{
auto dist = src->GetStartDistribution();
double bounds[4];
dist->Getbounds(bounds);
int roomID = dist->GetRoomId();
int subroomID = dist->GetSubroomID();
//Get all pedestrians in that location
vector<Pedestrian*> peds;
_building->GetPedestrians(roomID, subroomID, peds);
//filter the points that are not within the boundaries
for (auto&& iter = peds.begin(); iter != peds.end();)
{
const Point& pos = (*iter)->GetPos();
if ((bounds[0] <= pos._x && pos._x <= bounds[1])
&& (bounds[1] <= pos._y && pos._y <= bounds[2]))
{
iter = peds.erase(iter);
cout << "removing (testing only)..." << endl;
exit(0);
} else
{
++iter;
}
}
//special case with 1, 2 or only three pedestrians in the area
if (peds.size() < 3)
{
//TODO/random position in the area
return;
}
// compute the cells and cut with the bounds
const int count = peds.size();
float* xValues = new float[count];
float* yValues = new float[count];
//float xValues[count];
//float yValues[count];
for (int i = 0; i < count; i++)
{
xValues[i] = peds[i]->GetPos()._x;
yValues[i] = peds[i]->GetPos()._y;
}
VoronoiDiagramGenerator vdg;
vdg.generateVoronoi(xValues, yValues, count, bounds[0], bounds[1],
bounds[2], bounds[3], 3);
vdg.resetIterator();
vdg.resetVerticesIterator();
printf("\n------vertices---------\n");
//collect the positions
vector<Point> positions;
float x1, y1;
while (vdg.getNextVertex(x1, y1))
{
printf("GOT Point (%f,%f)\n", x1, y1);
positions.push_back(Point(x1, y1));
}
//look for the biggest spot
map<double, Point> map_dist_to_position;
for (auto&& pos : positions)
{
double min_dist = FLT_MAX;
for (auto&& ped : peds)
{
double dist = (pos - ped->GetPos()).NormSquare();
if (dist < min_dist)
{
min_dist = dist;
}
}
map_dist_to_position[min_dist] = pos;
}
//list the result
for (auto&& mp : map_dist_to_position)
{
cout << "dist: " << mp.first << " pos: " << mp.second.toString()
<< endl;
//agent->SetPos(mp.second, true);
}
//the elements are ordered.
// so the last one has the largest distance
if (!map_dist_to_position.empty())
{
agent->SetPos(map_dist_to_position.rbegin()->second, true);
cout << "position:" << agent->GetPos().toString() << endl;
//exit(0);
} else
{
cout << "position not set:" << endl;
cout << "size: " << map_dist_to_position.size() << endl;
cout << " for " << peds.size() << " pedestrians" << endl;
exit(0);
}
//exit(0);
// float x1,y1,x2,y2;
//while(vdg.getNext(x1,y1,x2,y2))
//{
// printf("GOT Line (%f,%f)->(%f,%f)\n",x1,y1,x2, y2);
//
//}
//compute the best position
//exit(0);
}
*/
void AgentsSourcesManager::ComputeBestPositionRandom(AgentsSource* src,
std::vector<Pedestrian*>& peds) const
std::vector<Pedestrian*>& peds) const
{
//generate the agents with default positions
auto dist = src->GetStartDistribution();
auto subroom = _building->GetRoom(dist->GetRoomId())->GetSubRoom(
dist->GetSubroomID());
dist->GetSubroomID());
vector<Point> positions = PedDistributor::PossiblePositions(*subroom);
double bounds[4] = { 0, 0, 0, 0 };
dist->Getbounds(bounds);
......@@ -330,28 +374,28 @@ void AgentsSourcesManager::ComputeBestPositionRandom(AgentsSource* src,
//cout<<"checking: "<<pos.toString()<<endl;
// for positions inside bounds, check it there is enough space
if ((bounds[0] <= pos._x) && (pos._x <= bounds[1])
&& (bounds[2] <= pos._y) && (pos._y < bounds[3]))
&& (bounds[2] <= pos._y) && (pos._y < bounds[3]))
{
bool enough_space = true;
bool enough_space = true;
//checking enough space!!
vector<Pedestrian*> neighbours;
_building->GetGrid()->GetNeighbourhood(pos,neighbours);
//checking enough space!!
vector<Pedestrian*> neighbours;
_building->GetGrid()->GetNeighbourhood(pos,neighbours);
for (const auto& ngh: neighbours)
if( (ngh->GetPos() - pos).NormSquare() < 4*radius*radius )
{
enough_space = false;
break;
}
for (const auto& ngh: neighbours)
if( (ngh->GetPos() - pos).NormSquare() < 4*radius*radius )
{
enough_space = false;
break;
}
if( enough_space )
{
index = a;
break;
}
if( enough_space )
{
index = a;
break;
}
}
}
......@@ -360,8 +404,8 @@ void AgentsSourcesManager::ComputeBestPositionRandom(AgentsSource* src,
if (positions.size())
{
Log->Write(
"ERROR:\t AgentSourceManager Cannot distribute pedestrians in the mentioned area [%0.2f,%0.2f,%0.2f,%0.2f]",
bounds[0], bounds[1], bounds[2], bounds[3]);
"ERROR:\t AgentSourceManager Cannot distribute pedestrians in the mentioned area [%0.2f,%0.2f,%0.2f,%0.2f]",
bounds[0], bounds[1], bounds[2], bounds[3]);
Log->Write(" \t Specifying a subroom_id might help");
Log->Write(" \t %d positions were available",positions.size());
//exit(EXIT_FAILURE);
......@@ -374,23 +418,23 @@ void AgentsSourcesManager::ComputeBestPositionRandom(AgentsSource* src,
{
const Point& pos = positions[index];
extra_positions.push_back(pos);
(*iter_ped)->SetPos(pos, true); //true for the initial position
positions.erase(positions.begin() + index);
extra_positions.push_back(pos);
(*iter_ped)->SetPos(pos, true); //true for the initial position
positions.erase(positions.begin() + index);
//at this point we have a position
//so we can adjust the velocity
//AdjustVelocityUsingWeidmann(ped);
AdjustVelocityByNeighbour( (*iter_ped) );
//move iterator
iter_ped++;
//at this point we have a position
//so we can adjust the velocity
//AdjustVelocityUsingWeidmann(ped);
AdjustVelocityByNeighbour( (*iter_ped) );
//move iterator
iter_ped++;
}
//return the pedestrians without place
}
if(peds_without_place.size()>0)
src->AddAgentsToPool(peds_without_place);
src->AddAgentsToPool(peds_without_place);
}
void AgentsSourcesManager::AdjustVelocityByNeighbour(Pedestrian* ped) const
......@@ -490,7 +534,7 @@ void AgentsSourcesManager::AdjustVelocityUsingWeidmann(Pedestrian* ped) const
}
else
{
Log->Write(">>> ERROR:\t no route could be found for agent [%d] going to [%d]",ped->GetID(),ped->GetFinalDestination());
Log->Write(">>> SOURCE ERROR:\t no route could be found for agent [%d] going to [%d]",ped->GetID(),ped->GetFinalDestination());
//that will be most probably be fixed in the next computation step.
// so do not abort
}
......@@ -512,8 +556,8 @@ void AgentsSourcesManager::SortPositionByDensity(std::vector<Point>& positions,
for(const auto& p: neighbours)
{
//FIXME: p can be null, if deleted in the main simulation thread.
if( p && (pt-p->GetPos()).NormSquare()<=radius_square)
//FIXME: p can be null, if deleted in the main simulation thread.
if( p && (pt-p->GetPos()).NormSquare()<=radius_square)
density+=1.0;
}
......@@ -571,6 +615,16 @@ bool AgentsSourcesManager::IsCompleted() const
}
bool AgentsSourcesManager::IsBuildingUpdated() const
{
return _buildingUpdated;
}
void AgentsSourcesManager::SetBuildingUpdated(bool update)
{
_buildingUpdated = update;
}
Building* AgentsSourcesManager::GetBuilding() const
{
return _building;
......
......@@ -91,6 +91,14 @@ public:
*/
bool IsCompleted() const;
/**
* @return true if the building is updated
*
*/
bool IsBuildingUpdated() const;
void SetBuildingUpdated(bool update);
/**
* Return a pointer to the building object
*/
......@@ -170,6 +178,8 @@ private:
/// whether all agents have been dispatched
static bool _isCompleted;
//std::atomic<bool>_isCompleted=false;
// std::atomic<bool>_buildingUpdated=false;
bool _buildingUpdated;
};
#endif /* AGENTSSOURCESMANAGER_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment