Commit 4ae99493 authored by Julian Zobel's avatar Julian Zobel 🦄
Browse files

Social Mobility Model: Add mobility to random points with 0.2 probability

parent 12c691d6
......@@ -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);
......
......@@ -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<PositionVector, Boolean> 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
......
......@@ -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<SimLocationActuator, roamingTransitionState> roamingStates = new LinkedHashMap<>();
protected LinkedHashMap<SimLocationActuator, roamingTransitionState> 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
......@@ -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);
}
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