Commit f9a127cd authored by tobias schroedter's avatar tobias schroedter

Merge branch '307-temp-close' into 'develop'

Resolve "New type for doors"

Closes #307

See merge request !47
parents 9ef6a348 d6611b95
Pipeline #18641 passed with stages
in 18 minutes and 37 seconds
......@@ -354,11 +354,6 @@ routing/global_shortest/AccessPoint.cpp
routing/global_shortest/GlobalRouter.cpp
routing/global_shortest/DTriangulation.cpp
#global_shortest
routing/global_shortest_trips/AccessPoint.cpp
routing/global_shortest_trips/GlobalRouterTrips.cpp
routing/global_shortest_trips/DTriangulation.cpp
#general
routing/DirectionStrategy.cpp
routing/Router.cpp
......@@ -473,11 +468,6 @@ routing/global_shortest/GlobalRouter.h
routing/global_shortest/AccessPoint.h
routing/global_shortest/DTriangulation.h
#global_shortest trips
routing/global_shortest_trips/AccessPoint.h
routing/global_shortest_trips/GlobalRouterTrips.h
routing/global_shortest_trips/DTriangulation.h
#quickest
routing/quickest/QuickestPathRouter.h
......
......@@ -46,8 +46,8 @@ void GeoFileParser::LoadBuilding(Building* building)
exit(EXIT_FAILURE);
}
if (!LoadTrafficInfo(building)) {
Log->Write("ERROR:\t could not load extra traffic information!");
exit(EXIT_FAILURE);
Log->Write("ERROR:\t could not load extra traffic information!");
exit(EXIT_FAILURE);
}
}
......@@ -75,10 +75,10 @@ bool GeoFileParser::LoadGeometry(Building* building)
return false;
}
if (xRootNode->Attribute("unit")) if (std::string(xRootNode->Attribute("unit"))!="m") {
Log->Write("ERROR:\tOnly the unit m (meters) is supported. \n\tYou supplied [%s]",
xRootNode->Attribute("unit"));
return false;
}
Log->Write("ERROR:\tOnly the unit m (meters) is supported. \n\tYou supplied [%s]",
xRootNode->Attribute("unit"));
return false;
}
double version = xmltof(xRootNode->Attribute("version"), -1);
......@@ -580,18 +580,37 @@ bool GeoFileParser::LoadTrafficInfo(Building* building)
sprintf(tmp, "\t>> ID: %d\n", id);
str.append(tmp);
//------------------ state
std::string state = xmltoa(xDoor->Attribute("state"), "open");
//store transition in a map and call getTransition/getCrossin
if (state=="open") {
std::string stateStr = xmltoa(xDoor->Attribute("state"), "open");
DoorState state = StringToDoorState(stateStr);
//store transition in a map and call getTransition/getCrossing
switch (state) {
case DoorState::OPEN:
building->GetTransition(id)->Open();
}
else if (state=="close") {
break;
case DoorState::CLOSE:
building->GetTransition(id)->Close();
break;
case DoorState::TEMP_CLOSE:
building->GetTransition(id)->TempClose();
break;
case DoorState::ERROR:
Log->Write("WARNING:\t Unknown door state: <%s>. open or close. Default: open",
stateStr.c_str());
building->GetTransition(id)->Open();
break;
}
else {
Log->Write("WARNING:\t Unknown door state: <%s>. open or close. Default: open", state.c_str());
}
sprintf(tmp, "\t>> state: %s\n", state.c_str());
// if (state=="open") {
// building->GetTransition(id)->Open();
// }
// else if (state=="close") {
// building->GetTransition(id)->Close();
// }
// else {
// Log->Write("WARNING:\t Unknown door state: <%s>. open or close. Default: open", state.c_str());
// }
// }
sprintf(tmp, "\t>> state: %s\n", stateStr.c_str());
str.append(tmp);
//------------------ outflow
double outflow = xmltof(xDoor->Attribute("outflow"), -1.0);
......
......@@ -40,7 +40,6 @@
#include "../math/GradientModel.h"
#include "../math/VelocityModel.h"
#include "../routing/global_shortest/GlobalRouter.h"
#include "../routing/global_shortest_trips/GlobalRouterTrips.h"
#include "../routing/quickest/QuickestPathRouter.h"
#include "../routing/smoke_router/SmokeRouter.h"
#include "../routing/ai_router/AIRouter.h"
......@@ -1137,13 +1136,6 @@ bool IniFileParser::ParseRoutingStrategies(TiXmlNode* routingNode, TiXmlNode* ag
Router *r = new GlobalRouter(id, ROUTING_GLOBAL_SHORTEST);
_config->GetRoutingEngine()->AddRouter(r);
}
else if ((strategy == "global_shortest_trips") &&
(std::find(usedRouter.begin(), usedRouter.end(), id) != usedRouter.end()) ) {
//pRoutingStrategies.push_back(make_pair(id, ROUTING_GLOBAL_SHORTEST));
Router *r = new GlobalRouterTrips(id, ROUTING_GLOBAL_SHORTEST);
_config->GetRoutingEngine()->AddRouter(r);
}
else if ((strategy == "quickest") &&
(std::find(usedRouter.begin(), usedRouter.end(), id) != usedRouter.end()) ) {
//pRoutingStrategies.push_back(make_pair(id, ROUTING_QUICKEST));
......
......@@ -349,9 +349,10 @@ void Simulation::UpdateRoutesAndLocations()
if(_gotSources)
ped->FindRoute();
//finally actualize the route
if ( !_gotSources && ped->FindRoute() == -1) {
if ( !_gotSources && ped->FindRoute() == -1 ) {
//a destination could not be found for that pedestrian
Log->Write("ERROR: \tCould not find a route for pedestrian %d",ped->GetID());
Log->Write("ERROR: \tCould not find a route for pedestrian %d in room %d and subroom %d",
ped->GetID(), ped->GetRoomID(), ped->GetSubRoomID());
//ped->FindRoute(); //debug only, plz remove
std::function<void(const Pedestrian&)> f = std::bind(&Simulation::UpdateFlowAtDoors, this, std::placeholders::_1);
ped->Relocate(f);
......@@ -578,20 +579,22 @@ double Simulation::RunBody(double maxSimTime)
#endif
// here open transition that should be closed
// TODO fix, opens door everytime...
for (auto& itr: _building->GetAllTransitions())
{
Transition* Trans = itr.second;
if(Trans->isTemporaryClosed())
if(Trans->IsTempClose())
{
Trans->UpdateClosingTime( _deltaT);
if(Trans->GetClosingTime() <= _deltaT)
{
Trans->changeTemporaryState();
Log-> Write("INFO:\tReset state of door %d, Time=%.2f", Trans->GetID(), Pedestrian::GetGlobalTime());
if ((Trans->GetMaxDoorUsage() != std::numeric_limits<int>::max()) ||
(Trans->GetOutflowRate() != std::numeric_limits<double>::max()) ){
// || (Trans->GetOutflowRate() != std::numeric_limits<double>::max)){
Trans->UpdateClosingTime( _deltaT);
if(Trans->GetClosingTime() <= _deltaT){
Trans->changeTemporaryState();
}
Log-> Write("INFO:\tReset state of door %d, Time=%.2f", Trans->GetID(), Pedestrian::GetGlobalTime());
}
}
}
}// while time
return t;
......
......@@ -41,7 +41,6 @@
#include "math/OperationalModel.h"
#include "math/ODESolver.h"
#include "routing/global_shortest/GlobalRouter.h"
#include "routing/global_shortest_trips/GlobalRouterTrips.h"
#include "routing/quickest/QuickestPathRouter.h"
#include "routing/DirectionStrategy.h"
#include "routing/RoutingEngine.h"
......
......@@ -13,7 +13,7 @@ Event::Event(int id, double time, const std::string& type,
_id=id;
_time=time;
_type=type;
_state=state;
_state= StringToDoorState(state);
}
Event::~Event()
......@@ -25,7 +25,7 @@ int Event::GetId() const
return _id;
}
const std::string& Event::GetState() const
const DoorState Event::GetState() const
{
return _state;
}
......@@ -43,6 +43,21 @@ const std::string& Event::GetType() const
const std::string Event::GetDescription() const
{
char tmp[1024];
sprintf(tmp,"After %.2f sec, %s door %d", _time,_state.c_str(), _id);
std::string state;
switch (_state){
case DoorState::OPEN:
state = "open";
break;
case DoorState::CLOSE:
state = "close";
break;
case DoorState::TEMP_CLOSE:
state = "temp_close";
break;
default:
state = "error";
break;
}
sprintf(tmp,"After %.2f sec, %s door %d", _time, state.c_str(), _id);
return std::string(tmp);
}
......@@ -9,6 +9,7 @@
#define EVENTS_EVENT_H_
#include <string>
#include "../general/Macros.h"
class Event
{
......@@ -37,7 +38,7 @@ public:
/**
* @return the state (open, close) of the event
*/
const std::string& GetState() const;
const DoorState GetState() const;
/**
* @return the time at which the event was recorded
......@@ -58,7 +59,7 @@ private:
double _time;
int _id;
std::string _type;
std::string _state;
DoorState _state;
};
#endif /* EVENTS_EVENT_H_ */
......@@ -38,7 +38,6 @@
#include "../geometry/SubRoom.h"
#include "../tinyxml/tinyxml.h"
#include "../routing/global_shortest/GlobalRouter.h"
#include "../routing/global_shortest_trips/GlobalRouterTrips.h"
#include "../routing/quickest/QuickestPathRouter.h"
#include "../routing/smoke_router/SmokeRouter.h"
#include "../routing/ff_router/ffRouter.h"
......@@ -259,25 +258,26 @@ bool EventManager::DisseminateKnowledge(Building* _b)
}
//TODO Was passiert hier?
//update the routers based on the configurations
//#pragma omp parallel
for(auto&& ped:_b->GetAllPedestrians())
{
if(UpdateRoute(ped)==false)
{
//Clear the memory and attempt to reroute
//this can happen if all doors are known to be closed
ped->ClearKnowledge();
Log->Write("ERROR: \t clearing ped knowledge");
//ped->Dump(ped->GetID());
if(UpdateRoute(ped)==false)
{
Log->Write("ERROR: \t cannot reroute the pedestrian. unknown problem");
//return false;
exit(EXIT_FAILURE);
}
}
}
// for(auto&& ped:_b->GetAllPedestrians())
// {
// if(UpdateRoute(ped)==false)
// {
// //Clear the memory and attempt to reroute
// //this can happen if all doors are known to be closed
// ped->ClearKnowledge();
// Log->Write("ERROR: \t clearing ped knowledge");
// //ped->Dump(ped->GetID());
// if(UpdateRoute(ped)==false)
// {
// Log->Write("ERROR: \t cannot reroute the pedestrian. unknown problem");
// //return false;
// exit(EXIT_FAILURE);
// }
// }
// }
return true;
}
......@@ -286,8 +286,17 @@ bool EventManager::UpdateRoute(Pedestrian* ped)
//create the key as string.
//map are sorted by default
string key= ped->GetKnowledgeAsString();
// std::cout << "key: <" << key << ">" << std::endl;
//get the router engine corresponding to the actual configuration
bool status=true;
// for (auto event : _eventEngineStorage){
// std::cout << "_eventEngineStorage " << event.first << ": " << std::endl;
// for (auto router : event.second->GetAvailableRouters()){
// std::cout << router->GetStrategy() << std::endl;
// }
// }
if (_eventEngineStorage.count(key)>0)
{
RoutingEngine* engine=_eventEngineStorage[key];
......@@ -309,9 +318,9 @@ bool EventManager::UpdateRoute(Pedestrian* ped)
}
else
{
//Log->Write("WARNING: \t unknown configuration <%s>", key.c_str());
//Log->Write("WARNING: \t [%d] router available", _eventEngineStorage.size());
//Log->Write(" : \t trying to create");
// Log->Write("WARNING: \t unknown configuration <%s>", key.c_str());
// Log->Write("WARNING: \t [%d] router available", _eventEngineStorage.size());
// Log->Write(" : \t trying to create");
//CreateRoutingEngine(_building);
status= false;
}
......@@ -517,10 +526,16 @@ void EventManager::ProcessEvent()
if (fabs(event.GetTime() - current_time_d) < J_EPS_EVENT) {
//Event with current time stamp detected
Log->Write("INFO:\tEvent: after %.2f sec: ", current_time_d);
if (event.GetState().compare("close") == 0) {
CloseDoor(event.GetId());
} else {
switch (event.GetState()){
case DoorState::OPEN:
OpenDoor(event.GetId());
break;
case DoorState::CLOSE:
CloseDoor(event.GetId());
break;
case DoorState::TEMP_CLOSE:
TempCloseDoor(event.GetId());
break;
}
}
......@@ -535,7 +550,7 @@ void EventManager::CloseDoor(int id)
{
Transition *t = _building->GetTransition(id);
if (t->IsOpen())
if (!t->IsClose())
{
t->Close();
Log->Write("INFO:\tClosing door %d ", id);
......@@ -550,6 +565,26 @@ void EventManager::CloseDoor(int id)
}
void EventManager::TempCloseDoor(int id)
{
Transition *t = _building->GetTransition(id);
if (!t->IsTempClose())
{
t->TempClose();
Log->Write("INFO:\tClosing door %d ", id);
//Create and save a graph corresponding to the actual state of the building.
if(CreateRoutingEngine(_building)==false)
{
Log->Write("ERROR: \tcannot create a routing engine with the new event");
}
} else {
Log->Write("WARNING: \tdoor %d is already close", id);
}
}
//open the door if it was open and relaunch the routing procedure
void EventManager::OpenDoor(int id)
{
......@@ -605,7 +640,7 @@ bool EventManager::CreateRoutingEngine(Building* _b, int first_engine)
for(auto&& t:_b->GetAllTransitions())
{
if(t.second->IsOpen()==false)
if(!t.second->IsClose())
closed_doors.push_back(t.second->GetID());
}
std::sort(closed_doors.begin(), closed_doors.end());
......@@ -670,11 +705,11 @@ Router * EventManager::CreateRouter(const RoutingStrategy& strategy)
switch(strategy)
{
case ROUTING_LOCAL_SHORTEST:
rout = new GlobalRouterTrips(ROUTING_LOCAL_SHORTEST, ROUTING_LOCAL_SHORTEST);
rout = new GlobalRouter(ROUTING_LOCAL_SHORTEST, ROUTING_LOCAL_SHORTEST);
break;
case ROUTING_GLOBAL_SHORTEST:
rout = new GlobalRouterTrips(ROUTING_GLOBAL_SHORTEST, ROUTING_GLOBAL_SHORTEST);
rout = new GlobalRouter(ROUTING_GLOBAL_SHORTEST, ROUTING_GLOBAL_SHORTEST);
break;
case ROUTING_QUICKEST:
......
......@@ -74,6 +74,7 @@ public:
void ProcessEvent();
//Eventhandling
void CloseDoor(int id);
void TempCloseDoor(int id);
void OpenDoor(int id);
//void ChangeRouting(int id, const std::string& state);
void GetEvent(char* c);
......
......@@ -43,7 +43,6 @@
#include "ArgumentParser.h"
#include "../pedestrian/AgentsParameters.h"
#include "../routing/global_shortest/GlobalRouter.h"
#include "../routing/global_shortest_trips/GlobalRouterTrips.h"
#include "../routing/quickest/QuickestPathRouter.h"
#include "../routing/smoke_router/SmokeRouter.h"
#include "../IO/IniFileParser.h"
......
......@@ -225,6 +225,27 @@ enum USERMODE {
DISTANCE_AND_DIRECTIONS_USED
};
// Describes the door
enum class DoorState { OPEN, CLOSE, TEMP_CLOSE, ERROR };
inline DoorState StringToDoorState(std::string name){
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
if (name.compare("open") == 0){
return DoorState::OPEN;
}
if (name.compare("temp_close") == 0){
return DoorState::TEMP_CLOSE;
}
if (name.compare("close") == 0){
return DoorState::CLOSE;
}
return DoorState::ERROR;
};
constexpr double magicnum(int i) {
return (i == UNKNOWN_DISTANCE) ? -3.0 : (i == UNKNOWN_COST) ? -2.0 : (i == WALL_ON_COSTARRAY) ? -7.0 : (i == TARGET_REGION) ? 0.0 : J_NAN;
// switch (i) {
......
......@@ -370,6 +370,9 @@ bool Building::InitGeometry()
for (auto& transItr : _transitions){
Transition* trans = transItr.second;
std::cout << trans->GetID() << " is open " << trans->IsOpen() << std::endl;
std::cout << trans->GetID() << " is close " << trans->IsClose() << std::endl;
std::cout << trans->GetID() << " is temp_close " << trans->IsTempClose() << std::endl;
}
return true;
}
......
......@@ -35,9 +35,6 @@ using namespace std;
Crossing::Crossing()
{
_id = -1;
_isOpen=true;
_temporaryClosed=false; // some doors have to be closed and opened again
// depending on _outflowRate.
_doorUsage = 0;
_maxDoorUsage = (std::numeric_limits<int>::max)(); //avoid name conflicts in windows winmindef.h
_outflowRate = (std::numeric_limits<double>::max)();
......@@ -48,6 +45,7 @@ Crossing::Crossing()
_partialDoorUsage = 0;
_closingTime = 0;
_state = DoorState::OPEN;
}
Crossing::~Crossing()
......@@ -86,7 +84,17 @@ bool Crossing::IsExit() const
bool Crossing::IsOpen() const
{
return _isOpen;
return _state == DoorState::OPEN;
}
bool Crossing::IsClose() const
{
return _state == DoorState::CLOSE;
}
bool Crossing::IsTempClose() const
{
return _state == DoorState::TEMP_CLOSE;
}
bool Crossing::IsTransition() const
......@@ -96,12 +104,18 @@ bool Crossing::IsTransition() const
void Crossing::Close()
{
_isOpen = false;
_state = DoorState::CLOSE;
}
void Crossing::TempClose()
{
_state = DoorState::TEMP_CLOSE;
}
void Crossing::Open()
{
_isOpen = true;
_state = DoorState::OPEN;
}
bool Crossing::IsInSubRoom(int subroomID) const
......@@ -141,10 +155,10 @@ void Crossing::WriteToErrorLog() const
string s;
char tmp[CLENGTH];
sprintf(tmp, "\t\tCROSS: %d (%f, %f) -- (%f, %f)\n", GetID(), GetPoint1()._x,
GetPoint1()._y, GetPoint2()._x, GetPoint2()._y);
GetPoint1()._y, GetPoint2()._x, GetPoint2()._y);
s.append(tmp);
sprintf(tmp, "\t\t\t\tSubRoom: %d <-> SubRoom: %d\n", GetSubRoom1()->GetSubRoomID(),
GetSubRoom2()->GetSubRoomID());
GetSubRoom2()->GetSubRoomID());
s.append(tmp);
Log->Write(s);
}
......@@ -159,14 +173,14 @@ string Crossing::GetDescription() const
geometry.append(tmp);
//geometry.append("\t\t<door color=\"250\">\n");
sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\" />\n",
(GetPoint1()._x) * FAKTOR,
(GetPoint1()._y) * FAKTOR,
_subRoom1->GetElevation(GetPoint1())*FAKTOR);
(GetPoint1()._x) * FAKTOR,
(GetPoint1()._y) * FAKTOR,
_subRoom1->GetElevation(GetPoint1())*FAKTOR);
geometry.append(tmp);
sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\" />\n",
(GetPoint2()._x) * FAKTOR,
(GetPoint2()._y) * FAKTOR,
_subRoom1->GetElevation(GetPoint2())*FAKTOR);
(GetPoint2()._x) * FAKTOR,
(GetPoint2()._y) * FAKTOR,
_subRoom1->GetElevation(GetPoint2())*FAKTOR);
geometry.append(tmp);
geometry.append("\t\t</crossing>\n");
return geometry;
......@@ -255,11 +269,6 @@ void Crossing::UpdateClosingTime(double dt)
_closingTime -= dt;
}
bool Crossing::isTemporaryClosed()
{
return _temporaryClosed;
}
double Crossing::GetDT()
{
......@@ -297,23 +306,9 @@ void Crossing::regulateFlow(double time)
// --> [1]
//---------------------------
_closingTime = number / _outflowRate - T; //[1]
_temporaryClosed = true;
this->Close();
// _temporaryClosed = true;
// this->Close();
this->TempClose();
Log-> Write("INFO:\tClosing door %d. DoorUsage = %d (max = %d). Flow = %.2f (max = %.2f) Time=%.2f", GetID(), GetDoorUsage(), GetMaxDoorUsage(), flow, _outflowRate, time);
}
......@@ -322,14 +317,45 @@ void Crossing::regulateFlow(double time)
{
Log-> Write("INFO:\tClosing door %d. DoorUsage = %d (>= %d). Time=%.2f", GetID(), GetDoorUsage(), GetMaxDoorUsage(), time);
this->Close();
_temporaryClosed = false;
// _temporaryClosed = false;
}
_lastFlowMeasurement = time + _closingTime;
}
void Crossing::changeTemporaryState()
{
_temporaryClosed = false;
_closingTime = 0;
this->Open();
// _temporaryClosed = false;
_closingTime = 0;
this->Open();
}
DoorState Crossing::GetState() const
{
return _state;
}
void Crossing::SetState(DoorState _state)
{
Crossing::_state = _state;
}
std::string Crossing::toString() const
{
std::stringstream tmp;
// tmp << _point1.toString() << "--" << _point2.toString();
tmp << this->GetPoint1().toString() << "--" << this->GetPoint2().toString();
switch (_state){
case DoorState::OPEN:
tmp << " open";
break;
case DoorState::CLOSE:
tmp << " close";
break;
case DoorState::TEMP_CLOSE:
tmp << " temp_close";
break;
}
return tmp.str();
}
......@@ -39,193 +39,194 @@ class SubRoom;
class Crossing : public Hline {
private:
// /// TODO ? unique between crossings and transitions ?
// int _id;
/// only one room needed, since a crossing only separates 2 subrooms
//Room* _room1;
//SubRoom* _subRoom1;
//SubRoom* _subRoom2;