Commit ecf693ca authored by Benedikt Kleinmeier's avatar Benedikt Kleinmeier
Browse files

Refactored "ThreatCognitionModel"

parent cfd3e5e1
Pipeline #204001 passed with stages
in 121 minutes and 46 seconds
......@@ -4,6 +4,7 @@ import org.vadere.state.psychology.cognition.GroupMembership;
import org.vadere.state.psychology.cognition.SelfCategory;
import org.vadere.state.psychology.perception.types.Bang;
import org.vadere.state.psychology.perception.types.ElapsedTime;
import org.vadere.state.psychology.perception.types.Stimulus;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -20,7 +21,7 @@ import java.util.stream.Collectors;
* <li>Is pedestrian inside threat area.</li>
* <li>Is pedestrian outside threat area.</li>
* <li>If pedestrian outside threat area, test if other pedestrians are nearby
* who have perceived the threat. If so, imitate their behavior if they are ingroup members.</li>
* who have perceived the threat. If so, imitate their behavior if they are in-group members.</li>
* </ol>
*/
public class ThreatCognitionModel implements ICognitionModel {
......@@ -38,63 +39,70 @@ public class ThreatCognitionModel implements ICognitionModel {
public void update(Collection<Pedestrian> pedestrians) {
for (Pedestrian pedestrian : pedestrians) {
if (pedestrian.getMostImportantStimulus() instanceof Bang) {
pedestrian.setPerceivedThreat(pedestrian.getMostImportantStimulus());
pedestrian.setSelfCategory(SelfCategory.INSIDE_THREAT_AREA);
handleThreat(pedestrian, pedestrian.getMostImportantStimulus());
} else if (pedestrian.getMostImportantStimulus() instanceof ElapsedTime) {
if (pedestrian.getPerceivedThreat() != null) {
if (pedIsInsideThreatArea(pedestrian, (Bang) pedestrian.getPerceivedThreat())) {
pedestrian.setSelfCategory(SelfCategory.INSIDE_THREAT_AREA);
} else {
pedestrian.setSelfCategory(SelfCategory.OUTSIDE_THREAT_AREA);
}
} else { // These agents did not perceive a threat but are aware of other threatened agents.
// TODO: Pedestrians must be spawned with a random "GroupMembership".
if (pedestrian.getGroupMembership() == GroupMembership.OUT_GROUP) {
pedestrian.setSelfCategory(SelfCategory.TARGET_ORIENTED);
} else if (pedestrian.getGroupMembership() == GroupMembership.IN_GROUP) {
// If a threatened pedestrian is identified, use the same reaction as if
// the current "pedestrian" would have perceived the same threat.
// I.e., store the perceived threat and use "INSIDE_THREAT_AREA" to
// accelerate and search for a safe zone.
List<Pedestrian> threatenedPedestrians = getClosestPedestriansWithSelfCategory(pedestrian, SelfCategory.OUTSIDE_THREAT_AREA);
if (threatenedPedestrians.isEmpty() == false) {
Pedestrian threatedPedestrian = threatenedPedestrians.get(0);
assert threatedPedestrian.getPerceivedThreat() != null;
pedestrian.setPerceivedThreat(threatedPedestrian.getPerceivedThreat());
pedestrian.setSelfCategory(SelfCategory.INSIDE_THREAT_AREA);
} else {
pedestrian.setSelfCategory(SelfCategory.TARGET_ORIENTED);
}
} else {
throw new IllegalArgumentException("Can only process \"OUT_GROUP\" and \"IN_GROUP\" group membership!");
}
}
handleElapsedTime(pedestrian);
} else {
throw new IllegalArgumentException("Can only process \"Bang\" and \"ElapsedTime\" stimuli!");
}
}
}
private boolean pedIsInsideThreatArea(Pedestrian pedestrian, Bang bang) {
VPoint bangOrigin = topography.getTarget(bang.getOriginAsTargetId()).getShape().getCentroid();
double distanceToBang = bangOrigin.distance(pedestrian.getPosition());
private void handleThreat(Pedestrian pedestrian, Stimulus stimulus) {
// Current stimulus is a threat => store it and make clear that pedestrian is inside threat area.
pedestrian.setPerceivedThreat(stimulus);
pedestrian.setSelfCategory(SelfCategory.INSIDE_THREAT_AREA);
}
private void handleElapsedTime(Pedestrian pedestrian) {
if (pedestrian.getPerceivedThreat() != null) {
testIfInsideOrOutsideThreatArea(pedestrian);
} else { // These agents did not perceive a threat but are aware of other threatened agents.
// TODO: Pedestrians must be spawned with a random "GroupMembership".
if (pedestrian.getGroupMembership() == GroupMembership.OUT_GROUP) {
pedestrian.setSelfCategory(SelfCategory.TARGET_ORIENTED);
} else if (pedestrian.getGroupMembership() == GroupMembership.IN_GROUP) {
imitateThreatenedPedestrianIfPresent(pedestrian);
} else {
throw new IllegalArgumentException("Can only process \"OUT_GROUP\" and \"IN_GROUP\" group membership!");
}
}
}
private void testIfInsideOrOutsideThreatArea(Pedestrian pedestrian) {
Bang threat = (Bang) pedestrian.getPerceivedThreat();
VPoint threatOrigin = topography.getTarget(threat.getOriginAsTargetId()).getShape().getCentroid();
double distanceToThreat = threatOrigin.distance(pedestrian.getPosition());
boolean isInsideThreatArea = (distanceToBang <= bang.getRadius());
boolean pedestrianIsInsideThreatArea = (distanceToThreat <= threat.getRadius());
return isInsideThreatArea;
if (pedestrianIsInsideThreatArea) {
pedestrian.setSelfCategory(SelfCategory.INSIDE_THREAT_AREA);
} else {
pedestrian.setSelfCategory(SelfCategory.OUTSIDE_THREAT_AREA);
}
}
private void imitateClosestInGroupMember(Pedestrian pedestrian) {
/* If a threatened pedestrian is nearby, use the same reaction as if
* the current "pedestrian" would have perceived the same threat.
* I.e., store the perceived threat and use "INSIDE_THREAT_AREA" to
* accelerate and search for a safe zone.
*/
private void imitateThreatenedPedestrianIfPresent(Pedestrian pedestrian) {
List<Pedestrian> threatenedPedestrians = getClosestPedestriansWithSelfCategory(pedestrian, SelfCategory.OUTSIDE_THREAT_AREA);
if (threatenedPedestrians.isEmpty() == false) {
Pedestrian threatenedPedestrian = threatenedPedestrians.get(0);
assert threatenedPedestrian.getPerceivedThreat() != null;
handleThreat(pedestrian, threatenedPedestrian.getPerceivedThreat());
} else {
pedestrian.setSelfCategory(SelfCategory.TARGET_ORIENTED);
}
}
private List<Pedestrian> getClosestPedestriansWithSelfCategory(Pedestrian pedestrian, SelfCategory expectedSelfCategory) {
......
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