Commit 95086b3f authored by Oliver Schmidts's avatar Oliver Schmidts

Merge branch 'v0.7' of https://cst.version.fz-juelich.de/jupedsim/jpscore into v0.7

parents 8032358c 380bf83e
......@@ -6,15 +6,18 @@ All notable changes to this project will be documented in this file.
### Added
- Changelog file
- Rimea testcases
- risk tolerance factor (value in [0 1]) for pedestrian. Pedestrians with high values are likely to take more risks.
- Boost testcases for geometry functions
- risk tolerance factor (value in [0 1]) for pedestrian. Pedestrians with high values are likely to take more risks.
- Sources for generating agents at runtime. Parameter are frequency(agents per seconds) and maximum number
- Option to color the pedestrians by group,spotlight,velocity,group,knowledge,router,final_goal,intermediate_goal ( <trajectories format="xml-plain" fps="8" color_mode="group">)
### Changed
-
-
### Fixed
-
-
- Visiblity in 3D
- Numerous geometrical operations
### Fixed
-
......
......@@ -158,7 +158,7 @@ void TrajectoriesJPSV04::WriteGeometry(Building* building)
// first the rooms
//to avoid writing navigation line twice
vector<int> navLineWritten;
rooms_to_plot.push_back("U9");
//rooms_to_plot.push_back("U9");
for (const auto& it:building->GetAllRooms())
{
......
......@@ -150,7 +150,7 @@ bool Simulation::InitArgs(const ArgumentParser& args)
case FORMAT_XML_PLAIN: {
OutputHandler* tofile = new FileHandler(
args.GetTrajectoriesFile().c_str());
Trajectories* output = new TrajectoriesJPSV04();
Trajectories* output = new TrajectoriesJPSV05();
output->SetOutputHandler(tofile);
_iod->AddIO(output);
break;
......
......@@ -30,7 +30,7 @@
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "../../geometry/Room.h"
#include "../../general/Macros.h"
#include <string>
BOOST_AUTO_TEST_SUITE(RoomTest)
......@@ -45,11 +45,13 @@ BOOST_AUTO_TEST_CASE(ROOM_CONST_SET_GET_TEST)
R1.SetCaption("Room" + std::to_string(i));
R1.SetZPos(10.0/i);
R1.SetEgressTime(i * 10.0 / 3);
R1.SetState(RoomState(i%2));
Room R2(R1);
BOOST_CHECK(R2.GetID() == i);
BOOST_CHECK(R2.GetCaption() == "Room" + std::to_string(i));
BOOST_CHECK(R2.GetZPos() == 10.0 / i);
BOOST_CHECK(R2.GetEgressTime() == i * 10.0 / 3);
BOOST_CHECK(R2.GetState() == i % 2);
}
BOOST_MESSAGE("Leaving const_set_get test");
}
......
DistributeInSubRoom(sr, N, allpos, &pid,dist,building);
sr -> subroom
N -> no of ped in subroom
pid -> pedestrian id
dist -> room
building -> building
void PedDistributor :: DistributeInSubRoom_MitchellAlg(int nAgents , std::vector<Point>& positions) {
AgentsParameters* agents_para=para->GetGroupParameters();
std::srand(time(0));
int index = rand() % positions.size();
std::vector<std::unique_ptr<Point>> pos;
for (int i = 0; i < nAgents; ++i) {
Pedestrian* ped = new Pedestrian();
// PedIndex
ped->SetID(*pid);
ped->SetAge(para->GetAge());
ped->SetGender(para->GetGender());
ped->SetHeight(para->GetHeight());
ped->SetFinalDestination(para->GetGoalId());
ped->SetGroup(para->GetGroupId());
ped->SetRouter(building->GetRoutingEngine()->GetRouter(para->GetRouterId()));
JEllipse E = JEllipse();
E.SetAv(agents_para->GetAtau());
E.SetAmin(agents_para->GetAmin());
E.SetBmax(agents_para->GetBmax());
E.SetBmin(agents_para->GetBmin());
ped->SetEllipse(E);
ped->SetTau(agents_para->GetTau());
ped->SetV0Norm(agents_para->GetV0(),
agents_para->GetV0DownStairs(),
agents_para->GetV0UpStairs());
if (i > 0) {
std::set<int> candidates;
while (candidates.size() < 10)
candidates.insert(rand() % positions.size());
double dist = 0;
double longest = 0;
for (auto itr :: candidates) {
double shortest = 0;
for (unsigned int j = 0; j < pos.size(); ++j)
dist = (positions[itr] - pos[j]).norm();
if (dist == 0 || dist < shortest)
shortest = dist;
if (shortest > longest) {
longest = shortest;
index = itr;
}
}
}
pos.push_back(positions[index]);
ped->SetPos(positions[index],true); //true for the initial position
ped->SetBuilding(building);
positions.erase(positions.begin() + index);
ped->SetRoomID(para->GetRoomId(),"");
ped->SetSubRoomID(r->GetSubRoomID());
ped->SetPatienceTime(para->GetPatience());
ped->SetPremovementTime(para->GetPremovementTime());
ped->SetRiskTolerance(para->GetRiskTolerance());
const Point& start_pos = para->GetStartPosition();
if((std::isnan(start_pos._x)==0 ) && (std::isnan(start_pos._y)==0 ) ) {
if(r->IsInSubRoom(start_pos)==false){
Log->Write("ERROR: \t cannot distribute pedestrian %d in Room %d at fixed position %s",
*pid, para->GetRoomId(), start_pos.toString().c_str());
Log->Write("ERROR: \t Make sure that the position is inside the geometry and belongs to the specified room / subroom");
exit(EXIT_FAILURE);
}
ped->SetPos(start_pos,true); //true for the initial position
Log->Write("INFO: \t fixed position for ped %d in Room %d %s",
*pid, para->GetRoomId(), start_pos.toString().c_str());
}
//r->AddPedestrian(ped);
building->AddPedestrian(ped);
(*pid)++;
}
}
......@@ -94,7 +94,17 @@ BOOST_AUTO_TEST_CASE(LINE_ISINLINESEGMENT_TEST)
for (int i = 0; i < 20; ++i)
BOOST_CHECK(!L1.IsInLineSegment(Point(i, i)));
Point P1 (30.1379, 124.485);
Point P2 (41.4647, 124.485);
Point P3 (38.4046,104.715);
Point P4 (33.7146,104.715);
Line L2(P1,P2);
Line L3(P3,P4);
BOOST_CHECK(L2.IsInLineSegment(P3)==false);
BOOST_CHECK(L2.IsInLineSegment(P4)==false);
BOOST_CHECK(L3.IsInLineSegment(P1)==false);
BOOST_CHECK(L3.IsInLineSegment(P2)==false);
BOOST_MESSAGE("Leaving is_in_linesegment test");
}
......@@ -132,7 +142,7 @@ BOOST_AUTO_TEST_CASE(LINE_OPERATOR_TEST)
BOOST_AUTO_TEST_CASE(LINE_LENGTH_TEST)
{
BOOST_MESSAGE("starting line length test");
BOOST_MESSAGE("starting line length and length square test");
Point P1;
const double PI = 3.14159265358979323846;
for (int i = -5; i < 5; ++i)
......@@ -146,6 +156,7 @@ BOOST_AUTO_TEST_CASE(LINE_LENGTH_TEST)
double normSq = P2.NormSquare();
BOOST_CHECK(L1.LengthSquare() == normSq);
}
BOOST_MESSAGE("Leaving line length and length square test");
}
BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
BOOST_AUTO_TEST_SUITE_END()
......@@ -153,7 +153,8 @@ BOOST_AUTO_TEST_CASE(Obstacle_ConvertLineToPoly_Test)
Point P2 (i, i*i);
Point P3 (2*i, i);
Point P4 (-i, -i*i);
Point P5 (100, 100);
Point P5 (-i, -2*i*i);
Point P6 (-2*i, -2*i*i);
std::vector<Point> added_pts;
added_pts.emplace_back(P1);
......@@ -161,6 +162,7 @@ BOOST_AUTO_TEST_CASE(Obstacle_ConvertLineToPoly_Test)
added_pts.emplace_back(P3);
added_pts.emplace_back(P4);
added_pts.emplace_back(P5);
added_pts.emplace_back(P6);
const unsigned temp = added_pts.size();
Obstacle obs1;
......@@ -169,20 +171,25 @@ BOOST_AUTO_TEST_CASE(Obstacle_ConvertLineToPoly_Test)
Wall w2(P2, P3);
Wall w3(P3, P4);
Wall w4(P4, P1);
Wall w5(P2, P5);
Wall w5(P4, P5);
Wall w6(P5, P6);
Wall w7(P6, P4);
obs1.SetId(i-1);
obs1.AddWall(w1);
obs1.AddWall(w2);
obs1.AddWall(w3);
obs1.AddWall(w4);
obs1.SetClosed(1);
//BOOST_CHECK_MESSAGE(obs1.ConvertLineToPoly() == false, obs1.ConvertLineToPoly());
obs1.AddWall(w4);
BOOST_CHECK_MESSAGE(obs1.ConvertLineToPoly() == true, obs1.ConvertLineToPoly());
// BOOST_CHECK_MESSAGE(obs1.ConvertLineToPoly() == true, obs1.ConvertLineToPoly());
obs1.AddWall(w5);
obs1.AddWall(w6);
obs1.AddWall(w7);
BOOST_CHECK_MESSAGE(obs1.ConvertLineToPoly() == true, obs1.ConvertLineToPoly());
// GetPolygon test
......@@ -233,4 +240,4 @@ BOOST_AUTO_TEST_CASE(Obstacle_GetCentroid_Test)
BOOST_MESSAGE("Leaving obstacle GetCentroid & IntersectWithLine test");
}
BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
BOOST_AUTO_TEST_SUITE_END()
/**
* \file testClassLine.cpp
* \date April 27, 2015
* \version v0.7
* \copyright <2009-2015> Forschungszentrum Jülich GmbH. All rights reserved.
*
* \section License
* This file is part of JuPedSim.
*
* JuPedSim is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JuPedSim. If not, see <http://www.gnu.org/licenses/>.
*
* \section Description
*
*
**/
#define BOOST_TEST_MODULE SubRoomTest
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "../../geometry/SubRoom.h"
#include <vector>
BOOST_AUTO_TEST_SUITE(SubRoomTest)
BOOST_AUTO_TEST_CASE(JTol_WallGap_test)
{
BOOST_MESSAGE("starting small gap between wall test");
NormalSubRoom sub1;
sub1.SetSubRoomID(1);
sub1.SetRoomID(1);
Point P1 (00.0, 00);
Point P2 (00.0, 10);
Point P3 (05.0, 10);
Point P4 (5.25, 10);
Point P5 (5.27, 10);
Point P6 (5.31, 10);
Point P7 (5.32, 10);
Point P8 (5.36, 10);
Point P9 (5.38, 10);
Point P10(5.50, 10);
Point P11(5.52, 10);
Point P12(10.0, 10);
Point P13(10.0, 05);
Point P14(10.0, 00);
// Walls with gap less than 0.03 were created
sub1.AddWall(Wall(P1, P2));
sub1.AddWall(Wall(P2, P3));
sub1.AddWall(Wall(P3, P4));
sub1.AddWall(Wall(P5, P6));
sub1.AddWall(Wall(P7, P8));
sub1.AddWall(Wall(P9, P10));
sub1.AddWall(Wall(P11, P12));
sub1.AddWall(Wall(P12, P13));
sub1.AddWall(Wall(P14, P1));
Line exit(P14, P13);
std::vector<Line*> goal; // (Line(Point(10, 5), Point(10, 0)));
goal.push_back(&exit);
sub1.SetClosed(1);
if (sub1.ConvertLineToPoly(goal) == true) {
std::vector<Point> poly = sub1.GetPolygon();
for (auto it:poly)
BOOST_CHECK_MESSAGE(poly.size() == 10, "x = " << it.GetX() << ", y = " << it.GetY());
}
else
BOOST_CHECK(false);
BOOST_MESSAGE("Leaving small wall test");
}
BOOST_AUTO_TEST_CASE(small_Wall_test)
{
BOOST_MESSAGE("starting small wall test");
NormalSubRoom sub;
sub.SetSubRoomID(1);
sub.SetRoomID(1);
Point P1 (0, 0);
Point P2 (0, 10);
Point P3 (5.0, 10);
Point P4 (5.029, 10);
Point P5 (10, 10);
Point P6 (10, 5);
Point P7 (10, 0);
sub.AddWall(Wall(P1, P2));
sub.AddWall(Wall(P2, P3));
sub.AddWall(Wall(P3, P4));
sub.AddWall(Wall(P4, P5));
sub.AddWall(Wall(P5, P6));
sub.AddWall(Wall(P1, P7));
Line exit(P6, P7);
std::vector<Line*> door; // (Line(Point(10, 5), Point(10, 0)));
door.push_back(&exit);
sub.SetClosed(1);
if (sub.ConvertLineToPoly(door) == true) {
std::vector<Point> poly = sub.GetPolygon();
for (auto it:poly)
BOOST_CHECK_MESSAGE(poly.size() == 7, "x = " << it.GetX() << ", y = " << it.GetY());
}
else
BOOST_CHECK(false);
BOOST_MESSAGE("Leaving small wall test");
}
BOOST_AUTO_TEST_CASE(overlap_Wall_test)
{
BOOST_MESSAGE("starting overlap wall test");
NormalSubRoom sub;
sub.SetSubRoomID(1);
sub.SetRoomID(1);
Point P1 (0, 0);
Point P2 (0, 10);
Point P3 (10, 10);
Point P4 (10, 2);
Point P5 (10, 0);
Point P6 (10, 5);
sub.AddWall(Wall(P1, P2));
sub.AddWall(Wall(P5, P1));
sub.AddWall(Wall(P3, P6));
sub.AddWall(Wall(P2, P3));
sub.AddWall(Wall(P5, P6));
Line exit(P6, P4);
std::vector<Line*> door; // door overlaps with the wall
door.push_back(&exit);
sub.SetClosed(1);
if (sub.ConvertLineToPoly(door) == true) {
std::vector<Point> poly = sub.GetPolygon();
for (auto it:poly)
BOOST_CHECK_MESSAGE(poly.size() == 6, "x = " << it.GetX() << ", y = " << it.GetY());
// needed result:: overlapping wall with exit to be split
}
else
BOOST_CHECK(false);
BOOST_MESSAGE("Leaving overlap wall test");
}
BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
......@@ -143,10 +143,9 @@ bool EventManager::ReadEventsXml()
_updateFrequency = xmltoi(xEvents->ToElement()->Attribute("update_time"), 1);
_updateRadius = xmltoi(xEvents->ToElement()->Attribute("update_radius"), 2);
string color=xmltoa(xEvents->ToElement()->Attribute("agents_color_by_knowledge"), "false");
if(color=="true")
Pedestrian::SetColorMode(BY_KNOWLEDGE);
//string color=xmltoa(xEvents->ToElement()->Attribute("agents_color_by_knowledge"), "false");
//if(color=="true")
// Pedestrian::SetColorMode(BY_KNOWLEDGE);
//Pedestrian::SetColorMode(BY_SPOTLIGHT);
for (TiXmlElement* e = xEvents->FirstChildElement("event"); e;
......
......@@ -340,6 +340,25 @@ bool ArgumentParser::ParseIniFile(string inifile)
if (format == "vtk")
pFormat = FORMAT_VTK;
//color mode
string color_mode =
xMainNode->FirstChildElement("trajectories")->Attribute(
"color_mode") ?
xMainNode->FirstChildElement("trajectories")->Attribute(
"color_mode") :
"velocity";
if(color_mode=="velocity") Pedestrian::SetColorMode(AgentColorMode::BY_VELOCITY);
if(color_mode=="spotlight") Pedestrian::SetColorMode(AgentColorMode::BY_SPOTLIGHT);
if(color_mode=="group") Pedestrian::SetColorMode(AgentColorMode::BY_GROUP);
if(color_mode=="knowledge") Pedestrian::SetColorMode(AgentColorMode::BY_KNOWLEDGE);
if(color_mode=="router") Pedestrian::SetColorMode(AgentColorMode::BY_ROUTER);
if(color_mode=="final_goal") Pedestrian::SetColorMode(AgentColorMode::BY_FINAL_GOAL);
if(color_mode=="intermediate_goal") Pedestrian::SetColorMode(AgentColorMode::BY_INTERMEDIATE_GOAL);
//a file descriptor was given
if (xTrajectories->FirstChild("file"))
{
......
......@@ -39,9 +39,6 @@
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
......@@ -137,8 +134,11 @@ enum AgentColorMode {
BY_VELOCITY=1,
BY_KNOWLEDGE,
BY_ROUTE,
BY_ROUTER,
BY_SPOTLIGHT,
//BY_GROUP
BY_GROUP,
BY_FINAL_GOAL,
BY_INTERMEDIATE_GOAL
};
//global functions for convenience
......
......@@ -206,53 +206,14 @@ Point Line::ShortestPoint(const Point &p) const {
return f;
}
/* Prüft, ob Punkt p im Liniensegment enthalten ist
* Verfahren wie bei Line::ShortestPoint(), d. h,
* lambda berechnen und prüfen ob zwischen 0 und 1
* */
//bool Line::IsInLine(const Point& p) const {
// double ax, ay, bx, by, px, py;
// const Point& a = GetPoint1();
// const Point& b = GetPoint2();
// double lambda;
// ax = a.GetX();
// ay = a.GetY();
// bx = b.GetX();
// by = b.GetY();
// px = p.GetX();
// py = p.GetY();
// if (fabs(ax - bx) > J_EPS_DIST) {
// lambda = (px - ax) / (bx - ax);
// } else if (fabs(ay - by) > J_EPS_DIST) {
// lambda = (py - ay) / (by - ay);
// } else {
// Log->Write("ERROR: \tIsInLine: Endpunkt = Startpunkt!!!");
// exit(0);
// }
// return (0 <= lambda) && (lambda <= 1);
//}
/*
* Prüft, ob Punkt p im Liniensegment enthalten ist
* algorithm from:
* http://stackoverflow.com/questions/328107/how-can-you-determine-a-point-is-between-two-other-points-on-a-line-segment
*
* TODO: FIXME Failing with test ( 30.1379 : 124.485 )--( 41.4647 : 124.485 ) and ( 38.4046 : 104.715 )--( 33.7146 : 104.715 )
* */
bool Line::IsInLineSegment(const Point &p) const
{
/*
Point differenceTwoAndOne = _point2 - _point1;
Point differencePAndOne = p - _point1;
// cross product to check if point i colinear
if ((differenceTwoAndOne).CrossProduct(differencePAndOne) > J_EPS)
return false;
// dotproduct and distSquared to check if point is in segment and not just in line
double dotp = differencePAndOne.ScalarProduct(differenceTwoAndOne);
return !(dotp < 0 || (differenceTwoAndOne).NormSquare() < dotp);
*/
return fabs( (_point1-p ).Norm() + (_point2-p ).Norm() - (_point2-_point1 ).Norm() )<J_EPS;
}
......
......@@ -37,13 +37,14 @@
#include <thread>
#include <functional>
#include <iomanip>
int main(int argc, char **argv)
{
//gathering some statistics about the runtime
time_t starttime, endtime;
// Log = new FileHandler("./Logfile.dat");
// default logger
Log = new STDIOHandler();
// Parsing the arguments
......@@ -60,6 +61,7 @@ int main(int argc, char **argv)
{
//evacuation time
int evacTime = 0;
Log->Write("INFO: \tStart runSimulation()");
#ifdef _USE_PROTOCOL_BUFFER
//Start the thread for managing incoming messages from MatSim
......@@ -72,25 +74,25 @@ int main(int argc, char **argv)
//process the normal simulation
else
#endif
if(sim.GetAgentSrcManager().GetMaxAgentNumber())
{
//Start the threads for managing the sources of agents if any
std::thread t1(sim.GetAgentSrcManager());
//std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());
//Start the thread for managing the sources of agents if any
//std::thread t1(sim.GetAgentSrcManager());
std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());
//main thread for the simulation
Log->Write("INFO: \tStart runSimulation()");
//evacTime = sim.RunSimulation(args->GetTmax());
evacTime = sim.RunStandardSimulation(args->GetTmax());
Log->Write("\nINFO: \tEnd runSimulation()");
time(&endtime);
//the execution is finished at this time
//so join the main thread
//Join the main thread
t1.join();
}
else
{
//main thread for the simulation
evacTime = sim.RunStandardSimulation(args->GetTmax());
}
Log->Write("\nINFO: \tEnd runSimulation()");
time(&endtime);
// some statistics output
if(args->ShowStatistics())
{
......@@ -104,23 +106,22 @@ int main(int argc, char **argv)
}
double execTime = difftime(endtime, starttime);
Log->Write("\nExec Time [s] : %.2f", execTime);
Log->Write("Evac Time [s] : %d", evacTime);
Log->Write("Realtime Factor : %.2f X", evacTime / execTime);
Log->Write("Number of Threads : %d", args->GetMaxOpenMPThreads());
Log->Write("Warnings : %d", Log->GetWarnings());
Log->Write("Errors : %d", Log->GetErrors());
std::stringstream summary;
summary << std::setprecision(2)<<std::fixed;
summary<<"\nExec Time [s] : "<< execTime<<std::endl;
summary<<"Evac Time [s] : "<< evacTime<<std::endl;
summary<<"Realtime Factor : "<< evacTime / execTime<<" X " <<std::endl;
summary<<"Number of Threads : "<< args->GetMaxOpenMPThreads()<<std::endl;
summary<<"Warnings : "<< Log->GetWarnings()<<std::endl;
summary<<"Errors : "<< Log->GetErrors()<<std::endl;
Log->Write(summary.str().c_str());
//force an output to the screen if the log is not the standard output
if (nullptr == dynamic_cast<STDIOHandler*>(Log))
{
printf("\nExec Time [s] : %4.2f\n", execTime);
printf("Evac Time [s] : %d\n", evacTime);
printf("Realtime Factor : %.2f (X)\n", evacTime / execTime);
printf("Number of Threads : %d\n", args->GetMaxOpenMPThreads());
printf("Warnings : %d\n", Log->GetWarnings());
printf("Errors : %d\n", Log->GetErrors());
printf("%s\n", summary.str().c_str());
}