The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 4dc3bf8d authored by Benedikt Kleinmeier's avatar Benedikt Kleinmeier
Browse files

Merge branch 'master' into event_handling

# Conflicts:
#	README.md
#	VadereSimulator/pom.xml
#	VadereUtils/src/org/vadere/util/opencl/CLUtils.java
parents 30a8af67 47f4bdd9
......@@ -27,12 +27,14 @@ variables:
VADERE_PACKAGE_NAME_RELEASES: "vadere.${CI_COMMIT_TAG}.${CI_RUNNER_TAGS}.zip"
# Stage Definitions
# Watch out: the seed_test is after deploy, because currently it fails
# only sometimes and does not define a successful/unsuccessful state.
# Watch out: integration tests and the seed tests run after deployment, because
# currently tests fail very often because of timeouts. It is not clear if
# Vadere has slowed down somehow or the test environment is not reliable
# (i.e.,the virtual machines). We have to track that!
stages:
- unit_test
- integration_test
- deploy
- integration_test
- seed_test
# PLEASE, OMIT FOLLOWING GITLAB PITFALLS:
......@@ -70,7 +72,7 @@ stages:
paths:
- "log_dir"
expire_in: 1 week
when: manual
when: on_success
.template_deploy_master_automatically:
stage: deploy
......
......@@ -66,7 +66,7 @@
- Removed directory `Documentation/version-control` which contained the Git hooks. The Git hooks are not required anymore. Instead, added `git rev-parse HEAD` to file `VadereSimulator/pom.xml` to create `VadereSimulator/resources/current_commit_hash.txt` during each build via `mvn compile`.
**Note:** The file `current_commit_hash.txt` is created during Maven's validation phase, i.e., before the actual build.
`
- Migration to Java 11 (OpenJDK)
## v0.6 (2018-09-07)
......
......@@ -38,13 +38,13 @@ The ZIP file contains:
* **vadere_console.jar** - provides the command line version of Vadere and allows easy integration into other applications.
* **VadereModelTests** - contains test scenarios for pedestrian locomotion models. Note: The tests are also useful for a "getting started" (see below "Run Built-In Examples" for details).
To execute the `.jar` files it is highly recommended to use Oracle Java 11.
To execute the `.jar` files it is highly recommended to use Java 11 (OpenJDK).
### Build from Source
#### Dependencies
* Java 11
* Java 11 (OpenJDK recommended)
* Maven 3.0
* Git
* OpenCL (optional but recommended)
......
......@@ -8,7 +8,10 @@ from vadereanalysistool import SameSeedTrajectory
def run_scenario_files_with_vadere_console(project, number_of_runs=3, vadere_console="VadereSimulator/target/vadere-console.jar",
scenario_timeout_in_sec=60*8):
scenario_timeout_in_sec=60*9):
if not os.path.exists(vadere_console):
raise ValueError("vadere console could not be found at path: {}".format(os.path.abspath(vadere_console)))
if not os.path.exists(vadere_console):
raise ValueError("vadere console could not be found at path: {}".format(os.path.abspath(vadere_console)))
......
......@@ -144,6 +144,8 @@ def run_all():
"thin_wall_and_closer_source_pso_could_fail",
"rimea_04_flow_osm1_550_up",
"stairs_diagonal_both_1_2_+1.scenario",
"04-NarrowedStreet-Pollichtrasse",
"05-Guimaraes-Platz"
]
excluded_scenarios = ["TESTOVM", "output", "legacy"]
......@@ -156,7 +158,7 @@ def run_all():
search_pattern = "*" + scenario + "*.scenario"
scenario_files_long = find_scenario_files(scenario_search_pattern=search_pattern)
tmp_passed_and_failed_scenarios = run_scenario_files_with_vadere_console(scenario_files_long,
scenario_timeout_in_sec=480)
scenario_timeout_in_sec=540)
passed_and_failed_scenarios["passed"].extend(tmp_passed_and_failed_scenarios["passed"])
passed_and_failed_scenarios["failed"].extend(tmp_passed_and_failed_scenarios["failed"])
passed_and_failed_scenarios["failed_summary"].extend(tmp_passed_and_failed_scenarios["failed_summary"])
......
......@@ -104,6 +104,9 @@ public class MeshPanel<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
this(mesh, f -> false, width, height, f -> Color.WHITE);
}
public MeshRenderer<P, V, E, F> getMeshRenderer() {
return meshRenderer;
}
@Override
public void paint(Graphics g) {
......@@ -120,7 +123,7 @@ public class MeshPanel<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
jFrame.setSize((int)width+10, (int)height+10);
jFrame.add(this);
jFrame.setTitle(title);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setVisible(true);
jFrame.setVisible(true);
repaint();
......
......@@ -119,7 +119,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
Color c = graphics.getColor();
Stroke stroke = graphics.getStroke();
synchronized (mesh) {
faces = mesh.clone().getFaces();
faces = mesh.getFaces();
}
graphics.translate(-bound.getMinX() * scale, -bound.getMinY() * scale);
......@@ -141,7 +141,10 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
graphics.setColor(colorFunction.apply(face));
graphics.fill(polygon);
}
else {
graphics.setColor(Color.WHITE);
graphics.fill(polygon);
}
if(alertPred.test(face)) {
graphics.setColor(Color.RED);
......@@ -176,4 +179,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
return image;
}
public void setMesh(IMesh<P, V, E, F> mesh) {
this.mesh = mesh;
}
}
package org.vadere.meshing.mesh.triangulation.triangulator;
import org.vadere.meshing.mesh.gen.IncrementalTriangulation;
import org.vadere.meshing.mesh.inter.IFace;
import org.vadere.meshing.mesh.inter.IHalfEdge;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.meshing.mesh.inter.IPointLocator;
import org.vadere.meshing.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
......@@ -41,6 +44,16 @@ public class PointSetTriangulator<P extends IPoint, V extends IVertex<P>, E exte
this.points = points;
}
/**
* <p>The default constructor.</p>
*
* @param points the collection of points P
*/
public PointSetTriangulator(final Collection<P> points, IMesh<P, V, E, F> mesh) {
this.triangulation = new IncrementalTriangulation<>(mesh, IPointLocator.Type.JUMP_AND_WALK, points);
this.points = points;
}
@Override
public IIncrementalTriangulation<P, V, E, F> generate() {
triangulation.init();
......
......@@ -97,7 +97,7 @@
}
},
"attributesSimulation" : {
"finishTime" : 300.0,
"finishTime" : 150.0,
"simTimeStepLength" : 0.4,
"realTimeSimTimeRatio" : 0.1,
"writeSimulationData" : true,
......@@ -935,4 +935,4 @@
} ]
} ]
}
}
\ No newline at end of file
}
......@@ -97,7 +97,7 @@
}
},
"attributesSimulation" : {
"finishTime" : 300.0,
"finishTime" : 150.0,
"simTimeStepLength" : 0.4,
"realTimeSimTimeRatio" : 0.1,
"writeSimulationData" : true,
......@@ -1206,4 +1206,4 @@
} ]
} ]
}
}
\ No newline at end of file
}
......@@ -118,7 +118,9 @@
</plugins>
</build>
<repositories>
<!--
use it again if error.
<repositories>
<repository>
<id>nativelibs4java</id>
<name>nativelibs4java Maven2 Repository</name>
......@@ -127,7 +129,7 @@
</repositories>
<properties>
<platform.dependency>windows-x86_64</platform.dependency>
</properties>
</properties>-->
<dependencies>
<dependency>
......
......@@ -45,7 +45,7 @@ public class ProjectRunSubCommand implements SubCommandRunner {
projectDirectory.toFile().toString(),scenarioFile);
new ScenarioRun(scenario, null).run();
} catch (Exception e) {
} catch (Throwable e) {
logger.error(e);
System.exit(-1);
}
......
......@@ -68,7 +68,7 @@ public class ScenarioRunSubCommand implements SubCommandRunner {
} else {
System.exit(-1);
}
} catch (Exception e){
} catch (Throwable e){
logger.error(e);
System.exit(-1);
}
......
......@@ -39,7 +39,7 @@ public class SuqSubCommand implements SubCommandRunner {
try {
Scenario scenario = ScenarioFactory.createScenarioWithScenarioFilePath(scenarioFile);
new ScenarioRun(scenario, outputDir.toFile().toString(), true, null).run();
} catch (Exception e){
} catch (Throwable e){
logger.error(e);
System.exit(-1);
}
......
......@@ -9,6 +9,7 @@ import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.logging.Logger;
import java.util.List;
......@@ -19,12 +20,15 @@ import java.util.List;
public class PotentialEvaluationFunction implements UnivariateRealFunction,
MultivariateRealFunction, MultivariateFunction {
private static Logger logger = Logger.getLogger(PotentialEvaluationFunction.class);
/** The pedestrian. */
private final PedestrianOSM pedestrian;
/** The step size. */
private double stepSize;
private double minStepSize;
private static int evaluationCounter = 0;
public int counter;
......@@ -73,6 +77,10 @@ public class PotentialEvaluationFunction implements UnivariateRealFunction,
VPoint pedPos = pedestrian.getPosition();
VPoint newPos = new VPoint(stepSize * Math.cos(angle) + pedPos.x,
stepSize * Math.sin(angle) + pedPos.y);
evaluationCounter++;
/*if(evaluationCounter % 100 == 0) {
logger.debugf("#evaluations: " + evaluationCounter);
}*/
return pedestrian.getPotential(newPos);
}
......@@ -145,6 +153,10 @@ public class PotentialEvaluationFunction implements UnivariateRealFunction,
final double tolInsideCircle = 0.00001;
if (sqx + sqy <= sqss + tolInsideCircle) {
result = pedestrian.getPotential(newPos);
evaluationCounter++;
/*if(evaluationCounter % 100 == 0) {
logger.debugf("#evaluations: " + evaluationCounter);
}*/
}
counter++;
return result;
......
......@@ -7,12 +7,15 @@ import org.apache.commons.math.optimization.MultivariateRealOptimizer;
import org.apache.commons.math.optimization.direct.DirectSearchOptimizer;
import org.apache.commons.math.optimization.direct.NelderMead;
import org.vadere.simulator.models.osm.PedestrianOSM;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.logging.Logger;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
......@@ -25,9 +28,11 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
.getLogger(StepCircleOptimizerNelderMead.class);
private final Random random;
private Map<PedestrianOSM, VPoint> lastSolution;
public StepCircleOptimizerNelderMead(Random random) {
this.random = random;
this.lastSolution = new HashMap<>();
}
@Override
......@@ -35,7 +40,6 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
double stepSize = ((VCircle) reachableArea).getRadius();
List<VPoint> positions = StepCircleOptimizerDiscrete.getReachablePositions(pedestrian, (VCircle)reachableArea, random);
PotentialEvaluationFunction potentialEvaluationFunction = new PotentialEvaluationFunction(pedestrian);
potentialEvaluationFunction.setStepSize(stepSize);
......@@ -48,14 +52,24 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
double step = stepSize / 2;
double threshold = 0.0001;
MultivariateRealOptimizer optimizer = new NelderMead();
NelderMead optimizer = new NelderMead();
try {
/*if(lastSolution.containsKey(pedestrian)) {
VPoint optimum = lastSolution.get(pedestrian).add(pedestrian.getPosition());
if(isLocalMinimum(potentialEvaluationFunction, (VCircle) reachableArea, optimum)) {
logger.info("quick solution found.");
return optimum;
}
}*/
//minimum = position;
double[][] simplex = new double[][] {{0, 0}, {step, step}, {step, -step}};
((DirectSearchOptimizer) optimizer).setStartConfiguration(simplex);
optimizer.setStartConfiguration(simplex);
optimizer.setConvergenceChecker(new NelderMeadConvergenceChecker());
newMinimum = optimizer.optimize(potentialEvaluationFunction, GoalType.MINIMIZE, minimum).getPoint();
newMinimum = optimizer.optimize(potentialEvaluationFunction, GoalType.MINIMIZE, position).getPoint();
//logger.info("["+0+","+0+"],["+step+","+step+"],["+step+","+(-step)+")]");
newMinimumValue = potentialEvaluationFunction.value(newMinimum);
int counter = 0;
......@@ -93,7 +107,9 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
simplex[2][0] = Math.min(step, outerDistance) * outerDirection.getX();
simplex[2][1] = Math.min(step, outerDistance) * outerDirection.getY();
((DirectSearchOptimizer) optimizer).setStartConfiguration(simplex);
//logger.info("["+simplex[0][0]+","+simplex[0][1]+"],["+simplex[1][0]+","+simplex[1][1]+"],["+simplex[2][0]+","+simplex[2][1]+")]");
optimizer.setStartConfiguration(simplex);
optimizer.setConvergenceChecker(new NelderMeadConvergenceChecker());
newMinimum = optimizer.optimize(potentialEvaluationFunction,
......@@ -105,6 +121,7 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
if ((minimumValue > newMinimumValue && Math.abs(minimumValue - newMinimumValue) > threshold)) {
minimumValue = newMinimumValue;
minimum = newMinimum;
//logger.info("new min: ["+minimum[0]+","+minimum[1]+"]");
}
}
......@@ -113,6 +130,8 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
logger.error(e);
}
// System.out.println(potentialEvaluationFunction.counter);
//logger.info("["+(minimum[0]-pedestrian.getPosition().getX())+","+(minimum[1]-pedestrian.getPosition().getY())+"]");
//lastSolution.put(pedestrian, new VPoint(minimum[0]-pedestrian.getPosition().getX(), minimum[1]-pedestrian.getPosition().getY()));
return new VPoint(minimum[0], minimum[1]);
}
......@@ -120,4 +139,18 @@ public class StepCircleOptimizerNelderMead implements StepCircleOptimizer {
public StepCircleOptimizer clone() {
return new StepCircleOptimizerNelderMead(random);
}
private boolean isLocalMinimum(PotentialEvaluationFunction evaluationFunction, VCircle stepDisc, VPoint optimum) throws FunctionEvaluationException {
double delta = 0.0001;
double angle = 0.05 * 2 * Math.PI;
double value = evaluationFunction.getValue(optimum);
for(double angleDelta = 0; angleDelta <= 2 * Math.PI; angleDelta += angle) {
VPoint newPoint = optimum.add(new VPoint(delta, 0).rotate(angleDelta));
if(stepDisc.contains(newPoint) && evaluationFunction.getValue(newPoint) < value) {
return false;
}
}
return evaluationFunction.getValue(stepDisc.getCenter()) > value;
}
}
package org.vadere.simulator.models.osm.updateScheme;
import org.jetbrains.annotations.NotNull;
import org.vadere.meshing.mesh.gen.MeshPanel;
import org.vadere.meshing.mesh.gen.PFace;
import org.vadere.meshing.mesh.gen.PHalfEdge;
import org.vadere.meshing.mesh.gen.PMesh;
import org.vadere.meshing.mesh.gen.PVertex;
import org.vadere.meshing.mesh.triangulation.triangulator.PointSetTriangulator;
import org.vadere.simulator.models.osm.PedestrianOSM;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.DataPoint;
import org.vadere.util.geometry.LinkedCellsGrid;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.logging.Logger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
......@@ -18,16 +31,25 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
private LinkedCellsGrid<PedestrianOSM> linkedCellsGrid;
private boolean[][] locked;
private double pedestrianPotentialWidth;
private Map<PedestrianOSM, PVertex<PedestrianPoint>> map;
private PMesh<PedestrianPoint> mesh;
private MeshPanel<PedestrianPoint, PVertex<PedestrianPoint>, PHalfEdge<PedestrianPoint>, PFace<PedestrianPoint>> panel;
public UpdateSchemeEventDrivenParallel(@NotNull final Topography topography, @NotNull final double pedestrianPotentialWidth) {
super(topography);
this.topography = topography;
this.pedestrianPotentialWidth = pedestrianPotentialWidth;
this.map = new HashMap<>();
}
@Override
public void update(final double timeStepInSec, final double currentTimeInSec) {
int count = 0;
// construct delaunay triangulation
/*for(PedestrianOSM pedestrianOSM : topography.getElements(PedestrianOSM.class)) {
pedestrianOSM.clearStrides();
......@@ -54,8 +76,32 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
int counter = 1;
// event driven update ignores time credits
do{
mesh = new PMesh<>((x, y) -> new PedestrianPoint(new VPoint(x,y), null));
Collection<PedestrianPoint> pedPoints = topography.getElements(PedestrianOSM.class)
.stream()
.map(ped -> new PedestrianPoint(ped.getPosition(), ped))
.collect(Collectors.toList());
PointSetTriangulator<PedestrianPoint, PVertex<PedestrianPoint>, PHalfEdge<PedestrianPoint>, PFace<PedestrianPoint>> triangulator
= new PointSetTriangulator<>(pedPoints, mesh);
triangulator.generate();
if(panel == null) {
panel = new MeshPanel<>(mesh, 1000, 1000);
panel.display();
}
else {
panel.getMeshRenderer().setMesh(mesh);
}
for(PVertex<PedestrianPoint> pedestrianPoint : mesh.getVertices()) {
map.put(mesh.getPoint(pedestrianPoint).pedestrianOSM, pedestrianPoint);
}
panel.repaint();
double stepSize = Math.max(maxStepSize, maxDesiredSpeed * timeStepInSec);
linkedCellsGrid = new LinkedCellsGrid<>(new VRectangle(topography.getBounds()), 2*(pedestrianPotentialWidth + stepSize));
linkedCellsGrid = new LinkedCellsGrid<>(new VRectangle(topography.getBounds()), (pedestrianPotentialWidth));
locked = new boolean[linkedCellsGrid.getGridWidth()][linkedCellsGrid.getGridHeight()];
List<PedestrianOSM> parallelUpdatablePeds = new ArrayList<>();
......@@ -65,32 +111,163 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
PedestrianOSM ped = pedestrianEventsQueue.poll();
int[] gridPos = linkedCellsGrid.gridPos(ped.getPosition());
if(!locked[gridPos[0]][gridPos[1]]) {
boolean requiresUpdate = requireUpdate(ped);
if(!locked[gridPos[0]][gridPos[1]] && requiresUpdate) {
parallelUpdatablePeds.add(ped);
}
else {
else if(requiresUpdate) {
unUpdatablePedsd.add(ped);
}
for(int y = -1; y <= 1; y++) {
for(int x = -1; x <= 1; x++) {
int col = Math.min(locked.length-1, Math.max(0, gridPos[0]+x));
int row = Math.min(locked[0].length-1, Math.max(0, gridPos[1]+y));
locked[col][row] = true;
if(requiresUpdate) {
for(int y = -1; y <= 1; y++) {
for(int x = -1; x <= 1; x++) {
int col = Math.min(locked.length-1, Math.max(0, gridPos[0]+x));
int row = Math.min(locked[0].length-1, Math.max(0, gridPos[1]+y));
locked[col][row] = true;
}
}
}
if(!requiresUpdate) {
double stepDuration = ped.getDurationNextStep();
ped.setTimeOfNextStep(ped.getTimeOfNextStep() + stepDuration);
pedestrianEventsQueue.add(ped);
count++;
}
}
logger.info("update " + parallelUpdatablePeds.size() + " in parallel in round " + counter + ".");
parallelUpdatablePeds.parallelStream().forEach(ped -> {
//logger.info("update " + parallelUpdatablePeds.size() + " in parallel in round " + counter + ".");
parallelUpdatablePeds.stream().forEach(ped -> {
//logger.info(ped.getTimeOfNextStep());
//System.out.println(ped.getId());
update(ped, currentTimeInSec);
});
pedestrianEventsQueue.addAll(unUpdatablePedsd);
pedestrianEventsQueue.addAll(parallelUpdatablePeds);
counter++;
} while (!pedestrianEventsQueue.isEmpty() && pedestrianEventsQueue.peek().getTimeOfNextStep() < currentTimeInSec);
logger.info("avoided updates: " + count);
}
private boolean requireUpdate(PedestrianOSM pedestrianOSM) {
PVertex<PedestrianPoint> vertex = map.get(pedestrianOSM);
if(mesh.getPoint(vertex).hasChanged()) {
return true;
}
for(PVertex<PedestrianPoint> v : mesh.getAdjacentVertexIt(vertex)) {
if(mesh.getPoint(v).hasChanged()) {
return true;
}
}
return false;
}
private class PedestrianPoint implements IPoint {
private final PedestrianOSM pedestrianOSM;
private final VPoint point;
public PedestrianPoint(VPoint point, PedestrianOSM pedestrianOSM) {
this.point = point;
this.pedestrianOSM = pedestrianOSM;
}
private boolean hasChanged() {
//System.out.println(pedestrianOSM.getFootSteps().getFootSteps().size());
return pedestrianOSM.getFootSteps().isEmpty() || pedestrianOSM.getFootSteps().getFootSteps().peekLast().length() > 0;
}
@Override
public double getX() {
return point.getX();
}
@Override
public double getY() {
return point.getY();
}