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 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,13 +197,19 @@ public class SimulationCommandHandler extends CommandHandler<SimulationVar> {
controlModelType = (String) cfg.getData(1, TraCIDataType.STRING);
reactionModelParameter = (String) cfg.getData(2, TraCIDataType.STRING);
ReactionModel reactionModel = new ReactionModel(reactionModelParameter);
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.init(topography, stimulusController, isUsePsychologyLayer, reactionModel);
iControlModelHashMap.put(controlModelName, controlModel);
}
if (!iControlModelHashMap.containsKey(controlModelName)) {
IControlModel controlModel = ControlModelBuilder.getModel(controlModelType);
controlModel.setReactionModel(reactionModel);
iControlModelHashMap.put(controlModelName, controlModel);
}
});
logger.infof("Received ControlInitCommand:");
logger.infof(cfg.toString());
......@@ -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.");
IControlModel controlModel = ControlModelBuilder.getModel(model_name);
iControlModelHashMap.put(model_name, controlModel);
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);
}
}
public void setReactionModel(ReactionModel reactionModel){
this.reactionModel = reactionModel;
else{
ped.getKnowledgeBase().setInformationState(InformationState.INFORMATION_UNCONVINCING_RECEIVED);
}
}
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();
ped.setTargets(newTargetList);
logger.debug("Pedestrian " + ped.getId() + ": changed target list from " + oldTarget + " to " + newTargetList);
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);