In January 2021 we will introduce a 10 GB quota for project repositories. Higher limits for individual projects will be available on request. Please see https://doku.lrz.de/display/PUBLIC/GitLab for more information.

Commit 76a45b86 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck

Merge branch 'master' into add_artery_support

parents 91246161 442d062a
Pipeline #320155 passed with stages
in 141 minutes and 17 seconds
......@@ -145,7 +145,9 @@
},
"attributesStrategy" : {
"useStrategyModel" : true,
"strategyModel" : "RouteChoiceThreeCorridors"
"strategyModel" : "RouteChoiceThreeCorridors",
"arguments" : [ ],
"requiredDataProcessorIds" : [ ]
},
"topography" : {
"attributes" : {
......
......@@ -19,6 +19,10 @@
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile",
"filename" : "densities.csv",
"processors" : [ 5, 6, 7, 8 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
"filename" : "pedestrianDensities.txt",
"processors" : [ 9, 10 ]
} ],
"processors" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor",
......@@ -64,6 +68,31 @@
"attributes" : {
"measurementAreaId" : 1000
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDensityCountingProcessor",
"id" : 9,
"attributesType" : "org.vadere.state.attributes.processor.AttributesPedestrianDensityCountingProcessor",
"attributes" : {
"pedestrianPositionProcessorId" : 11,
"radius" : 1.5
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDensityGaussianProcessor",
"id" : 10,
"attributesType" : "org.vadere.state.attributes.processor.AttributesPedestrianDensityGaussianProcessor",
"attributes" : {
"pedestrianPositionProcessorId" : 11,
"scale" : 10.0,
"standardDeviation" : 0.7,
"obstacleDensity" : true
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPositionProcessor",
"id" : 11,
"attributesType" : "org.vadere.state.attributes.processor.AttributesPedestrianPositionProcessor",
"attributes" : {
"interpolate" : true
}
} ],
"isTimestamped" : false,
"isWriteMetaData" : false
......@@ -145,7 +174,9 @@
},
"attributesStrategy" : {
"useStrategyModel" : false,
"strategyModel" : "RouteChoiceThreeCorridors"
"strategyModel" : "RouteChoiceThreeCorridors",
"arguments" : [ ],
"requiredDataProcessorIds" : [ ]
},
"topography" : {
"attributes" : {
......
......@@ -23,6 +23,14 @@
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile",
"filename" : "AreaDensityCounting.txt",
"processors" : [ 8 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepKeyIdOutputFile",
"filename" : "MeshDensityCounting.txt",
"processors" : [ 9 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile",
"filename" : "Mesh.txt",
"processors" : [ 10 ]
} ],
"processors" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor",
......@@ -77,7 +85,8 @@
"attributesType" : "org.vadere.state.attributes.processor.AttributesMeshProcessor",
"attributes" : {
"measurementAreaId" : 1,
"edgeLength" : 1.5
"edgeLength" : 1.5,
"displayMesh" : false
}
} ],
"isTimestamped" : true,
......@@ -160,7 +169,9 @@
},
"attributesStrategy" : {
"useStrategyModel" : false,
"strategyModel" : "RouteChoiceThreeCorridors"
"strategyModel" : "RouteChoiceThreeCorridors",
"arguments" : [ ],
"requiredDataProcessorIds" : [ ]
},
"topography" : {
"attributes" : {
......
......@@ -23,6 +23,14 @@
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile",
"filename" : "AreaDensityCounting.txt",
"processors" : [ 8 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepKeyIdOutputFile",
"filename" : "MeshDensityCounting.txt",
"processors" : [ 9 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile",
"filename" : "Mesh.txt",
"processors" : [ 10 ]
} ],
"processors" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor",
......@@ -77,7 +85,8 @@
"attributesType" : "org.vadere.state.attributes.processor.AttributesMeshProcessor",
"attributes" : {
"measurementAreaId" : 1,
"edgeLength" : 1.5
"edgeLength" : 1.5,
"displayMesh" : false
}
} ],
"isTimestamped" : true,
......@@ -160,7 +169,9 @@
},
"attributesStrategy" : {
"useStrategyModel" : false,
"strategyModel" : "RouteChoiceThreeCorridors"
"strategyModel" : "RouteChoiceThreeCorridors",
"arguments" : [ ],
"requiredDataProcessorIds" : [ ]
},
"topography" : {
"attributes" : {
......@@ -350,4 +361,4 @@
},
"stimulusInfos" : [ ]
}
}
}
\ No newline at end of file
......@@ -66,7 +66,7 @@ public class OfflineSimulation {
.map(t -> t.getAgent(step.getStepNumber()))
.filter(opt -> opt.isPresent()).forEach(opt -> topography.addElement(opt.get()));
return new SimulationState(vadere.getName(), topography, vadere.getScenarioStore(),
(step.getStepNumber()-1) * vadere.getAttributesSimulation().getSimTimeStepLength(), step.getStepNumber(), null);
(step.getStepNumber()-1) * vadere.getAttributesSimulation().getSimTimeStepLength(), step.getStepNumber(), null, null);
}
private void prepareOutput() {
......
......@@ -18,7 +18,6 @@ import org.vadere.simulator.projects.Domain;
import org.vadere.simulator.projects.ScenarioStore;
import org.vadere.simulator.projects.SimulationResult;
import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.simulator.projects.dataprocessing.processor.DataProcessor;
import org.vadere.simulator.utils.cache.ScenarioCache;
import org.vadere.state.attributes.AttributesSimulation;
import org.vadere.state.attributes.scenario.AttributesAgent;
......@@ -228,7 +227,7 @@ public class Simulation {
}
private void postLoop() {
simulationState = new SimulationState(name, topography, scenarioStore, simTimeInSec, step, mainModel);
simulationState = new SimulationState(name, topography, scenarioStore, simTimeInSec, step, mainModel, strategyModel);
topographyController.postLoop(this.simTimeInSec);
for (Model m : models) {
......@@ -287,7 +286,7 @@ public class Simulation {
updateCallbacks(simTimeInSec);
step++;
this.simulationState = new SimulationState(name, topography, scenarioStore, simTimeInSec, step, mainModel);
this.simulationState = new SimulationState(name, topography, scenarioStore, simTimeInSec, step, mainModel, strategyModel);
if (attributesSimulation.isWriteSimulationData()) {
processorManager.update(this.simulationState);
......@@ -374,7 +373,7 @@ public class Simulation {
}
private SimulationState initialSimulationState() {
SimulationState state = new SimulationState(name, topography.clone(), scenarioStore, simTimeInSec, step, mainModel);
SimulationState state = new SimulationState(name, topography.clone(), scenarioStore, simTimeInSec, step, mainModel, strategyModel );
return state;
}
......@@ -426,12 +425,11 @@ public class Simulation {
private void updateStrategyLayer(double simTimeInSec) {
if (scenarioStore.getAttributesStrategyModel().isUseStrategyModel()) {
Collection<Pedestrian> pedestrians = topography.getElements(Pedestrian.class);
if (simTimeInSec == startTimeInSec) {
strategyModel.update(simTimeInSec, pedestrians, null);
strategyModel.update(simTimeInSec, topography, null);
}
strategyModel.update(simTimeInSec, pedestrians, processorManager);
strategyModel.update(simTimeInSec, topography, processorManager);
}
......
package org.vadere.simulator.control.simulation;
import org.jetbrains.annotations.Nullable;
import org.vadere.simulator.control.strategy.models.IStrategyModel;
import org.vadere.simulator.models.MainModel;
import org.vadere.simulator.projects.ScenarioStore;
import org.vadere.state.scenario.Topography;
......@@ -17,30 +18,34 @@ public class SimulationState {
private final String name;
private final MainModel mainModel;
private boolean simStop = false;
private final IStrategyModel strategyModel;
protected SimulationState(final String name,
final Topography topography,
final ScenarioStore scenarioStore,
final double simTimeInSec,
final int step,
@Nullable final MainModel mainModel) {
@Nullable final MainModel mainModel,
final IStrategyModel strategyModel) {
this.name = name;
this.topography = topography;
this.simTimeInSec = simTimeInSec;
this.step = step;
this.scenarioStore = scenarioStore;
this.mainModel = mainModel;
this.strategyModel = strategyModel;
}
@Deprecated
public SimulationState(final Map<Integer, VPoint> pedestrianPositionMap, final Topography topography,
final double simTimeInSec, final int step) {
final double simTimeInSec, final int step, final IStrategyModel strategyModel) {
this.name = "";
this.topography = topography;
this.simTimeInSec = simTimeInSec;
this.step = step;
this.scenarioStore = null;
this.mainModel = null;
this.strategyModel = null;
}
// public access to getters
......@@ -84,4 +89,10 @@ public class SimulationState {
public boolean isSimStop() {
return simStop;
}
public IStrategyModel getStrategyModel(){
return strategyModel;
}
}
......@@ -3,6 +3,7 @@ package org.vadere.simulator.control.strategy.helpers;
import org.vadere.simulator.control.strategy.models.IStrategyModel;
import org.vadere.simulator.projects.ScenarioStore;
import org.vadere.state.attributes.AttributesStrategyModel;
import org.vadere.util.reflection.DynamicClassInstantiator;
public class StrategyModelBuilder {
......@@ -17,6 +18,8 @@ public class StrategyModelBuilder {
DynamicClassInstantiator<IStrategyModel> instantiator = new DynamicClassInstantiator<>();
IStrategyModel strategyModel = instantiator.createObject(fullyQualifiedClassName);
strategyModel.build(scenarioStore.getAttributesStrategyModel());
return strategyModel;
}
else{
......
package org.vadere.simulator.control.strategy.models;
import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.attributes.AttributesStrategyModel;
import org.vadere.state.scenario.Topography;
import java.util.Collection;
public interface IStrategyModel {
public interface IStrategyModel<V> {
/*
* @param pedestrians The pedestrians to update
*/
void update(double simTimeInSec, Collection<Pedestrian> pedestrians, ProcessorManager processorManager);
void update(double simTimeInSec, Topography top, ProcessorManager processorManager);
void build(AttributesStrategyModel attr);
void initialize(double simTimeInSec);
V getStrategyInfoForDataProcessor();
}
......@@ -2,6 +2,7 @@ package org.vadere.simulator.control.strategy.models.navigation;
import org.vadere.simulator.control.strategy.models.IStrategyModel;
import org.vadere.state.attributes.AttributesStrategyModel;
public interface INavigationModel extends IStrategyModel {
......
package org.vadere.simulator.models.sfm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.vadere.simulator.models.ode.AbstractModelEquations;
import org.vadere.simulator.models.ode.ODEModel;
......@@ -9,7 +12,12 @@ import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.Vector2D;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.logging.Logger;
import org.vadere.util.math.MathUtil;
import org.vadere.util.parallel.AParallelWorker;
import org.vadere.util.parallel.AParallelWorker.Work;
import org.vadere.util.parallel.CountableParallelWorker;
import org.vadere.util.parallel.IAsyncComputable;
/**
* Implementation of the Social Force Model (Helbing 1995). This implementation
......@@ -24,7 +32,10 @@ import org.vadere.util.math.MathUtil;
* IGradientProvider given in the constructor.
*
*/
public class SFMEquations extends AbstractModelEquations<Pedestrian> {
public class SFMEquations extends AbstractModelEquations<Pedestrian> implements IAsyncComputable {
private static Logger logger = Logger.getLogger(SFMEquations.class);
/**
* Four dimensions: 2 for position, 2 for velocity
......@@ -41,99 +52,155 @@ public class SFMEquations extends AbstractModelEquations<Pedestrian> {
* double[], double[])
*/
@Override
public void computeDerivatives(double t, double[] y, double[] yDot) {
double[] position = new double[2];
double[] velocity = new double[2];
double[] positionDot = new double[2];
double[] velocityDot = new double[2];
double[] grad_field = new double[2];
double[] viewing_direction = new double[2];
public void computeDerivatives(final double t, double[] y, final double[] yDot) {
// update the pedestrian positions in the topography to the ones computed in the integrator
ODEModel.updateElementPositions(Pedestrian.class, t, topography, this, y);
// create workers for each pedestrian
List<AParallelWorker<Double[]>> workers = new ArrayList<AParallelWorker<Double[]>>();
// loop over all persons and compute the next step
int personCounter = 0; // used for arrays, not identical to personID!
for (Pedestrian currentPed : elements) {
// ///////////////////////////////////////
// extract data
// position
getPosition(personCounter, y, position);
// velocity
getVelocity(personCounter, y, velocity);
// ///////////////////////////////////////
// generate gradients
assert (!Double.isNaN(position[0]));
assert (!Double.isNaN(position[1]));
// get the static gradient
staticGradientProvider.gradient(t, currentPed.getNextTargetId(),
position, grad_field);
assert (!Double.isNaN(position[0]));
assert (!Double.isNaN(position[1]));
/*
* Target target = this.topography.getTarget(currentPed.getTargets()
* .get(0));
* double distance2Target = target.getShape().distance(
* new VPoint(position[0], position[1]));
* if (distance2Target < 1) {
* MathUtil.normalize(grad_field);
* MathUtil.mult(grad_field, distance2Target);
* }
*/
// compute the velocity from the static gradient.
viewing_direction[0] = -grad_field[0];
viewing_direction[1] = -grad_field[1];
double normViewingDir = MathUtil.norm2(viewing_direction);
// set to the correct length (= speed)
if (normViewingDir > 0) {
MathUtil.normalize(viewing_direction);
for (final Pedestrian pedestrian : elements) {
AParallelWorker<Double[]> w = new CountableParallelWorker<Double[]>(
personCounter, new Work<Double[]>() {
private int ID;
@Override
public Double[] call() throws Exception {
computeSinglePerson(pedestrian, getWorkerID(), t,
y, yDot);
return null;
}
@Override
public void setID(int ID) {
this.ID = ID;
}
@Override
public int getWorkerID() {
return this.ID;
}
});
personCounter++;
workers.add(w);
w.start();
}
// finish the work
for (AParallelWorker<Double[]> worker : workers) {
try {
worker.finish();
} catch (ExecutionException e) {
logger.error(e);
e.printStackTrace();
} catch (InterruptedException e) {
// Necessary in order to tell Simulation the thread has been
// interrupted.
// TODO [priority=low] [task=refactoring] Hack, other solution?
Thread.currentThread().interrupt();
break;
}
}
}
VPoint pos = new VPoint(position[0], position[1]);
Vector2D vel = new Vector2D(velocity[0], velocity[1]);
// get the static gradient for obstacles
Vector2D obstacleGradient = obstacleGradientProvider
.getObstaclePotentialGradient(pos, currentPed);
// get the dynamic gradient for pedestrians
Collection<? extends Agent> otherPedestrians = pedestrianGradientProvider
.getRelevantAgents(new VCircle(pos, 0.1), currentPed,
topography);
Vector2D pedestrianGradient = pedestrianGradientProvider
.getAgentPotentialGradient(pos, vel, currentPed,
otherPedestrians);
// get ped speed and acceleration data
double v0 = currentPed.getFreeFlowSpeed();
double acc = currentPed.getAcceleration();
// perform the computational steps that define this equation model
positionDot[0] = velocity[0]
* normalizer(v0 * 1.3, MathUtil.norm2(velocity));
positionDot[1] = velocity[1]
* normalizer(v0 * 1.3, MathUtil.norm2(velocity));
velocityDot[0] = (-grad_field[0] * v0 - velocity[0]) * acc
- obstacleGradient.x - pedestrianGradient.x;
velocityDot[1] = (-grad_field[1] * v0 - velocity[1]) * acc
- obstacleGradient.y - pedestrianGradient.y;
assert (!Double.isNaN(positionDot[0]));
assert (!Double.isNaN(positionDot[1]));
assert (!Double.isNaN(velocityDot[0]));
assert (!Double.isNaN(velocityDot[1]));
// store data
setPosition(personCounter, yDot, positionDot);
setVelocity(personCounter, yDot, velocityDot);
personCounter++;
/**
* Computes yDot for a single person given by personID. This is computed
* asynchronously by an {@link AParallelWorker}.
*
* @param currentPed
* @param personCounter
* @param t
* @param y
* @param yDot
*/
private void computeSinglePerson(Pedestrian currentPed, int personCounter, double t, double[] y, double[] yDot) {
double[] position = new double[2];
double[] velocity = new double[2];
double[] positionDot = new double[2];
double[] velocityDot = new double[2];
double[] grad_field = new double[2];
double[] viewing_direction = new double[2];
// ///////////////////////////////////////
// extract data
// position
getPosition(personCounter, y, position);
// velocity
getVelocity(personCounter, y, velocity);
// ///////////////////////////////////////
// generate gradients
assert (!Double.isNaN(position[0]));
assert (!Double.isNaN(position[1]));
// get the static gradient
staticGradientProvider.gradient(t, currentPed.getNextTargetId(),
position, grad_field);
assert (!Double.isNaN(position[0]));
assert (!Double.isNaN(position[1]));
/*
* Target target = this.topography.getTarget(currentPed.getTargets()
* .get(0));
* double distance2Target = target.getShape().distance(
* new VPoint(position[0], position[1]));
* if (distance2Target < 1) {
* MathUtil.normalize(grad_field);
* MathUtil.mult(grad_field, distance2Target);
* }
*/
// compute the velocity from the static gradient.
viewing_direction[0] = -grad_field[0];
viewing_direction[1] = -grad_field[1];
double normViewingDir = MathUtil.norm2(viewing_direction);
// set to the correct length (= speed)
if (normViewingDir > 0) {
MathUtil.normalize(viewing_direction);
}
VPoint pos = new VPoint(position[0], position[1]);
Vector2D vel = new Vector2D(velocity[0], velocity[1]);
// get the static gradient for obstacles
Vector2D obstacleGradient = obstacleGradientProvider
.getObstaclePotentialGradient(pos, currentPed);
// get the dynamic gradient for pedestrians
Collection<? extends Agent> otherPedestrians = pedestrianGradientProvider
.getRelevantAgents(new VCircle(pos, 0.1), currentPed,
topography);
Vector2D pedestrianGradient = pedestrianGradientProvider
.getAgentPotentialGradient(pos, vel, currentPed,
otherPedestrians);
// get ped speed and acceleration data
double v0 = currentPed.getFreeFlowSpeed();
double acc = currentPed.getAcceleration();
// perform the computational steps that define this equation model
positionDot[0] = velocity[0]
* normalizer(v0 * 1.3, MathUtil.norm2(velocity));
positionDot[1] = velocity[1]
* normalizer(v0 * 1.3, MathUtil.norm2(velocity));
velocityDot[0] = (-grad_field[0] * v0 - velocity[0]) * acc
- obstacleGradient.x - pedestrianGradient.x;
velocityDot[1] = (-grad_field[1] * v0 - velocity[1]) * acc
- obstacleGradient.y - pedestrianGradient.y;
assert (!Double.isNaN(positionDot[0]));
assert (!Double.isNaN(positionDot[1]));
assert (!Double.isNaN(velocityDot[0]));
assert (!Double.isNaN(velocityDot[1]));
// store data
setPosition(personCounter, yDot, positionDot);
setVelocity(personCounter, yDot, velocityDot);
}
/**
......
......@@ -6,6 +6,11 @@ import org.vadere.simulator.models.Model;
import org.vadere.simulator.models.ode.IntegratorFactory;
import org.vadere.simulator.models.ode.ODEModel;
import org.vadere.simulator.models.potential.FloorGradientProviderFactory;
import org.vadere.simulator.models.potential.PotentialFieldModel;
import org.vadere.simulator.models.potential.fields.IPotentialFieldTarget;
import org.vadere.simulator.models.potential.fields.IPotentialFieldTargetGrid;
import org.vadere.simulator.models.potential.fields.PotentialFieldAgent;
import org.vadere.simulator.models.potential.fields.PotentialFieldObstacle;
import org.vadere.simulator.models.potential.fields.IPotentialFieldTargetGrid;
import org.vadere.simulator.models.potential.fields.PotentialFieldAgent;
import org.vadere.simulator.models.potential.fields.PotentialFieldObstacle;
......@@ -21,11 +26,12 @@ import org.vadere.state.scenario.Target;
import org.vadere.state.types.GradientProviderType;
import org.vadere.util.geometry.shapes.VPoint;