Commit 5639ef66 authored by Christina Maria Mayr's avatar Christina Maria Mayr
Browse files

[Psychology Layer] Add probabilistic perception model + [Post-vis] Fix footstep bug

parent 4c38ef02
{
"name" : "09-Wait-Probabilistic-OSMEventDriven",
"description" : "",
"release" : "1.15",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile",
"filename" : "postvis.traj",
"processors" : [ 1, 2, 3 ]
} ],
"processors" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor",
"id" : 1
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepTargetIDProcessor",
"id" : 2
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepPsychologyStatusProcessor",
"id" : 3
} ],
"isTimestamped" : true,
"isWriteMetaData" : false
},
"scenario" : {
"mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel",
"attributesModel" : {
"org.vadere.state.attributes.models.AttributesFloorField" : {
"createMethod" : "HIGH_ACCURACY_FAST_MARCHING",
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
"obstacleDensityWeight" : 3.5,
"pedestrianSameTargetDensityWeight" : 3.5,
"pedestrianOtherTargetDensityWeight" : 3.5,
"pedestrianWeight" : 3.5,
"queueWidthLoading" : 1.0,
"pedestrianDynamicWeight" : 6.0,
"loadingType" : "CONSTANT",
"width" : 0.2,
"height" : 1.0
}
},
"org.vadere.state.attributes.models.AttributesOSM" : {
"stepCircleResolution" : 18,
"numberOfCircles" : 1,
"optimizationType" : "DISCRETE",
"varyStepDirection" : false,
"movementType" : "ARBITRARY",
"stepLengthIntercept" : 0.4625,
"stepLengthSlopeSpeed" : 0.2345,
"stepLengthSD" : 0.036,
"movementThreshold" : 0.0,
"minStepLength" : 0.4625,
"minimumStepLength" : false,
"maxStepDuration" : 1.7976931348623157E308,
"dynamicStepLength" : false,
"updateType" : "EVENT_DRIVEN",
"seeSmallWalls" : false,
"targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid",
"pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell",
"obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell",
"submodels" : [ ]
},
"org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : {
"pedPotentialIntimateSpaceWidth" : 0.45,
"pedPotentialPersonalSpaceWidth" : 1.2,
"pedPotentialHeight" : 50.0,
"obstPotentialWidth" : 0.8,
"obstPotentialHeight" : 6.0,
"intimateSpaceFactor" : 1.2,
"personalSpacePower" : 1,
"intimateSpacePower" : 1
}
},
"attributesSimulation" : {
"finishTime" : 40.0,
"simTimeStepLength" : 0.4,
"realTimeSimTimeRatio" : 0.3,
"writeSimulationData" : true,
"visualizationEnabled" : true,
"printFPS" : false,
"digitsPerCoordinate" : 2,
"useFixedSeed" : true,
"fixedSeed" : 1,
"simulationSeed" : 1
},
"attributesPsychology" : {
"usePsychologyLayer" : true,
"psychologyLayer" : {
"perception" : "ProbabilisticPerceptionModel",
"cognition" : "SimpleCognitionModel"
}
},
"topography" : {
"attributes" : {
"bounds" : {
"x" : 0.0,
"y" : 0.0,
"width" : 40.0,
"height" : 16.0
},
"boundingBoxWidth" : 0.5,
"bounded" : true,
"referenceCoordinateSystem" : null
},
"obstacles" : [ ],
"measurementAreas" : [ ],
"stairs" : [ ],
"targets" : [ {
"id" : 2,
"absorbing" : true,
"shape" : {
"x" : 36.2,
"y" : 1.1754385964912277,
"width" : 2.5,
"height" : 13.724561403508773,
"type" : "RECTANGLE"
},
"waitingTime" : 0.0,
"waitingTimeYellowPhase" : 0.0,
"parallelWaiters" : 0,
"individualWaiting" : true,
"deletionDistance" : 0.1,
"startingWithRedLight" : false,
"nextSpeed" : -1.0
} ],
"targetChangers" : [ ],
"absorbingAreas" : [ ],
"sources" : [ {
"id" : 2,
"shape" : {
"x" : 1.0,
"y" : 1.0,
"width" : 6.456140350877193,
"height" : 14.035087719298245,
"type" : "RECTANGLE"
},
"interSpawnTimeDistribution" : "org.vadere.state.scenario.ConstantDistribution",
"distributionParameters" : [ 1.0 ],
"spawnNumber" : 2,
"maxSpawnNumberTotal" : -1,
"startTime" : 0.0,
"endTime" : 0.0,
"spawnAtRandomPositions" : true,
"spawnAtGridPositionsCA" : false,
"useFreeSpaceOnly" : true,
"targetIds" : [ 2 ],
"groupSizeDistribution" : [ 1.0 ],
"dynamicElementType" : "PEDESTRIAN",
"attributesPedestrian" : null
} ],
"dynamicElements" : [ ],
"attributesPedestrian" : {
"radius" : 0.195,
"densityDependentSpeed" : false,
"speedDistributionMean" : 1.34,
"speedDistributionStandardDeviation" : 0.26,
"minimumSpeed" : 0.5,
"maximumSpeed" : 2.2,
"acceleration" : 2.0,
"footstepHistorySize" : 4,
"searchRadius" : 1.0,
"walkingDirectionCalculation" : "BY_TARGET_CENTER",
"walkingDirectionSameIfAngleLessOrEqual" : 45.0
},
"teleporter" : null,
"attributesCar" : null
},
"stimulusInfos" : [ {
"timeframe" : {
"startTime" : 5.2,
"endTime" : 10.0,
"repeat" : false,
"waitTimeBetweenRepetition" : 0.0
},
"stimuli" : [ {
"type" : "Wait",
"perceptionProbability" : 1.0
} ]
} ]
}
}
\ No newline at end of file
......@@ -7,7 +7,8 @@
"waitTimeBetweenRepetition" : 0.0
},
"stimuli" : [ {
"type" : "Wait"
"type" : "Wait",
"perceptionProbability" : 1.0
} ]
} ]
}
\ No newline at end of file
......@@ -4,7 +4,6 @@ package org.vadere.simulator.control.external.models;
import org.json.JSONObject;
import org.vadere.simulator.control.external.reaction.ReactionModel;
import org.vadere.simulator.control.psychology.perception.StimulusController;
import org.vadere.state.psychology.information.InformationState;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.logging.Logger;
......@@ -47,17 +46,6 @@ public abstract class ControlModel implements IControlModel {
this.simTimeStepLength = simTimeStepLength;
}
@Override
public void init(final Topography topography, final StimulusController stimulusController, final boolean isUsePsychologyLayer, final ReactionModel reactionModel) {
processedAgents = new HashMap<>();
simTime = 0.0;
this.topography = topography;
this.stimulusController = stimulusController;
this.isUsePsychologyLayer = isUsePsychologyLayer;
this.reactionModel = reactionModel;
}
@Override
public void init(final Topography topography, final StimulusController stimulusController, final boolean isUsePsychologyLayer){
processedAgents = new HashMap<>();
......@@ -79,11 +67,20 @@ public abstract class ControlModel implements IControlModel {
this.reactionModel = reactionModel;
}
public double getBernoulliParameter(){
return this.reactionModel.getBernoulliParameter(getOptionIndex());
}
public abstract boolean isPedReact();
protected abstract void triggerPedReaction(Pedestrian ped);
int getOptionIndex(){
// if there is one option only
return 0;
};
public void setProcessedAgents(Pedestrian ped, LinkedList<Integer> ids){
......@@ -124,7 +121,7 @@ public abstract class ControlModel implements IControlModel {
if (this.isInformationProcessed(ped, getCommandId())){
if (isInfoInTime() && isPedInDefinedArea(ped)) {
this.getControlAction(ped, command.getPedCommand());
this.setAction(ped);
this.triggerPedReaction(ped);
this.setProcessedAgents(ped,getCommandId());
}
}
......@@ -164,16 +161,6 @@ public abstract class ControlModel implements IControlModel {
return command.getCommandId();
}
public void setAction(Pedestrian ped){
if (isPedReact()){
triggerPedReaction(ped);
}
else{
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_UNCONVINCING_RECEIVED);
}
}
public boolean isInformationProcessed(Pedestrian ped, int commandId){
// 1. handle conflicting instructions over time
......@@ -204,16 +191,4 @@ public abstract class ControlModel implements IControlModel {
public double getSimTimeStepLength() {
return simTimeStepLength;
}
public void setSimTimeStepLength(final double simTimeStepLength) {
this.simTimeStepLength = simTimeStepLength;
}
public double getTimeOfNextStimulusAvailable(){
return getTimeOfNextStimulusAvailable(this.simTime);
}
public double getTimeOfNextStimulusAvailable(double currentSimTime){
return this.simTime + getSimTimeStepLength();
}
}
......@@ -15,9 +15,7 @@ import org.vadere.state.scenario.Topography;
public interface IControlModel {
void init(final Topography topo, final StimulusController stimulusController, final boolean isUsePsychologyLayer, final ReactionModel reactionModel, final double simTimeStepLength);
void init(final Topography topo, final StimulusController stimulusController, final boolean isUsePsychologyLayer, final ReactionModel reactionModel);
void init(final Topography topo, final StimulusController stimulusController, final boolean isUsePsychologyLayer);
void init(final Topography topo, final ReactionModel reactionModel);
......
......@@ -38,10 +38,7 @@ public class RouteChoice extends ControlModel {
@Override
public boolean isPedReact() {
LinkedList<Integer> alternativeTargets = readTargetsFromJson();
int i = alternativeTargets.indexOf(newTargetList.get(0));
int i = getOptionIndex();
try {
return reactionModel.isPedReact(i);
} catch (Exception e) {
......@@ -51,26 +48,37 @@ public class RouteChoice extends ControlModel {
}
protected int getOptionIndex() {
LinkedList<Integer> alternativeTargets = readTargetsFromJson();
return alternativeTargets.indexOf(newTargetList.get(0));
}
@Override
protected void triggerPedReaction(Pedestrian ped) {
LinkedList<Integer> oldTarget = ped.getTargets();
if (isUsePsychologyLayer()) {
// in this case the targets are set in the next time step when updating the psychology layer
double timeCommandExecuted = getTimeOfNextStimulusAvailable();
this.stimulusController.setDynamicStimulus(ped, new ChangeTarget(timeCommandExecuted, newTargetList), timeCommandExecuted);
double timeCommandExecuted = this.simTime + getSimTimeStepLength();
this.stimulusController.setDynamicStimulus(ped, new ChangeTarget(timeCommandExecuted, getBernoulliParameter() , newTargetList), timeCommandExecuted);
logger.debug("Pedestrian " + ped.getId() + ": created Stimulus ChangeTarget. New target list " + newTargetList);
}else{
ped.setTargets(newTargetList);
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_CONVINCING_RECEIVED);
// in this case the targets are set directly
logger.debug("Pedestrian " + ped.getId() + ": changed target list from " + oldTarget + " to " + newTargetList);
if (isPedReact()){
ped.setTargets(newTargetList);
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_CONVINCING_RECEIVED);
logger.debug("Pedestrian " + ped.getId() + ": changed target list from " + oldTarget + " to " + newTargetList);
}
else{
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_UNCONVINCING_RECEIVED);
}
}
}
private LinkedList<Integer> getTargetFromNavigationApp() {
EnumeratedIntegerDistribution dist = getDiscreteDistribution(readTargetsFromJson(), readProbabilitiesFromJson());
......
......@@ -59,7 +59,9 @@ public class ReactionModel implements IReactModel{
return isPedReact(0);
}
private double getBernoulliParameter(int i){
public double getBernoulliParameter(int i){
if (numberOfReactionBehaviors == 1){
i = 0;
......
......@@ -15,7 +15,7 @@ public class CognitionModelBuilder {
public static final String JAVA_PACKAGE_SEPARATOR = ".";
public static ICognitionModel instantiateModel(ScenarioStore scenarioStore) {
public static ICognitionModel instantiateModel(final ScenarioStore scenarioStore) {
String simpleClassName = scenarioStore.getAttributesPsychology().getPsychologyLayer().getCognition();
String classSearchPath = ICognitionModel.class.getPackageName();
String fullyQualifiedClassName = classSearchPath + JAVA_PACKAGE_SEPARATOR + simpleClassName;
......
......@@ -4,10 +4,9 @@ import org.jcodec.codecs.mjpeg.JpegDecoder;
import org.lwjgl.system.CallbackI;
import org.vadere.simulator.projects.ScenarioStore;
import org.vadere.state.psychology.perception.json.StimulusInfo;
import org.vadere.state.psychology.perception.types.ElapsedTime;
import org.vadere.state.psychology.perception.types.Stimulus;
import org.vadere.state.psychology.perception.types.Timeframe;
import org.vadere.state.psychology.perception.types.*;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VPoint;
import java.util.*;
import java.util.stream.Collectors;
......@@ -79,6 +78,10 @@ public class StimulusController {
return stimuli;
}
public void setPedSpecificStimuli(final HashMap<Pedestrian, List<StimulusInfo>> pedSpecificStimuli) {
this.pedSpecificStimuli = pedSpecificStimuli;
}
public HashMap<Pedestrian,List<Stimulus>> getStimuliForTime(double simulationTime, Collection<Pedestrian> peds) {
HashMap<Pedestrian, List<Stimulus>> pedSpecificStimuliForTime = new HashMap<>();
......@@ -94,33 +97,93 @@ public class StimulusController {
List<Stimulus> stimuli = new ArrayList<>();
stimuli = getStimuliForTime(simulationTime);
stimuli.addAll(getPedSpecificDynamicStimuli(ped, simulationTime));
return stimuli;
List<Stimulus> waitInAreaStimuli = stimuli.stream().filter(stimulus -> stimulus instanceof WaitInArea).collect(Collectors.toList());
List<Stimulus> threatStimuli = stimuli.stream().filter(stimulus -> stimulus instanceof Threat).collect(Collectors.toList());
Stimulus mostImportantWaitInArea = selectWaitInAreaContainingPedestrian(ped, waitInAreaStimuli);
Stimulus mostImportantThrea = selectClosestAndPerceptibleThreat(ped,threatStimuli);
stimuli.removeAll(waitInAreaStimuli);
stimuli.removeAll(threatStimuli);
if (mostImportantThrea!= null) stimuli.add(mostImportantThrea);
if (mostImportantWaitInArea != null)stimuli.add(mostImportantWaitInArea);
stimuli.addAll(getPedSpecificDynamicStimuli(ped, simulationTime, stimuli));
return stimuli.stream().distinct().collect(Collectors.toList());
}
private List<Stimulus> getPedSpecificDynamicStimuli(Pedestrian pedestrian, double simulationTime){
private List<Stimulus> getPedSpecificDynamicStimuli(Pedestrian pedestrian, double simulationTime, List<Stimulus> stimuli){
List<Stimulus> activeStimuli = new ArrayList<>();
if (pedSpecificStimuli.containsKey(pedestrian)){
pedSpecificStimuli.get(pedestrian).stream()
.filter(stimulusInfo -> oneTimeTimeframeIsActiveAtSimulationTime(stimulusInfo.getTimeframe(), simulationTime))
.forEach(stimulusInfo -> activeStimuli.addAll(stimulusInfo.getStimuli()));
}
List<Stimulus> waitInAreaStimuli = activeStimuli.stream().filter(stimulus -> stimulus instanceof WaitInArea).collect(Collectors.toList());
List<Stimulus> threatStimuli = activeStimuli.stream().filter(stimulus -> stimulus instanceof Threat).collect(Collectors.toList());
Stimulus mostImportantWaitInArea = selectWaitInAreaContainingPedestrian(pedestrian, waitInAreaStimuli);
Stimulus mostImportantThrea = selectClosestAndPerceptibleThreat(pedestrian,threatStimuli);
activeStimuli.removeAll(waitInAreaStimuli);
activeStimuli.removeAll(threatStimuli);
if (mostImportantThrea!= null) activeStimuli.add(mostImportantThrea);
if (mostImportantWaitInArea != null) activeStimuli.add(mostImportantWaitInArea);
List<Stimulus> finalstimuli = stimuli;
List<Stimulus> sorted = activeStimuli.stream().filter(stimulus -> finalstimuli.contains(stimulus) == false).collect(Collectors.toList());
return sorted;
}
private Stimulus selectClosestAndPerceptibleThreat(Pedestrian pedestrian, List<Stimulus> threatStimuli) {
Threat closestAndPerceptibleThreat = null;
double distanceToClosestThreat = -1;
for (Stimulus stimulus : threatStimuli) {
Threat currentThreat = (Threat) stimulus;
VPoint threatOrigin = this.scenarioStore.getTopography().getTarget(currentThreat.getOriginAsTargetId()).getShape().getCentroid();
double distanceToThreat = threatOrigin.distance(pedestrian.getPosition());
if (distanceToThreat <= currentThreat.getRadius()) {
if (closestAndPerceptibleThreat == null) {
closestAndPerceptibleThreat = currentThreat;
distanceToClosestThreat = distanceToThreat;
} else {
if (distanceToThreat < distanceToClosestThreat) {
closestAndPerceptibleThreat = currentThreat;
distanceToClosestThreat = distanceToThreat;
}
}
}
}
return activeStimuli;
return closestAndPerceptibleThreat;
}
private List<Stimulus> getPedSpecificDynamicStimuli(Pedestrian pedestrian){
List<Stimulus> activeStimuli = new ArrayList<>();
if (pedSpecificStimuli.containsKey(pedestrian)){
pedSpecificStimuli.get(pedestrian).forEach(stimulusInfo -> activeStimuli.addAll(stimulusInfo.getStimuli()));
private Stimulus selectWaitInAreaContainingPedestrian(Pedestrian pedestrian, List<Stimulus> waitInAreaStimuli) {
WaitInArea selectedWaitInArea = null;
for (Stimulus stimulus : waitInAreaStimuli) {
WaitInArea waitInArea = (WaitInArea) stimulus;
boolean pedInArea = waitInArea.getArea().contains(pedestrian.getPosition());
if (pedInArea) {
selectedWaitInArea = waitInArea;
}
}
return activeStimuli;
return selectedWaitInArea;
}
public void setDynamicStimulus(StimulusInfo stimulusInfo){
List<StimulusInfo> stimuliList = new ArrayList<>();
stimuliList.add(stimulusInfo);
......@@ -171,11 +234,6 @@ public class StimulusController {
}
private List<Stimulus> getOneTimeStimuliForSimulationTime(double simulationTime) {
List<Stimulus> activeStimuli = new ArrayList<>();
......
......@@ -15,7 +15,7 @@ public class PerceptionModelBuilder {
public static final String JAVA_PACKAGE_SEPARATOR = ".";
public static IPerceptionModel instantiateModel(ScenarioStore scenarioStore) {
public static IPerceptionModel instantiateModel(final ScenarioStore scenarioStore) {
String simpleClassName = scenarioStore.getAttributesPsychology().getPsychologyLayer().getPerception();
String classSearchPath = IPerceptionModel.class.getPackageName();
String fullyQualifiedClassName = classSearchPath + JAVA_PACKAGE_SEPARATOR + simpleClassName;
......@@ -23,7 +23,7 @@ public class PerceptionModelBuilder {
DynamicClassInstantiator<IPerceptionModel> instantiator = new DynamicClassInstantiator<>();
IPerceptionModel perceptionModel = instantiator.createObject(fullyQualifiedClassName);
perceptionModel.initialize(scenarioStore.getTopography());
perceptionModel.initialize(scenarioStore.getTopography(), scenarioStore.getAttributesSimulation().getSimTimeStepLength());
return perceptionModel;
}
......
......@@ -31,7 +31,7 @@ public interface IPerceptionModel {
* a model can acquire additional information about a pedestrian's surrounding
* when evaluating pedestrian's perception.
*/
void initialize(Topography topography);
void initialize(Topography topography, final double simTimeStepLengh);
/**
* Usually, this method iterates over the pededestrians and calls
......
package org.vadere.simulator.control.psychology.perception.models;
import org.apache.commons.math3.distribution.EnumeratedIntegerDistribution;
import org.apache.commons.math3.random.JDKRandomGenerator;
import org.apache.commons.math3.random.RandomGenerator;
import org.vadere.state.psychology.perception.types.*;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.logging.Logger;
import javax.management.RuntimeErrorException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ProbabilisticPerceptionModel implements IPerceptionModel {
private static Logger logger = Logger.getLogger(ProbabilisticPerceptionModel.class);
HashMap<Pedestrian, L