Commit 32795a9e authored by Mohcine Chraibi's avatar Mohcine Chraibi

Parsing train tables and types

- Parsing these information in two separate files
- Format in #300
parent 02706b98
This diff is collapsed.
......@@ -44,6 +44,11 @@ public:
Goal* parseGoalNode(TiXmlElement * e);
Transition* parseTransitionNode(TiXmlElement * xTrans, Building * building);
Goal* parseWaitingAreaNode(TiXmlElement * e);
bool LoadTrainInfo(Building* building);
bool LoadTrainTimetable(Building* building, TiXmlElement * xRootNode);
bool LoadTrainType(Building* building, TiXmlElement * xRootNode);
std::shared_ptr<TrainType> parseTrainTypeNode(TiXmlElement * e);
std::shared_ptr<TrainTimeTable> parseTrainTimeTableNode(TiXmlElement * e);
private:
Configuration* _configuration;
......
......@@ -370,16 +370,69 @@ std::string getEventFileName(const std::string & GetProjectFile)
TiXmlNode* xMainNode = doc.RootElement();
string eventfile = "";
if (xMainNode->FirstChild("events_file")) {
ret = xMainNode->FirstChild("events_file")->FirstChild()->Value();
Log->Write("INFO: \tevents <" + eventfile + ">");
ret = xMainNode->FirstChild("events_file")->FirstChild()->ValueStr();
Log->Write("INFO: \tevents <" + ret + ">");
} else {
Log->Write("INFO: \tNo events found");
return ret;
}
return ret;
}
// <train_constraints>
// <train_time_table>ttt.xml</train_time_table>
// <train_types>train_types.xml</train_types>
// </train_constraints>
std::string getTrainTimeTableFileName(const std::string & GetProjectFile)
{
std::string ret="";
TiXmlDocument doc(GetProjectFile);
if (!doc.LoadFile()) {
Log->Write("ERROR: \t%s", doc.ErrorDesc());
Log->Write("ERROR: \tGetTrainTimeTable could not parse the project file");
return ret;
}
TiXmlNode* xMainNode = doc.RootElement();
string tttfile = "";
if (xMainNode->FirstChild("train_constraints")) {
TiXmlNode * xFileNode = xMainNode->FirstChild("train_constraints")->FirstChild("train_time_table");
if(xFileNode)
ret = xFileNode->FirstChild()->ValueStr();
Log->Write("INFO: \ttrain_time_table <" + ret + ">");
} else {
Log->Write("INFO: \tNo events no ttt file found");
return ret;
}
return ret;
}
std::string getTrainTypeFileName(const std::string & GetProjectFile)
{
std::string ret="";
TiXmlDocument doc(GetProjectFile);
if (!doc.LoadFile()) {
Log->Write("ERROR: \t%s", doc.ErrorDesc());
Log->Write("ERROR: \tGetTrainType could not parse the project file");
return ret;
}
TiXmlNode* xMainNode = doc.RootElement();
string tttfile = "";
if (xMainNode->FirstChild("train_constraints")) {
auto xFileNode = xMainNode->FirstChild("train_constraints")->FirstChild("train_types");
if(xFileNode)
ret = xFileNode->FirstChild()->ValueStr();
Log->Write("INFO: \ttrain_types <" + ret + ">");
} else {
Log->Write("INFO: \tNo events no train types file found");
return ret;
}
return ret;
}
std::string getGoalFileName(const std::string & GetProjectFile)
{
std::string ret="";
......@@ -411,6 +464,8 @@ void TrajectoriesFLAT::WriteHeader(long nPeds, double fps, Building* building, i
std::string sourceFileName = getSourceFileName(building->GetProjectFilename());
std::string goalFileName = getGoalFileName(building->GetProjectFilename());
std::string eventFileName = getEventFileName(building->GetProjectFilename());
std::string trainTimeTableFileName = getTrainTimeTableFileName(building->GetProjectFilename());
std::string trainTypeFileName = getTrainTypeFileName(building->GetProjectFilename());
(void) seed; (void) nPeds;
char tmp[100] = "";
sprintf(tmp, "#description: jpscore (%s)", JPSCORE_VERSION);
......@@ -436,6 +491,16 @@ void TrajectoriesFLAT::WriteHeader(long nPeds, double fps, Building* building, i
sprintf(tmp,"#events: %s", eventFileName.c_str());
Write(tmp);
}
if( trainTimeTableFileName != "")
{
sprintf(tmp,"#trainTimeTable: %s", trainTimeTableFileName.c_str());
Write(tmp);
}
if( trainTypeFileName != "")
{
sprintf(tmp,"#trainType: %s", trainTypeFileName.c_str());
Write(tmp);
}
Write("#ID: the agent ID");
Write("#FR: the current frame");
Write("#X,Y,Z: the agents coordinates (in metres)");
......
......@@ -1635,6 +1635,9 @@ bool IniFileParser::ParseStrategyNodeToObject(const TiXmlNode& strategyNode)
};
_config->set_dirStrategy(dynamic_cast<DirectionSubLocalFloorfieldTripsVoronoi*>(_exit_strategy.get()));
break;
case 12:
_exit_strategy = std::shared_ptr<DirectionStrategy>(new DirectionTrain());
break;
default:
_exit_strategy = std::shared_ptr<DirectionStrategy>(new DirectionMinSeperationShorterLine());
......
This diff is collapsed.
......@@ -49,6 +49,9 @@
#include "events/EventManager.h"
#include "pedestrian/AgentsSourcesManager.h"
#include "general/Configuration.h"
#include <filesystem>
//Forward declarations
//class AgentsSourcesManager;
......@@ -88,6 +91,8 @@ private:
int _maxSimTime;
bool _gotSources; // is true if we got some sources. Otherwise, false.
bool _trainConstraints; // true if inifile has some train constraints
// bool _printPB; // print progressbar
public:
/**
......@@ -185,6 +190,11 @@ public:
*/
void UpdateDoorticks() const;
int GetMaxSimTime() const;
void incrementCountTraj();
bool correctGeometry(std::shared_ptr<Building> building, std::shared_ptr<TrainTimeTable>);
bool WriteTrajectories(std::string trajName);
bool TrainTraffic();
int _countTraj=0; // count number of TXT trajectories to produce
double _maxFileSize; // in MB
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -45,6 +45,43 @@
#include "Goal.h"
#include "../general/Configuration.h"
typedef std::pair<Point, Wall> PointWall;
// train schedules: Trains get deleted and added.
struct Platform
{
int id;
int rid;
int sid;
std::map<int, std::vector<Wall> > tracks;
};
struct TrainTimeTable
{
int id;
std::string type;
int rid; // room id
int sid; // subroom id
double tin; // arrival time
double tout; //leaving time
Point pstart; // track start
Point pend; // track end
Point tstart; // train start
Point tend; // train end
int pid; // Platform id
bool arrival;
bool departure;
};
struct TrainType
{
std::string type;
int nmax; // agents_max
float len; //length
std::vector<Transition> doors;
};
class RoutingEngine;
class Pedestrian;
......@@ -74,8 +111,9 @@ private:
std::map<int, Transition*> _transitions;
std::map<int, Hline*> _hLines;
std::map<int, Goal*> _goals;
std::map<int, std::vector<WaitingArea*>> _sr2wa;
std::map<std::string, std::shared_ptr<TrainType> > _trainTypes;
std::map<int, std::shared_ptr<TrainTimeTable> > _trainTimeTables;
std::map<int, std::shared_ptr<Platform> > _platforms;
/// pedestrians pathway
bool _savePathway;
std::ofstream _pathWayStream;
......@@ -83,10 +121,13 @@ private:
public:
/// constructor
Building();
std::map<int, std::vector<Wall> > TempAddedWalls; // map to trainTimeTable
std::map<int, std::vector<Wall> > TempRemovedWalls;
std::map<int, std::vector<Transition> > TempAddedDoors;
// Building(const std::string &, const std::string &, RoutingEngine &, PedDistributor &, double);
Building(Configuration* config, PedDistributor& pedDistributor);
bool resetGeometry(std::shared_ptr<TrainTimeTable> tab);
/// destructor
virtual ~Building();
......@@ -176,7 +217,7 @@ public:
*/
Transition* GetTransitionByUID(int uid) const;
Crossing* GetCrossingByUID(int uid) const;
Crossing* GetCrossingByUID(int uid) const;
//TOD0: rename later to GetGoal
Goal* GetFinalGoal(int id) const;
......@@ -208,15 +249,33 @@ public:
const std::map<int, Hline*>& GetAllHlines() const;
const std::map<int, Goal*>& GetAllGoals() const;
// --------------- Trains interface
const std::map<std::string, std::shared_ptr<TrainType> >& GetTrainTypes() const;
const std::map<int, std::shared_ptr<TrainTimeTable> >& GetTrainTimeTables() const;
const std::map<int, std::shared_ptr<Platform> >& GetPlatforms() const;
const std::vector<Wall> GetTrackWalls(Point TrackStart, Point TrackEnd, int & room_id, int & subroom_id) const;
const std::vector<std::pair<PointWall, PointWall > > GetIntersectionPoints(const std::vector<Transition> doors, const std::vector<Wall>) const;
// ------------------------------------
bool AddCrossing(Crossing* line);
bool RemoveTransition(Transition * line);
bool AddTransition(Transition* line);
bool AddHline(Hline* line);
bool AddGoal(Goal* goal);
bool AddTrainType(std::shared_ptr<TrainType> TT);
bool AddTrainTimeTable(std::shared_ptr<TrainTimeTable> TTT);
bool AddPlatform(std::shared_ptr<Platform> P);
const std::string& GetProjectRootDir() const;
const std::string& GetProjectFilename() const;
......@@ -258,9 +317,9 @@ public:
private:
bool InitInsideGoals();
void StringExplode(std::string str, std::string separator, std::vector<std::string>* results);
bool InitInsideGoals();
bool InitPlatforms();
void StringExplode(std::string str, std::string separator, std::vector<std::string>* results);
/** @defgroup auto-correct-geometry
* functions used to auto-correct the geometry.
* Main function is correct()
......@@ -349,7 +408,7 @@ private:
* @param subroom
* @return bool
*/
bool RemoveOverlappingDoors(
bool RemoveOverlappingDoors(
const std::shared_ptr<SubRoom>& subroom) const;
/** @} */ // end of group
......
......@@ -334,9 +334,9 @@ DoorState Crossing::GetState() const
return _state;
}
void Crossing::SetState(DoorState _state)
void Crossing::SetState(DoorState state)
{
Crossing::_state = _state;
Crossing::_state = state;
}
std::string Crossing::toString() const
......@@ -355,6 +355,9 @@ std::string Crossing::toString() const
case DoorState::TEMP_CLOSE:
tmp << " temp_close";
break;
case DoorState::Error:
tmp << " Error";
break;
}
return tmp.str();
......
......@@ -201,6 +201,16 @@ Point Line::LotPoint(const Point& p) const
return f;
}
// return true if point the orthogonal projection of p on Line segment is on the
// line segment.
bool Line::isBetween(const Point& p) const
{
const Point& t = _point1-_point2;
double lambda = (p-_point2).ScalarProduct(t)/t.ScalarProduct(t);
return (lambda>0) && (lambda <1);
}
/* Punkt auf der Linie mit kürzestem Abstand zu p
* In der Regel Lotfußpunkt, Ist der Lotfußpunkt nicht im Segment
* wird der entsprechende Eckpunkt der Line genommen
......@@ -273,6 +283,12 @@ bool Line::operator!=(const Line& l) const
return (!(*this==l));
}
// this function is necessary to use std::set and is basically the same as !=
bool Line::operator<(const Line& l) const
{
return (!(*this==l));
}
double Line::GetLength() const
{
......@@ -350,7 +366,8 @@ int Line::IntersectionWith(const Point& p1, const Point& p2, Point& p3) const
double t = (_point1-p1).CrossProduct(s)/(r.CrossProduct(s));
double u = (_point1-p1).CrossProduct(r)/(r.CrossProduct(s));
if (0>t || t>1) {
if (-0.05>t || t>1) {
return LineIntersectType::NO_INTERSECTION;
}
......@@ -448,6 +465,7 @@ int Line::WichSide(const Point& pt)
bool Line::ShareCommonPointWith(const Line& line, Point& P) const
{
if (line.GetPoint1()==_point1 || line.GetPoint2()==_point1) {
P = _point1;
return true;
......@@ -472,6 +490,23 @@ bool Line::HasEndPoint(const Point& point) const
return _point2==point;
}
bool Line::NearlyHasEndPoint(const Point& point) const
{
// std::cout << _point1.toString() << "\n";
// std::cout << _point2.toString() << "\n";
// std::cout << point.toString() << "\n";
// std::cout << "--> " << (_point1-point).Norm() << "\n";
// std::cout << "--> " << (_point2-point).Norm() << "\n";
// std::cout << "<-- " << J_EPS_DIST << "\n";
if ((_point1-point).Norm() <= J_EPS_DIST) return true;
return ((_point2-point).Norm() <= J_EPS_DIST);
}
bool Line::IntersectionWithCircle(const Point& centre, double radius /*cm for pedestrians*/)
{
......
......@@ -134,6 +134,7 @@ public:
bool IsInLineSegment(const Point& p) const;
bool NearlyInLineSegment(const Point& p) const;
bool NearlyHasEndPoint(const Point& point) const;
/**
* @return the distance from the line to the point p
......@@ -161,6 +162,12 @@ public:
*/
bool Overlapp(const Line& l) const;
/**
* return true if point the orthogonal projection of p on Line segment is on the
* line segment.
*/
bool isBetween(const Point& p) const;
/**
* @return true if both segments are equal. The end points must be in the range of J_EPS.
* @see Macro.h
......@@ -173,6 +180,15 @@ public:
*/
bool operator!=(const Line& l) const;
/**
* @return true if this < l segments are not equal. The end points must be in the range of J_EPS.
* @see Macro.h
*/
bool operator<(const Line& l) const;
/**
* @see http://alienryderflex.com/intersect/
* @see http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/e5993847-c7a9-46ec-8edc-bfb86bd689e3/
......
......@@ -247,9 +247,23 @@ bool SubRoom::AddCrossing(Crossing* line)
_goalIDs.push_back(line->GetUniqueID());
return true;
}
// return true is walls was erased, otherwise false.
bool SubRoom::RemoveTransition(Transition * t)
{
auto it = std::find(_transitions.begin(), _transitions.end(), t);
if (it != _transitions.end()) {
// std::cout << "subroom remove transition "<< t->GetID() << ", " << t->GetUniqueID()<< "\n";
_transitions.erase(it);
RemoveGoalID(t->GetUniqueID());
// std::cout << "enter Remove Transitions with " << _transitions.size() << "\n";
return true;
}
// std::cout << "2 enter Remove Transitions with " << _transitions.size() << "\n";
return false;
}
bool SubRoom::AddTransition(Transition* line)
{
// std::cout << "subroom addtransition "<< line->GetID() << ", " << line->GetUniqueID()<< "\n";
_transitions.push_back(line);
_goalIDs.push_back(line->GetUniqueID());
return true;
......
......@@ -304,6 +304,7 @@ public:
//navigation
bool AddCrossing(Crossing* line);
bool AddTransition(Transition* line);
bool RemoveTransition(Transition * t);
bool AddHline(Hline* line);
void AddNeighbor(SubRoom* sub);
......
......@@ -212,7 +212,7 @@ void VelocityModel::ComputeNextTimeStep(double current, double deltaT, Building*
for (int i = 0; i < size; i++) {
Pedestrian* ped1 = neighbours[i];
// if (ped->GetID() == 71) {
// std::cout << "Velocity Model debug ped1: " << ped1->GetID() << "\t" << ped1->GetPos().toString() <<std::endl;
......@@ -293,11 +293,11 @@ void VelocityModel::ComputeNextTimeStep(double current, double deltaT, Building*
spacings.clear(); //clear for ped p
// stuck peds get removed. Warning is thrown. low speed due to jam is omitted.
if(ped->GetTimeInJam() > ped->GetPatienceTime() && ped->GetGlobalTime() > 30 + ped->GetPremovementTime() &&
if(ped->GetTimeInJam() > ped->GetPatienceTime() && ped->GetGlobalTime() > 10000 + ped->GetPremovementTime() &&
std::max(ped->GetMeanVelOverRecTime(), ped->GetV().Norm()) < 0.01 &&
size == 0 ) // size length of peds neighbour vector
{
Log->Write("WARNING:\tped %d with vmean %f has been deleted in room [%i]/[%i] after time %f s (current=%f\n", ped->GetID(), ped->GetMeanVelOverRecTime(), ped->GetRoomID(), ped->GetSubRoomID(), ped->GetGlobalTime(), current);
Log->Write("WARNING:\tped %d with vmean %f has been deleted in room [%i]/[%i] after time %f s (current=%f\n", ped->GetID(), ped->GetMeanVelOverRecTime(), ped->GetRoomID(), ped->GetSubRoomID(), ped->GetGlobalTime(), current);
Log->incrementDeletedAgents();
#pragma omp critical(VelocityModel_ComputeNextTimeStep_pedsToRemove)
pedsToRemove.push_back(ped);
......@@ -352,9 +352,19 @@ Point VelocityModel::e0(Pedestrian* ped, Room* room) const
Point target;
if(_direction && ped->GetExitLine())
target = _direction->GetTarget(room, ped); // target is where the ped wants to be after the next timestep
else {
else { //@todo: we need a model for waiting pedestrians
std::cout << ped->GetID() << " VelocityModel::e0 Ped has no navline.\n";
exit(EXIT_FAILURE);
//exit(EXIT_FAILURE);
// set random destination
std::mt19937 mt(ped->GetBuilding()->GetConfig()->GetSeed());
std::uniform_real_distribution<double> dist(0, 1.0);
double random_x = dist(mt);
double random_y = dist(mt);
Point P1 = Point(ped->GetPos()._x - random_x, ped->GetPos()._y - random_y);
Point P2 = Point(ped->GetPos()._x + random_x, ped->GetPos()._y + random_y);
const NavLine L = Line(P1, P2);
ped->SetExitLine((const NavLine *)&L);
target = P1;
}
Point desired_direction;
const Point pos = ped->GetPos();
......
......@@ -167,7 +167,7 @@ Point DirectionGeneral::GetTarget(Room* room, Pedestrian* ped) const
#if DEBUG
printf("\n----------\nEnter GetTarget() with PED=%d\n----------\n",ped->GetID());
printf("nextPointOn Line: %f %f\n", NextPointOnLine.GetX(), NextPointOnLine.GetY());
printf("nextPointOn Line: %f %f\n", NextPointOnLine._x, NextPointOnLine._y);
#endif
double dist;
int inear = -1;
......@@ -186,7 +186,7 @@ Point DirectionGeneral::GetTarget(Room* room, Pedestrian* ped) const
#if DEBUG
printf("Check wall number %d. Dist = %f (%f)\n", i, dist, minDist);
printf("%f %f --- %f %f\n===========\n",walls[i].GetPoint1().GetX(),walls[i].GetPoint1().GetY(), walls[i].GetPoint2().GetX(),walls[i].GetPoint2().GetY());
printf("%f %f --- %f %f\n===========\n",walls[i].GetPoint1()._x,walls[i].GetPoint1()._y, walls[i].GetPoint2()._x,walls[i].GetPoint2()._y);
#endif
}
......@@ -207,7 +207,7 @@ Point DirectionGeneral::GetTarget(Room* room, Pedestrian* ped) const
iObs = obs;
#if DEBUG
printf("Check OBS:obs=%d, i=%d Dist = %f (%f)\n", obs, i, dist, minDist);
printf("%f %f --- %f %f\n===========\n",owalls[i].GetPoint1().GetX(),owalls[i].GetPoint1().GetY(), owalls[i].GetPoint2().GetX(),owalls[i].GetPoint2().GetY());
printf("%f %f --- %f %f\n===========\n",owalls[i].GetPoint1()._x,owalls[i].GetPoint1()._y, owalls[i].GetPoint2()._x,owalls[i].GetPoint2()._y);
#endif
}
}//walls of obstacle
......@@ -226,7 +226,7 @@ Point DirectionGeneral::GetTarget(Room* room, Pedestrian* ped) const
// angle = tmpDirection.GetDeviationAngle(owalls[inear].enlarge(2*ped->GetLargerAxis()));
#if DEBUG
printf("COLLISION WITH OBSTACLE %f %f --- %f %f\n===========\n",owalls[inear].GetPoint1().GetX(),owalls[inear].GetPoint1().GetY(), owalls[inear].GetPoint2().GetX(),owalls[inear].GetPoint2().GetY());
printf("COLLISION WITH OBSTACLE %f %f --- %f %f\n===========\n",owalls[inear].GetPoint1()._x,owalls[inear].GetPoint1()._y, owalls[inear].GetPoint2()._x,owalls[inear].GetPoint2()._y);
#endif
} //iObs
......@@ -234,7 +234,7 @@ Point DirectionGeneral::GetTarget(Room* room, Pedestrian* ped) const
angle = tmpDirection.GetDeviationAngle(walls[inear].Enlarge(2*ped->GetLargerAxis()));
#if DEBUG
printf("COLLISION WITH WALL %f %f --- %f %f\n===========\n",walls[inear].GetPoint1().GetX(),walls[inear].GetPoint1().GetY(), walls[inear].GetPoint2().GetX(),walls[inear].GetPoint2().GetY());
printf("COLLISION WITH WALL %f %f --- %f %f\n===========\n",walls[inear].GetPoint1()._x,walls[inear].GetPoint1()._y, walls[inear].GetPoint2()._x,walls[inear].GetPoint2()._y);
#endif
} //else
}//inear
......@@ -263,9 +263,9 @@ Point DirectionGeneral::GetTarget(Room* room, Pedestrian* ped) const
#if DEBUG
printf("inear=%d, iObs=%d, minDist=%f\n", inear, iObs, minDist);
printf("PED=%d\n", ped->GetID());
printf ("MC Posx = %.2f, Posy=%.2f, Lot=[%.2f, %.2f]\n", ped->GetPos().GetX(), ped->GetPos().GetY(), NextPointOnLine.GetX(), NextPointOnLine.GetY());
printf("MC p1=[%.2f, %.2f] p2=[%.2f, %.2f]\n", p1.GetX(), p1.GetY(), p2.GetX(), p2.GetY());
printf("angle=%f, G=[%.2f, %.2f]\n", angle, G.GetX(), G.GetY());
printf ("MC Posx = %.2f, Posy=%.2f, Lot=[%.2f, %.2f]\n", ped->GetPos()._x, ped->GetPos()._y, NextPointOnLine._x, NextPointOnLine._y);
printf("MC p1=[%.2f, %.2f] p2=[%.2f, %.2f]\n", p1._x, p1._y, p2._x, p2._y);
printf("angle=%f, G=[%.2f, %.2f]\n", angle, G._x, G._y);
printf("\n----------\nLEAVE function with PED=%d\n----------\n",ped->GetID());
// getc(stdin);
......@@ -292,7 +292,8 @@ Point DirectionFloorfield::GetTarget(Room* room, Pedestrian* ped) const
{
UNUSED(room);
#if DEBUG
if (initDone && (ffviafm != nullptr)) {
if (1) {
#endif // DEBUG
Point p;
......@@ -351,7 +352,7 @@ DirectionFloorfield::~DirectionFloorfield() {
Point DirectionLocalFloorfield::GetTarget(Room* room, Pedestrian* ped) const
{
#if DEBUG
if (initDone && (ffviafm != nullptr)) {
if (1) {
#endif // DEBUG
Point p;
......@@ -367,6 +368,7 @@ Point DirectionLocalFloorfield::GetTarget(Room* room, Pedestrian* ped) const
// if (floorfield->getCostToDestination(ped->GetExitIndex(), ped->GetPos()) < 1.0) {
// p = p * floorfield->getCostToDestination(ped->GetExitIndex(), ped->GetPos());
// }
Point P = p + ped->GetPos();
return (p + ped->GetPos());
#if DEBUG
......@@ -374,7 +376,7 @@ Point DirectionLocalFloorfield::GetTarget(Room* room, Pedestrian* ped) const
#endif // DEBUG
//this should not execute:
//std::cerr << "Failure in DirectionFloorfield::GetTarget!!" << std::endl;
std::cerr << "Failure in DirectionFloorfield::GetTarget!!" << std::endl;
// exit(EXIT_FAILURE);
}
......@@ -456,7 +458,7 @@ Point DirectionSubLocalFloorfield::GetTarget(Room* room, Pedestrian* ped) const
{
(void)room; // silence warning
#if DEBUG
if (initDone && (ffviafm != nullptr)) {
if (1) {
#endif // DEBUG
Point p;
......@@ -837,3 +839,55 @@ DirectionSubLocalFloorfieldTripsVoronoi::~DirectionSubLocalFloorfieldTripsVorono
}
}
// 12
Point DirectionTrain::GetTarget(Room* room, Pedestrian* ped) const
{
Point p1 = ped->GetExitLine()->GetPoint1();
Point p2 = ped->GetExitLine()->GetPoint2();
Line ExitLine = Line(p1, p2, 0);
auto TrainTypes = ped->GetBuilding()->GetTrainTypes();
auto TrainTimeTables = ped->GetBuilding()->GetTrainTimeTables();
auto now = ped->GetGlobalTime();
string type_delme="";
// std::cout << ">>> Enter with ped at " << ped->GetPos().toString().c_str() << "\n";
for(auto && t: TrainTimeTables)
{
if(ped->GetRoomID() != t.second->rid) continue;
if( (now>=t.second->tin) && (now<=t.second->tout) )
{
auto doors = TrainTypes[t.second->type]->doors;
int i=-1, imin=0;
double dist_min = 10000;
for(auto door: doors)
{
i++;
const Point & d1 = door.GetPoint1();
const Point & d2 = door.GetPoint2();
const Point & c = (d1+d2)*0.5;
double dist = (ped->GetPos()-c).Norm();
// std::cout << "door id: " << door.GetID()<< " dist: " << dist<< "\n";
if(dist <= dist_min)
{
dist_min = dist;