From 4ae99493bd430273190c4c9aaffd126b22908403 Mon Sep 17 00:00:00 2001 From: Julian Zobel Date: Wed, 26 Jan 2022 13:17:45 +0100 Subject: [PATCH] Social Mobility Model: Add mobility to random points with 0.2 probability --- .../groupforming/AbstractGroupForming.java | 14 ++- .../groupforming/DefaultGroupForming.java | 7 +- .../AttractionPointRoamingStrategy.java | 94 ++++++++++++++++--- .../IAttractionAssigmentStrategy.java | 24 ++++- 4 files changed, 115 insertions(+), 24 deletions(-) diff --git a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/AbstractGroupForming.java b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/AbstractGroupForming.java index 825c7df2..4326a805 100644 --- a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/AbstractGroupForming.java +++ b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/AbstractGroupForming.java @@ -205,12 +205,16 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior { // force a new attraction point assignment on the leader IAttractionPoint currentDestination = movementModel.getAttractionAssignmentStrategy().getAssignment(group.getLeader()); - movementModel.getAttractionAssignmentStrategy().addComponent(group.getLeader()); + movementModel.getAttractionAssignmentStrategy().newAssignment(group.getLeader()); IAttractionPoint targetDestination = movementModel.getAttractionAssignmentStrategy().getAssignment(group.getLeader()); - - // Add Offset to group destination - PositionVector destination = movementModel.addOffset(new PositionVector(targetDestination), - targetDestination.getRadius() / 3); + + PositionVector destination = new PositionVector(targetDestination); + + // Add offset to group destination, if the attraction point has a radius + if(targetDestination.hasRadius()) { + destination = movementModel.addOffset(destination, targetDestination.getRadius() / 3); + } + group.setDestination(destination); setGroupMeetingPoint(group); diff --git a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/DefaultGroupForming.java b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/DefaultGroupForming.java index a3010547..44be10ef 100644 --- a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/DefaultGroupForming.java +++ b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/groups/groupforming/DefaultGroupForming.java @@ -26,6 +26,7 @@ import java.util.LinkedList; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.api.topology.movement.local.LocalMovementStrategy; import de.tud.kom.p2psim.impl.topology.movement.modularosm.ISocialGroupMovementAnalyzer; +import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.BasicAttractionPoint; import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.hostcount.HostAtAttractionPointCounter; import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup; import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.IAttractionAssigmentStrategy; @@ -177,7 +178,11 @@ public class DefaultGroupForming extends AbstractGroupForming { Either either = movementStrategy.nextPosition(leader, target); if (either.hasLeft()) { // Do nothing - } else { + } + else if(leader.getCurrentTargetAttractionPoint() instanceof BasicAttractionPoint) { + // do nothing, only intermediate AP + } + else { transition.reachedAttractionPoint(leader, leader.getCurrentTargetAttractionPoint()); // Inform analyzer of group removal diff --git a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/AttractionPointRoamingStrategy.java b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/AttractionPointRoamingStrategy.java index d043a29e..b31134f8 100644 --- a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/AttractionPointRoamingStrategy.java +++ b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/AttractionPointRoamingStrategy.java @@ -21,27 +21,37 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition; import java.util.LinkedHashMap; -import java.util.Map; +import java.util.Random; + +import de.tud.kom.p2psim.api.topology.Topology; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.impl.topology.movement.distributions.ISpeedDistributionProvider; import de.tud.kom.p2psim.impl.topology.movement.modularosm.ISocialGroupMovementAnalyzer; -import de.tud.kom.p2psim.impl.topology.movement.modularosm.ModularMovementModel; +import de.tud.kom.p2psim.impl.topology.movement.modularosm.SocialGroupMovementModel; +import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.AttractionPoint; +import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.BasicAttractionPoint; +import de.tud.kom.p2psim.impl.topology.util.PositionVector; +import de.tudarmstadt.maki.simonstrator.api.Binder; import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.Monitor; -import de.tudarmstadt.maki.simonstrator.api.Time; +import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; /** - * With this transition strategy, nodes are roaming around {@link IAttractionPoint}s, without transitions between them. As the {@link ModularMovementModel} - * uses a Gauss function to add jitter and offsets to the movement, some nodes may also roam outside of the circle's radius (this is intended to make it more realistic) + * With this transition strategy, nodes are roaming around {@link IAttractionPoint}s without a set transition time. + * A specific call from outside is required to trigger a transition to another {@link IAttractionPoint}, such as + * used in the {@link SocialGroupMovementModel}. Nodes may also go to a random location instead of a pre-defined + * {@link IAttractionPoint} with a certain probability. * * @author Julian Zobel * @version 10.02.2020 */ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssignmentStrategy implements EventHandler { + private Random rand = Randoms.getRandom(AttractionPointRoamingStrategy.class); + public static enum roamingTransitionState { PAUSE, ROAMING @@ -49,10 +59,12 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig protected ISpeedDistributionProvider roamSpeedProvider; - protected Map roamingStates = new LinkedHashMap<>(); + protected LinkedHashMap roamingStates = new LinkedHashMap<>(); protected long roamingPauseTime; + protected double randomTargetProbability = 0.2; + @XMLConfigurableConstructor({ "defaultPauseTimeMin", "defaultPauseTimeMax", "roamingPauseTime" }) public AttractionPointRoamingStrategy(long defaultPauseTimeMin, long defaultPauseTimeMax, long roamingPauseTime) { super(defaultPauseTimeMin, defaultPauseTimeMax); @@ -62,24 +74,36 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig @Override public void addComponent(SimLocationActuator comp) { this.roamingStates.put(comp, null); - IAttractionPoint nextAP = getNewAttractionPointAssignment(comp); // trigger recalculation of speed - comp.setMovementSpeed(-1); - + comp.setMovementSpeed(-1); + + IAttractionPoint nextAP = getNewAttractionPointAssignment(comp); updateTargetAttractionPoint(comp, nextAP); } + @Override + public void newAssignment(SimLocationActuator comp) { + if(rand.nextDouble() > randomTargetProbability) { + IAttractionPoint nextAP = getNewAttractionPointAssignment(comp); + updateTargetAttractionPoint(comp, nextAP); + } + else { + IAttractionPoint nextAP = createRandomAttraction(comp); + updateTargetAttractionPoint(comp, nextAP); + } + } + @Override public void updateTargetAttractionPoint(SimLocationActuator comp, - IAttractionPoint attractionPoint) { + IAttractionPoint attractionPoint) { this.roamingStates.put(comp, null); super.updateTargetAttractionPoint(comp, attractionPoint); } @Override public void reachedAttractionPoint(SimLocationActuator comp, IAttractionPoint attractionPoint) { - + if(roamingStates.get(comp) == roamingTransitionState.PAUSE) { return; } @@ -111,10 +135,10 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig SimLocationActuator comp = (SimLocationActuator) content; IAttractionPoint currentAttractionPoint = this.assignments.get(comp); - + // if the attraction point was removed in the meantime, go directly to transit state if(currentAttractionPoint == null || !attractionProvider.getAttractionPoints().contains(currentAttractionPoint)) { - this.addComponent(comp); + this.newAssignment(comp); } else { this.roamAroundAttractionPoint(comp); @@ -124,4 +148,48 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig public void setRoamingSpeedDistribution(ISpeedDistributionProvider dist) { this.roamSpeedProvider = dist; } + + /////////////////// + private PositionVector createPosVec() { + double x = rand.nextDouble() * Binder.getComponentOrNull(Topology.class).getWorldDimensions().getX(); + double y = rand.nextDouble() * Binder.getComponentOrNull(Topology.class).getWorldDimensions().getY(); + return new PositionVector(x, y); + } + + private BasicAttractionPoint createRandomAttraction(SimLocationActuator comp) { + + + // make a break counter to prevent more than 10 iterations and an infinity loop in general. + int tries = 0; + + PositionVector r = null; + + while(tries < 100) { + r = createPosVec(); + + IAttractionPoint currentAttractionPoint = this.assignments.get(comp); + + if(currentAttractionPoint == null) { + break; + } + else if (currentAttractionPoint instanceof AttractionPoint) { + AttractionPoint ap = (AttractionPoint) currentAttractionPoint; + + // check that random location is outside of current attraction point + if(ap.distanceTo(r) > ap.getRadius()) { + break; + } + } + else if (currentAttractionPoint instanceof BasicAttractionPoint) { + break; + } + + tries++; + continue; + } + + if(tries >= 100) throw new AssertionError("Unable to find a valid target destination within <100 tries."); + + return new BasicAttractionPoint("RNDPOS", r); + } } \ No newline at end of file diff --git a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/IAttractionAssigmentStrategy.java b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/IAttractionAssigmentStrategy.java index 6d07a684..ef53a78e 100644 --- a/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/IAttractionAssigmentStrategy.java +++ b/src/de/tud/kom/p2psim/impl/topology/movement/modularosm/transition/IAttractionAssigmentStrategy.java @@ -22,6 +22,7 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionProvider; +import de.tud.kom.p2psim.impl.util.NotImplementedException; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint; /** @@ -59,6 +60,15 @@ public interface IAttractionAssigmentStrategy { * @param ms */ public void addComponent(SimLocationActuator host); + + /** + * Assign the host to a new {@link IAttractionPoint} + * + * @param host + */ + public default void newAssignment(SimLocationActuator host) { + throw new NotImplementedException(); + } /** * Notify the TransitionStrategy, that the component has reached an @@ -75,7 +85,15 @@ public interface IAttractionAssigmentStrategy { */ public void updateTargetAttractionPoint(SimLocationActuator comp, IAttractionPoint attractionPoint); - + + + public boolean hostInAttractionPointArea(SimLocationActuator host); + + public long getPauseTime(IAttractionPoint attractionPoint); + + /** + * + */ public interface AttractionAssignmentListener { /** @@ -89,8 +107,4 @@ public interface IAttractionAssigmentStrategy { IAttractionPoint newAssignment); } - - public boolean hostInAttractionPointArea(SimLocationActuator host); - - public long getPauseTime(IAttractionPoint attractionPoint); } -- GitLab