Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit ad56441d authored by Christina Maria Mayr's avatar Christina Maria Mayr
Browse files

Merge branch 'extend_stimuliController' into 'master'

Feature: Add stimuli dynamically for crowd guiding strategies

See merge request !162
parents 7b2feac8 8bfffe5a
Pipeline #596142 passed with stages
in 131 minutes and 45 seconds
......@@ -13,6 +13,7 @@ import org.vadere.manager.traci.commands.TraCIGetCommand;
import org.vadere.manager.traci.commands.TraCISetCommand;
import org.vadere.manager.traci.response.TraCIGetResponse;
import org.vadere.simulator.control.simulation.SimulationState;
import org.vadere.state.psychology.information.InformationState;
import org.vadere.state.psychology.perception.types.KnowledgeItem;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.traci.CompoundObject;
......@@ -419,6 +420,7 @@ public class PersonCommandHandler extends CommandHandler<PersonVar> {
if (checkIfPedestrianExists(ped, cmd)) {
KnowledgeItem s = new KnowledgeItem(start_t, obsolete_at, information);
ped.getKnowledgeBase().addInformation(s);
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_RECEIVED);
cmd.setOK();
}
});
......
......@@ -16,15 +16,16 @@ import org.vadere.manager.traci.compound.object.CoordRef;
import org.vadere.manager.traci.compound.object.PointConverter;
import org.vadere.manager.traci.compound.object.SimulationCfg;
import org.vadere.manager.traci.response.TraCIGetResponse;
import org.vadere.simulator.control.external.models.ControlModel;
import org.vadere.simulator.control.external.models.ControlModelBuilder;
import org.vadere.simulator.control.external.models.IControlModel;
import org.vadere.simulator.control.external.reaction.ReactionModel;
import org.vadere.simulator.control.psychology.perception.StimulusController;
import org.vadere.simulator.entrypoints.ScenarioFactory;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.utils.cache.ScenarioCache;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.ReferenceCoordinateSystem;
import org.vadere.state.scenario.Topography;
import org.vadere.state.traci.*;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.logging.Logger;
......@@ -196,14 +197,20 @@ public class SimulationCommandHandler extends CommandHandler<SimulationVar> {
controlModelType = (String) cfg.getData(1, TraCIDataType.STRING);
reactionModelParameter = (String) cfg.getData(2, TraCIDataType.STRING);
remoteManager.accessState((manager, state) -> {
StimulusController stimulusController = manager.getRemoteSimulationRun().getStimulusController();
Topography topography = state.getTopography();
boolean isUsePsychologyLayer = state.getScenarioStore().getAttributesPsychology().isUsePsychologyLayer();
ReactionModel reactionModel = new ReactionModel(reactionModelParameter);
if (!iControlModelHashMap.containsKey(controlModelName)) {
IControlModel controlModel = ControlModelBuilder.getModel(controlModelType);
controlModel.setReactionModel(reactionModel);
controlModel.init(topography, stimulusController, isUsePsychologyLayer, reactionModel);
iControlModelHashMap.put(controlModelName, controlModel);
}
});
logger.infof("Received ControlInitCommand:");
logger.infof(cfg.toString());
cmd.setOK();
......@@ -232,15 +239,23 @@ public class SimulationCommandHandler extends CommandHandler<SimulationVar> {
if (!iControlModelHashMap.containsKey(model_name)) {
logger.infof("Model" + model_name + " not found. Try to initialize from model name.");
remoteManager.accessState((manager, state) -> {
StimulusController stimulusController = manager.getRemoteSimulationRun().getStimulusController();
Topography topography = state.getTopography();
boolean isUsePsychologyLayer = state.getScenarioStore().getAttributesPsychology().isUsePsychologyLayer();
ReactionModel reactionModel = new ReactionModel();
IControlModel controlModel = ControlModelBuilder.getModel(model_name);
controlModel.init(topography, stimulusController, isUsePsychologyLayer, reactionModel);
iControlModelHashMap.put(model_name, controlModel);
});
}
IControlModel controlModel = iControlModelHashMap.get(model_name);
remoteManager.accessState((manager, state) -> {
int i;
controlModel.update(state.getScenarioStore().getTopography(), state.getSimTimeInSec(), msg_content, specify_id);
controlModel.update(msg_content, state.getSimTimeInSec(), specify_id);
});
logger.infof("Received ControlCommand:");
......
......@@ -3,6 +3,9 @@ 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.simulator.projects.ScenarioStore;
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;
......@@ -21,6 +24,8 @@ public abstract class ControlModel implements IControlModel {
private CtlCommand command;
protected ReactionModel reactionModel;
protected HashMap<Pedestrian,LinkedList<Integer>> processedAgents;
protected StimulusController stimulusController;
private boolean isUsePsychologyLayer = false;
public ControlModel(){
......@@ -29,13 +34,41 @@ public abstract class ControlModel implements IControlModel {
processedAgents = new HashMap<>();
}
public ControlModel(ReactionModel reactionModel){
@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<>();
simTime = 0.0;
this.topography = topography;
this.stimulusController = stimulusController;
this.isUsePsychologyLayer = isUsePsychologyLayer;
this.reactionModel = new ReactionModel();
}
@Override
public void init(final Topography topography, final ReactionModel reactionModel){
processedAgents = new HashMap<>();
simTime = 0.0;
this.topography = topography;
this.isUsePsychologyLayer = false;
this.reactionModel = reactionModel;
}
public abstract boolean isPedReact();
protected abstract void triggerRedRaction(Pedestrian ped);
......@@ -69,8 +102,8 @@ public abstract class ControlModel implements IControlModel {
public abstract void getControlAction(Pedestrian ped, JSONObject command);
public void update(Topography topo, Double time, String commandStr, Integer pedId) {
topography = topo;
public void update(String commandStr, Double time, Integer pedId) {
simTime = time;
command = new CtlCommand(commandStr);
......@@ -86,9 +119,8 @@ public abstract class ControlModel implements IControlModel {
}
}
public void update(Topography topography, Double time, String command) {
update(topography,time,command,-1);
public void update(String command, Double time) {
update(command, time,-1);
}
private LinkedList<Integer> get_pedIds(Integer pedId)
......@@ -125,10 +157,9 @@ public abstract class ControlModel implements IControlModel {
if (isPedReact()){
triggerRedRaction(ped);
}
else{
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_UNCONVINCING_RECEIVED);
}
public void setReactionModel(ReactionModel reactionModel){
this.reactionModel = reactionModel;
}
public boolean isInformationProcessed(Pedestrian ped, int commandId){
......@@ -154,5 +185,7 @@ public abstract class ControlModel implements IControlModel {
}
public boolean isUsePsychologyLayer() {
return isUsePsychologyLayer;
}
}
package org.vadere.simulator.control.external.models;
import org.vadere.simulator.control.external.reaction.ReactionModel;
import org.vadere.simulator.control.psychology.perception.StimulusController;
import org.vadere.state.scenario.Topography;
/**
......@@ -14,9 +15,10 @@ import org.vadere.state.scenario.Topography;
public interface IControlModel {
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);
void update(Topography topo, Double time, String commandStr, Integer pedId);
void update(Topography topography, Double time, String command);
void setReactionModel(ReactionModel reactionModel);
void update(String commandStr, Double time, Integer pedId);
}
......@@ -6,6 +6,8 @@ import org.apache.commons.math3.random.RandomGenerator;
import org.json.JSONArray;
import org.json.JSONObject;
import org.vadere.simulator.control.external.reaction.ReactionModel;
import org.vadere.state.psychology.information.InformationState;
import org.vadere.state.psychology.perception.types.ChangeTarget;
import org.vadere.state.scenario.Pedestrian;
import java.util.LinkedList;
......@@ -53,8 +55,17 @@ public class RouteChoice extends ControlModel {
protected void triggerRedRaction(Pedestrian ped) {
LinkedList<Integer> oldTarget = ped.getTargets();
if (isUsePsychologyLayer()) {
double timeCommandExecuted = this.simTime + 0.4;
this.stimulusController.setDynamicStimulus(ped, new ChangeTarget(timeCommandExecuted, 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);
logger.debug("Pedestrian " + ped.getId() + ": changed target list from " + oldTarget + " to " + newTargetList);
}
}
......
package org.vadere.simulator.control.psychology.perception;
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.scenario.Pedestrian;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -27,6 +29,8 @@ public class StimulusController {
private List<StimulusInfo> oneTimeStimuli;
private List<StimulusInfo> recurringStimuli;
private HashMap<Pedestrian, List<StimulusInfo>> pedSpecificStimuli;
// Constructors
public StimulusController(ScenarioStore scenarioStore) {
this.scenarioStore = scenarioStore;
......@@ -37,6 +41,8 @@ public class StimulusController {
oneTimeStimuli.stream().forEach(stimulusInfo -> throwExceptionIfTimeframeIsInvalid(stimulusInfo.getTimeframe(), false));
recurringStimuli.stream().forEach(stimulusInfo -> throwExceptionIfTimeframeIsInvalid(stimulusInfo.getTimeframe(), true));
pedSpecificStimuli = new HashMap<>();
}
// Getters
......@@ -73,6 +79,101 @@ public class StimulusController {
return stimuli;
}
public HashMap<Pedestrian,List<Stimulus>> getStimuliForTime(double simulationTime, Collection<Pedestrian> peds) {
HashMap<Pedestrian, List<Stimulus>> pedSpecificStimuliForTime = new HashMap<>();
for (Pedestrian ped : peds) {
pedSpecificStimuliForTime.put(ped, getStimuliForTime(simulationTime, ped));
}
return pedSpecificStimuliForTime;
}
public List<Stimulus> getStimuliForTime(double simulationTime, Pedestrian ped) {
List<Stimulus> stimuli = new ArrayList<>();
stimuli = getStimuliForTime(simulationTime);
stimuli.addAll(getPedSpecificDynamicStimuli(ped, simulationTime));
return stimuli;
}
private List<Stimulus> getPedSpecificDynamicStimuli(Pedestrian pedestrian, double simulationTime){
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()));
}
return activeStimuli;
}
private List<Stimulus> getPedSpecificDynamicStimuli(Pedestrian pedestrian){
List<Stimulus> activeStimuli = new ArrayList<>();
if (pedSpecificStimuli.containsKey(pedestrian)){
pedSpecificStimuli.get(pedestrian).forEach(stimulusInfo -> activeStimuli.addAll(stimulusInfo.getStimuli()));
}
return activeStimuli;
}
public void setDynamicStimulus(StimulusInfo stimulusInfo){
List<StimulusInfo> stimuliList = new ArrayList<>();
stimuliList.add(stimulusInfo);
List<StimulusInfo> oneTimeDynamicStimuli = filterOneTimeStimuli(stimuliList);
List<StimulusInfo> recurringDynamicStimuli = filterRecurringStimuli(stimuliList);
oneTimeStimuli.addAll(oneTimeDynamicStimuli);
recurringStimuli.addAll(recurringDynamicStimuli);
}
private void setDynamicStimulus(Collection<Pedestrian> peds, StimulusInfo stimulusInfo){
for (Pedestrian ped : peds){
setDynamicStimulus(ped, stimulusInfo);
}
}
public void setDynamicStimulus(Pedestrian ped, StimulusInfo stimulusInfo){
//TODO: check whether if-else is necessary
if (pedSpecificStimuli.containsKey(ped)) {
pedSpecificStimuli.get(ped).add(stimulusInfo);
}
else{
List<StimulusInfo> stimulusInfos = new ArrayList<>();
stimulusInfos.add(stimulusInfo);
pedSpecificStimuli.put(ped, stimulusInfos);
}
}
public void setDynamicStimulus(Pedestrian ped, Stimulus stimulus, double simTimeNextTimeStep){
List<StimulusInfo> stimuliList = new ArrayList<>();
if (pedSpecificStimuli.containsKey(ped)){
stimuliList.addAll(pedSpecificStimuli.get(ped));
}
List<Stimulus> newStimulus = new ArrayList<>();
newStimulus.add(stimulus);
StimulusInfo stimulusInfo = new StimulusInfo();
stimulusInfo.setTimeframe(new Timeframe(0, simTimeNextTimeStep, false, 0));
stimulusInfo.setStimuli(newStimulus);
pedSpecificStimuli.put(ped, stimuliList);
}
private List<Stimulus> getOneTimeStimuliForSimulationTime(double simulationTime) {
List<Stimulus> activeStimuli = new ArrayList<>();
......
......@@ -6,7 +6,7 @@ import org.vadere.state.psychology.perception.types.Stimulus;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
......@@ -39,10 +39,7 @@ public interface IPerceptionModel {
*
* The current simulation time (in seconds) can be extracted from the list of
* stimuli. It is expected that the list contains an {@link ElapsedTime}.
*
* @param pedestrians The pedestrians to update
* @param stimuli The stimuli which occurred in this simulation step.
*/
void update(Collection<Pedestrian> pedestrians, List<Stimulus> stimuli);
* */
void update(HashMap<Pedestrian, List<Stimulus>> pedSpecificStimuli);
}
package org.vadere.simulator.control.psychology.perception.models;
import org.lwjgl.system.CallbackI;
import org.vadere.state.psychology.perception.types.*;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
......@@ -24,13 +26,21 @@ public class SimplePerceptionModel implements IPerceptionModel {
}
@Override
public void update(Collection<Pedestrian> pedestrians, List<Stimulus> stimuli) {
for (Pedestrian pedestrian : pedestrians) {
Stimulus mostImportantStimulus = rankChangeTargetAndThreatHigherThanWait(stimuli, pedestrian);
public void update(HashMap<Pedestrian, List<Stimulus>> pedSpecificStimuli) {
for (Pedestrian pedestrian : pedSpecificStimuli.keySet()) {
Stimulus mostImportantStimulus = rankChangeTargetAndThreatHigherThanWait(pedSpecificStimuli.get(pedestrian), pedestrian);
pedestrian.setMostImportantStimulus(mostImportantStimulus);
}
}
public void update(Collection<Pedestrian> pedestrians, List<Stimulus> generalStimuli) {
for (Pedestrian pedestrian :pedestrians) {
Stimulus mostImportantStimulus = rankChangeTargetAndThreatHigherThanWait(generalStimuli, pedestrian);
pedestrian.setMostImportantStimulus(mostImportantStimulus);
}
}
private Stimulus rankChangeTargetAndThreatHigherThanWait(List<Stimulus> stimuli, Pedestrian pedestrian) {
// Assume the "ElapsedTime" is the most important stimulus
// unless there is something more important.
......
......@@ -27,10 +27,7 @@ import org.vadere.state.scenario.*;
import org.vadere.util.logging.Logger;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.*;
import java.util.stream.Collectors;
public class Simulation implements ControllerProvider{
......@@ -453,8 +450,8 @@ public class Simulation implements ControllerProvider{
Collection<Pedestrian> pedestrians = topography.getElements(Pedestrian.class);
if (scenarioStore.getAttributesPsychology().isUsePsychologyLayer()) {
List<Stimulus> stimuli = stimulusController.getStimuliForTime(simTimeInSec);
perceptionModel.update(pedestrians, stimuli);
HashMap<Pedestrian, List<Stimulus>> pedSpecificStimuli = stimulusController.getStimuliForTime(simTimeInSec, pedestrians);
perceptionModel.update(pedSpecificStimuli);
cognitionModel.update(pedestrians);
} else {
ElapsedTime elapsedTime = new ElapsedTime(simTimeInSec);
......
......@@ -3,6 +3,7 @@ package org.vadere.simulator.control.external.models;
import org.apache.commons.math3.util.Precision;
import org.junit.Test;
import org.vadere.simulator.control.external.reaction.ReactionModel;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.attributes.scenario.AttributesTarget;
import org.vadere.state.psychology.cognition.SelfCategory;
......@@ -135,8 +136,9 @@ public class RouteChoiceTest {
RouteChoice routeChoice = new RouteChoice();
Topography topo = createTopography(createPedestrians(nr_peds));
routeChoice.init(topo, new ReactionModel());
routeChoice.update(topo, -1.0, msg);
routeChoice.update(msg, -1.0);
double prob;
for (int i = 0; i < targets.length; i++) {
......@@ -155,7 +157,8 @@ public class RouteChoiceTest {
String msg = readInputFile();
RouteChoice routeChoice = new RouteChoice();
routeChoice.update(topo, 6.0, msg);
routeChoice.init(topo, new ReactionModel());
routeChoice.update(msg, 6.0);
int target = topo.getPedestrianDynamicElements().getElement(0).getNextTargetId();
assertEquals(target, 4);
......@@ -170,8 +173,10 @@ public class RouteChoiceTest {
String msg = readInputFile();
RouteChoice routeChoice = new RouteChoice();
routeChoice.init(topo, new ReactionModel());
// keep old target nr.5 because timeout reached
routeChoice.update(topo, 10.0, msg);
routeChoice.update(msg, 10.0);
int target = topo.getPedestrianDynamicElements().getElement(0).getNextTargetId();
assertEquals(target, 5);
......@@ -188,8 +193,10 @@ public class RouteChoiceTest {
String msg = readInputFile();
RouteChoice routeChoice = new RouteChoice();
routeChoice.init(topo, new ReactionModel());
// keep old target nr.5 because timeout reached
routeChoice.update(topo, -1., msg);
routeChoice.update(msg, -1.);
int target = ped.getNextTargetId();
assertEquals(target, 5);
......@@ -205,8 +212,10 @@ public class RouteChoiceTest {
String msg = readInputFile();
RouteChoice routeChoice = new RouteChoice();
routeChoice.init(topo, new ReactionModel());
// keep old target nr.5 because timeout reached
routeChoice.update(topo, -1., msg);
routeChoice.update(msg, -1.);
int target = ped.getNextTargetId();
assertEquals(target, 4);
......@@ -222,8 +231,10 @@ public class RouteChoiceTest {
String msg = readInputFile3();
RouteChoice routeChoice = new RouteChoice();
routeChoice.init(topo, new ReactionModel());
// keep old target nr.5 because timeout reached
routeChoice.update(topo, -1., msg);
routeChoice.update(msg, -1.);
int target = ped.getNextTargetId();
assertEquals(target, 2);
......@@ -241,7 +252,9 @@ public class RouteChoiceTest {
String msg = readInputFile2();
RouteChoice routeChoice = new RouteChoice();
routeChoice.update(topo, -1., msg);
routeChoice.init(topo, new ReactionModel());
routeChoice.update(msg, -1.);
}
@Test
......@@ -262,12 +275,13 @@ public class RouteChoiceTest {
ped.setPosition(new VPoint(0.,0.));
RouteChoice routeChoice = new RouteChoice();
routeChoice.init(topo,new ReactionModel());
// keep old target nr.5 because timeout reached
routeChoice.update(topo, -1., readInputFile());
routeChoice.update(readInputFile(), -1.);
assertEquals(ped.getNextTargetId(), 4);
// readInputFile3() provides target 2. it is skipped because the command id is the same.
routeChoice.update(topo, -1., readInputFile3());
routeChoice.update(readInputFile3(), -1.);
assertEquals(ped.getNextTargetId(), 4);
}
......
......@@ -134,7 +134,7 @@ public class SimplePerceptionModelTest {
pedestrians.forEach(pedestrian -> assertNull(pedestrian.getMostImportantStimulus()));
simplePerceptionModel.update(pedestrians, stimuli);
simplePerceptionModel.update(pedestrians,stimuli);