Commit 311f63fa authored by Mohcine Chraibi's avatar Mohcine Chraibi

Merge branch '158' into 'develop'

Issue 158

See merge request !21
parents 60b744d8 2d1fb525
Pipeline #9289 failed with stages
in 5 minutes and 7 seconds
......@@ -6,8 +6,8 @@ before_script:
- nproc=`grep -c '^processor' /proc/cpuinfo`
- echo "nproc = $nproc"
- export LD_LIBRARY_PATH=$HOME/boost_1_61_0/stage/lib/:$LD_LIBRARY_PATH
#========== Pipeline ==================
stages:
- configure
......@@ -46,7 +46,7 @@ make-linux:
- lib
- lib/Debug
- bin
stage: compile
tags:
- linux
......@@ -54,13 +54,14 @@ make-linux:
- cd build
- make -j$nproc
- echo "compile | ${CI_PROJECT_DIR}"
tags:
- linux
#============== unit_test ============
test:
dependencies:
- make-linux
stage: unit_test
stage: unit_test
script:
- cd build
- ctest -R Boost
......@@ -75,7 +76,7 @@ verification:
script:
- cd build
- ctest -R juelich
only:
only:
- develop
tags:
- linux
......@@ -90,7 +91,7 @@ verification:
# script:
# - cd build
# - ctest -R rimea
# only:
# only:
# - develop
# tags:
# - linux
......@@ -105,7 +106,7 @@ verification:
# script:
# - cd build
# - ctest -R validation
# only:
# only:
# - develop
# tags:
# - linux
......
......@@ -35,7 +35,7 @@
#include "math/GompertzModel.h"
#include "math/GradientModel.h"
#include "pedestrian/AgentsQueue.h"
#include "pedestrian/AgentsSourcesManager.h"
#ifdef _OPENMP
#else
......@@ -61,6 +61,7 @@ Simulation::Simulation(Configuration* args)
_fps = 1;
_em = nullptr;
_gotSources = false;
_maxSimTime = 100;
// _config = args;
}
......@@ -201,6 +202,7 @@ bool Simulation::InitArgs()
sprintf(tmp, "\tt_max: %f\n", _config->GetTmax());
s.append(tmp);
_deltaT = _config->Getdt();
_maxSimTime = _config->GetTmax();
sprintf(tmp, "\tdt: %f\n", _deltaT);
_periodic = _config->IsPeriodic();
sprintf(tmp, "\t periodic: %d\n", _periodic);
......@@ -214,10 +216,11 @@ bool Simulation::InitArgs()
_routingEngine = _config->GetRoutingEngine();
auto distributor = std::unique_ptr<PedDistributor>(new PedDistributor(_config));
// IMPORTANT: do not change the order in the following..
_building = std::unique_ptr<Building>(new Building(_config, *distributor));
_building = std::shared_ptr<Building>(new Building(_config, *distributor));
// Initialize the agents sources that have been collected in the pedestrians distributor
_agentSrcManager.SetBuilding(_building.get());
_agentSrcManager.SetMaxSimTime(GetMaxSimTime());
_gotSources = (bool) distributor->GetAgentsSources().size(); // did we have any sources? false if no sources
for (const auto& src: distributor->GetAgentsSources()) {
_agentSrcManager.AddSource(src);
......@@ -529,12 +532,31 @@ void Simulation::RunFooter()
void Simulation::ProcessAgentsQueue()
{
/* std::cout << "Call Simulation::ProcessAgentsQueue() at: " << Pedestrian::GetGlobalTime() << std::endl; */
/* std::cout << KRED << " SIMULATION building " << _building << " size " << _building->GetAllPedestrians().size() << "\n" << RESET; */
/* for(auto pp: _building->GetAllPedestrians()) */
/* std::cout<< KBLU << "BUL: Simulation: " << pp->GetPos()._x << ", " << pp->GetPos()._y << RESET << std::endl; */
//incoming pedestrians
vector<Pedestrian*> peds;
// std::cout << ">>> peds " << peds.size() << RESET<< std::endl;
AgentsQueueIn::GetandClear(peds);
//std::cout << "SIMULATION BEFORE BOOL = " << _agentSrcManager.IsBuildingUpdated() << " peds size " << peds.size() << "\n" ;
//_agentSrcManager.SetBuildingUpdated(true);
/* std::cout << "SIMULATION AFTER BOOL = " << _agentSrcManager.IsBuildingUpdated() << "\n" ; */
for (auto&& ped: peds) {
/* std::cout << "Add to building : " << ped->GetPos()._x << ", " << ped->GetPos()._y << " t: "<< Pedestrian::GetGlobalTime() << std::endl; */
_building->AddPedestrian(ped);
}
// for(auto pp: _building->GetAllPedestrians())
// std::cout<< KBLU << "BUL: Simulation: " << pp->GetPos()._x << ", " << pp->GetPos()._y << " t: "<< Pedestrian::GetGlobalTime() <<RESET << std::endl;
/* std::cout << "LEAVE Simulation::ProcessAgentsQueue() with " << " size " << _building->GetAllPedestrians().size() << "\n" << RESET; */
}
void Simulation::UpdateDoorticks() const {
......@@ -619,3 +641,7 @@ Building* Simulation::GetBuilding()
{
return _building.get();
}
int Simulation::GetMaxSimTime() const{
return _maxSimTime;
}
......@@ -67,7 +67,7 @@ private:
///seed using for the random number generator
unsigned int _seed;
/// building object
std::unique_ptr<Building> _building;
std::shared_ptr<Building> _building;
/// Force model to use
std::shared_ptr<OperationalModel> _operationalModel;
/// Manage all route choices algorithms
......@@ -85,6 +85,8 @@ private:
/// hybrid simulation manager
//HybridSimulationManager
int _periodic;
int _maxSimTime;
bool _gotSources; // is true if we got some sources. Otherwise, false.
// bool _printPB; // print progressbar
public:
......@@ -182,6 +184,8 @@ public:
*
*/
void UpdateDoorticks() const;
int GetMaxSimTime() const;
};
......
......@@ -841,7 +841,7 @@ void Building::AddPedestrian(Pedestrian* ped)
for (unsigned int p = 0; p<_allPedestians.size(); p++) {
Pedestrian* ped1 = _allPedestians[p];
if (ped->GetID()==ped1->GetID()) {
cout << "Pedestrian already in the room ??? " << ped->GetID() << endl;
cout << "Pedestrian " << ped->GetID() << " already in the room." << endl;
return;
}
}
......@@ -1047,5 +1047,3 @@ Transition* Building::GetTransitionByUID(int uid) const
//}
#endif // _SIMULATOR
......@@ -49,7 +49,7 @@ int main(int argc, char** argv)
Configuration* configuration = new Configuration();
// Parsing the arguments
bool status = false;
{
{
//ArgumentParser* p = new ArgumentParser(configuration); //Memory Leak
std::unique_ptr<ArgumentParser> p(new ArgumentParser(configuration));
status = p->ParseArgs(argc, argv);
......@@ -86,8 +86,12 @@ int main(int argc, char** argv)
//Start the thread for managing the sources of agents if any
//std::thread t1(sim.GetAgentSrcManager());
double simMaxTime = configuration->GetTmax();
std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());//@todo pass simMaxTime to Run
//main thread for the simulation
std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());
while(!sim.GetAgentSrcManager().IsRunning())
{
// std::cout << "waiting...\n";
}
//main thread for the simulation
evacTime = sim.RunStandardSimulation(simMaxTime);
//Join the main thread
t1.join();
......@@ -111,7 +115,6 @@ int main(int argc, char** argv)
}
double execTime = difftime(endtime, starttime);
std::stringstream summary;
summary << std::setprecision(2) << std::fixed;
summary << "\nExec Time [s] : " << execTime << std::endl;
......
......@@ -242,7 +242,7 @@ void VelocityModel::ComputeNextTimeStep(double current, double deltaT, Building*
//double winkel = spacings[0].second;
//Point tmp;
Point speed = direction.Normalized() *OptimalSpeed(ped, spacing);
result_acc.push_back(speed);
result_acc.push_back(speed);
spacings.clear(); //clear for ped p
......@@ -358,7 +358,8 @@ my_pair VelocityModel::GetSpacing(Pedestrian* ped1, Pedestrian* ped2, Point ei,
//printf("ERROR: \tin VelocityModel::forcePedPed() ep12 can not be calculated!!!\n");
Log->Write("WARNING: \tin VelocityModel::GetSPacing() ep12 can not be calculated!!!\n");
Log->Write("\t\t Pedestrians are too near to each other (%f).", Distance);
exit(EXIT_FAILURE);
my_pair(FLT_MAX, ped2->GetID());
exit(EXIT_FAILURE); //TODO
}
double condition1 = ei.ScalarProduct(ep12); // < e_i , e_ij > should be positive
......@@ -399,7 +400,9 @@ Point VelocityModel::ForceRepPed(Pedestrian* ped1, Pedestrian* ped2, int periodi
Log->Write("\t\t Maybe the value of <a> in force_ped should be increased. Going to exit.\n");
printf("ped1 %d ped2 %d\n", ped1->GetID(), ped2->GetID());
printf("ped1 at (%f, %f), ped2 at (%f, %f)\n", ped1->GetPos()._x, ped1->GetPos()._y, ped2->GetPos()._x, ped2->GetPos()._y);
exit(EXIT_FAILURE);
exit(EXIT_FAILURE); //TODO: quick and dirty fix for issue #158
// (sometimes sources create peds on the same location)
}
Point ei = ped1->GetV().Normalized();
if(ped1->GetV().NormSquare()<0.01){
......
......@@ -29,7 +29,6 @@
#include "AgentsSourcesManager.h"
#include "Pedestrian.h"
#include "../mpi/LCGrid.h"
#include <thread>
#include "AgentsQueue.h"
......@@ -56,12 +55,15 @@ void AgentsSourcesManager::operator()()
void AgentsSourcesManager::Run()
{
SetRunning(true);
Log->Write("INFO:\tStarting agent manager thread");
/* std::cout<< KGRN << "\n Starting agent manager thread\n" << "\n>> time: " << Pedestrian::GetGlobalTime() << RESET << "\n"; */
//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)
{
/* std::cout << "Generate AgentsAndAddToPool src: " << src->GetId() << "\n" ; */
src->GenerateAgentsAndAddToPool(src->GetMaxAgents(), _building);
}
......@@ -72,18 +74,31 @@ 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();
/* std::cout << KBLU << ">> RUN: current_time " << current_time << " last update " << _lastUpdateTime << "\n" << RESET; */
if ((current_time != _lastUpdateTime)
&& ((current_time % updateFrequency) == 0))
{
finished=ProcessAllSources();
_lastUpdateTime = current_time;
&& ((current_time % updateFrequency) == 0))
{
/* std::cout << " --- Enter IF --- \n" << KRED << "QUEUE isempty: " << AgentsQueueIn::IsEmpty() << "\n" << RESET; */
if(AgentsQueueIn::IsEmpty())
//if queue is empty. Otherwise, wait for main thread to empty it and update _building
{
/* std::cout << " --- Enter QUEUE EMPTY --- \n"; */
finished=ProcessAllSources();
_lastUpdateTime = current_time;
//SetBuildingUpdated(false);
}
}
//wait some time
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
// wait for main thread to update building
if(current_time >= GetMaxSimTime())
break; // break if max simulation time is reached.
} while (!finished);
Log->Write("INFO:\tTerminating agent manager thread");
_isCompleted = true;
......@@ -91,66 +106,89 @@ void AgentsSourcesManager::Run()
bool AgentsSourcesManager::ProcessAllSources() const
{
/* std::cout << "\nSTART AgentsSourcesManager::ProcessAllSources()\n"; */
bool empty=true;
double current_time = Pedestrian::GetGlobalTime();
// std::cout << "\n -- current time: " << current_time << " number " << _building->GetAllPedestrians().size() << std::endl;
vector<Pedestrian*> source_peds; // we have to collect peds from all sources, so that we can consider them while computing new positions
for (const auto& src : _sources)
{
/* std::cout << KRED << "\nprocessing src: " << src->GetId() << " -- current time: " << current_time << " schedule time: " << src->GetPlanTime() <<". number of peds in building " << _building->GetAllPedestrians().size() << "\n" << RESET; */
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)",src->GetId(),peds.size(),src->GetPoolSize());
src->RemoveAgentsFromPool(peds, src->GetFrequency());
source_peds.reserve(source_peds.size() + peds.size());
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) )
if( !ComputeBestPositionVoronoiBoost(src.get(), peds, _building, source_peds) )
Log->Write("WARNING:\tThere was no place for some pedestrians");
source_peds.insert(source_peds.end(), peds.begin(), peds.end());
/* std::cout << KRED << ">> Add to queue " << peds.size() << "\n" << RESET; */
/* for( auto pp: peds) */
/* std::cout << "id: "<< pp->GetID() << " pos " << pp->GetPos()._x << ", " << pp->GetPos()._y << "\n"; */
/* std::cout << "------\n"; */
/* for( auto pp: source_peds) */
/* std::cout << "id: "<< pp->GetID() << " POS " << pp->GetPos()._x << ", " << pp->GetPos()._y << "\n"; */
AgentsQueueIn::Add(peds);
empty = false;
//src->Dump();
}
if (src->GetPlanTime() > current_time) // for the case we still expect
// agents coming
// agents coming
empty = false;
//src->Dump();//exit(0);
}
return empty;
/* 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;
}
//4 agents frequency, just for an example
void AgentsSourcesManager::ComputeBestPositionDummy(AgentsSource* src,
vector<Pedestrian*>& peds)const
{
UNUSED(src);
peds[0]->SetPos( Point(10,5.5) );
peds[1]->SetPos( Point(10,4.9) );
peds[2]->SetPos( Point(10,4.3) );
peds[3]->SetPos( Point(10,3.7) );
//4 agents frequency, just for an example
void AgentsSourcesManager::ComputeBestPositionDummy(AgentsSource* src,
vector<Pedestrian*>& peds)const
{
peds[0]->SetPos( Point(10,5.5) );
peds[1]->SetPos( Point(10,4.9) );
peds[2]->SetPos( Point(10,4.3) );
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[0]->SetPos( Point(10,5.4) );
peds[1]->SetPos( Point(10,4.6) );
peds[2]->SetPos( Point(10,3.8) );*/
for(auto&& ped : peds)
{
Point v = (ped->GetExitLine()->ShortestPoint(ped->GetPos())- ped->GetPos()).Normalized();
double speed=ped->GetV0Norm();
v=v*speed;
ped->SetV(v);
for(auto&& ped : peds)
{
Point v = (ped->GetExitLine()->ShortestPoint(ped->GetPos())- ped->GetPos()).Normalized();
double speed=ped->GetV0Norm();
v=v*speed;
ped->SetV(v);
}
}
}
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(0);
//TODO: get the seed from the simulation
srand (time(NULL));
std:: cout << "seed: "<< seed << std::endl;
srand (seed);
for (auto& ped : peds)
{
......@@ -160,6 +198,8 @@ void AgentsSourcesManager::ComputeBestPositionCompleteRandom(AgentsSource* src,
Point new_pos = positions[index];
positions.erase(positions.begin() + index);
ped->SetPos(new_pos, true);
std:: cout << "pos: " << new_pos._x << new_pos._y << std::endl;
AdjustVelocityByNeighbour(ped);
}
else
......@@ -172,134 +212,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