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 043151d2 authored by Christina Maria Mayr's avatar Christina Maria Mayr

Merge branch 'define_strategy' into 'master'

Write data computed in strategy layer with data processor

See merge request !142
parents 2463c808 e9de6cbc
Pipeline #314194 passed with stages
in 129 minutes and 22 seconds
......@@ -31,6 +31,10 @@
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile",
"filename" : "Mesh.txt",
"processors" : [ 10 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile",
"filename" : "controllerOutput.txt",
"processors" : [ 11 ]
} ],
"processors" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor",
......@@ -88,6 +92,9 @@
"edgeLength" : 1.5,
"displayMesh" : false
}
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.StrategyControllerValuesRealized",
"id" : 11
} ],
"isTimestamped" : true,
"isWriteMetaData" : false
......@@ -149,7 +156,7 @@
}
},
"attributesSimulation" : {
"finishTime" : 160.0,
"finishTime" : 200.0,
"simTimeStepLength" : 0.4,
"realTimeSimTimeRatio" : 0.1,
"writeSimulationData" : true,
......@@ -187,7 +194,7 @@
},
"obstacles" : [ {
"shape" : {
"x" : 15.0,
"x" : 5.0,
"y" : 10.5,
"width" : 15.5,
"height" : 30.0,
......@@ -198,24 +205,45 @@
"shape" : {
"x" : 0.5,
"y" : 10.5,
"width" : 12.5,
"width" : 2.5,
"height" : 30.0,
"type" : "RECTANGLE"
},
"id" : 7
}, {
"shape" : {
"x" : 32.5,
"y" : 10.5,
"width" : 27.0,
"height" : 30.0,
"type" : "RECTANGLE"
"type" : "POLYGON",
"points" : [ {
"x" : 22.5,
"y" : 40.5
}, {
"x" : 22.5,
"y" : 4.5
}, {
"x" : 40.0,
"y" : 4.5
}, {
"x" : 40.0,
"y" : 30.0
}, {
"x" : 59.5,
"y" : 30.0
}, {
"x" : 59.5,
"y" : 50.5
}, {
"x" : 39.9,
"y" : 50.5
}, {
"x" : 40.0,
"y" : 40.5
} ]
},
"id" : 3
} ],
"measurementAreas" : [ {
"shape" : {
"x" : 30.5,
"x" : 20.5,
"y" : 10.5,
"width" : 2.0,
"height" : 10.0,
......@@ -231,13 +259,22 @@
"type" : "RECTANGLE"
},
"id" : 1
}, {
"shape" : {
"x" : 27.9,
"y" : 0.5,
"width" : 10.0,
"height" : 4.0,
"type" : "RECTANGLE"
},
"id" : 555
} ],
"stairs" : [ ],
"targets" : [ {
"id" : 1,
"absorbing" : true,
"shape" : {
"x" : 44.5,
"x" : 25.0,
"y" : 40.5,
"width" : 15.0,
"height" : 10.0,
......@@ -254,7 +291,7 @@
"id" : 2001,
"absorbing" : false,
"shape" : {
"x" : 13.0,
"x" : 3.0,
"y" : 13.4,
"width" : 2.0,
"height" : 1.0,
......@@ -271,7 +308,7 @@
"id" : 2002,
"absorbing" : false,
"shape" : {
"x" : 30.5,
"x" : 20.5,
"y" : 13.6,
"width" : 2.0,
"height" : 1.0,
......@@ -285,33 +322,20 @@
"startingWithRedLight" : false,
"nextSpeed" : -1.0
} ],
"targetChangers" : [ {
"id" : 4,
"shape" : {
"x" : 39.5,
"y" : 0.5,
"width" : 5.0,
"height" : 10.0,
"type" : "RECTANGLE"
},
"reachDistance" : 0.0,
"changeAlgorithmType" : "SELECT_LIST",
"nextTarget" : [ 2001, 1 ],
"probabilityToChangeTarget" : [ 0.5 ]
} ],
"targetChangers" : [ ],
"absorbingAreas" : [ ],
"sources" : [ {
"id" : 2,
"shape" : {
"x" : 44.5,
"y" : 0.5,
"width" : 15.0,
"height" : 10.0,
"x" : 40.0,
"y" : 10.5,
"width" : 19.5,
"height" : 19.5,
"type" : "RECTANGLE"
},
"interSpawnTimeDistribution" : "org.vadere.state.scenario.ConstantDistribution",
"distributionParameters" : [ 1.0 ],
"spawnNumber" : 100,
"spawnNumber" : 250,
"maxSpawnNumberTotal" : -1,
"startTime" : 0.0,
"endTime" : 0.0,
......
......@@ -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;
}
}
......@@ -2,21 +2,21 @@ package org.vadere.simulator.control.strategy.models;
import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.state.attributes.AttributesStrategyModel;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import java.util.Collection;
import java.util.LinkedList;
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();
}
package org.vadere.simulator.models.strategy;
import com.github.cschen1205.fuzzylogic.Clause;
import com.github.cschen1205.fuzzylogic.FuzzySet;
import com.github.cschen1205.fuzzylogic.Rule;
import com.github.cschen1205.fuzzylogic.RuleInferenceEngine;
import com.github.cschen1205.fuzzylogic.memberships.FuzzyGrade;
import com.github.cschen1205.fuzzylogic.memberships.FuzzyReverseGrade;
import com.github.cschen1205.fuzzylogic.memberships.FuzzyTriangle;
import org.vadere.simulator.control.strategy.models.navigation.INavigationModel;
import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.simulator.projects.dataprocessing.processor.AreaDensityCountingProcessor;
import org.vadere.state.attributes.AttributesStrategyModel;
import org.vadere.state.scenario.MeasurementArea;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.logging.Logger;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
// https://github.com/cschen1205/java-fuzzy-logic
/**
* The ReadSetControllerInputs is directly connected to
* 1. the *.scenario file Scenarios/Demos/Density_controller/scenarios/TwoCorridors_forced_controller.scenario
* 2 .the *.csv file Scenarios/Demos/Density_controller/scenarios/TwoCorridors_forced_controller_input.csv
*
* The ReadSetControllerInputs class serves as a simple script which allows to proceed
* external multidimensional controller input which can not be passed as a parameter.
*
* In the scenario, there are two corridors.
* The time dependent parameter "percentageLeft" controls how many agents use the left corridor.
* If percentageLeft=0, the agents use the right and shorter path only (default OSM behavior)
* If percentageLeft=1, the agents use the left corridor only.
* @author Christina Mayr
* @since 2020-08-28
*/
public class ReadSetControllerInputs implements INavigationModel {
......@@ -27,6 +35,12 @@ public class ReadSetControllerInputs implements INavigationModel {
private double[][] controllerInputs;
private int counter = 0;
private String filePath;
private ArrayList<Pedestrian> newAgents = new ArrayList<Pedestrian>();
private ArrayList<Pedestrian> processedAgents = new ArrayList<Pedestrian>();
double ratioReal = 0.0;
private static Logger logger = Logger.getLogger(ReadSetControllerInputs.class);
@Override
public void initialize(double simTimeInSec) {
......@@ -38,46 +52,86 @@ public class ReadSetControllerInputs implements INavigationModel {
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.controllerInputs[0][0]);
}
public void update(double simTimeInSec, Collection<Pedestrian> pedestrians, ProcessorManager processorManager) {
public void update(double simTimeInSec, Topography top, ProcessorManager processorManager) {
double percentageLeft = controllerInputs[counter][1];
getAgentsInControllerArea(top);
List<Pedestrian> newAgents = pedestrians.stream().filter(p -> p.getFootstepHistory().getFootSteps().size() == 0).collect(Collectors.toList());
int numberLeft = (int) (newAgents.size() * percentageLeft);
int numberRight = newAgents.size() - numberLeft;
if ((!newAgents.isEmpty()) && (counter % 10 == 0)) {
LinkedList<Integer> targets = new LinkedList<Integer>();
for (int i = 0; i < numberLeft; i++) {
targets.add(2001);
}
for (int i = 0; i < numberRight; i++) {
targets.add(2002);
}
printAgentIds(simTimeInSec);
int numberLeft = (int) (newAgents.size() * percentageLeft);
int numberRight = newAgents.size() - numberLeft;
ratioReal = numberLeft * 1.0 / newAgents.size();
LinkedList<Integer> targets = new LinkedList<Integer>();
for (int i = 0; i < numberLeft; i++) {
targets.add(2001);
}
for (int i = 0; i < numberRight; i++) {
targets.add(2002);
}
int c = 0;
for (Pedestrian pedestrian : newAgents) {
int c = 0;
for (Pedestrian pedestrian : newAgents) {
LinkedList<Integer> nextTargets = new LinkedList<Integer>();
nextTargets.add(targets.get(c));
nextTargets.add(1);
pedestrian.setTargets(nextTargets);
c += 1;
}
processedAgents.addAll(newAgents);
newAgents.clear();
LinkedList<Integer> nextTargets = new LinkedList<Integer>();
nextTargets.add(targets.get(c));
nextTargets.add(1);
pedestrian.setTargets(nextTargets);
c += 1;
}
counter += 1;
}
private void printAgentIds(double simTimeInSec) {
String info = "Time: " + String.format("%5.1fs", simTimeInSec) + ": Agents in control area: ";
for (Pedestrian agent : newAgents) {
info += " " + agent.getId();
}
logger.info(info);
}
@Override
public void build(AttributesStrategyModel attr) {
filePath = attr.getArguments().get(0); // first element contains path to file
}
private void getAgentsInControllerArea(Topography topography) {
MeasurementArea m = topography.getMeasurementArea(555);
Collection<Pedestrian> pedestrians = topography.getElements(Pedestrian.class);
for (Pedestrian p : pedestrians) {
if (m.getShape().contains(p.getPosition())) {
if (!newAgents.contains(p) && !processedAgents.contains(p)) {
newAgents.add(p);
}
}
}
}
@Override
public Double getStrategyInfoForDataProcessor() {
return ratioReal;
}
}
......@@ -8,6 +8,7 @@ import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.simulator.projects.dataprocessing.processor.AreaDensityCountingProcessor;
import org.vadere.state.attributes.AttributesStrategyModel;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import java.util.*;
import java.util.stream.Collectors;
......@@ -29,12 +30,12 @@ public class RouteChoiceThreeCorridors implements INavigationModel {
@Override
public void initialize(double simTimeInSec) {
this.rie=new RuleInferenceEngine();
this.rie = new RuleInferenceEngine();
double dX = 0.05;
corridor = new FuzzySet("corridor", 2001, 2004, dX);
corridor.addMembership("use3", new FuzzyReverseGrade(2001,2002));
corridor.addMembership("use3", new FuzzyReverseGrade(2001, 2002));
corridor.addMembership("use2", new FuzzyTriangle(2001, 2002, 2003));
corridor.addMembership("use1", new FuzzyTriangle(2002, 2003, 2004));
corridor.addMembership("wait", new FuzzyGrade(2003, 2004));
......@@ -58,15 +59,15 @@ public class RouteChoiceThreeCorridors implements INavigationModel {
Rule rule;
String ruleName;
String[] d0 = {"high","high","high","high","low","low","low","low"};
String[] d1 = {"high","high","low","low","high","high","low","low"};
String[] d2 = {"high","low","high","low","high","low","high","low"};
String[] re = {"wait","wait","wait","wait","use3","use2","use1","use1"};
String[] d0 = {"high", "high", "high", "high", "low", "low", "low", "low"};
String[] d1 = {"high", "high", "low", "low", "high", "high", "low", "low"};
String[] d2 = {"high", "low", "high", "low", "high", "low", "high", "low"};
String[] re = {"wait", "wait", "wait", "wait", "use3", "use2", "use1", "use1"};
for (int i = 0; i < d0.length; i++) {
ruleName = "Rule " + (i+1);
ruleName = "Rule " + (i + 1);
rule = new Rule(ruleName);
rule.addAntecedent(new Clause(density, "Is", d0[i]));
......@@ -79,9 +80,15 @@ public class RouteChoiceThreeCorridors implements INavigationModel {
}
@Override
public Object getStrategyInfoForDataProcessor() {
return null;
}
public void update(double simTimeInSec, Collection<Pedestrian> pedestrians, ProcessorManager processorManager) {
public void update(double simTimeInSec, Topography top, ProcessorManager processorManager) {
Collection<Pedestrian> pedestrians = top.getElements(Pedestrian.class);
if (simTimeInSec > 0.0) {
......@@ -102,8 +109,7 @@ public class RouteChoiceThreeCorridors implements INavigationModel {
if (Double.isNaN(targetD)) {
target = 2003;
}
else{
} else {
target = (int) Math.round(targetD);
}
......@@ -139,7 +145,7 @@ public class RouteChoiceThreeCorridors implements INavigationModel {
double area = a.getMeasurementArea().asPolygon().getArea();
if (data.size() > 0) {
density = (double) (Integer) data.lastEntry().getValue();
density = density/area;
density = density / area;
}
}
return density;
......
package org.vadere.simulator.projects.dataprocessing.processor;
import org.vadere.annotation.factories.dataprocessors.DataProcessorClass;
import org.vadere.simulator.control.simulation.SimulationState;
import org.vadere.simulator.projects.dataprocessing.datakey.TimestepKey;
/**
* @author Christina Mayr
*/
@DataProcessorClass()
public class StrategyControllerValuesRealized extends StrategyDataProcessor<Double> {
public StrategyControllerValuesRealized() {
super("RealizedValues");
}
@Override
protected void doUpdate(final SimulationState state) {
this.putValue(new TimestepKey(state.getStep()), getStrategyModelOutput(state));
}
}
package org.vadere.simulator.projects.dataprocessing.processor;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.dataprocessors.DataProcessorClass;
import org.vadere.simulator.control.simulation.SimulationState;
import org.vadere.simulator.control.strategy.models.IStrategyModel;
import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.simulator.projects.dataprocessing.datakey.TimestepKey;
import org.vadere.state.attributes.processor.AttributesAreaProcessor;
/**
* @author Christina Mayr
*
*/
public abstract class StrategyDataProcessor<V> extends DataProcessor<TimestepKey, V> {
protected StrategyDataProcessor(final String... headers) {
super(headers);
}
@Override
public void init(final ProcessorManager manager) {
super.init(