Commit 04ece8f7 authored by Jakob Schöttl's avatar Jakob Schöttl
Browse files

Merge branch 'targetcontroller' into 'develop'

TargetController

@michael-seitz @BZoennchen @dietrich @Isabella-vonSivers 

Es wird Zeit, dass wir das mit der Target Liste angehen.

Ich hab seit gestern Fehler gesucht, weil ich nicht mehr wusste, dass die Modelle selbst die Benutzung der Target Liste der Agents aktivieren müssen (indem der `nextTargetListIndex` auf 0 statt -1 gesetzt wird). Wir sollten das aber zum Standard machen, bevor noch mehr Modelle auf dem deprecated System entwickelt werden und noch mehr Leute Fehler suchen!

Also an alle, die Modelle (insbesondere Modelle mit mehreren Zielen) haben: Bitte mal kurz auf diesem Branch testen.

See merge request !10
parents 1ac3188a c2408a8f
......@@ -16,6 +16,7 @@ import org.vadere.state.scenario.TargetListener;
import org.vadere.state.scenario.Topography;
import org.vadere.state.types.TrafficLightPhase;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
public class TargetController {
......@@ -38,20 +39,11 @@ public class TargetController {
}
public void update(double simTimeInSec) {
if (this.target.isTargetPedestrian()) {
if (target.isTargetPedestrian()) {
return;
}
final double reachedDistance = target.getAttributes().getDeletionDistance();
final Rectangle2D bounds = target.getShape().getBounds2D();
final VPoint center = new VPoint(bounds.getCenterX(), bounds.getCenterY());
final double radius = Math.max(bounds.getHeight(), bounds.getWidth()) + reachedDistance;
final Collection<DynamicElement> elementsInRange = new LinkedList<>();
elementsInRange.addAll(getObjectsInCircle(Pedestrian.class, center, radius));
elementsInRange.addAll(getObjectsInCircle(Car.class, center, radius));
for (DynamicElement element : elementsInRange) {
for (DynamicElement element : getPrefilteredDynamicElements()) {
final Agent agent;
if (element instanceof Agent) {
......@@ -62,39 +54,57 @@ public class TargetController {
}
if (isNextTargetForAgent(agent)
&& hasAgentReachedThisTarget(agent, reachedDistance)) {
&& hasAgentReachedThisTarget(agent)) {
notifyListenersTargetReached(agent);
if (target.getWaitingTime() <= 0) {
checkRemove(agent);
} else {
final int agentId = agent.getId();
// individual waiting behaviour, as opposed to waiting at a traffic light
if (target.getAttributes().isIndividualWaiting()) {
final Map<Integer, Double> enteringTimes = target.getEnteringTimes();
if (enteringTimes.containsKey(agentId)) {
if (simTimeInSec - enteringTimes.get(agentId) > target
.getWaitingTime()) {
enteringTimes.remove(agentId);
checkRemove(agent);
}
} else {
final int parallelWaiters = target.getParallelWaiters();
if (parallelWaiters <= 0 || (parallelWaiters > 0 &&
enteringTimes.size() < parallelWaiters)) {
enteringTimes.put(agentId, simTimeInSec);
}
}
} else {
// traffic light switching based on waiting time. Light starts green.
phase = getCurrentTrafficLightPhase(simTimeInSec);
if (phase == TrafficLightPhase.GREEN) {
checkRemove(agent);
}
}
waitingBehavior(simTimeInSec, agent);
}
}
}
}
private Collection<DynamicElement> getPrefilteredDynamicElements() {
final double reachedDistance = target.getAttributes().getDeletionDistance();
final Rectangle2D bounds = target.getShape().getBounds2D();
final VPoint center = new VPoint(bounds.getCenterX(), bounds.getCenterY());
final double radius = Math.max(bounds.getHeight(), bounds.getWidth()) + reachedDistance;
final Collection<DynamicElement> elementsInRange = new LinkedList<>();
elementsInRange.addAll(getObjectsInCircle(Pedestrian.class, center, radius));
elementsInRange.addAll(getObjectsInCircle(Car.class, center, radius));
return elementsInRange;
}
private void waitingBehavior(double simTimeInSec, final Agent agent) {
final int agentId = agent.getId();
// individual waiting behaviour, as opposed to waiting at a traffic light
if (target.getAttributes().isIndividualWaiting()) {
final Map<Integer, Double> enteringTimes = target.getEnteringTimes();
if (enteringTimes.containsKey(agentId)) {
if (simTimeInSec - enteringTimes.get(agentId) > target
.getWaitingTime()) {
enteringTimes.remove(agentId);
checkRemove(agent);
}
} else {
final int parallelWaiters = target.getParallelWaiters();
if (parallelWaiters <= 0 || (parallelWaiters > 0 &&
enteringTimes.size() < parallelWaiters)) {
enteringTimes.put(agentId, simTimeInSec);
}
}
} else {
// traffic light switching based on waiting time. Light starts green.
phase = getCurrentTrafficLightPhase(simTimeInSec);
if (phase == TrafficLightPhase.GREEN) {
checkRemove(agent);
}
}
}
......@@ -103,9 +113,13 @@ public class TargetController {
return topography.getSpatialMap(clazz).getObjects(center, radius);
}
private boolean hasAgentReachedThisTarget(Agent agent, double reachedDistance) {
return target.getShape().contains(agent.getPosition())
|| target.getShape().distance(agent.getPosition()) < reachedDistance;
private boolean hasAgentReachedThisTarget(Agent agent) {
final double reachedDistance = target.getAttributes().getDeletionDistance();
final VPoint agentPosition = agent.getPosition();
final VShape targetShape = target.getShape();
return targetShape.contains(agentPosition)
|| targetShape.distance(agentPosition) < reachedDistance;
}
private TrafficLightPhase getCurrentTrafficLightPhase(double simTimeInSec) {
......@@ -144,14 +158,16 @@ public class TargetController {
if (target.isAbsorbing()) {
topography.removeElement(agent);
} else {
final int nextTargetListIndex = agent.getNextTargetListIndex();
// Deprecated target list usage
if (agent.getNextTargetListIndex() == -1 && !agent.getTargets().isEmpty()) {
if (nextTargetListIndex == -1 && !agent.getTargets().isEmpty()) {
agent.getTargets().removeFirst();
}
// The right way (later this first check should not be necessary anymore):
if (agent.getNextTargetListIndex() != -1) {
if (agent.getNextTargetListIndex() < agent.getTargets().size()) {
if (nextTargetListIndex != -1) {
if (nextTargetListIndex < agent.getTargets().size()) {
agent.incrementNextTargetListIndex();
}
}
......
......@@ -7,7 +7,6 @@ import java.util.List;
import java.util.Map;
import org.vadere.simulator.models.potential.fields.PotentialFieldTarget;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -33,11 +32,11 @@ public class CentroidGroup implements Group {
this.id = id;
this.size = size;
this.potentialFieldTarget = potentialFieldTarget;
members = new ArrayList<Pedestrian>();
members = new ArrayList<>();
this.lastVision = new HashMap<Pedestrian, Map<Pedestrian, VPoint>>();
this.lostMembers = new LinkedList<Pedestrian>();
this.noVisionOfLeaderCount = new HashMap<Pedestrian, Integer>();
this.lastVision = new HashMap<>();
this.lostMembers = new LinkedList<>();
this.noVisionOfLeaderCount = new HashMap<>();
}
@Override
......@@ -199,10 +198,8 @@ public class CentroidGroup implements Group {
double result;
VPoint pedLocation = ped.getPosition();
double pedDistance = potentialFieldTarget.getTargetPotential(
ped.getTargets(), pedLocation, ped);
double centroidDistance = potentialFieldTarget.getTargetPotential(
ped.getTargets(), getCentroidOthers(ped), ped);
double pedDistance = potentialFieldTarget.getTargetPotential(pedLocation, ped);
double centroidDistance = potentialFieldTarget.getTargetPotential(getCentroidOthers(ped), ped);
result = centroidDistance - pedDistance;
......@@ -216,12 +213,10 @@ public class CentroidGroup implements Group {
public Pedestrian getLeader(Pedestrian ped) {
Pedestrian result = members.get(0);
double smallestDistance = potentialFieldTarget.getTargetPotential(
ped.getTargets(), result.getPosition(), ped);
double smallestDistance = potentialFieldTarget.getTargetPotential(result.getPosition(), ped);
for (Pedestrian p : members) {
double pedDistance = potentialFieldTarget.getTargetPotential(
ped.getTargets(), p.getPosition(), p);
double pedDistance = potentialFieldTarget.getTargetPotential(p.getPosition(), p);
if (pedDistance < smallestDistance) {
result = p;
smallestDistance = pedDistance;
......
......@@ -17,6 +17,7 @@ import org.vadere.simulator.models.osm.updateScheme.UpdateSchemeOSM.CallMethod;
import org.vadere.simulator.models.potential.fields.PotentialFieldAgent;
import org.vadere.simulator.models.potential.fields.PotentialFieldObstacle;
import org.vadere.simulator.models.potential.fields.PotentialFieldTarget;
import org.vadere.simulator.models.potential.fields.PotentialFieldTargetRingExperiment;
import org.vadere.state.attributes.models.AttributesOSM;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.scenario.Agent;
......@@ -135,9 +136,8 @@ public class PedestrianOSM extends Pedestrian {
public void updateNextPosition() {
if (org.vadere.simulator.models.potential.fields.PotentialFieldTargetRingExperiment.class
.equals(this.potentialFieldTarget.getClass())) {
VCircle reachableArea = new VCircle(this.getPosition(), getStepSize());
if (PotentialFieldTargetRingExperiment.class.equals(potentialFieldTarget.getClass())) {
VCircle reachableArea = new VCircle(getPosition(), getStepSize());
this.relevantPedestrians = potentialFieldPedestrian
.getRelevantAgents(reachableArea, this, topography);
......@@ -146,11 +146,11 @@ public class PedestrianOSM extends Pedestrian {
// nextPosition = this.getPosition();
// }
} else if (!hasNextTarget()) {
this.nextPosition = this.getPosition();
} else if (topography.getTarget(super.getNextTargetId()).getShape().contains(super.getPosition())) {
this.nextPosition = this.getPosition();
this.nextPosition = getPosition();
} else if (topography.getTarget(getNextTargetId()).getShape().contains(getPosition())) {
this.nextPosition = getPosition();
} else {
VCircle reachableArea = new VCircle(this.getPosition(), getStepSize());
VCircle reachableArea = new VCircle(getPosition(), getStepSize());
this.relevantPedestrians = potentialFieldPedestrian
.getRelevantAgents(reachableArea, this, topography);
......@@ -159,7 +159,7 @@ public class PedestrianOSM extends Pedestrian {
// get stairs pedestrian is on - remains null if on area
Stairs stairs = null;
for (Stairs singleStairs : topography.getStairs()) {
if (singleStairs.getShape().contains(this.getPosition())) {
if (singleStairs.getShape().contains(getPosition())) {
stairs = singleStairs;
break;
}
......@@ -169,7 +169,7 @@ public class PedestrianOSM extends Pedestrian {
nextPosition = stepCircleOptimizer.getNextPosition(this, reachableArea);
} else {
stairStepOptimizer = new StairStepOptimizer(stairs);
reachableArea = new VCircle(this.getPosition(), stairs.getTreadDepth() * 1.99);
reachableArea = new VCircle(getPosition(), stairs.getTreadDepth() * 1.99);
nextPosition = stairStepOptimizer.getNextPosition(this, reachableArea);
// Logger.getLogger(this.getClass()).info("Pedestrian " + this.getId() + " is on
// stairs @position: " + nextPosition);
......@@ -221,7 +221,7 @@ public class PedestrianOSM extends Pedestrian {
public double getPotential(VPoint newPos) {
double targetPotential = potentialFieldTarget.getTargetPotential(getTargets(), newPos, this);
double targetPotential = potentialFieldTarget.getTargetPotential(newPos, this);
double pedestrianPotential = potentialFieldPedestrian
.getAgentPotential(newPos, this, relevantPedestrians);
......@@ -239,7 +239,7 @@ public class PedestrianOSM extends Pedestrian {
// Getters...
public double getTargetPotential(VPoint pos) {
return potentialFieldTarget.getTargetPotential(getTargets(), pos, this);
return potentialFieldTarget.getTargetPotential(pos, this);
}
public PotentialFieldTarget getPotentialFieldTarget() {
......@@ -247,8 +247,7 @@ public class PedestrianOSM extends Pedestrian {
}
public Vector2D getTargetGradient(VPoint pos) {
return potentialFieldTarget.getTargetPotentialGradient(getTargets(),
pos, this);
return potentialFieldTarget.getTargetPotentialGradient(pos, this);
}
public Vector2D getObstacleGradient(VPoint pos) {
......
......@@ -50,30 +50,22 @@ public abstract class AbstractPotentialFieldTarget implements IPotentialTargetGr
*
*/
@Override
public double getTargetPotential(final List<Integer> targetIds, final VPoint pos, final Agent ped) {
public double getTargetPotential(final VPoint pos, final Agent ped) {
CellGrid potentialField;
Topography floor = topography;
double targetPotential = Double.MAX_VALUE;
int targetId = -1;
assert targetIds.size() > 0;
if (targetIds.size() > 0) {
targetId = targetIds.get(0);
} else {
return 0;
}
int targetId = ped.getNextTargetId();
// Pedestrian has reached the target
if (floor.getTarget(targetId) != null) {
if (floor.getTarget(targetId).getShape().contains(pos)) {
return 0; // the arrival time is zero
}
// TODO Is this necessary? The target controller changes the
// pedestrian's target as soon the pedestrian arrives it.
if (topography.getTarget(targetId).getShape().contains(pos)) {
return 0; // the arrival time is zero
}
// Pedestrain inside an obstacle
for (ScenarioElement b : floor.getObstacles()) {
for (ScenarioElement b : topography.getObstacles()) {
if (b.getShape().contains(pos)) {
return Double.MAX_VALUE;
}
......@@ -107,7 +99,7 @@ public abstract class AbstractPotentialFieldTarget implements IPotentialTargetGr
incY = 0;
}
List<Point> points = new LinkedList<Point>();
List<Point> points = new LinkedList<>();
points.add(gridPoint);
points.add(new Point(gridPoint.x + incX, gridPoint.y));
points.add(new Point(gridPoint.x + incX, gridPoint.y + incY));
......@@ -222,7 +214,7 @@ public abstract class AbstractPotentialFieldTarget implements IPotentialTargetGr
*/
@Override
public HashMap<Integer, CellGrid> getCellGrids() {
HashMap<Integer, CellGrid> map = new HashMap<Integer, CellGrid>();
HashMap<Integer, CellGrid> map = new HashMap<>();
for (Map.Entry<Integer, PotentialFieldAndInitializer> entry2 : targetPotentialFields
......
......@@ -8,7 +8,6 @@ import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.models.AttributesFloorField;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Target;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.Vector2D;
......@@ -59,7 +58,7 @@ public class PotentialFieldMultiTargetGrid<T extends Agent> extends AbstractPote
}
@Override
public Vector2D getTargetPotentialGradient(List<Integer> targetIds, VPoint pos, Agent ped) {
public Vector2D getTargetPotentialGradient(VPoint pos, Agent ped) {
throw new UnsupportedOperationException("method not jet implemented.");
}
......
......@@ -50,7 +50,7 @@ public class PotentialFieldSingleTargetGrid extends AbstractPotentialFieldTarget
}
@Override
public Vector2D getTargetPotentialGradient(List<Integer> targetIds, VPoint pos, Agent ped) {
public Vector2D getTargetPotentialGradient(VPoint pos, Agent ped) {
throw new UnsupportedOperationException("method not jet implemented.");
}
......
package org.vadere.simulator.models.potential.fields;
import java.util.List;
import java.util.Random;
import org.vadere.simulator.control.ActiveCallback;
import org.vadere.simulator.models.Model;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.scenario.AttributesAgent;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.Vector2D;
import org.vadere.util.geometry.shapes.VPoint;
public interface PotentialFieldTarget extends ActiveCallback, Model {
boolean needsUpdate();
double getTargetPotential(List<Integer> targetIds,
final VPoint pos, final Agent ped);
double getTargetPotential(final VPoint pos, final Agent ped);
Vector2D getTargetPotentialGradient(final List<Integer> targetIds,
final VPoint pos, final Agent ped);
Vector2D getTargetPotentialGradient(final VPoint pos, final Agent ped);
}
......@@ -53,8 +53,7 @@ public class PotentialFieldTargetGrid<T extends Agent> extends AbstractPotential
@Override
public Vector2D getTargetPotentialGradient(List<Integer> targetIds,
VPoint pos, Agent ped) {
public Vector2D getTargetPotentialGradient(VPoint pos, Agent ped) {
throw new UnsupportedOperationException("gradient not yet implemented");
}
......
......@@ -44,8 +44,7 @@ public class PotentialFieldTargetRingExperiment implements IPotentialTargetGrid
* Afterwards, rate "pos" and check if it lies in the same direction as tangent vector.
*/
@Override
public double getTargetPotential(List<Integer> targetIds, VPoint pos,
Agent ped) {
public double getTargetPotential(VPoint pos, Agent ped) {
Vector2D pedestrian = new Vector2D(ped.getPosition());
Vector2D center = new Vector2D(attributes.getCenter());
......@@ -69,8 +68,7 @@ public class PotentialFieldTargetRingExperiment implements IPotentialTargetGrid
}
@Override
public Vector2D getTargetPotentialGradient(List<Integer> targetIds,
VPoint pos, Agent ped) {
public Vector2D getTargetPotentialGradient(VPoint pos, Agent ped) {
Vector2D pedestrian = new Vector2D(ped.getPosition());
Vector2D center = new Vector2D(attributes.getCenter());
......
......@@ -126,7 +126,7 @@ public class PotentialFieldTargetQueuingGrid implements IPotentialTargetGrid, Dy
}
@Override
public double getTargetPotential(final List<Integer> targetIds, final VPoint pos, final Agent pedArgument) {
public double getTargetPotential(final VPoint pos, final Agent pedArgument) {
if (Pedestrian.class.isAssignableFrom(pedArgument.getClass()))
throw new IllegalArgumentException("Target grid can only handle type Pedestrian");
Pedestrian ped = (Pedestrian) pedArgument;
......@@ -134,14 +134,14 @@ public class PotentialFieldTargetQueuingGrid implements IPotentialTargetGrid, Dy
if (pedestrianAttitudeMap.containsKey(ped) && queues.stream().anyMatch(queue -> queue.isQueued(ped))) {
switch (pedestrianAttitudeMap.get(ped)) {
case COMPETITIVE:
return competitiveField.getTargetPotential(targetIds, pos, ped);
return competitiveField.getTargetPotential(pos, ped);
case GENTLE:
return gentleField.getTargetPotential(targetIds, pos, ped);
return gentleField.getTargetPotential(pos, ped);
default:
throw new IllegalArgumentException(ped + " is not contained in the attitude map.");
}
} else if (queues.stream().noneMatch(queue -> queue.isQueued(ped))) {
return competitiveField.getTargetPotential(targetIds, pos, ped);
return competitiveField.getTargetPotential(pos, ped);
} else {
logger.warn("ped is neither queued nor not-queued.");
return 0;
......@@ -149,7 +149,7 @@ public class PotentialFieldTargetQueuingGrid implements IPotentialTargetGrid, Dy
}
@Override
public Vector2D getTargetPotentialGradient(final List<Integer> targetIds, final VPoint pos, final Agent ped) {
public Vector2D getTargetPotentialGradient(final VPoint pos, final Agent ped) {
throw new UnsupportedOperationException("method not implemented jet.");
}
......
......@@ -37,7 +37,7 @@ public abstract class Agent implements DynamicElement {
position = new VPoint(0, 0);
velocity = new Vector2D(0, 0);
targetIds = new LinkedList<>();
nextTargetListIndex = -1;
nextTargetListIndex = 0;
attributes = attributesAgent;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment