Simulation.cpp 45.2 KB
Newer Older
1
/**
Weichen's avatar
Weichen committed
2 3
 * \file        Simulation.cpp
 * \date        Dec 15, 2010
Mohcine Chraibi's avatar
Mohcine Chraibi committed
4
 * \version     v0.8.1
5
 * \copyright   <2009-2015> Forschungszentrum Jülich GmbH. All rights reserved.
6
 *
Weichen's avatar
Weichen committed
7
 * \section License
8 9 10
 * This file is part of JuPedSim.
 *
 * JuPedSim is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Lesser General Public License as published by
12 13 14 15 16 17 18 19
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * JuPedSim is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
20
 * You should have received a copy of the GNU Lesser General Public License
Weichen's avatar
Weichen committed
21
 * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 * \section Description
24 25 26 27
 * The Simulation class represents a simulation of pedestrians
 * based on a certain model in a specific scenario. A simulation is defined by
 * various parameters and functions.
 *
Weichen's avatar
Weichen committed
28 29 30
 *
 **/

Ulrich Kemloh's avatar
Ulrich Kemloh committed
31
#include "Simulation.h"
Mohcine Chraibi's avatar
Mohcine Chraibi committed
32
#include "IO/progress_bar.hpp"
33
#include "routing/ff_router/ffRouter.h"
Ulrich Kemloh's avatar
Ulrich Kemloh committed
34 35
#include "math/GCFMModel.h"
#include "math/GompertzModel.h"
Arne Graf's avatar
Arne Graf committed
36
#include "math/GradientModel.h"
37
#include "pedestrian/AgentsQueue.h"
38
#include "pedestrian/AgentsSourcesManager.h"
39 40
#include "geometry/WaitingArea.h"

41
#ifdef _OPENMP
GrgrLmml's avatar
GrgrLmml committed
42

43 44 45 46
#else
#define omp_get_thread_num() 0
#define omp_get_max_threads()  1
#endif
47
namespace fs = std::filesystem;
Ulrich Kemloh's avatar
Ulrich Kemloh committed
48
using namespace std;
Ulrich Kemloh's avatar
Ulrich Kemloh committed
49

50
OutputHandler* Log;
51
Trajectories* outputTXT;
52 53 54
// todo: add these variables to class simulation
std::map<std::string, std::shared_ptr<TrainType> > TrainTypes;
std::map<int, std::shared_ptr<TrainTimeTable> >  TrainTimeTables;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
55
std::map<int, double> trainOutflow;
56
//--------
Arne Graf's avatar
Arne Graf committed
57
Simulation::Simulation(Configuration* args)
GrgrLmml's avatar
GrgrLmml committed
58
        :_config(args)
59
{
60 61
     _countTraj = 0;
     _maxFileSize = 10; // MB
GrgrLmml's avatar
GrgrLmml committed
62 63 64 65 66 67 68 69 70 71
    _nPeds = 0;
    _seed = 8091983;
    _deltaT = 0;
    _building = nullptr;
    //_direction = NULL;
    _operationalModel = nullptr;
    _solver = nullptr;
    _iod = new IODispatcher();
    _fps = 1;
    _em = nullptr;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
72
    _gotSources = false;
73
    _trainConstraints = false;
74
    _maxSimTime = 100;
GrgrLmml's avatar
GrgrLmml committed
75
//     _config = args;
Ulrich Kemloh's avatar
Ulrich Kemloh committed
76 77
}

78 79
Simulation::~Simulation()
{
GrgrLmml's avatar
GrgrLmml committed
80 81 82
    delete _solver;
    delete _iod;
    delete _em;
Ulrich Kemloh's avatar
Ulrich Kemloh committed
83 84
}

Oliver Schmidts's avatar
Oliver Schmidts committed
85
long Simulation::GetPedsNumber() const
86
{
GrgrLmml's avatar
GrgrLmml committed
87
    return _nPeds;
Ulrich Kemloh's avatar
Ulrich Kemloh committed
88 89
}

GrgrLmml's avatar
GrgrLmml committed
90
bool Simulation::InitArgs()
91
{
GrgrLmml's avatar
GrgrLmml committed
92 93 94 95
    char tmp[CLENGTH];
    string s = "Parameter:\n";

    switch (_config->GetLog()) {
Mohcine Chraibi's avatar
Mohcine Chraibi committed
96 97
    case 0: {

GrgrLmml's avatar
GrgrLmml committed
98
        break;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
99 100
    }
    case 1: {
GrgrLmml's avatar
GrgrLmml committed
101 102 103 104
        if (Log)
            delete Log;
        Log = new STDIOHandler();
        break;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
105
    }
GrgrLmml's avatar
GrgrLmml committed
106 107
    case 2: {
        char name[CLENGTH] = "";
Mohcine Chraibi's avatar
Mohcine Chraibi committed
108
        sprintf(name, "%s.txt", _config->GetErrorLogFile().c_str());
GrgrLmml's avatar
GrgrLmml committed
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
        if (Log)
            delete Log;
        Log = new FileHandler(name);
    }
        break;
    default:
        printf("Wrong option for Logfile!\n\n");
        return false;
    }

    if (_config->GetPort()!=-1) {
        switch (_config->GetFileFormat()) {
        case FORMAT_XML_PLAIN_WITH_MESH:
        case FORMAT_XML_PLAIN: {
            OutputHandler* travisto = new SocketHandler(_config->GetHostname(),
                    _config->GetPort());
Mohcine Chraibi's avatar
Mohcine Chraibi committed
125
            Trajectories* output = new TrajectoriesJPSV05();
GrgrLmml's avatar
GrgrLmml committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
            output->SetOutputHandler(travisto);
            _iod->AddIO(output);
            break;
        }
        case FORMAT_XML_BIN: {
            Log->Write(
                    "INFO: \tFormat xml-bin not yet supported in streaming\n");
            //exit(0);
            break;
        }
        case FORMAT_PLAIN: {
            Log->Write(
                    "INFO: \tFormat plain not yet supported in streaming\n");
            return false;
        }
        case FORMAT_VTK: {
            Log->Write(
                    "INFO: \tFormat vtk not yet supported in streaming\n");
            return false;
        }
        default: {
            return false;
        }
        }

        s.append("\tonline streaming enabled \n");
    }

    if (!_config->GetTrajectoriesFile().empty()) {
        switch (_config->GetFileFormat()) {
        case FORMAT_XML_PLAIN: {
            OutputHandler* tofile = new FileHandler(
                    _config->GetTrajectoriesFile().c_str());
            Trajectories* output = new TrajectoriesJPSV05();
            output->SetOutputHandler(tofile);
            _iod->AddIO(output);
            break;
        }
        case FORMAT_PLAIN: {
            OutputHandler* file = new FileHandler(
                    _config->GetTrajectoriesFile().c_str());
167 168 169
            outputTXT = new TrajectoriesFLAT();
            outputTXT->SetOutputHandler(file);
            _iod->AddIO(outputTXT);
GrgrLmml's avatar
GrgrLmml committed
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
            break;
        }
        case FORMAT_VTK: {
            Log->Write("INFO: \tFormat vtk not yet supported\n");
            OutputHandler* file = new FileHandler(
                    (_config->GetTrajectoriesFile()+".vtk").c_str());
            Trajectories* output = new TrajectoriesVTK();
            output->SetOutputHandler(file);
            _iod->AddIO(output);
            break;
        }

        case FORMAT_XML_PLAIN_WITH_MESH: {
            //OutputHandler* tofile = new FileHandler(args->GetTrajectoriesFile().c_str());
            //if(_iod) delete _iod;
            //_iod = new TrajectoriesXML_MESH();
            //_iod->AddIO(tofile);
            break;
        }
        case FORMAT_XML_BIN: {
            // OutputHandler* travisto = new SocketHandler(args->GetHostname(), args->GetPort());
            // Trajectories* output= new TrajectoriesJPSV06();
            // output->SetOutputHandler(travisto);
            // _iod->AddIO(output);
            break;
        }
        default: {
            break;
        }
        }
    }

    _operationalModel = _config->GetModel();
    s.append(_operationalModel->GetDescription());

    // ODE solver which is never used!
    auto solver = _config->GetSolver();
    sprintf(tmp, "\tODE Solver: %d\n", solver);
    s.append(tmp);

    sprintf(tmp, "\tnCPU: %d\n", _config->GetMaxOpenMPThreads());
    s.append(tmp);
    sprintf(tmp, "\tt_max: %f\n", _config->GetTmax());
    s.append(tmp);
    _deltaT = _config->Getdt();
215
    _maxSimTime = _config->GetTmax();
GrgrLmml's avatar
GrgrLmml committed
216 217 218 219 220 221 222 223 224 225 226 227 228
    sprintf(tmp, "\tdt: %f\n", _deltaT);
    _periodic = _config->IsPeriodic();
    sprintf(tmp, "\t periodic: %d\n", _periodic);
    s.append(tmp);

    _fps = _config->GetFps();
    sprintf(tmp, "\tfps: %f\n", _fps);
    s.append(tmp);
    //Log->Write(s.c_str());

    _routingEngine = _config->GetRoutingEngine();
    auto distributor = std::unique_ptr<PedDistributor>(new PedDistributor(_config));
    // IMPORTANT: do not change the order in the following..
229
    _building = std::shared_ptr<Building>(new Building(_config, *distributor));
GrgrLmml's avatar
GrgrLmml committed
230 231 232

    // Initialize the agents sources that have been collected in the pedestrians distributor
    _agentSrcManager.SetBuilding(_building.get());
233
    _agentSrcManager.SetMaxSimTime(GetMaxSimTime());
Mohcine Chraibi's avatar
Mohcine Chraibi committed
234
    _gotSources = (bool) distributor->GetAgentsSources().size(); // did we have any sources? false if no sources
Mohcine Chraibi's avatar
Mohcine Chraibi committed
235
    std::cout << "\nGot " << _gotSources  << " sources"<< std::endl ;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
236

GrgrLmml's avatar
GrgrLmml committed
237 238
    for (const auto& src: distributor->GetAgentsSources()) {
        _agentSrcManager.AddSource(src);
Mohcine Chraibi's avatar
Mohcine Chraibi committed
239
        src->Dump();
GrgrLmml's avatar
GrgrLmml committed
240 241 242 243
    }



Mohcine Chraibi's avatar
Mohcine Chraibi committed
244

GrgrLmml's avatar
GrgrLmml committed
245 246 247 248 249 250 251
    //perform customs initialisation, like computing the phi for the gcfm
    //this should be called after the routing engine has been initialised
    // because a direction is needed for this initialisation.
    Log->Write("INFO:\t Init Operational Model starting ...");
    if (!_operationalModel->Init(_building.get()))
        return false;
    Log->Write("INFO:\t Init Operational Model done");
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
    Log->Write("Got %d Train Types", _building->GetTrainTypes().size());
    for(auto&& TT: _building->GetTrainTypes())
    {
          Log->Write("INFO\ttype         : %s",TT.second->type.c_str());
          Log->Write("INFO\tMax          : %d",TT.second->nmax);
          Log->Write("INFO\tnumber doors : %d\n",TT.second->doors.size());
    }
    Log->Write("Got %d Train Time Tables",_building->GetTrainTimeTables().size());
    for(auto&& TT: _building->GetTrainTimeTables())
    {
          Log->Write("INFO\tid           : %d",TT.second->id);
          Log->Write("INFO\ttype         : %s",TT.second->type.c_str());
          Log->Write("INFO\troom id      : %d",TT.second->rid);
          Log->Write("INFO\ttin          : %.2f%",TT.second->tin);
          Log->Write("INFO\ttout         : %.2f",TT.second->tout);
          Log->Write("INFO\ttrack start  : (%.2f, %.2f)",TT.second->pstart._x,TT.second->pstart._y);
          Log->Write("INFO\ttrack end    : (%.2f, %.2f)",TT.second->pend._x,TT.second->pend._y);
          Log->Write("INFO\ttrain start  : (%.2f, %.2f)",TT.second->tstart._x, TT.second->tstart._y);
          Log->Write("INFO\ttrain end    : (%.2f, %.2f)\n",TT.second->tend._x, TT.second->tend._y);
    }
272 273 274
    //@todo: these variables are global
    TrainTypes = _building->GetTrainTypes();
    TrainTimeTables = _building->GetTrainTimeTables();
275
    _trainConstraints = (bool) TrainTimeTables.size();
276 277

    //-----
f.mack's avatar
f.mack committed
278 279 280 281 282
    // Give the DirectionStrategy the chance to perform some initialization.
    // This should be done after the initialization of the operationalModel
    // because then, invalid pedestrians have been deleted and FindExit()
    // has been called.

GrgrLmml's avatar
GrgrLmml committed
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
    //other initializations
    for (auto&& ped: _building->GetAllPedestrians()) {
        ped->Setdt(_deltaT);
    }
    _nPeds = _building->GetAllPedestrians().size();
    //_building->WriteToErrorLog();
    Log->Write("INFO:\t nPeds %d received", _nPeds);
    //get the seed
    _seed = _config->GetSeed();

    //size of the cells/GCFM/Gompertz
    if (_config->GetDistEffMaxPed()>_config->GetLinkedCellSize()) {
        Log->Write(
                "ERROR: the linked-cell size [%f] should be bigger than the force range [%f]",
                _config->GetLinkedCellSize(), _config->GetDistEffMaxPed());
        return false;
    }

    //read and initialize events
    _em = new EventManager(_building.get(), _config->GetSeed());
    if (!_em->ReadEventsXml()) {
        Log->Write("ERROR: \tCould not initialize events handling");
    }
306 307 308 309 310
     if (!_em->ReadSchedule()) {
          Log->Write("ERROR: \tCould not initialize schedule handling");
     }

     _em->ListEvents();
GrgrLmml's avatar
GrgrLmml committed
311 312 313 314 315 316 317 318

    //_building->SaveGeometry("test.sav.xml");

    //if(_building->SanityCheck()==false)
    //     return false;

    //everything went fine
    return true;
319
}
320

321
double Simulation::RunStandardSimulation(double maxSimTime)
322
{
GrgrLmml's avatar
GrgrLmml committed
323 324 325
    RunHeader(_nPeds+_agentSrcManager.GetMaxAgentNumber());
    double t = RunBody(maxSimTime);
    RunFooter();
326
    return t;
327
}
328

329
void Simulation::UpdateRoutesAndLocations()
330
{
331 332
     //pedestrians to be deleted
     //you should better create this in the constructor and allocate it once.
333 334
     set<Pedestrian*> pedsToRemove;
//     pedsToRemove.reserve(500); //just reserve some space
335 336

     // collect all pedestrians in the simulation.
337 338
     const vector<Pedestrian*>& allPeds = _building->GetAllPedestrians();
     const map<int, Goal*>& goals = _building->GetAllGoals();
Oliver Schmidts's avatar
Oliver Schmidts committed
339
     auto allRooms = _building->GetAllRooms();
340

341 342 343 344 345 346
//    for (signed int p = 0; p < allPeds.size(); ++p) {
//        Pedestrian* ped = allPeds[p];
//
//        std::cout << "FinalDestination of [" << ped->GetID() << "] in (" << ped->GetRoomID() << ", " << ped->GetSubRoomID() << "/" <<  ped->GetSubRoomUID() << "): " << ped->GetFinalDestination() << std::endl;
//    }

Oliver Schmidts's avatar
Oliver Schmidts committed
347
#pragma omp parallel for shared(pedsToRemove, allRooms)
348
     for (signed int p = 0; p < allPeds.size(); ++p) {
Oliver Schmidts's avatar
Oliver Schmidts committed
349 350 351
          auto ped = allPeds[p];
          Room* room = _building->GetRoom(ped->GetRoomID());
          SubRoom* sub0 = room->GetSubRoom(ped->GetSubRoomID());
352

Oliver Schmidts's avatar
Oliver Schmidts committed
353 354
          //set the new room if needed
          if ((ped->GetFinalDestination() == FINAL_DEST_OUT)
355
                    && (room->GetCaption() == "outside")) { //TODO Hier aendern fuer inside goals?
f.mack's avatar
f.mack committed
356
#pragma omp critical(Simulation_Update_pedsToRemove)
357
               pedsToRemove.insert(ped);
Oliver Schmidts's avatar
Oliver Schmidts committed
358
          } else if ((ped->GetFinalDestination() != FINAL_DEST_OUT)
GrgrLmml's avatar
GrgrLmml committed
359
                    && (goals.at(ped->GetFinalDestination())->Contains(
360
                              ped->GetPos()))&& (goals.at(ped->GetFinalDestination())->GetIsFinalGoal())) {
f.mack's avatar
f.mack committed
361
#pragma omp critical(Simulation_Update_pedsToRemove)
362
               pedsToRemove.insert(ped);
Oliver Schmidts's avatar
Oliver Schmidts committed
363
          }
GrgrLmml's avatar
GrgrLmml committed
364

Oliver Schmidts's avatar
Oliver Schmidts committed
365 366 367 368 369
          // reposition in the case the pedestrians "accidently left the room" not via the intended exit.
          // That may happen if the forces are too high for instance
          // the ped is removed from the simulation, if it could not be reassigned
          else if (!sub0->IsInSubRoom(ped))
          {
370

Oliver Schmidts's avatar
Oliver Schmidts committed
371 372 373 374
               bool assigned = false;
               std::function<void(const Pedestrian&)> f = std::bind(&Simulation::UpdateFlowAtDoors, this, std::placeholders::_1);
               assigned = ped->Relocate(f);
               //this will delete agents, that are pushed outside (maybe even if inside obstacles??)
375

Oliver Schmidts's avatar
Oliver Schmidts committed
376
               if (!assigned) {
f.mack's avatar
f.mack committed
377
#pragma omp critical(Simulation_Update_pedsToRemove)
378
                       pedsToRemove.insert(ped); //the agent left the old room
GrgrLmml's avatar
GrgrLmml committed
379
                    //actualize the eggress time for that room
f.mack's avatar
f.mack committed
380
#pragma omp critical(SetEgressTime)
GrgrLmml's avatar
GrgrLmml committed
381 382
                    allRooms.at(ped->GetRoomID())->SetEgressTime(ped->GetGlobalTime());

383 384
               }
          }
Mohcine Chraibi's avatar
Mohcine Chraibi committed
385 386 387
          // actualize routes for sources
          if(_gotSources)
               ped->FindRoute();
Oliver Schmidts's avatar
Oliver Schmidts committed
388
          //finally actualize the route
389
          if ( !_gotSources && ped->FindRoute() == -1 && !_trainConstraints) {
Oliver Schmidts's avatar
Oliver Schmidts committed
390
               //a destination could not be found for that pedestrian
391 392
               Log->Write("ERROR: \tCould not find a route for pedestrian %d in room %d and subroom %d",
                         ped->GetID(), ped->GetRoomID(), ped->GetSubRoomID());
Mohcine Chraibi's avatar
Mohcine Chraibi committed
393
               //ped->FindRoute(); //debug only, plz remove
Arne Graf's avatar
Arne Graf committed
394 395
               std::function<void(const Pedestrian&)> f = std::bind(&Simulation::UpdateFlowAtDoors, this, std::placeholders::_1);
               ped->Relocate(f);
Oliver Schmidts's avatar
Oliver Schmidts committed
396
               //exit(EXIT_FAILURE);
f.mack's avatar
f.mack committed
397
#pragma omp critical(Simulation_Update_pedsToRemove)
398
               {
Mohcine Chraibi's avatar
Mohcine Chraibi committed
399
                    pedsToRemove.insert(ped);
400 401
                    Log->incrementDeletedAgents();
               }
Oliver Schmidts's avatar
Oliver Schmidts committed
402 403
          }
     }
GrgrLmml's avatar
GrgrLmml committed
404

405

Ulrich Kemloh's avatar
Ulrich Kemloh committed
406
#ifdef _USE_PROTOCOL_BUFFER
407 408
     if (_hybridSimManager)
     {
Arne Graf's avatar
Arne Graf committed
409
          AgentsQueueOut::Add(pedsToRemove);    //this should be critical region (and it is)
410 411
     }
     else
Ulrich Kemloh's avatar
Ulrich Kemloh committed
412
#endif
GrgrLmml's avatar
GrgrLmml committed
413
    {
414

GrgrLmml's avatar
GrgrLmml committed
415
        // remove the pedestrians that have left the building
416 417 418
        for (auto p : pedsToRemove){
            UpdateFlowAtDoors(*p);
            _building->DeletePedestrian(p);
GrgrLmml's avatar
GrgrLmml committed
419
        }
Arne Graf's avatar
Arne Graf committed
420
        pedsToRemove.clear();
GrgrLmml's avatar
GrgrLmml committed
421 422 423 424 425 426 427 428
    }

    //    temporary fix for the safest path router
    //    if (dynamic_cast<SafestPathRouter*>(_routingEngine->GetRouter(1)))
    //    {
    //         SafestPathRouter* spr = dynamic_cast<SafestPathRouter*>(_routingEngine->GetRouter(1));
    //         spr->ComputeAndUpdateDestinations(_allPedestians);
    //    }
Ulrich Kemloh's avatar
Ulrich Kemloh committed
429
}
430

Mohcine Chraibi's avatar
Mohcine Chraibi committed
431
void Simulation::PrintStatistics(double simTime)
432
{
Mohcine Chraibi's avatar
Mohcine Chraibi committed
433
    Log->Write("\nRooms Egress. Simulation Time: %.2f", simTime);
GrgrLmml's avatar
GrgrLmml committed
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
    Log->Write("==================");
    Log->Write("id\tcaption\tegress time (s)");

    for (const auto& it:_building->GetAllRooms()) {
        auto&& room = it.second;
        if (room->GetCaption()!="outside")
            Log->Write("%d\t%s\t%.2f", room->GetID(), room->GetCaption().c_str(), room->GetEgressTime());
    }

    Log->Write("\nUsage of Exits");
    Log->Write("==========");
    for (const auto& itr : _building->GetAllTransitions()) {
        Transition* goal = itr.second;
        if (goal->GetDoorUsage()) {
            Log->Write(
                    "\nExit ID [%d] used by [%d] pedestrians. Last passing time [%0.2f] s",
                    goal->GetID(), goal->GetDoorUsage(),
                    goal->GetLastPassingTime());

453
            string statsfile = "flow_exit_id_"+to_string(goal->GetID())+".txt";
454 455 456 457
            if(goal->GetOutflowRate() <  (std::numeric_limits<double>::max)())
            {
                 char tmp[50];
                 sprintf(tmp, "%.2f", goal->GetOutflowRate());
458
                 statsfile = "flow_exit_id_"+to_string(goal->GetID())+"_rate_"+tmp+".txt";
459
            }
GrgrLmml's avatar
GrgrLmml committed
460
            Log->Write("More Information in the file: %s", statsfile.c_str());
461 462 463 464 465 466 467 468 469
            {
                 auto statOutput = new FileHandler(statsfile.c_str());
                 statOutput->Write("#Simulation time: %.2f", simTime);
                 statOutput->Write("#Flow at exit "+goal->GetCaption()+"( ID "+to_string(goal->GetID())+" )");
                 statOutput->Write("#Time (s)  cummulative number of agents \n");
                 statOutput->Write(goal->GetFlowCurve());
                 statOutput->FileHandler::~FileHandler();
            }

GrgrLmml's avatar
GrgrLmml committed
470 471
        }
    }
472 473 474 475

        Log->Write("\nUsage of Crossings");
        Log->Write("==========");
        for (const auto& itr : _building->GetAllCrossings()) {
476 477 478 479 480 481 482 483 484 485 486 487 488
             Crossing* goal = itr.second;
             if (goal->GetDoorUsage()) {
                  Log->Write(
                       "\nCrossing ID [%d] in Room ID [%d] used by [%d] pedestrians. Last passing time [%0.2f] s",
                       goal->GetID(), itr.first/1000, goal->GetDoorUsage(),
                       goal->GetLastPassingTime());

                  string statsfile = "flow_crossing_id_"
                       + to_string(itr.first/1000) + "_" + to_string(itr.first % 1000) +".dat";
                  Log->Write("More Information in the file: %s", statsfile.c_str());
                  auto output = new FileHandler(statsfile.c_str());
                  output->Write("#Simulation time: %.2f", simTime);
                  output->Write("#Flow at crossing " + goal->GetCaption() + "( ID " + to_string(goal->GetID())
489
                                + " ) in Room ( ID "+ to_string(itr.first / 1000) + " )");
490 491 492
                  output->Write("#Time (s)  cummulative number of agents \n");
                  output->Write(goal->GetFlowCurve());
             }
493 494
        }

GrgrLmml's avatar
GrgrLmml committed
495
    Log->Write("\n");
Ulrich Kemloh's avatar
Ulrich Kemloh committed
496 497
}

498 499
void Simulation::RunHeader(long nPed)
{
GrgrLmml's avatar
GrgrLmml committed
500 501
    // writing the header
    if (nPed==-1) nPed = _nPeds;
502 503
    _iod->WriteHeader(nPed, _fps, _building.get(), _seed, 0);// first trajectory
                                                             // count = 0
GrgrLmml's avatar
GrgrLmml committed
504
    _iod->WriteGeometry(_building.get());
Mohcine Chraibi's avatar
Mohcine Chraibi committed
505 506
    if( _gotSources)
         _iod->WriteSources( GetAgentSrcManager().GetSources());
507

GrgrLmml's avatar
GrgrLmml committed
508 509 510
    int writeInterval = (int) ((1./_fps)/_deltaT+0.5);
    writeInterval = (writeInterval<=0) ? 1 : writeInterval; // mustn't be <= 0
    int firstframe = (Pedestrian::GetGlobalTime()/_deltaT)/writeInterval;
511

GrgrLmml's avatar
GrgrLmml committed
512 513 514 515
    _iod->WriteFrame(firstframe, _building.get());
    //first initialisation needed by the linked-cells
    UpdateRoutesAndLocations();
    ProcessAgentsQueue();
516
}
Ulrich Kemloh's avatar
Ulrich Kemloh committed
517

518
double Simulation::RunBody(double maxSimTime)
519
{
GrgrLmml's avatar
GrgrLmml committed
520 521 522 523 524 525 526
    //needed to control the execution time PART 1
    //in the case you want to run in no faster than realtime
    //time_t starttime, endtime;
    //time(&starttime);

    //take the current time from the pedestrian
    double t = Pedestrian::GetGlobalTime();
527 528 529 530
    fs::path TrajectoryName(_config->GetTrajectoriesFile());// in case we
                                                                // may need to
                                                                // generate
                                                                // several small files
GrgrLmml's avatar
GrgrLmml committed
531 532 533
    //frame number. This function can be called many times,
    static int frameNr = (int) (1+t/_deltaT); // Frame Number

534 535 536 537
    //##########
    //PROBLEMATIC: time when frame should be printed out
    // possibly skipped when using the following lines
    // NEEDS TO BE FIXED!
GrgrLmml's avatar
GrgrLmml committed
538 539
    int writeInterval = (int) ((1./_fps)/_deltaT+0.5);
    writeInterval = (writeInterval<=0) ? 1 : writeInterval; // mustn't be <= 0
540
    // ##########
GrgrLmml's avatar
GrgrLmml committed
541 542 543 544 545 546

    //process the queue for incoming pedestrians
    //important since the number of peds is used
    //to break the main simulation loop
    ProcessAgentsQueue();
    _nPeds = _building->GetAllPedestrians().size();
Mohcine Chraibi's avatar
Mohcine Chraibi committed
547
    std::cout << "\n";
Mohcine Chraibi's avatar
Mohcine Chraibi committed
548
    std::string description = "Evacutation ";
Mohcine Chraibi's avatar
Mohcine Chraibi committed
549 550 551 552 553 554 555
    ProgressBar *bar = new ProgressBar(_nPeds, description);
    // bar->SetFrequencyUpdate(10);
#ifdef _WINDOWS
    bar->SetStyle("|","-");
#else
    bar->SetStyle("\u2588", "-"); //for linux
#endif
GrgrLmml's avatar
GrgrLmml committed
556 557
    int initialnPeds = _nPeds;
    // main program loop
Mohcine Chraibi's avatar
Mohcine Chraibi committed
558
    while ((_nPeds || (!_agentSrcManager.IsCompleted()&& _gotSources) ) && t<maxSimTime) {
GrgrLmml's avatar
GrgrLmml committed
559
        t = 0+(frameNr-1)*_deltaT;
560 561
        // Handle train traffic: coorect geometry
        bool geometryChanged= TrainTraffic();
562

563
        //process the queue for incoming pedestrians
GrgrLmml's avatar
GrgrLmml committed
564 565 566 567 568 569 570 571 572 573 574 575
        ProcessAgentsQueue();

        if (t>Pedestrian::GetMinPremovementTime()) {
            //update the linked cells
            _building->UpdateGrid();

            // update the positions
            _operationalModel->ComputeNextTimeStep(t, _deltaT, _building.get(), _periodic);

            //update the events
            _em->ProcessEvent();

576 577 578
            //here we could place router-tasks (calc new maps) that can use multiple cores AND we have 't'
            //update quickestRouter
            if (_routingEngine.get()->GetRouter(ROUTING_FF_QUICKEST)) {
579 580
                if(geometryChanged)
                {
Mohcine Chraibi's avatar
Mohcine Chraibi committed
581 582 583 584 585
                     FFRouter* ffrouter2 = dynamic_cast<FFRouter*>(_routingEngine.get()->GetRouter(ROUTING_FF_QUICKEST));
                     ffrouter2->Init(_building.get());
                     // debug
                     fs::path f("tmp_"+std::to_string(t)+"_"+_config->GetGeometryFile());
                     std::string filename = f.string();
586 587 588
                     std::cout << "\nUpdate geometry. New  geometry --> " << filename.c_str() << "\n";

                     std::cout<< KGRN << "Enter correctGeometry: Building Has " << _building->GetAllTransitions().size() << " Transitions\n" << RESET;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
589 590 591 592 593 594 595 596 597 598 599
                     _building->SaveGeometry(filename);
                     //
                     double _deltaH = _building->GetConfig()->get_deltaH();
                     double _wallAvoidDistance = _building->GetConfig()->get_wall_avoid_distance();
                     bool _useWallAvoidance = _building->GetConfig()->get_use_wall_avoidance();

                     if(auto dirlocff = dynamic_cast<DirectionLocalFloorfield*>(_building->GetConfig()->get_dirStrategy())){
                          Log->Write("INFO:\t Init DirectionLOCALFloorfield starting ...");
                          dirlocff->Init(_building.get(), _deltaH, _wallAvoidDistance, _useWallAvoidance);
                          Log->Write("INFO:\t Init DirectionLOCALFloorfield done");
                     }
600 601


Mohcine Chraibi's avatar
Mohcine Chraibi committed
602 603 604 605 606 607 608 609
                     std::cout << KBLU << " Init router in simulation\n" << RESET;
                }
                else{
                     FFRouter* ffrouter = dynamic_cast<FFRouter*>(_routingEngine.get()->GetRouter(ROUTING_FF_QUICKEST));
                     if (ffrouter->MustReInit()) {
                          ffrouter->ReInit();
                          ffrouter->SetRecalc(t);
                     }
610 611
                }
            }
612

tobias schroedter's avatar
tobias schroedter committed
613 614
            // here the used routers are update, when needed due to external changes
            if (_routingEngine->NeedsUpdate()){
615 616 617
                 _routingEngine->UpdateRouter();
            }

GrgrLmml's avatar
GrgrLmml committed
618 619 620 621 622 623 624 625 626 627 628 629 630
            //update the routes and locations
            UpdateRoutesAndLocations();

            //other updates
            //someone might have left the building
            _nPeds = _building->GetAllPedestrians().size();
        }

        // update the global time
        Pedestrian::SetGlobalTime(t);

        // write the trajectories
        if (0==frameNr%writeInterval) {
631 632
              _iod->WriteFrame(frameNr/writeInterval, _building.get());
              WriteTrajectories(TrajectoryName.stem().string());
GrgrLmml's avatar
GrgrLmml committed
633
        }
Mohcine Chraibi's avatar
Mohcine Chraibi committed
634 635

        if(!_gotSources && !_periodic && _config->print_prog_bar())
Arne Graf's avatar
Arne Graf committed
636 637 638
              // Log->ProgressBar(initialnPeds, initialnPeds-_nPeds, t);
              bar->Progressed(initialnPeds-_nPeds);
        else
Mohcine Chraibi's avatar
No  
Mohcine Chraibi committed
639 640 641
             if ((!_gotSources) &&
                 ((frameNr < 100 &&  frameNr % 10 == 0) ||
                  (frameNr > 100 &&  frameNr % 100 == 0)))
Mohcine Chraibi's avatar
Mohcine Chraibi committed
642
                  printf("time: %6.2f (%4.0f)  | Agents: %6ld / %d [%4.1f%%]\n",  t , maxSimTime, _nPeds, initialnPeds, (double)(initialnPeds-_nPeds)/initialnPeds*100);
Arne Graf's avatar
Arne Graf committed
643

Mohcine Chraibi's avatar
Mohcine Chraibi committed
644

GrgrLmml's avatar
GrgrLmml committed
645 646 647 648 649 650
        // needed to control the execution time PART 2
        // time(&endtime);
        // double timeToWait=t-difftime(endtime, starttime);
        // clock_t goal = timeToWait*1000 + clock();
        // while (goal > clock());
        ++frameNr;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
651 652 653

        //Trigger JPSfire Toxicity Analysis
        //only executed every 3 seconds
Mohcine Chraibi's avatar
Mohcine Chraibi committed
654
        #ifdef JPSFIRE
Mohcine Chraibi's avatar
Mohcine Chraibi committed
655 656 657 658 659
        if( fmod(Pedestrian::GetGlobalTime(), 3) == 0 ) {
            for (auto&& ped: _building->GetAllPedestrians()) {
                ped->ConductToxicityAnalysis();
            }
        }
Mohcine Chraibi's avatar
Mohcine Chraibi committed
660
        #endif
661

Mohcine Chraibi's avatar
Mohcine Chraibi committed
662 663 664 665 666 667
        //init train trainOutfloww
        for (auto tab : TrainTimeTables)
        {
              trainOutflow[tab.first] = 0;
        }
        // regulate flow
668 669 670 671 672
        for (auto& itr: _building->GetAllTransitions())
        {
             Transition* Trans = itr.second;
             if(Trans->IsTempClose())
             {
qiancheng xu's avatar
qiancheng xu committed
673 674
                  if ((Trans->GetMaxDoorUsage() != (std::numeric_limits<int>::max)()) ||
                    (Trans->GetOutflowRate() != (std::numeric_limits<double>::max)()) ){
675 676
                        Trans->UpdateClosingTime( _deltaT);
                        if(Trans->GetClosingTime() <= _deltaT){
677
                             Trans->changeTemporaryState();
678
                      }
679 680
                  }// normal transition
             }
Mohcine Chraibi's avatar
Mohcine Chraibi committed
681
             //-----------
682
             // regulate train doorusage
Mohcine Chraibi's avatar
Mohcine Chraibi committed
683 684 685 686 687 688 689 690 691 692
             std::string transType = Trans->GetType();
             if (Trans->IsOpen() && transType.rfind("Train", 0) == 0)
             {
                   std::vector<std::string> strs;
                   boost::split(strs, transType, boost::is_any_of("_"),boost::token_compress_on);
                   int id = atoi(strs[1].c_str());
                   std::string type = Trans->GetCaption();
                   trainOutflow[id] += Trans->GetDoorUsage();
                   if(trainOutflow[id] >= TrainTypes[type]->nmax)
                   {
693 694
                        std::cout << "INFO:\tclosing train door "<<  transType.c_str() << " at "<<  Pedestrian::GetGlobalTime() << " capacity " <<  TrainTypes[type]->nmax<< "\n";
                         Log->Write("INFO:\tclosing train door %s at t=%.2f. Flow = %.2f (Train Capacity %d)", transType.c_str(), Pedestrian::GetGlobalTime(), trainOutflow[id], TrainTypes[type]->nmax);
Mohcine Chraibi's avatar
Mohcine Chraibi committed
695 696 697 698
                         Trans->Close();
                   }
             }
             //-----------
699
        }// Transitions
Mohcine Chraibi's avatar
Mohcine Chraibi committed
700 701
        if(frameNr % 1000 == 0)
        {
702 703
              Log->Write("INFO:\tUpdate door statistics at t=%.2f", t);
              PrintStatistics(t);
Mohcine Chraibi's avatar
Mohcine Chraibi committed
704
        }
705
    }// while time
706
    return t;
707
}
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
bool Simulation::WriteTrajectories(std::string trajectoryName)
{
      if(_config-> GetFileFormat() == FORMAT_PLAIN)
      {
            fs::path p = _config->GetTrajectoriesFile();
            int sf = fs::file_size(p);
            if(sf>_maxFileSize*1024*1024)
            {
                  std::string extention = p.extension().string();
                  this->incrementCountTraj();
                  char tmp_traj_name[100];
                  sprintf(tmp_traj_name,"%s_%.4d_%s", trajectoryName.c_str(), _countTraj, extention.c_str());
                  _config->SetTrajectoriesFile(tmp_traj_name);
                  Log->Write("INFO:\tNew trajectory file <%s>", tmp_traj_name);
                  OutputHandler* file = new FileHandler(_config->GetTrajectoriesFile().c_str());
                  outputTXT->SetOutputHandler(file);

//_config->GetProjectRootDir()+"_1_"+_config->GetTrajectoriesFile());
                  // _config->SetTrajectoriesFile(name);
                  _iod->WriteHeader(_nPeds, _fps, _building.get(), _seed, _countTraj);
                  // _iod->WriteGeometry(_building.get());
            }
      }
731
      return true;
732
}
733 734 735 736 737 738 739 740 741 742
//      |             |
//      *-------------* <---door
//      |             |
//      |             |
//      |             |
//      |             |
//      |             |
//*-----x-------------x--------* <- wall
//      |             |

743 744 745 746 747 748 749 750

/*
 * in this function this happens:
* remove walls
* add walls
* add doors
* set _routingEngine->setNeedUpdate(true);
*/
Mohcine Chraibi's avatar
Mohcine Chraibi committed
751
bool Simulation::correctGeometry(std::shared_ptr<Building> building, std::shared_ptr<TrainTimeTable> tab)
752
{
Mohcine Chraibi's avatar
Mohcine Chraibi committed
753 754 755 756
     //auto platforms = building->GetPlatforms();
     int trainId = tab->id;
     std::string trainType = tab->type;
     Point TrackStart = tab->pstart;
757
     Point TrainStart = tab->tstart;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
758 759 760 761 762
     Point TrackEnd = tab->pend;
     SubRoom * subroom;
     int room_id, subroom_id;
     auto mytrack = building->GetTrackWalls(TrackStart, TrackEnd, room_id, subroom_id);
     Room* room = building->GetRoom(room_id);
763 764 765 766 767 768
     subroom = room->GetSubRoom(subroom_id);
     if(subroom == nullptr)
     {
          Log->Write("ERROR:\t Simulation::correctGeometry got wrong room_id|subroom_id (%d|%d). TrainId %d", room_id, subroom_id, trainId);
          exit(EXIT_FAILURE);
     }
769
     static int transition_id = 10000; // randomly high number
Mohcine Chraibi's avatar
Mohcine Chraibi committed
770 771 772 773 774

     std::cout << "enter with train " << trainType.c_str() << "\n";
     std::cout<< KBLU << "Enter correctGeometry: Building Has " << building->GetAllTransitions().size() << " Transitions\n" << RESET;
     std::cout << "room: " << room_id << " subroom_id " << subroom_id << "\n" ;

775

776
      if(mytrack.empty() || subroom == nullptr)
777
            return false;
778

779

780 781
      auto train = building->GetTrainTypes().at(trainType);
      auto doors = train->doors;
782 783 784 785 786 787 788 789 790 791 792 793 794 795
      for(auto && d: doors)
      {
           auto newX  = d.GetPoint1()._x + TrainStart._x + TrackStart._x;
           auto newY  = d.GetPoint1()._y + TrainStart._y + TrackStart._y;
           d.SetPoint1(Point(newX, newY));
           newX  = d.GetPoint2()._x + TrainStart._x + TrackStart._x;
           newY  = d.GetPoint2()._y + TrainStart._y + TrackStart._y;
           d.SetPoint2(Point(newX, newY));
      }
      for(auto d: doors)
      {
           Log->Write("Train %s %d. Transformed coordinates of doors: %s -- %s", trainType.c_str(), trainId, d.GetPoint1().toString().c_str(), d.GetPoint2().toString().c_str());
      }

796 797 798
      // std::vector<std::pair<PointWall, pointWall > >
      auto pws = building->GetIntersectionPoints(doors, mytrack);
      if(pws.empty())
799
           std::cout << KRED << "simulation::correctGeometry: pws are empty. Something went south with train doors\n" << RESET;
800

801
      auto walls = subroom->GetAllWalls();
802
      //---
803 804 805 806 807 808 809 810
      for(auto pw: pws)
      {
            auto pw1 = pw.first;
            auto pw2 = pw.second;
            auto p1 = pw1.first;
            auto w1 = pw1.second;
            auto p2 = pw2.first;
            auto w2 = pw2.second;
Mohcine Chraibi's avatar
Mohcine Chraibi committed
811 812 813
            // std::cout << "p1 " << p1.toString() << ", wall: " << w1.toString() << "\n";
            // std::cout << "p2 " << p2.toString() << ", wall: " << w2.toString() << "\n";
            // std::cout << "------\n";
814 815
            // case 1
            Point P;
816 817 818 819 820
            if(w1 == w2)
            {
                  std::cout << "EQUAL\n";
                  Transition* e = new Transition();
                  e->SetID(transition_id++);
Mohcine Chraibi's avatar
Mohcine Chraibi committed
821
                  e->SetCaption(trainType);
822 823
                  e->SetPoint1(p1);
                  e->SetPoint2(p2);
Mohcine Chraibi's avatar
Mohcine Chraibi committed
824 825
                  std::string transType = "Train_"+std::to_string(tab->id)+"_"+std::to_string(tab->tin)+"_"+std::to_string(tab->tout);
                  e->SetType(transType);
826 827 828 829 830
                  room->AddTransitionID(e->GetUniqueID());// danger area
                  e->SetRoom1(room);
                  e->SetSubRoom1(subroom);
                  subroom->AddTransition(e);// danger area
                  building->AddTransition(e);// danger area
831 832 833
                  /* std::cout << KRED << "Trans added: " << e->toString() << "\n" << RESET; */

                  /* std::cout<< KGRN << "Transition added. Building Has " << building->GetAllTransitions().size() << " Transitions\n" << RESET; */
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
                  double dist_pt1 = (w1.GetPoint1() - e->GetPoint1()).NormSquare();
                  double dist_pt2 = (w1.GetPoint1() - e->GetPoint2()).NormSquare();
                  Point A, B;

                  if(dist_pt1<dist_pt2)
                  {
                        A = e->GetPoint1();
                        B = e->GetPoint2();
                  }
                  else
                  {
                        A = e->GetPoint2();
                        B = e->GetPoint1();
                  }

                  Wall NewWall(w1.GetPoint1(), A);
                  Wall NewWall1(w1.GetPoint2(), B);
851 852 853
                  NewWall.SetType(w1.GetType());
                  NewWall1.SetType(w1.GetType());

854
                  // add new lines to be controled against overlap with exits
Mohcine Chraibi's avatar
Mohcine Chraibi committed
855 856 857 858
                  building->TempAddedWalls[trainId].push_back(NewWall);
                  building->TempAddedWalls[trainId].push_back(NewWall1);
                  building->TempAddedDoors[trainId].push_back(*e);
                  building->TempRemovedWalls[trainId].push_back(w1);
859 860 861
                  subroom->AddWall(NewWall);
                  subroom->AddWall(NewWall1);
                  subroom->RemoveWall(w1);
862 863 864 865 866 867

                  /* std::cout << KRED << "WALL added " << NewWall.toString() << "\n" << RESET ; */
                  /* std::cout << KRED << "WALL added " << NewWall1.toString() << "\n" << RESET ; */
                  /* std::cout << KRED << "WALL removed " << w1.toString() << "\n" << RESET ; */
                  /* getc(stdin); */

868 869 870
                  //room->AddTransitionID(e->GetUniqueID());
            }
            else if(w1.ShareCommonPointWith(w2, P))
871
            {
872

873
                  std::cout << "ONE POINT COMON\n";
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
                  //------------ transition --------
                  Transition* e = new Transition();
                  e->SetID(transition_id++);
                  e->SetCaption(trainType);
                  e->SetPoint1(p1);
                  e->SetPoint2(p2);
                  std::string transType = "Train_"+std::to_string(tab->id)+"_"+std::to_string(tab->tin)+"_"+std::to_string(tab->tout);
                  e->SetType(transType);
                  room->AddTransitionID(e->GetUniqueID());// danger area
                  e->SetRoom1(room);
                  e->SetSubRoom1(subroom);

                  subroom->AddTransition(e);// danger area
                  building->AddTransition(e);// danger area
                  //--------------------------------
                  Point N, M;
                  if(w1.GetPoint1()==P)
                        N = w1.GetPoint2();
                  else
                        N = w1.GetPoint1();

                  if(w2.GetPoint1()==P)
                        M = w2.GetPoint2();
                  else
                        M = w2.GetPoint1();

                  Wall NewWall(N, p1);
                  Wall NewWall1(M, p2);
                  NewWall.SetType(w1.GetType());
                  NewWall1.SetType(w2.GetType());
                  // changes to building
                  building->TempAddedWalls[trainId].push_back(NewWall);
                  building->TempAddedWalls[trainId].push_back(NewWall1);
                  building->TempAddedDoors[trainId].push_back(*e);
                  building->TempRemovedWalls[trainId].push_back(w1);
                  building->TempRemovedWalls[trainId].push_back(w2);
                  subroom->AddWall(NewWall);
                  subroom->AddWall(NewWall1);
                  subroom->RemoveWall(w1);
                  subroom->RemoveWall(w2);
                  /* std::cout << KRED << ". WALL added " << NewWall.toString() << "\n" << RESET ; */
                  /* std::cout << KRED << "WALL added " << NewWall1.toString() << "\n" << RESET ; */
                  /* std::cout << KRED << "WALL removed " << w1.toString() << "\n" << RESET ; */
                  /* std::cout << KRED << "WALL removed " << w2.toString() << "\n" << RESET ; */
                  /* getc(stdin); */
919 920 921
            }
            else // disjoint
            {
922
                  std::cout << "DISJOINT\n";
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937
                                    //------------ transition --------
                  Transition* e = new Transition();
                  e->SetID(transition_id++);
                  e->SetCaption(trainType);
                  e->SetPoint1(p1);
                  e->SetPoint2(p2);
                  std::string transType = "Train_"+std::to_string(tab->id)+"_"+std::to_string(tab->tin)+"_"+std::to_string(tab->tout);
                  e->SetType(transType);
                  room->AddTransitionID(e->GetUniqueID());// danger area
                  e->SetRoom1(room);
                  e->SetSubRoom1(subroom);

                  subroom->AddTransition(e);// danger area
                  building->AddTransition(e);// danger area
                  //--------------------------------
938 939
                  // find points on w1 and w2 between p1 and p2
                  // (A, B)
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
                  Point A, B;
                  if(e->isBetween(w1.GetPoint1()))
                        A = w1.GetPoint2();
                  else
                        A = w1.GetPoint1();

                  if(e->isBetween(w2.GetPoint1()))
                        B = w2.GetPoint2();
                  else
                        B = w2.GetPoint1();

                  Wall NewWall(A, p1);
                  Wall NewWall1(B, p2);
                  NewWall.SetType(w1.GetType());
                  NewWall1.SetType(w2.GetType());
                  // remove walls between
                  for(auto wall: mytrack)
                  {
                       if(e->isBetween(wall.GetPoint1()) || e->isBetween(wall.GetPoint2()))
                        {
                             building->TempRemovedWalls[trainId].push_back(wall);
                             subroom->RemoveWall(wall);
                        }
                  }
                  // changes to building
                  building->TempAddedWalls[trainId].push_back(NewWall);
                  building->TempAddedWalls[trainId].push_back(NewWall1);
                  building->TempAddedDoors[trainId].push_back(*e);
                  subroom->AddWall(NewWall);
                  subroom->AddWall(NewWall1);

971 972 973
                  // remove walls w1 and w2
            }
      }
974
      _routingEngine->setNeedUpdate(true);
975 976 977
     return true;

}
978 979
void Simulation::RunFooter()
{
GrgrLmml's avatar
GrgrLmml committed
980 981
    // writing the footer
    _iod->WriteFooter();
Ulrich Kemloh's avatar
Ulrich Kemloh committed
982 983
}

984
void Simulation::ProcessAgentsQueue()
985
{
986

987 988 989 990
     /* 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; */
991

GrgrLmml's avatar
GrgrLmml committed
992 993
    //incoming pedestrians
    vector<Pedestrian*> peds;
994 995
    //  std::cout << ">>> peds " << peds.size() << RESET<< std::endl;

GrgrLmml's avatar
GrgrLmml committed
996
    AgentsQueueIn::GetandClear(peds);
997
    //std::cout << "SIMULATION BEFORE BOOL = " <<  _agentSrcManager.IsBuildingUpdated() << " peds size " << peds.size() << "\n" ;
998

999 1000
    //_agentSrcManager.SetBuildingUpdated(true);
    /* std::cout << "SIMULATION AFTER BOOL = " <<  _agentSrcManager.IsBuildingUpdated() << "\n" ; */
1001

GrgrLmml's avatar
GrgrLmml committed
1002
    for (auto&& ped: peds) {
1003
            /* std::cout << "Add to building : " << ped->GetPos()._x << ", " << ped->GetPos()._y << " t: "<< Pedestrian::GetGlobalTime() << std::endl; */
GrgrLmml's avatar
GrgrLmml committed
1004 1005
        _building->AddPedestrian(ped);
    }
tobias schroedter's avatar
tobias schroedter committed
1006
    _building->UpdateGrid();
1007 1008 1009 1010
    //  for(auto pp: _building->GetAllPedestrians())
    //         std::cout<< KBLU << "BUL: Simulation: " << pp->GetPos()._x << ", " << pp->GetPos()._y  << " t: "<< Pedestrian::GetGlobalTime() <<RESET << std::endl;


1011
    /* std::cout << "LEAVE Simulation::ProcessAgentsQueue() with " << " size "  << _building->GetAllPedestrians().size() << "\n" << RESET; */
Ulrich Kemloh's avatar
Ulrich Kemloh committed
1012
}
Ulrich Kemloh's avatar
Ulrich Kemloh committed
1013

1014
void Simulation::UpdateDoorticks() const {
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
//    int softstateDecay = 1;
//    //Softstate of _lastTickTime is valid for X seconds as in (X/_deltaT); here it is 2s
//    auto& allCross = _building->GetAllCrossings();
//    for (auto& crossPair : allCross) {
//        crossPair.second->_refresh1 += 1;
//        crossPair.second->_refresh2 += 1;
//        if (crossPair.second->_refresh1 > (softstateDecay/_deltaT)) {
//            crossPair.second->_lastTickTime1 = 0;
//            crossPair.second->_refresh1 = 0;
//        }
//        if (crossPair.second->_refresh2 > (softstateDecay/_deltaT)) {
//            crossPair.second->_lastTickTime2 = 0;
//            crossPair.second->_refresh2 = 0;
//        }
//    }
//
//    auto& allTrans = _building->GetAllTransitions();
//    for (auto& transPair : allTrans) {
//        transPair.second->_refresh1 += 1;
//        transPair.second->_refresh2 += 1;
//        if (transPair.second->_refresh1 > (softstateDecay/_deltaT)) {
//            transPair.second->_lastTickTime1 = 0;
//            transPair.second->_refresh1 = 0;
//        }
//        if (transPair.second->_refresh2 > (softstateDecay/_deltaT)) {
//            transPair.second->_lastTickTime2 = 0;
//            transPair.second->_refresh2 = 0;
//        }
//    }
1044 1045
};

Ulrich Kemloh's avatar
Ulrich Kemloh committed
1046 1047
void Simulation::UpdateFlowAtDoors(const Pedestrian& ped) const
{
GrgrLmml's avatar
GrgrLmml committed
1048 1049 1050 1051
    if (_config->ShowStatistics()) {
        Transition* trans = _building->GetTransitionByUID(ped.GetExitIndex());
        if (trans) {
            //check if the pedestrian left the door correctly
Arne Graf's avatar
Arne Graf committed
1052
            if (trans->DistTo(ped.GetPos())>0.5) {
GrgrLmml's avatar
GrgrLmml committed
1053 1054 1055
                Log->Write("WARNING:\t pedestrian [%d] left room/subroom [%d/%d] in an unusual way. Please check",
                        ped.GetID(), ped.GetRoomID(), ped.GetSubRoomID());
                Log->Write("       :\t distance to last door (%d | %d) is %f. That should be smaller.",
Arne Graf's avatar
fix 233  
Arne Graf committed
1056 1057
                        trans->GetUniqueID(), ped.GetExitIndex(),
                        trans->DistTo(ped.GetPos()));
GrgrLmml's avatar
GrgrLmml committed
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
                Log->Write("       :\t correcting the door statistics");
                //ped.Dump(ped.GetID());

                //checking the history and picking the nearest previous destination
                double biggest = 0.3;
                bool success = false;
                for (const auto& dest:ped.GetLastDestinations()) {
                    if (dest!=-1) {
                        Transition* trans_tmp = _building->GetTransitionByUID(dest);
                        if (trans_tmp && trans_tmp->DistTo(ped.GetPos())<biggest) {
                            biggest = trans_tmp->DistTo(ped.GetPos());
                            trans = trans_tmp;
                            Log->Write("       :\t Best match found at door %d", dest);
                            success = true;//at least one door was found
                        }
1073
                    }
GrgrLmml's avatar
GrgrLmml committed
1074 1075 1076 1077 1078 1079 1080
                }

                if (!success) {
                    Log->Write("WARNING       :\t correcting the door statistics");
                    return; //todo we need to check if the ped is in a subroom neighboring the target. If so, no problems!
                }
            }
1081
//#pragma omp critical
1082
            bool regulateFlow = trans->GetOutflowRate() <  (std::numeric_limits<double>::max)();
1083

1084 1085
            trans->IncreaseDoorUsage(1, ped.GetGlobalTime());
            trans->IncreasePartialDoorUsage(1);
1086 1087 1088 1089 1090 1091 1092 1093 1094

            if(regulateFlow)
            {
                 // when <dn> agents pass <trans>, we start evaluating the flow
                 // .. and maybe close the <trans>
                 if( trans->GetPartialDoorUsage() ==  trans->GetDN() ) {
                      trans->regulateFlow(Pedestrian::GetGlobalTime());
                      trans->ResetPartialDoorUsage();
                 }
1095
            }
1096

GrgrLmml's avatar
GrgrLmml committed
1097
        }
1098

1099 1100 1101
        Crossing* cross = _building->GetCrossingByUID(ped.GetExitIndex());
        if (cross) {
             cross->IncreaseDoorUsage(1, ped.GetGlobalTime());
GrgrLmml's avatar
GrgrLmml committed
1102 1103
        }
    }
Ulrich Kemloh's avatar
Ulrich Kemloh committed
1104 1105
}

1106 1107 1108 1109 1110
void Simulation::incrementCountTraj()
{
      _countTraj++;
}

1111
AgentsSourcesManager& Simulation::GetAgentSrcManager()
1112
{
GrgrLmml's avatar
GrgrLmml committed
1113
    return _agentSrcManager;
<