Commit a3343b19 authored by BZoennchen's avatar BZoennchen

add processor which writes out each small step (PedestrianFootStepProcessor)....

add processor which writes out each small step (PedestrianFootStepProcessor). If the information is available the PostVis will use it.
parent 7f428aea
......@@ -174,12 +174,12 @@ public class ScenarioElementView extends JPanel implements ISelectScenarioElemen
} else {
if (scenarioElement instanceof AgentWrapper) {
this.txtrTextfiletextarea.setText(
StateJsonConverter.serializeObject(((AgentWrapper) scenarioElement).getAgentInitialStore()));
StateJsonConverter.serializeObjectPretty(((AgentWrapper) scenarioElement).getAgentInitialStore()));
} else if (scenarioElement instanceof Pedestrian) {
this.txtrTextfiletextarea.setText(StateJsonConverter.serializeObject(scenarioElement));
this.txtrTextfiletextarea.setText(StateJsonConverter.serializeObjectPretty(scenarioElement));
} else {
this.txtrTextfiletextarea.setText(StateJsonConverter
.serializeObject(scenarioElement.getAttributes()));
.serializeObjectPretty(scenarioElement.getAttributes()));
}
}
}
......
......@@ -4,12 +4,15 @@ import java.awt.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.view.DefaultRenderer;
import org.vadere.gui.components.view.SimulationRenderer;
import org.vadere.gui.onlinevisualization.model.OnlineVisualizationModel;
import org.vadere.gui.renderer.agent.AgentRender;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VPoint;
public class OnlinevisualizationRenderer extends SimulationRenderer {
......@@ -102,4 +105,18 @@ public class OnlinevisualizationRenderer extends SimulationRenderer {
}
}
}
/*
* This method should replace pedestrianPositions.get(ped.getId()).addFirst(ped.getPosition());
* However the simulation runs in an separated thread. Therefore, foot steps might be cleared
* before they can be drawn! Solution: deep clone of the topography, which is costly and difficult.
*/
private Stream<VPoint> getFootStepsPosition(@NotNull final Agent agent) {
if(agent instanceof Pedestrian) {
return ((Pedestrian) agent).getFootSteps().stream().map(footStep -> footStep.getStart());
}
else {
return Stream.of(agent.getPosition());
}
}
}
......@@ -111,7 +111,6 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
// to have fast access to the key values.
Map<Integer, Step> map = agentsByStep
.keySet().stream()
.sorted(stepComparator)
.collect(Collectors.toMap(s -> s.getStepNumber(), s -> s));
......
......@@ -102,6 +102,11 @@ public class BehaviouralHeuristicsModel implements MainModel {
@Override
public void update(final double simTimeInSec) {
// all those foot steps are done in previous sim time steps
for(PedestrianBHM ped : pedestrianEventsQueue) {
ped.clearFootSteps();
}
// event driven update
if (!pedestrianEventsQueue.isEmpty()) {
while (pedestrianEventsQueue.peek().getTimeOfNextStep() < simTimeInSec) {
......
......@@ -13,6 +13,7 @@ import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Target;
import org.vadere.state.scenario.Topography;
import org.vadere.state.simulation.FootStep;
import org.vadere.util.geometry.shapes.Vector2D;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -152,9 +153,11 @@ public class PedestrianBHM extends Pedestrian {
updateTargetDirection();
this.nextPosition = navigation.getNavigationPosition();
VPoint position = getPosition();
makeStep();
getFootSteps().add(new FootStep(position, getPosition(), timeOfNextStep, timeOfNextStep + durationNextStep));
this.timeOfNextStep = timeOfNextStep + durationNextStep;
}
......
......@@ -3,6 +3,7 @@ package org.vadere.simulator.models.bmm;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import org.vadere.annotation.factories.models.ModelClass;
......@@ -15,6 +16,7 @@ import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.scenario.DynamicElement;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.state.simulation.FootStep;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
......@@ -92,6 +94,8 @@ public class BiomechanicsModel implements MainModel {
public void update(final double simTimeInSec) {
double deltaTime = simTimeInSec - lastSimTimeInSec;
List<VPoint> positions = pedestriansBMM.stream().map(ped -> ped.getPosition()).collect(Collectors.toList());
for (PedestrianBMM agent : pedestriansBMM) {
agent.update(simTimeInSec, deltaTime);
}
......@@ -104,6 +108,12 @@ public class BiomechanicsModel implements MainModel {
agent.reverseCollisions();
}
for(int i = 0; i < pedestriansBMM.size(); i++) {
PedestrianBMM agent = pedestriansBMM.get(i);
agent.clearFootSteps();
agent.getFootSteps().add(new FootStep(positions.get(i), agent.getPosition(), lastSimTimeInSec, simTimeInSec));
}
this.lastSimTimeInSec = simTimeInSec;
}
......
package org.vadere.simulator.models.ode;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import org.apache.commons.math3.exception.MathIllegalNumberException;
import org.apache.commons.math3.ode.FirstOrderIntegrator;
......@@ -13,6 +15,7 @@ import org.vadere.state.scenario.Car;
import org.vadere.state.scenario.DynamicElement;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.state.simulation.FootStep;
import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.Vector2D;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -72,6 +75,9 @@ public abstract class ODEModel<T extends DynamicElement, TAttributes extends Att
// get pedestrian and car data
Collection<T> dynamicElements = topography.getElements(type);
List<T> orderedDynamicElements = topography.getElements(type).stream().collect(Collectors.toList());
List<VPoint> positions = orderedDynamicElements.stream().map(ped -> ped.getPosition()).collect(Collectors.toList());
double[] y;
// if no peds are present, return
......@@ -117,6 +123,15 @@ public abstract class ODEModel<T extends DynamicElement, TAttributes extends Att
}
updateElementPositions(type, simTimeInSec, topography, equations, y);
for(int i = 0; i < orderedDynamicElements.size(); i++) {
DynamicElement element = orderedDynamicElements.get(i);
if (element.getType() == ScenarioElementType.PEDESTRIAN) {
Pedestrian pedestrian = (Pedestrian)element;
pedestrian.clearFootSteps();
pedestrian.getFootSteps().add(new FootStep(positions.get(i), pedestrian.getPosition(), lastSimTimeInSec, simTimeInSec));
}
}
}
// reset the time
......@@ -128,8 +143,7 @@ public abstract class ODEModel<T extends DynamicElement, TAttributes extends Att
* double vector.
* The {@link AbstractModelEquations} are used to get the correct positions from the vector.
*/
public static <T extends DynamicElement> void updateElementPositions(Class<T> type, double simTimeInSec,
Topography topography, AbstractModelEquations equations, double[] y) {
public static <T extends DynamicElement> void updateElementPositions(Class<T> type, double t, Topography topography, AbstractModelEquations equations, double[] y) {
Collection<T> dynamicElements = topography.getElements(type);
......
......@@ -25,9 +25,8 @@ public class UpdateSchemeEventDriven implements UpdateSchemeOSM {
@Override
public void update(final double timeStepInSec, final double currentTimeInSec) {
for(PedestrianOSM pedestrianOSM : topography.getElements(PedestrianOSM.class)) {
pedestrianOSM.clearStrides();
}
clearStrides(topography);
if(!pedestrianEventsQueue.isEmpty()) {
// event driven update ignores time credits!
......
......@@ -11,6 +11,7 @@ import org.vadere.state.scenario.DynamicElementAddListener;
import org.vadere.state.scenario.DynamicElementRemoveListener;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.state.simulation.FootStep;
import org.vadere.state.types.UpdateType;
import org.vadere.util.geometry.shapes.Vector2D;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -28,6 +29,16 @@ public interface UpdateSchemeOSM extends DynamicElementRemoveListener<Pedestrian
void update(double timeStepInSec, double currentTimeInSec);
default void clearStrides(@NotNull final Topography topography) {
/**
* strides and foot steps have no influence on the simulation itself, i.e. they are saved to analyse trajectories
*/
for(PedestrianOSM pedestrianOSM : topography.getElements(PedestrianOSM.class)) {
pedestrianOSM.clearStrides();
pedestrianOSM.clearFootSteps();
}
}
static UpdateSchemeOSM create(@NotNull final UpdateType updateType, @NotNull final Topography topography, final Random random) {
switch (updateType) {
case SEQUENTIAL: return new UpdateSchemeSequential(topography);
......@@ -73,6 +84,13 @@ public interface UpdateSchemeOSM extends DynamicElementRemoveListener<Pedestrian
default void makeStep(@NotNull final Topography topography, @NotNull final PedestrianOSM pedestrian, final double stepTime) {
VPoint currentPosition = pedestrian.getPosition();
VPoint nextPosition = pedestrian.getNextPosition();
// start time
double timeOfNextStep = pedestrian.getTimeOfNextStep();
// end time
double entTimeOfStep = pedestrian.getTimeOfNextStep() + pedestrian.getDurationNextStep();
if (nextPosition.equals(currentPosition)) {
pedestrian.setTimeCredit(0);
pedestrian.setVelocity(new Vector2D(0, 0));
......@@ -85,7 +103,11 @@ public interface UpdateSchemeOSM extends DynamicElementRemoveListener<Pedestrian
pedestrian.setVelocity(pedVelocity);
}
pedestrian.getStrides().add(Pair.of(currentPosition.distance(nextPosition), pedestrian.getTimeOfNextStep()));
/**
* strides and foot steps have no influence on the simulation itself, i.e. they are saved to analyse trajectories
*/
pedestrian.getStrides().add(Pair.of(currentPosition.distance(nextPosition), timeOfNextStep));
pedestrian.getFootSteps().add(new FootStep(currentPosition, nextPosition, timeOfNextStep, entTimeOfStep));
}
}
......@@ -32,6 +32,8 @@ public class UpdateSchemeParallel implements UpdateSchemeOSM {
@Override
public void update(double timeStepInSec, double currentTimeInSec) {
clearStrides(topography);
movedPedestrians.clear();
CallMethod[] callMethods = {CallMethod.SEEK, CallMethod.MOVE, CallMethod.CONFLICTS, CallMethod.STEPS};
List<Future<?>> futures;
......
......@@ -18,6 +18,7 @@ public class UpdateSchemeSequential implements UpdateSchemeOSM {
@Override
public void update(double timeStepInSec, double currentTimeInSec) {
clearStrides(topography);
update(topography.getElements(Pedestrian.class), timeStepInSec);
}
......
......@@ -4,6 +4,7 @@ import java.util.Random;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.simulation.FootStep;
import org.vadere.util.geometry.shapes.Vector2D;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -11,12 +12,14 @@ public class PedestrianReynolds extends Pedestrian {
private Vector2D lastMovement;
private double startTime;
private double lastSimTimeInSec;
public PedestrianReynolds(AttributesAgent attributesPedestrian, Random random) {
super(attributesPedestrian, random);
this.lastMovement = new Vector2D(0, 0);
this.startTime = -1;
this.lastSimTimeInSec = -1;
}
public VPoint getLastMovement() {
......@@ -32,9 +35,16 @@ public class PedestrianReynolds extends Pedestrian {
if (startTime < 0) {
startTime = simTime;
lastSimTimeInSec = 0;
}
this.setPosition(this.getPosition().add(mov));
VPoint oldPosition = getPosition();
VPoint newPosition = oldPosition.add(mov);
setPosition(newPosition);
clearFootSteps();
getFootSteps().add(new FootStep(oldPosition, newPosition, lastSimTimeInSec, simTime));
lastSimTimeInSec = simTime;
}
}
package org.vadere.simulator.projects.dataprocessing.processor;
import org.vadere.annotation.factories.dataprocessors.DataProcessorClass;
import org.vadere.simulator.control.SimulationState;
import org.vadere.simulator.projects.dataprocessing.ProcessorManager;
import org.vadere.simulator.projects.dataprocessing.datakey.PedestrianIdKey;
import org.vadere.simulator.projects.dataprocessing.datakey.TimestepKey;
import org.vadere.simulator.projects.dataprocessing.datakey.TimestepPedestrianIdKey;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.simulation.FootStep;
import org.vadere.state.util.StateJsonConverter;
import java.util.LinkedList;
import java.util.Map;
import java.util.stream.Collectors;
/**
* During one time step a pedestrian my move multiple times which is saved by {@link Pedestrian#getFootSteps()}, i.e. the list of {@link FootStep}s
* will be adjusted after each update(simTimeInSec) call such that it contains the foot steps which started at the lastSimTimeInSec!
*
* This processor writes out all those {@link FootStep}s using the standard JSON-format, e.g. one foot steps:
* [{"startTime":26.588661014252686,"endTime":27.123123483931312,"start":{"x":29.4730189272315,"y":24.965262390895376},"end":{"x":29.59817287115996,"y":25.182035380547074}}]
*
* @author Benedikt Zoennchen
*/
@DataProcessorClass()
public class PedestrianFootStepProcessor extends DataProcessor<TimestepPedestrianIdKey, LinkedList<FootStep>>{
private double lastSimTime;
public PedestrianFootStepProcessor() {
super("strides");
lastSimTime = 0.0;
}
Map<PedestrianIdKey, LinkedList<FootStep>> getPositions(TimestepKey timestepKey) {
return this.getData().entrySet().stream()
.filter(e -> e.getKey().getTimestep().equals(timestepKey.getTimestep()))
.collect(Collectors.toMap(e -> new PedestrianIdKey(e.getKey().getPedestrianId()), Map.Entry::getValue));
}
@Override
protected void doUpdate(final SimulationState state) {
Integer timeStep = state.getStep();
for (Pedestrian pedestrian : state.getTopography().getElements(Pedestrian.class)) {
LinkedList<FootStep> copy = pedestrian.getFootSteps()
.stream()
//.filter(footStep -> footStep.getEndTime() > lastSimTime)
//.filter(footStep -> footStep.getEndTime() <= state.getSimTimeInSec())
.collect(Collectors.toCollection(LinkedList::new));
putValue(new TimestepPedestrianIdKey(timeStep, pedestrian.getId()), copy);
}
lastSimTime = state.getSimTimeInSec();
}
@Override
public void init(final ProcessorManager manager) {
super.init(manager);
}
@Override
public String[] toStrings(TimestepPedestrianIdKey key) {
LinkedList<FootStep> strides = this.getValue(key);
StringBuilder builder = new StringBuilder();
if(strides == null) {
return new String[]{"{}"};
}
else {
builder.append("[");
String stridesString = StateJsonConverter.serialidzeObject(strides);
builder.append("]");
return new String[]{stridesString};
}
}
}
\ No newline at end of file
package org.vadere.simulator.projects.dataprocessing.processor;
import org.vadere.simulator.control.SimulationState;
import org.vadere.simulator.projects.dataprocessing.datakey.PedestrianIdKey;
import org.vadere.state.attributes.processor.AttributesPedestrianLineCrossProcessor;
public class PedestrianLineCrossProcessor extends DataProcessor<PedestrianIdKey, Double> {
public PedestrianLineCrossProcessor() {
super("crossTime");
setAttributes(new AttributesPedestrianLineCrossProcessor());
}
@Override
protected void doUpdate(SimulationState state) {
}
}
package org.vadere.simulator.projects.io;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.math3.util.Pair;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
......@@ -9,7 +11,9 @@ import org.vadere.simulator.projects.dataprocessing.processor.PedestrianPosition
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.simulation.FootStep;
import org.vadere.state.simulation.Step;
import org.vadere.state.util.StateJsonConverter;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.io.IOUtils;
......@@ -52,6 +56,7 @@ public class TrajectoryReader {
private Set<String> targetIdKeys;
private Set<String> groupIdKeys;
private Set<String> groupSizeKeys;
private Set<String> stridesKeys;
private int pedIdIndex;
......@@ -61,6 +66,7 @@ public class TrajectoryReader {
private int targetIdIndex;
private int groupIdIndex;
private int groupSizeIndex;
private int stridesIndex;
public TrajectoryReader(final Path trajectoryFilePath, final Scenario scenario) {
this(trajectoryFilePath, scenario.getAttributesPedestrian());
......@@ -80,6 +86,7 @@ public class TrajectoryReader {
targetIdKeys = new HashSet<>();
groupIdKeys = new HashSet<>();
groupSizeKeys = new HashSet<>();
stridesKeys = new HashSet<>();
//should be set via Processor.getHeader
pedestrianIdKeys.add("id");
......@@ -91,6 +98,8 @@ public class TrajectoryReader {
targetIdKeys.add("targetId");
groupIdKeys.add("groupId");
groupSizeKeys.add("groupSize");
stridesKeys.add("strides");
stridesKeys.add("footSteps");
pedIdIndex = -1;
stepIndex = -1;
......@@ -99,6 +108,7 @@ public class TrajectoryReader {
targetIdIndex = -1;
groupIdIndex = -1;
groupSizeIndex = -1;
stridesIndex = -1;
}
......@@ -128,6 +138,9 @@ public class TrajectoryReader {
else if (groupSizeKeys.contains(columns[index])){
groupSizeIndex = index;
}
else if(stridesKeys.contains(columns[index])) {
stridesIndex = index;
}
}
try {
if (pedIdIndex != -1 && xIndex != -1 && yIndex != -1 && stepIndex != -1) {
......@@ -198,7 +211,7 @@ public class TrajectoryReader {
// pedestrian id
int pedestrianId = Integer.parseInt(rowTokens[pedIdIndex]);
Pedestrian ped = new Pedestrian(new AttributesAgent(this.attributesPedestrian, pedestrianId), new Random());
Pedestrian ped = new Pedestrian(new AttributesAgent(attributesPedestrian, pedestrianId), new Random());
// pedestrian position
VPoint pos = new VPoint(Double.parseDouble(rowTokens[xIndex]), Double.parseDouble(rowTokens[yIndex]));
......@@ -211,11 +224,18 @@ public class TrajectoryReader {
ped.setTargets(targets);
if(groupIdIndex != -1) {
int groupId = groupIdIndex != -1 ? Integer.parseInt(rowTokens[groupIdIndex]) : -1;
int groupId = Integer.parseInt(rowTokens[groupIdIndex]);
int groupSize = groupSizeIndex != -1 ? Integer.parseInt(rowTokens[groupSizeIndex]) : -1;
ped.addGroupId(groupId, groupSize);
}
if(stridesIndex != -1) {
FootStep[] footSteps = StateJsonConverter.deserializeObjectFromJson(rowTokens[stridesIndex], FootStep[].class);
for(FootStep footStep : footSteps) {
ped.getFootSteps().add(footStep);
}
}
return Pair.create(new Step(step), ped);
}
}
package org.vadere.state.attributes.processor;
import org.vadere.util.geometry.shapes.VLine;
public class AttributesPedestrianLineCrossProcessor extends AttributesProcessor {
private VLine line = new VLine(0, 0, 1, 0);
}
package org.vadere.state.scenario;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.simulation.FootStep;
import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.VShape;
......@@ -21,6 +22,15 @@ public class Pedestrian extends Agent {
private LinkedList<Integer> groupIds; // TODO should actually be an attribute or a member of a subclass
/**
* Footsteps is a list of foot steps a pedestrian made during the duration of one time step.
* For all non event driven models this is exactly one foot step. For the event driven update
* one pedestrian can move multiple times during one time step. To save memory the list of foot steps
* will be cleared after each completion of a time step. The output processor <tt>PedestrianStrideProcessor</tt>
* can write out those foot steps.
*/
private LinkedList<FootStep> footSteps;
/** Used only for JSON serialization? */
// TODO used at all? Car does NOT have this field. remove if unused!
private ScenarioElementType type = ScenarioElementType.PEDESTRIAN;
......@@ -47,6 +57,7 @@ public class Pedestrian extends Agent {
isLikelyInjured = false;
groupIds = new LinkedList<>();
groupSizes = new LinkedList<>();
footSteps = new LinkedList<>();
}
/**
......@@ -67,6 +78,17 @@ public class Pedestrian extends Agent {
groupIds = new LinkedList<>();
groupSizes = new LinkedList<>();
}
footSteps = new LinkedList<>();
footSteps.addAll(other.footSteps);
}
public void clearFootSteps() {
footSteps.clear();
}
public LinkedList<FootStep> getFootSteps() {
return footSteps;
}
public void addGroupId(int groupId, int size){
......
package org.vadere.state.simulation;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.shapes.VPoint;
/**
* A foot step is a simple java bean which represents one pedestrian foot step which is defined by
* <ol>
* <li>start time (simulation time in seconds)</li>
* <li>end time (simulation time in seconds)</li>
* <li>start point</li>
* <li>end point</li>
* </ol>
*
* @author Benedikt Zoennchen
*/
public final class FootStep {
/*
* These are not final because of Jackson.
*/
private double startTime;
private double endTime;
private VPoint start;
private VPoint end;
/**
* Constructor for Jackson.
*/
public FootStep() {}
/**
* Default constructor.
*
* @param start start point of the foot step
* @param end end point of the foot step
* @param startTime start time of the foot step
* @param endTime end time of the foot step
*/
public FootStep(@NotNull final VPoint start, @NotNull final VPoint end, final double startTime, final double endTime) {
this.start = start;
this.end = end;
this.startTime = startTime;
this.endTime = endTime;
}
public double getEndTime() {
return endTime;
}
public double getStartTime() {
return startTime;
}
public VPoint getEnd() {
return end;
}
public VPoint getStart() {
return start;
}
}
......@@ -7,9 +7,11 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.jetbrains.annotations.NotNull;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VPoint;
/**
......@@ -181,7 +183,7 @@ public class Trajectory {
* Return a {@link java.util.stream.Stream<>} stream of
* {@link org.vadere.util.geometry.shapes.VPoint} pedestrian positions
* from the first step (1) to the (step.getStepNumber()) in reverse order.
*
*
* @param step the step of the last pedestrian position
* @return a stream of pedestrian positions to from 1 to step.getStepNumber() in reverse order
*/
......@@ -189,8 +191,21 @@ public class Trajectory {
return Stream.iterate(step, s -> new Step(s.getStepNumber() - 1))
.limit(step.getStepNumber())
.map(s -> getAgent(s))
.filter(optPed -> optPed.isPresent())
.map(optPed -> optPed.get().getPosition());
.filter(optAgent -> optAgent.isPresent())
.map(optAgent -> optAgent.get())
.flatMap(agent -> toPointStream(agent));
}
private Stream<VPoint> toPointStream(@NotNull final Agent agent) {
// use the foot step information if available
if(agent instanceof Pedestrian) {
Pedestrian pedestrian = (Pedestrian)agent;
if(!pedestrian.getFootSteps().isEmpty()) {
Iterable<FootStep> iterable = () -> pedestrian.getFootSteps().descendingIterator();
return StreamSupport.stream(iterable.spliterator(), false).map(footStep -> footStep.getEnd());
}
}
return Stream.of(agent.getPosition());
}
public Optional<Step> getStartStep() {
......
......@@ -60,7 +60,9 @@ public abstract class StateJsonConverter {
private static ObjectMapper mapper = new JacksonObjectMapper();
/** Connection to jackson library. */
private static ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
private static ObjectWriter prettyWriter = mapper.writerWithDefaultPrettyPrinter();
private static ObjectWriter writer = mapper.writer();
public static ObjectMapper getMapper() {
return mapper;
......@@ -78,6 +80,18 @@ public abstract class StateJsonConverter {
}
}
public static <T> T deserializeObjectFromJson(String json, final TypeReference<T> type) {
T data = null;
try {
data = mapper.readValue(json, type);
} catch (Exception e) {