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

Commit a26ebf08 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

add attribute and scenario builders to change scenarios via java code

parent aa8ff1fe
......@@ -19,7 +19,7 @@ import org.apache.log4j.Logger;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.Theme;
import org.vadere.gui.components.control.ReflectionAttributeModifier;
import org.vadere.simulator.entrypoints.ReflectionAttributeModifier;
import org.vadere.gui.components.model.IDefaultModel;
import org.vadere.gui.projectview.view.JsonValidIndicator;
import org.vadere.gui.projectview.view.ProjectView;
......
......@@ -31,7 +31,7 @@ public class ReflectionAttributeModifier {
((AgentWrapper) element).getAgentInitialStore().setPosition(new VPoint(x, y));
} else {
Attributes attributes =
org.vadere.gui.components.control.ReflectionAttributeModifier.getAttributes(element);
org.vadere.simulator.entrypoints.ReflectionAttributeModifier.getAttributes(element);
field = attributes.getClass().getDeclaredField("shape");
field.setAccessible(true);
field.set(attributes, shape);
......
package org.vadere.gui.components.control;
package org.vadere.simulator.entrypoints;
import java.lang.reflect.Field;
import org.vadere.gui.topographycreator.model.AgentWrapper;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.state.scenario.Topography;
/**
* Setter and getter implementation to modify Attributes. This class uses use of reflection.
......@@ -17,6 +15,23 @@ import org.vadere.util.geometry.shapes.VShape;
*/
public class ReflectionAttributeModifier {
/**
* Sets the attribute to the topography element. Use this method only in the control!
*
* @param element the topography element
* @param attributes the attributes
*/
public static void setAttributes(final Topography element, final Attributes attributes) {
try {
Field field = element.getClass().getDeclaredField("attributes");
field.setAccessible(true);
field.set(element, attributes);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* Sets the attribute to the topography element. Use this method only in the control!
*
......
package org.vadere.simulator.entrypoints;
import java.lang.reflect.Field;
import java.util.List;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.ScenarioStore;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.AttributesBuilder;
import org.vadere.state.attributes.AttributesSimulation;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.attributes.scenario.AttributesCar;
import org.vadere.state.attributes.scenario.AttributesTopography;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Teleporter;
/**
* {@link ScenarioBuilder} provide methods to manipulate the attributes/parameters of a scenario.
* It's an interface for generate multiple Scenarios based on the same infrastructure but
* with different attributes/parameters. The class does not provide methods to change the
* infrastructure of the {@link org.vadere.state.scenario.Topography}. To use this effectively the user need a
* good knowledge about the parameters of the given scenario!
*
* @author Benedikt Zoennchen
*
*/
public class ScenarioBuilder {
private static Logger logger = LogManager.getLogger(ScenarioBuilder.class);
private Scenario scenario;
private ScenarioStore store;
public ScenarioBuilder(final Scenario base) {
scenario = base.clone();
store = scenario.getScenarioStore();
}
/*public Scenario build() {
store.topography = IOVadere
JsonSerializerTopography.topographyToJson(scenario.getTopography());
return scenario;
}*/
/**
* Changes the name of the output-files that will be generated during and after the simulation.
* To prevent yourself from overriding files it's necessary to set a new output name for every
* generated scenario!
*
* @param name the name of the output file
*/
public void setName(final String name) {
scenario.setName(name);
}
public <T, E extends Attributes> void setAttributesField(final String fieldName, final T value, final Class<E> clazz) {
AttributesBuilder<E> builder;
// TODO: duplicated code
if(AttributesSimulation.class == clazz){
builder = new AttributesBuilder<>((E)store.attributesSimulation);
builder.setField(fieldName, value);
store.attributesSimulation = (AttributesSimulation) builder.build();
}
else if(AttributesAgent.class == clazz){
builder = new AttributesBuilder<>((E)store.topography.getAttributesPedestrian());
builder.setField(fieldName, value);
setAttributesAgent((AttributesAgent) builder.build());
}
else if(AttributesCar.class == clazz){
builder = new AttributesBuilder<>((E)store.topography.getAttributesCar());
builder.setField(fieldName, value);
setAttributesCar((AttributesCar) builder.build());
}
else if(AttributesTopography.class == clazz){
builder = new AttributesBuilder<>((E)store.topography.getAttributes());
builder.setField(fieldName, value);
ReflectionAttributeModifier reflectionAttributeModifier = new ReflectionAttributeModifier();
reflectionAttributeModifier.setAttributes(store.topography, builder.build());
}
else {
builder = new AttributesBuilder<>(store.getAttributes(clazz));
builder.setField(fieldName, value);
store.attributesList.removeIf(attributes -> attributes.getClass() == clazz);
store.attributesList.add(builder.build());
}
}
private void setAttributesCar(@NotNull final AttributesCar attributesCar) {
Field field;
try {
field = store.topography.getClass().getDeclaredField("attributesCar");
field.setAccessible(true);
field.set(store.topography, attributesCar);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
logger.error(e);
}
}
private void setAttributesAgent(@NotNull final AttributesAgent attributesAgent) {
Field field;
try {
field = store.topography.getClass().getDeclaredField("attributesPedestrian");
field.setAccessible(true);
field.set(store.topography, attributesAgent);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
logger.error(e);
}
}
// change topography
/**
* Assign the value to the field identified by fieldName of the first source, identified by sourceId.
* If no source was found, nothing will happen.
*
* @param fieldName name of the field (e.g. spawnNumber)
* @param sourceId id of the source
* @param value value that will be assigned
*/
public <T> void setSourceField(final String fieldName, final int sourceId, final T value) {
setField(scenario.getTopography().getSources(), sourceId, fieldName, value);
}
/**
* Assign the value to the field identified by fieldName of the first target, identified by sourceId.
* If no source was found, nothing will happen.
*
* @param fieldName name of the field (e.g. spawnNumber)
* @param targetId id of the target
* @param value value that will be assigned
*/
public <T> void setTargetField(final String fieldName, final int targetId, final T value) {
setField(scenario.getTopography().getTargets(), targetId, fieldName, value);
}
/**
* Assign the value to the field identified by fieldName.
* @param fieldName field identifier
* @param value the assigned value
*/
public <T> void setTeleporterField(final String fieldName, final T value) {
Teleporter teleporter = scenario.getTopography().getTeleporter();
teleporter = setField(fieldName, teleporter, value);
scenario.getTopography().setTeleporter(teleporter);
}
/**
* Assign the value to all the fields, identified by fieldName, of all sources.
*
* @param fieldName field identifier
* @param value the assigned value
*/
public <T> void setAllSourcesField(final String fieldName, final T value) {
setAllField(scenario.getTopography().getSources(), fieldName, value);
}
/**
* Assign the value to all the fields, identified by fieldName, of all targets.
*
* @param fieldName field identifier
* @param value the assigned value
*/
public <T> void setAllTargetsField(final String fieldName, final T value) {
setAllField(scenario.getTopography().getTargets(), fieldName, value);
}
/**
* Assign the i-th element of value to the field, identified by the fieldName, of the i-th source.
* sources.get(i)[field] = values(i).
*
* @param fieldName name of the attribute
* @param values array of values
*/
@SuppressWarnings("unchecked")
public <T> void setMultipleSourcesField(final String fieldName, final T ...values) {
setFieldOfElements(fieldName, scenario.getTopography().getSources(), values);
}
/**
* Assign the i-th element of value to the field, identified by the fieldName, of the i-th target.
* targets.get(i)[field] = values(i).
*
* @param fieldName name of the attribute
* @param values array of values
*/
@SuppressWarnings("unchecked")
public <T> void setMulitipleTargetsField(final String fieldName, final T ...values) {
setFieldOfElements(fieldName, scenario.getTopography().getTargets(), values);
}
// private helpers
/**
* Sets the value of the field, identified by fieldName, of the i-th element in the list to the i-th value.
* list.get(i)[field] = values(i).
*
* @param fieldName the name of the field that will be affected
* @param list list of elements that will be affected
* @param values values that correspond to the element.
*/
@SuppressWarnings("unchecked")
private static <T, E extends ScenarioElement> void setFieldOfElements(final String fieldName, final List<E> list, final T ...values){
int i = 0;
while(i < values.length && i < list.size()){
E element = setField(fieldName, list.get(i), values[i]);
list.remove(i);
list.add(i, element);
i++;
}
}
private static <T, E extends ScenarioElement> void setAllField(final List<E> scenarioElements, final String name, final T value) {
E tmp = null;
for (int i = 0; i < scenarioElements.size(); i++) {
tmp = scenarioElements.get(i);
E element = setField(name, tmp, value);
scenarioElements.remove(i);
scenarioElements.add(i, element);
}
}
/**
* Sets the field with the name=fieldName of element in scenarioElements, identified by his id, to value.
* If no element was found, nothing will happen. If there are more than one element with the id in the list,
* only the first one will be affected.
*/
private static <T, E extends ScenarioElement> void setField(final List<E> scenarioElements, final int id, final String name, final T value) {
E tmp = null;
for (int i = 0; i < scenarioElements.size(); i++) {
tmp = scenarioElements.get(i);
if(tmp.getId() == id) {
E element = setField(name, tmp, value);
scenarioElements.remove(i);
scenarioElements.add(i, element);
return;
}
}
logger.warn("couldn't find scenarioElement ("+(tmp!=null?tmp.getType():null)+") with the id " + id);
}
/**
* Set's the field with the name=fieldName of element to value.
*/
private static <T, E extends ScenarioElement> E setField(final String fieldName, final E element, final T value){
ReflectionAttributeModifier reflectionAttributeModifier = new ReflectionAttributeModifier();
AttributesBuilder<Attributes> attBuilder = new AttributesBuilder<>(element.getAttributes());
attBuilder.setField(fieldName, value);
E clone = (E) element.clone();
reflectionAttributeModifier.setAttributes(clone, attBuilder.build());
return clone;
}
public Scenario build() {
return scenario.clone();
}
}
......@@ -5,12 +5,15 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;
import org.jetbrains.annotations.NotNull;
import org.vadere.simulator.projects.io.JsonConverter;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.AttributesSimulation;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.attributes.scenario.AttributesCar;
import org.vadere.state.scenario.Topography;
import org.vadere.state.util.StateJsonConverter;
import org.vadere.util.data.FindByClass;
import org.vadere.util.reflection.VadereClassNotFoundException;
import com.fasterxml.jackson.core.JsonProcessingException;
......@@ -67,4 +70,7 @@ public class ScenarioStore {
topography.sealAllAttributes();
}
public <T extends Attributes> T getAttributes(@NotNull final Class<T> clazz) {
return FindByClass.findSingleObjectOfClass(attributesList, clazz);
}
}
package org.vadere.simulator.entrypoints;
import org.junit.Test;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.io.IOVadere;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.AttributesBuilder;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.attributes.scenario.AttributesSource;
import org.vadere.state.attributes.scenario.AttributesTopography;
import org.vadere.util.geometry.shapes.VRectangle;
import java.io.IOException;
import static junit.framework.TestCase.assertTrue;
/**
* @author Benedikt Zoennchen
*/
public class TestScenarioBuilder {
private AttributesBuilder<AttributesAgent> attributesAgentAttributesBuilder;
private double radius = 0.195;
@Test
public void testChangeAttributes() throws IOException {
// 1. read the scenario from a string
Scenario scenario = IOVadere.fromJson(jsonScenario);
// 2. change the source id = -1 to source id = 1
assertTrue(scenario.getTopography().getSources().get(0).getId() == -1);
ScenarioBuilder builder = new ScenarioBuilder(scenario);
builder.setSourceField("id", -1, 1);
assertTrue(scenario.getTopography().getSources().get(0).getId() == -1);
scenario = builder.build();
assertTrue(scenario.getTopography().getSources().get(0).getId() == 1);
// 3. change pedestrianAttributes / radius
builder.setAttributesField("radius", 30.0, AttributesAgent.class);
scenario = builder.build();
assertTrue(scenario.getAttributesPedestrian().getRadius() == 30.0);
// 4. change topographyAttributes / radius
builder.setAttributesField("bounds", new VRectangle(10, 10, 100, 100), AttributesTopography.class);
scenario = builder.build();
assertTrue(scenario.getTopography().getBounds().equals(new VRectangle(10, 10, 100, 100)));
// 5. change sourceAttributes
builder.setSourceField("spawnNumber", 1, 400);
scenario = builder.build();
assertTrue(scenario.getTopography().getSources().get(0).getAttributes().getSpawnNumber() == 400);
}
private static String jsonScenario = "{\n" +
" \"name\" : \"basic_1_chicken_osm1\",\n" +
" \"description\" : \"\",\n" +
" \"release\" : \"0.2\",\n" +
" \"processWriters\" : {\n" +
" \"files\" : [ {\n" +
" \"type\" : \"org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile\",\n" +
" \"filename\" : \"out.txt\",\n" +
" \"processors\" : [ 1 ]\n" +
" } ],\n" +
" \"processors\" : [ {\n" +
" \"type\" : \"org.vadere.simulator.projects.dataprocessing.processor.PedestrianPositionProcessor\",\n" +
" \"id\" : 1\n" +
" } ],\n" +
" \"isTimestamped\" : true\n" +
" },\n" +
" \"scenario\" : {\n" +
" \"mainModel\" : \"org.vadere.simulator.models.osm.OptimalStepsModel\",\n" +
" \"attributesModel\" : {\n" +
" \"org.vadere.state.attributes.models.AttributesPotentialCompact\" : {\n" +
" \"pedPotentialWidth\" : 0.5,\n" +
" \"pedPotentialHeight\" : 12.6,\n" +
" \"obstPotentialWidth\" : 0.25,\n" +
" \"obstPotentialHeight\" : 20.1,\n" +
" \"useHardBodyShell\" : false,\n" +
" \"obstDistanceDeviation\" : 0.0,\n" +
" \"visionFieldRadius\" : 5.0\n" +
" },\n" +
" \"org.vadere.state.attributes.models.AttributesOSM\" : {\n" +
" \"stepCircleResolution\" : 18,\n" +
" \"numberOfCircles\" : 1,\n" +
" \"varyStepDirection\" : false,\n" +
" \"stepLengthIntercept\" : 0.4625,\n" +
" \"stepLengthSlopeSpeed\" : 0.2345,\n" +
" \"stepLengthSD\" : 0.036,\n" +
" \"movementThreshold\" : 0.0,\n" +
" \"optimizationType\" : \"DISCRETE\",\n" +
" \"movementType\" : \"ARBITRARY\",\n" +
" \"dynamicStepLength\" : false,\n" +
" \"updateType\" : \"EVENT_DRIVEN\",\n" +
" \"seeSmallWalls\" : false,\n" +
" \"minimumStepLength\" : false,\n" +
" \"targetPotentialModel\" : \"org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid\",\n" +
" \"pedestrianPotentialModel\" : \"org.vadere.simulator.models.potential.PotentialFieldPedestrianCompact\",\n" +
" \"obstaclePotentialModel\" : \"org.vadere.simulator.models.potential.PotentialFieldObstacleCompact\",\n" +
" \"submodels\" : [ ]\n" +
" },\n" +
" \"org.vadere.state.attributes.models.AttributesFloorField\" : {\n" +
" \"createMethod\" : \"HIGH_ACCURACY_FAST_MARCHING\",\n" +
" \"potentialFieldResolution\" : 0.1,\n" +
" \"obstacleGridPenalty\" : 0.1,\n" +
" \"targetAttractionStrength\" : 1.0,\n" +
" \"timeCostAttributes\" : {\n" +
" \"standardDerivation\" : 0.7,\n" +
" \"type\" : \"UNIT\",\n" +
" \"obstacleDensityWeight\" : 3.5,\n" +
" \"pedestrianSameTargetDensityWeight\" : 3.5,\n" +
" \"pedestrianOtherTargetDensityWeight\" : 3.5,\n" +
" \"pedestrianWeight\" : 3.5,\n" +
" \"queueWidthLoading\" : 1.0,\n" +
" \"pedestrianDynamicWeight\" : 6.0,\n" +
" \"loadingType\" : \"CONSTANT\"\n" +
" }\n" +
" }\n" +
" },\n" +
" \"attributesSimulation\" : {\n" +
" \"finishTime\" : 200.0,\n" +
" \"simTimeStepLength\" : 0.4,\n" +
" \"realTimeSimTimeRatio\" : 0.0,\n" +
" \"writeSimulationData\" : true,\n" +
" \"visualizationEnabled\" : true,\n" +
" \"printFPS\" : false,\n" +
" \"needsBoundary\" : false,\n" +
" \"digitsPerCoordinate\" : 2,\n" +
" \"useRandomSeed\" : true,\n" +
" \"randomSeed\" : 1\n" +
" },\n" +
" \"topography\" : {\n" +
" \"attributes\" : {\n" +
" \"bounds\" : {\n" +
" \"x\" : 0.0,\n" +
" \"y\" : 0.0,\n" +
" \"width\" : 35.0,\n" +
" \"height\" : 60.0\n" +
" },\n" +
" \"boundingBoxWidth\" : 0.5,\n" +
" \"bounded\" : true\n" +
" },\n" +
" \"obstacles\" : [ {\n" +
" \"shape\" : {\n" +
" \"x\" : 10.0,\n" +
" \"y\" : 40.0,\n" +
" \"width\" : 15.0,\n" +
" \"height\" : 1.0,\n" +
" \"type\" : \"RECTANGLE\"\n" +
" },\n" +
" \"id\" : -1\n" +
" }, {\n" +
" \"shape\" : {\n" +
" \"x\" : 9.0,\n" +
" \"y\" : 21.0,\n" +
" \"width\" : 1.0,\n" +
" \"height\" : 20.0,\n" +
" \"type\" : \"RECTANGLE\"\n" +
" },\n" +
" \"id\" : -1\n" +
" }, {\n" +
" \"shape\" : {\n" +
" \"x\" : 25.0,\n" +
" \"y\" : 21.0,\n" +
" \"width\" : 1.0,\n" +
" \"height\" : 20.0,\n" +
" \"type\" : \"RECTANGLE\"\n" +
" },\n" +
" \"id\" : -1\n" +
" } ],\n" +
" \"stairs\" : [ ],\n" +
" \"targets\" : [ {\n" +
" \"id\" : 1,\n" +
" \"absorbing\" : true,\n" +
" \"shape\" : {\n" +
" \"x\" : 10.0,\n" +
" \"y\" : 51.0,\n" +
" \"width\" : 15.0,\n" +
" \"height\" : 5.0,\n" +
" \"type\" : \"RECTANGLE\"\n" +
" },\n" +
" \"waitingTime\" : 0.0,\n" +
" \"waitingTimeYellowPhase\" : 0.0,\n" +
" \"parallelWaiters\" : 0,\n" +
" \"individualWaiting\" : true,\n" +
" \"deletionDistance\" : 0.1,\n" +
" \"startingWithRedLight\" : false,\n" +
" \"nextSpeed\" : -1.0\n" +
" } ],\n" +
" \"sources\" : [ {\n" +
" \"id\" : -1,\n" +
" \"shape\" : {\n" +
" \"x\" : 10.0,\n" +
" \"y\" : 6.0,\n" +
" \"width\" : 15.0,\n" +
" \"height\" : 5.0,\n" +
" \"type\" : \"RECTANGLE\"\n" +
" },\n" +
" \"interSpawnTimeDistribution\" : \"org.vadere.state.scenario.ConstantDistribution\",\n" +
" \"distributionParameters\" : [ 1.0 ],\n" +
" \"spawnNumber\" : 200,\n" +
" \"maxSpawnNumberTotal\" : -1,\n" +
" \"startTime\" : 0.0,\n" +
" \"endTime\" : 0.0,\n" +
" \"spawnAtRandomPositions\" : true,\n" +
" \"useFreeSpaceOnly\" : false,\n" +
" \"targetIds\" : [ 1 ],\n" +
" \"dynamicElementType\" : \"PEDESTRIAN\"\n" +
" } ],\n" +
" \"dynamicElements\" : [ ],\n" +
" \"attributesPedestrian\" : {\n" +
" \"radius\" : 0.195,\n" +
" \"densityDependentSpeed\" : false,\n" +
" \"speedDistributionMean\" : 1.34,\n" +
" \"speedDistributionStandardDeviation\" : 0.26,\n" +
" \"minimumSpeed\" : 0.3,\n" +
" \"maximumSpeed\" : 3.0,\n" +
" \"acceleration\" : 2.0\n" +
" },\n" +
" \"attributesCar\" : null\n" +
" }\n" +
" }\n" +
"}";
}
package org.vadere.state.attributes;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;