Commit 71342c70 authored by Ulrich Kemloh's avatar Ulrich Kemloh

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

parents b01a988d b0ec8fab
......@@ -8,6 +8,8 @@
/figs_bot
/Utest/*/inifiles*/
/Utest/*/trajectories
/Utest/rimea_tests/*/inifiles*/
/Utest/rimea_tests/*/trajectories
*~
# Compiled Object files
......@@ -75,3 +77,16 @@ vgcore.*
/veloModel2.pdf
/veloModel2.tex
/.project
/#%2Aediff-merge%2A#14545CrI#
/#%2Aediff-merge%3C2%3E%2A#145452Th#
/.idea/dictionaries/chraibi.xml
/Dumping
/Martella/corridor_8x3.xml
/Martella/regular_simmetric_90-90.xml
/Utest/JPSRunTest.pyc
/Utest/test.py
/Utest/test_13/flow.txt
/compile_commands.json
/delme.py
/mencoderVideos.sh
/true_false.xml
......@@ -2,20 +2,28 @@
All notable changes to this project will be documented in this file.
[comment]: <> (## v0.8.0 [Unreleased])
## v0.7.0 [Unreleased]
### New Module
- JuPedSim: Editor for the geometry
### Added
- Risk tolerance factor (value in [0 1]) for pedestrian. Pedestrians with high values are likely to take more risks.
- Added pre-movement time of the agents. Only after this time, the concerned agents will start moving.
- 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. Usage: (
```<trajectories format="xml-plain" fps="8" color_mode="group"> ```)
- More control over the triangulation specially to avoid skinny triangles. Usage: ```<navigation_mesh method="triangulation" minimum_distance_between_edges="0.5" minimum_angle_in_triangles="20" use_for_local_planning="true" />```
- Improved statistics. The flow curve for the different exits can be computed at runtime.
- Changelog file
- Rimea testcases
- 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. Usage: ( <trajectories format="xml-plain" fps="8" color_mode="group"> )
- More control over the triangulation specially to avoid skinny triangles. Usage: <navigation_mesh method="triangulation" minimum_distance_between_edges="0.5" minimum_angle_in_triangles="20" use_for_local_planning="true" />
- Improved statistics Flow curve for the different exits.
- Unit tests are now based on the Boost testing engine
#### JPSVIS
- Display the geometry structure individual room/subroom
- Now build on OSX
- Display the geometry structure individual room/subroom.
- Now build on OSX/Linux/Windows
### Changed
-
......@@ -25,8 +33,6 @@ All notable changes to this project will be documented in this file.
- Visiblity in 3D
- Numerous geometrical operations
### Fixed
-
## v0.6.0 - 2015-01-31
### Added
......@@ -45,7 +51,15 @@ All notable changes to this project will be documented in this file.
### Changed
- refactor NumCPU and ExitCrossingStrategy tags to num_threads and exit_crossing_strategy
### Fixed
-
## v0.5.0 - 2014-08-05
\ No newline at end of file
## v0.5.0 - 2014-08-05
First release of the the Juelich Pedestrian Simulator. Most noteworthy features:
- Simulate pedestrians movement in a space continuous geometry
- Forces based models for describing the pedestrians interactions
- Shortest and quickest path route choice strategies
- Loading and visualizing trajectories and geometries
- Easy to use visualization interface
- Making high quality videos directly from the visualization interface or generating png sequences
- XML based input files
......@@ -343,31 +343,33 @@ endif(CGAL_FOUND)
#protocol buffer
find_package(Protobuf)
if(PROTOBUF_FOUND)
message(STATUS "Protocol buffer library found")
include_directories(${PROTOBUF_INCLUDE_DIRS})
set (hybrid_source_files
matsim/HybridSimulationManager.cpp
matsim/JPSserver.cpp
matsim/JPSclient.cpp
matsim/MATSimInterface.pb.cc
matsim/MATSimInterface.grpc.pb.cc
)
set (hybrid_header_files
matsim/JPSclient.h
matsim/MATSimInterface.grpc.pb.h
matsim/MATSimInterface.proto
matsim/HybridSimulationManager.h
matsim/JPSserver.h
matsim/MATSimInterface.pb.h
)
message(STATUS "Protocol buffer library found")
include_directories(${PROTOBUF_INCLUDE_DIRS})
set (hybrid_source_files
matsim/HybridSimulationManager.cpp
matsim/JPSserver.cpp
matsim/JPSclient.cpp
matsim/MATSimInterface.pb.cc
matsim/MATSimInterface.grpc.pb.cc
)
set (hybrid_header_files
matsim/JPSclient.h
matsim/MATSimInterface.grpc.pb.h
matsim/MATSimInterface.proto
matsim/HybridSimulationManager.h
matsim/JPSserver.h
matsim/MATSimInterface.pb.h
)
add_library (hybrid STATIC ${hybrid_source_files} )
target_link_libraries (core hybrid grpc++_unsecure grpc gpr ${PROTOBUF_LIBRARY} dl)
#PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto)
#add_executable(jpscore ${PROTO_SRCS} ${PROTO_HDRS})
else()
message(STATUS "protocol buffer not found")
endif(PROTOBUF_FOUND)
#----------------------------------------------------------------------
......
......@@ -587,8 +587,8 @@ void TrajectoriesJPSV06::WriteFrame(int frameNr, Building* building)
double b = ped->GetSmallerAxis();
double phi = atan2(ped->GetEllipse().GetSinPhi(), ped->GetEllipse().GetCosPhi());
sprintf(tmp1, "<agent ID=\"%d\"\t"
"x=\"%.2f\"\ty=\"%.2f\"\t"
"z=\"%.2f\"\t"
"x=\"%.6f\"\ty=\"%.6f\"\t"
"z=\"%.6f\"\t"
"rA=\"%.2f\"\trB=\"%.2f\"\t"
"eO=\"%.2f\" eC=\"%d\"/>\n",
ped->GetID(), (ped->GetPos().GetX()) * FAKTOR,
......@@ -702,8 +702,8 @@ void TrajectoriesJPSV05::WriteFrame(int frameNr, Building* building)
double b = ped->GetSmallerAxis();
double phi = atan2(ped->GetEllipse().GetSinPhi(), ped->GetEllipse().GetCosPhi());
sprintf(s, "<agent ID=\"%d\"\t"
"x=\"%.2f\"\ty=\"%.2f\"\t"
"z=\"%.2f\"\t"
"x=\"%.6f\"\ty=\"%.6f\"\t"
"z=\"%.6f\"\t"
"rA=\"%.2f\"\trB=\"%.2f\"\t"
"eO=\"%.2f\" eC=\"%d\"/>\n",
ped->GetID(), (ped->GetPos().GetX()) * FAKTOR,
......
......@@ -22,17 +22,22 @@ __license__ = 'GNU Lesser General Public License'
__version__ = '0.1'
__status__ = 'Production'
def getScriptPath():
return os.path.dirname(os.path.realpath(sys.argv[0]))
class JPSRunTestDriver(object):
def __init__(self, testnumber, argv0, testdir):
def __init__(self, testnumber, argv0, testdir, utestdir=".."):
self.SUCCESS = 0
self.FAILURE = 1
# check if testnumber is digit
assert isinstance(testnumber, float) or isinstance(testnumber, int)
assert isinstance(testnumber, float) or isinstance(testnumber, int), "argument <testnumber> is not digit"
# only allow path and strings as path directory name
assert path.exists(argv0)
assert path.exists(testdir)
assert isinstance(argv0, str)
assert isinstance(argv0, str), "argument <testdir> is not string"
assert path.exists(testdir), "%s does not exist"%testdir
assert path.exists(utestdir), "%s does not exist"%utestdir
assert isinstance(argv0, str), "argument <argv0> is not string"
assert path.exists(argv0), "%s is does not exist"%argv0
self.testno = testnumber
self.logfile = "log_test_%d.txt" % self.testno
self.logfile = os.path.join(testdir, self.logfile)
......@@ -44,34 +49,40 @@ class JPSRunTestDriver(object):
self.HOME = path.expanduser("~")
self.DIR = testdir
self.UTEST = utestdir
self.CWD = os.getcwd()
self.FILE = os.path.join(self.DIR, "master_ini.xml")
def run_test(self, testfunction, *args):
assert hasattr(testfunction, '__call__')
assert hasattr(testfunction, '__call__'), "run_test: testfunction has no __call__ function"
self.__configure()
executable = self.__find_executable()
results = []
for inifile in self.inifiles:
self.__execute_test(executable, inifile, testfunction, *args)
return
res = self.__execute_test(executable, inifile, testfunction, *args)
results.append(res)
return results
def __configure(self):
if self.CWD != self.DIR:
logging.info("working dir is %s. Change to %s", os.getcwd(), self.DIR)
os.chdir(self.DIR)
logging.info("change directory to ..")
os.chdir("..")
logging.info("change directory to utest=%s", self.UTEST)
os.chdir(self.UTEST)
# -------- get directory of the code TRUNK
# *** Note: assume that UTEST is always a direct subdirectory of TRUNK ***
self.trunk = os.path.dirname(os.getcwd())
logging.info("call makeini.py with -f %s", self.FILE)
subprocess.call(["python", "makeini.py", "-f", "%s" % self.FILE])
os.chdir(self.DIR)
# -------- get directory of the code TRUNK
os.chdir("../..")
self.trunk = os.getcwd()
os.chdir(self.DIR)
lib_path = os.path.abspath(os.path.join(self.trunk, "Utest"))
sys.path.append(lib_path)
# os.chdir(self.DIR)
logging.info("change directory back to %s", self.DIR)
os.chdir(self.DIR)
if self.UTEST == "..":
lib_path = os.path.abspath(os.path.join(self.trunk, "Utest"))
else:
lib_path = os.path.abspath(self.UTEST)
sys.path.append(lib_path)
# initialise the inputfiles for jpscore
self.geofile = os.path.join(self.DIR, "geometry.xml")
self.inifiles = glob.glob(os.path.join("inifiles", "*.xml"))
......@@ -116,6 +127,11 @@ class JPSRunTestDriver(object):
if not path.exists(trajfile):
logging.critical("trajfile <%s> does not exist", trajfile)
exit(self.FAILURE)
testfunction(inifile, trajfile, *args)
return
res = testfunction(inifile, trajfile, *args)
return res
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<geometry version="0.5" caption="second life" unit="m"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../xsd/jps_geometry.xsd">
<rooms>
<room id="0" caption="hall">
<subroom id="0" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="40.0" py="2.0" />
<vertex px="-2.0" py="2.0" />
<vertex px="-2.0" py="0.0" />
<vertex px="40.0" py="0.0" />
</polygon>
</subroom>
</room>
</rooms>
<transitions>
<!-- exits like crossings but between rooms or to outside (room with index
= -1) -->
<transition id="0" caption="main exit" type="emergency"
room1_id="0" subroom1_id="0" room2_id="-1" subroom2_id="-1">
<vertex px="40.0" py="0.0" />
<vertex px="40.0" py="2.0" />
</transition>
</transitions>
</geometry>
<?xml version="1.0" encoding="UTF-8" ?>
<JuPedSim project="JPS-Project" version="0.5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../xsd/jps_ini_core.xsd">
<!-- seed used for initialising random generator -->
<seed>1254</seed>
<max_sim_time>200</max_sim_time>
<!-- geometry file -->
<geometry>../geometry.xml</geometry>
<!-- trajectories file and format -->
<trajectories format="xml-plain" fps="8">
<file location="RiMEATest1_traj.xml" />
<!--<socket hostname="127.0.0.1" port="8989"/> -->
</trajectories>
<!-- where to store the logs -->
<!--<logfile>log.txt</logfile> -->
<!-- traffic information: e.g closed doors -->
<traffic_constraints>
</traffic_constraints>
<routing>
</routing>
<!--persons information and distribution -->
<agents operational_model_id="1">
<agents_distribution>
<group group_id="0" agent_parameter_id="1" room_id="0" subroom_id="0" number="1" goal_id="-1" router_id="1" start_x="0" start_y="1" />
</agents_distribution>
</agents>
<!-- These parameters may be overwritten -->
<!-- These parameters may be overwritten -->
<operational_models>
<model operational_model_id="1" description="gcfm">
<model_parameters>
<solver>euler</solver>
<stepsize>0.01</stepsize>
<exit_crossing_strategy>4</exit_crossing_strategy>
<linkedcells enabled="true" cell_size="2.2" />
<force_ped nu="0.3" dist_max="3" disteff_max="2" interpolation_width="0.1" />
<force_wall nu="0.2" dist_max="3" disteff_max="2" interpolation_width="0.1" />
</model_parameters>
<agent_parameters agent_parameter_id="1">
<v0 mu="1.33" sigma="0.0" />
<bmax mu="0.25" sigma="0.001" />
<bmin mu="0.20" sigma="0.001" />
<amin mu="0.18" sigma="0.001" />
<tau mu="0.5" sigma="0.001" />
<atau mu="0.5" sigma="0.001" />
</agent_parameters>
<agent_parameters agent_parameter_id="2">
<v0 mu="0.5" sigma="0.0" />
<bmax mu="0.25" sigma="0.001" />
<bmin mu="0.20" sigma="0.001" />
<amin mu="0.18" sigma="0.001" />
<tau mu="0.5" sigma="0.001" />
<atau mu="0.5" sigma="0.001" />
</agent_parameters>
</model>
<model operational_model_id="2" description="gompertz">
<model_parameters>
<solver>euler</solver>
<stepsize>0.01</stepsize>
<exit_crossing_strategy>3</exit_crossing_strategy>
<linkedcells enabled="true" cell_size="2.2" />
<force_ped nu="3" b="0.25" c="3.0"/>
<force_wall nu="10" b="0.70" c="3.0"/>
</model_parameters>
<agent_parameters agent_parameter_id="1">
<v0 mu="1.33" sigma="0.05" />
<bmax mu="0.25" sigma="0.001" />
<bmin mu="0.20" sigma="0.001" />
<amin mu="0.18" sigma="0.001" />
<tau mu="0.5" sigma="0.001" />
<atau mu="0.5" sigma="0.001" />
</agent_parameters>
<agent_parameters agent_parameter_id="2">
<v0 mu="0" sigma="0.0" />
<bmax mu="0.25" sigma="0.001" />
<bmin mu="0.20" sigma="0.001" />
<amin mu="0.18" sigma="0.001" />
<tau mu="0.5" sigma="0.001" />
<atau mu="0.5" sigma="0.001" />
</agent_parameters>
</model>
</operational_models>
<route_choice_models>
<router router_id="1" description="global_shortest">
<parameters>
</parameters>
</router>
</route_choice_models>
</JuPedSim>
#!/usr/bin/env python
"""
Test description
================
One pedestrian is moving along a corridor.
Test if pedestrian can maintain its speed constant
Remarks
=======
Source
======
http://www.rimea.de/fileadmin/files/dok/richtlinien/r2.2.1.pdfs
"""
import os
import sys
utestdir = os.path.abspath(os.path.dirname(os.path.dirname(sys.path[0])))
from sys import *
sys.path.append(utestdir)
from JPSRunTest import JPSRunTestDriver
from utils import *
def run_rimea_test1(inifile, trajfile):
must_min_time = 26
must_max_time = 34
# pedestrians in force-based models accelerate from 0 to v0 after some time (\tau)
fps, n, traj = parse_file(trajfile)
evac_time = (max(traj[:, 1]) - min(traj[:, 1])) / float(fps)
if must_min_time <= evac_time <= must_max_time:
logging.info("evac_time: %f <= %f <= %f", must_min_time, evac_time, must_max_time)
else:
logging.info("%s exits with FAILURE. evac_time: %f <= %f <= %f ?",
argv[0], must_min_time, evac_time, must_max_time)
exit(FAILURE)
if __name__ == "__main__":
test = JPSRunTestDriver(1, argv0=argv[0], testdir=sys.path[0], utestdir=utestdir)
test.run_test(testfunction=run_rimea_test1)
logging.info("%s exits with SUCCESS" % (argv[0]))
exit(SUCCESS)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<geometry version="0.5" caption="second life" unit="m"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../xsd/jps_geometry.xsd">
<rooms>
<room id="0" caption="hall">
<subroom id="0" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="1.05" py="6.0" />
<vertex px="0.0" py="6.0" />
<vertex px="0.0" py="11.0" />
<vertex px="3.0" py="11.0" />
<vertex px="3.0" py="6.0" />
<vertex px="1.95" py="6.0" />
</polygon>
</subroom>
<subroom id="1" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="4.05" py="6.0" />
<vertex px="3.0" py="6.0" />
<vertex px="3.0" py="11.0" />
<vertex px="6.0" py="11.0" />
<vertex px="6.0" py="6.0" />
<vertex px="4.95" py="6.0" />
</polygon>
</subroom>
<subroom id="2" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="7.65" py="6.0" />
<vertex px="7.2" py="6.0" />
<vertex px="7.2" py="11.0" />
<vertex px="9.0" py="11.0" />
<vertex px="9.0" py="6.0" />
<vertex px="8.55" py="6.0" />
</polygon>
</subroom>
<subroom id="3" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="10.05" py="6.0" />
<vertex px="9.0" py="6.0" />
<vertex px="9.0" py="11.0" />
<vertex px="12.0" py="11.0" />
<vertex px="12.0" py="6.0" />
<vertex px="10.95" py="6.0" />
</polygon>
</subroom>
<subroom id="4" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="13.05" py="6.0" />
<vertex px="12.0" py="6.0" />
<vertex px="12.0" py="11.0" />
<vertex px="15.0" py="11.0" />
<vertex px="15.0" py="6.0" />
<vertex px="13.95" py="6.0" />
</polygon>
</subroom>
<subroom id="5" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="16.05" py="6.0" />
<vertex px="15.0" py="6.0" />
<vertex px="15.0" py="11.0" />
<vertex px="18.0" py="11.0" />
<vertex px="18.0" py="6.0" />
<vertex px="16.95" py="6.0" />
</polygon>
</subroom>
<subroom id="6" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="1.05" py="5.0" />
<vertex px="0.0" py="5.0" />
<vertex px="0.0" py="0.0" />
<vertex px="3.0" py="0.0" />
<vertex px="3.0" py="5.0" />
<vertex px="1.95" py="5.0" />
</polygon>
</subroom>
<subroom id="7" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="4.05" py="5.0" />
<vertex px="3.0" py="5.0" />
<vertex px="3.0" py="0.0" />
<vertex px="6.0" py="0.0" />
<vertex px="6.0" py="5.0" />
<vertex px="4.95" py="5.0" />
</polygon>
</subroom>
<subroom id="8" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="7.05" py="5.0" />
<vertex px="6.0" py="5.0" />
<vertex px="6.0" py="0.0" />
<vertex px="9.0" py="0.0" />
<vertex px="9.0" py="5.0" />
<vertex px="7.95" py="5.0" />
</polygon>
</subroom>
<subroom id="9" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="10.05" py="5.0" />
<vertex px="9.0" py="5.0" />
<vertex px="9.0" py="0.0" />
<vertex px="12.0" py="0.0" />
<vertex px="12.0" py="5.0" />
<vertex px="10.95" py="5.0" />
</polygon>
</subroom>
<subroom id="10" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="13.05" py="5.0" />
<vertex px="12.0" py="5.0" />
<vertex px="12.0" py="0.0" />
<vertex px="15.0" py="0.0" />
<vertex px="15.0" py="5.0" />
<vertex px="13.95" py="5.0" />
</polygon>
</subroom>
<subroom id="11" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="16.05" py="5.0" />
<vertex px="15.0" py="5.0" />
<vertex px="15.0" py="0.0" />
<vertex px="18.0" py="0.0" />
<vertex px="18.0" py="5.0" />
<vertex px="16.95" py="5.0" />
</polygon>
</subroom>
<subroom id="12" closed="0" class="subroom">
<polygon caption="wall">
<vertex px="6.0" py="11.0" />
<vertex px="6.0" py="6.0" />
<vertex px="4.95" py="6.0" />
</polygon>
<polygon caption="wall">