Commit 6aa5caf6 authored by Julian Zobel's avatar Julian Zobel
Browse files

More refactoring for social group movement

parent dc857437
...@@ -230,12 +230,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac ...@@ -230,12 +230,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
int tries = 0; int tries = 0;
do { do {
destination = new PositionVector(attractionCenter); destination = addGaussianOffsetToPosition(attractionCenter, apRadius / 3);
// Gaussian with std = 1 --> >99% of nodes
PositionVector offset = new PositionVector(
rand.nextGaussian() * apRadius / 3,
rand.nextGaussian() * apRadius / 3);
destination.add(offset);
// Check constraints // Check constraints
if (!checkBoundaries(destination)) { if (!checkBoundaries(destination)) {
destination = null; destination = null;
...@@ -257,6 +252,14 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac ...@@ -257,6 +252,14 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null, Event.scheduleWithDelay(timeBetweenMoveOperation, this, null,
EVENT_MOVE); EVENT_MOVE);
} }
public PositionVector addGaussianOffsetToPosition(PositionVector position, double std) {
PositionVector offsetPosition = new PositionVector(position);
// Gaussian with std = 1 --> >99% of nodes
PositionVector offset = new PositionVector(rand.nextGaussian() * std, rand.nextGaussian() * std);
offsetPosition.add(offset);
return offsetPosition;
}
/** /**
* *
......
...@@ -111,9 +111,8 @@ public class SocialGroupMovementModel extends ModularMovementModel { ...@@ -111,9 +111,8 @@ public class SocialGroupMovementModel extends ModularMovementModel {
// Check POIs if groups can be created. Delete groups, if destination reached. // Check POIs if groups can be created. Delete groups, if destination reached.
groupFormingBehavior.manageGroups(); groupFormingBehavior.manageGroups();
// Checks if groups encounter each other and applies a specified action to these groups. // Checks if groups encounter each other and applies a specified action to these groups.
Set<SocialMovementGroup[]> encounteringGroups = groupEncounterBehavior.getEncounteringGroups(); groupEncounterBehavior.handleEncounters();
groupEncounterBehavior.handleEncounters(encounteringGroups);
/* /*
* Moves all nodes according to definition in group movement method * Moves all nodes according to definition in group movement method
......
...@@ -89,6 +89,10 @@ public class MovementGroupContainer { ...@@ -89,6 +89,10 @@ public class MovementGroupContainer {
public void addGroup(SocialMovementGroup group) { public void addGroup(SocialMovementGroup group) {
groups.add(group); groups.add(group);
} }
public boolean hasGroup(SocialMovementGroup group) {
return groups.contains(group);
}
/** /**
* Removes a group from the set of groups and sets the leftGroupAtTime variable for all group members. * Removes a group from the set of groups and sets the leftGroupAtTime variable for all group members.
......
...@@ -32,13 +32,14 @@ import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovement ...@@ -32,13 +32,14 @@ import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovement
import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.common.datastructures.Pair;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/** /**
* This class contains methods used by all encounter strategies. * This class contains methods used by all encounter strategies.
* *
* @author Marcel Verst * @author Marcel Verst, Julian Zobel
* @version 1.0, 22.11.2018 * @version 1.1, 30.01.2020
*/ */
public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior { public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior {
...@@ -79,6 +80,7 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior ...@@ -79,6 +80,7 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
@Override @Override
public void initialize(SocialGroupMovementModel movementModel) { public void initialize(SocialGroupMovementModel movementModel) {
this.movementModel = movementModel;
groupCon = MovementGroupContainer.getInstance(); groupCon = MovementGroupContainer.getInstance();
for(SimLocationActuator host : movementModel.getAllLocationActuators()) { for(SimLocationActuator host : movementModel.getAllLocationActuators()) {
...@@ -86,61 +88,77 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior ...@@ -86,61 +88,77 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
} }
} }
public Set<SocialMovementGroup[]> getEncounteringGroups() { @Override
public Set<Pair<SocialMovementGroup>> getEncounteringGroups() {
if(!enableGroupEncounters) if(!enableGroupEncounters)
return null; return null;
Set<SocialMovementGroup[]> encounteringGroups = new LinkedHashSet<>(); Set<Pair<SocialMovementGroup>> encounteringGroups = new LinkedHashSet<>();
Set<SocialMovementGroup> alreadyProcessed = new LinkedHashSet<>(); Set<SocialMovementGroup> alreadyProcessed = new LinkedHashSet<>();
Set<SocialMovementGroup> allGroups = groupCon.getGroups(); Set<SocialMovementGroup> allGroups = groupCon.getGroups();
for(SocialMovementGroup group1 : allGroups) { for(SocialMovementGroup group1 : allGroups) {
for(SocialMovementGroup group2 : allGroups) { for(SocialMovementGroup group2 : allGroups) {
if(group1 != group2) { if(group1 == group2) {
if(!(alreadyProcessed.contains(group1) && alreadyProcessed.contains(group2))) { continue;
if(getDistanceBetweenGroups(group1, group2) <= groupEncounterMeetingDistance) {
SimLocationActuator g1Leader = group1.getLeader();
if(!groupCon.getHasMerged().get(g1Leader)) {
SocialMovementGroup[] groups = new SocialMovementGroup[2];
groups[0] = group1;
groups[1] = group2;
encounteringGroups.add(groups);
alreadyProcessed.add(group1);
alreadyProcessed.add(group2);
}
else {
if(waitedLongEnoughAfterMerging(g1Leader)) {
SocialMovementGroup[] groups = new SocialMovementGroup[2];
groups[0] = group1;
groups[1] = group2;
encounteringGroups.add(groups);
alreadyProcessed.add(group1);
alreadyProcessed.add(group2);
}
}
}
}
} }
// skip if at least one of the groups is in the area of an attraction point
if(movementModel.getAttractionAssignmentStrategy().hostInAttractionPointArea(group1.getLeader())
|| movementModel.getAttractionAssignmentStrategy().hostInAttractionPointArea(group2.getLeader())) {
continue;
}
if(!(alreadyProcessed.contains(group1) && alreadyProcessed.contains(group2))) {
if(getDistanceBetweenGroups(group1, group2) <= groupEncounterMeetingDistance) {
SimLocationActuator g1Leader = group1.getLeader();
if(!groupCon.getHasMerged().get(g1Leader) || waitedLongEnoughAfterMerging(g1Leader) ) {
Pair<SocialMovementGroup> encounter = new Pair<SocialMovementGroup>(group1, group2);
encounteringGroups.add(encounter);
alreadyProcessed.add(group1);
alreadyProcessed.add(group2);
}
}
}
} }
} }
return encounteringGroups; return encounteringGroups;
} }
/**
* {@inheritDoc} public void handleEncounters() {
*/
public void handleEncounters(Set<SocialMovementGroup[]> encounteringGroups) { if(!enableGroupEncounters)
return;
Set<Pair<SocialMovementGroup>> encounteringGroups = getEncounteringGroups();
if(encounteringGroups == null || encounteringGroups.isEmpty()) { if(encounteringGroups == null || encounteringGroups.isEmpty()) {
return; return;
} }
for(SocialMovementGroup[] groups : encounteringGroups) {
handleGroupEncounter(groups[0], groups[1]); for(Pair<SocialMovementGroup> encounter : encounteringGroups) {
if(groupCon.hasGroup(encounter.getFirst()) && groupCon.hasGroup(encounter.getSecond())) {
handleGroupEncounter(encounter.getFirst(), encounter.getSecond());
}
} }
} }
/**
* Defines what to do with both groups in case they encountered.
*
* @param SocialMovementGroup The first group.
* @param SocialMovementGroup The second group.
*
*/
protected abstract void handleGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2);
/** /**
* Returns the distance between two groups based on their leaders position. * Returns the distance between two groups based on their leaders position.
* *
...@@ -236,9 +254,8 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior ...@@ -236,9 +254,8 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
SocialMovementGroup large = getLargerGroup(group1, group2); SocialMovementGroup large = getLargerGroup(group1, group2);
SocialMovementGroup small = getSmallerGroup(group1, group2); SocialMovementGroup small = getSmallerGroup(group1, group2);
Set<SimLocationActuator> toRemove = new LinkedHashSet<>(); Set<SimLocationActuator> toRemove = new LinkedHashSet<>(small.getMembers());
toRemove.addAll(small.getMembers());
for(SimLocationActuator participant : toRemove) { for(SimLocationActuator participant : toRemove) {
small.removeHostFromGroup(participant); small.removeHostFromGroup(participant);
groupCon.addLeftGroupAtTimeEntry(participant, Time.getCurrentTime()); groupCon.addLeftGroupAtTimeEntry(participant, Time.getCurrentTime());
......
...@@ -22,9 +22,9 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounte ...@@ -22,9 +22,9 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounte
import java.util.Set; import java.util.Set;
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.SocialGroupMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup; import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup;
import de.tudarmstadt.maki.simonstrator.api.common.datastructures.Pair;
/** /**
* Handles group encounters. Check group encounters based on the leaders location of {@link SocialMovementGroup}s. * Handles group encounters. Check group encounters based on the leaders location of {@link SocialMovementGroup}s.
...@@ -37,35 +37,22 @@ public interface IGroupEncounterBehavior { ...@@ -37,35 +37,22 @@ public interface IGroupEncounterBehavior {
/** /**
* Initializes class variables. * Initializes class variables.
* *
* @author Marcel Verst
*/ */
void initialize(SocialGroupMovementModel movementModel); void initialize(SocialGroupMovementModel movementModel);
/** /**
* Checks if any of the current groups come in a close range which is equivalent to a group meeting. * Checks if any of the current groups come in a close range which is equivalent to a group meeting.
* Calls the handleGroupEncounters(Group, Group) method to define the group behavior. * Calls the handleGroupEncounters(Group, Group) method to define the group behavior.
* *
* @author Marcel Verst
* @return * @return
*/ */
Set<SocialMovementGroup[]> getEncounteringGroups(); Set<Pair<SocialMovementGroup>> getEncounteringGroups();
/** /**
* Applies an encountering action to each detected encountering groups. * Applies an encountering action to each detected encountering groups.
* *
* @param Set<Group[]> The set of encountering groups.
*
* @author Marcel Verst
*/ */
void handleEncounters(Set<SocialMovementGroup[]> encounteringGroups); public void handleEncounters();
/**
* Defines what to do with both groups in case they encountered.
*
* @param SocialMovementGroup The first group.
* @param SocialMovementGroup The second group.
*
* @author Marcel Verst
*/
void handleGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2);
} }
\ No newline at end of file
...@@ -66,12 +66,9 @@ public class Wait extends AbstractGroupEncounter{ ...@@ -66,12 +66,9 @@ public class Wait extends AbstractGroupEncounter{
*/ */
private void wait(SocialMovementGroup group1, SocialMovementGroup group2) { private void wait(SocialMovementGroup group1, SocialMovementGroup group2) {
// Do not apply waiting process if one of both groups is already waiting // Do not apply waiting process if one of both groups is already waiting
if(groupCon.waitingGroups.containsKey(group1) && !groupCon.waitingGroups.containsKey(group2)) { if(groupCon.waitingGroups.containsKey(group1) ^ groupCon.waitingGroups.containsKey(group2)) {
return; return;
} }
if(!groupCon.waitingGroups.containsKey(group1) && groupCon.waitingGroups.containsKey(group2)) {
return;
}
// If both groups are not waiting, declare them as waiting groups for a duration of timeToWait // If both groups are not waiting, declare them as waiting groups for a duration of timeToWait
if(!groupCon.waitingGroups.containsKey(group1) && !groupCon.waitingGroups.containsKey(group2)) { if(!groupCon.waitingGroups.containsKey(group1) && !groupCon.waitingGroups.containsKey(group2)) {
......
...@@ -193,12 +193,9 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior { ...@@ -193,12 +193,9 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
} while(nextDestination == leaderTarget); } while(nextDestination == leaderTarget);
// Add Offset to destination // Add Offset to destination
PositionVector destination = new PositionVector(nextDestination); PositionVector destination = movementModel.addGaussianOffsetToPosition(new PositionVector(nextDestination),
double apRadius = nextDestination.getRadius(); nextDestination.getRadius() / 3);
PositionVector offset = new PositionVector(rand.nextGaussian() * apRadius / 3, rand.nextGaussian() * apRadius / 3);
destination.plus(offset);
group.setDestination(destination); group.setDestination(destination);
setGroupMeetingPoint(group); setGroupMeetingPoint(group);
...@@ -350,23 +347,13 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior { ...@@ -350,23 +347,13 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
/** /**
* Checks if a host has waited long enough before he is allowed to join groups again. * Checks if a host has waited long enough before he is allowed to join groups again.
* Returns true, if the host has waited long enough, false else. * Returns true, if the host has waited long enough, false otherwise.
* *
* @param SimLocationActuator The host to be checked. * @param SimLocationActuator The host to be checked.
* @param int The current time.
* @return boolean * @return boolean
*
* @author Marcel Verst
*/ */
protected boolean groupRejoinTimerExpired(SimLocationActuator host) { protected boolean groupRejoinTimerExpired(SimLocationActuator host) {
long t = groupCon.getTimeSinceHostLeftLastGroup(host); return groupCon.getTimeSinceHostLeftLastGroup(host) >= groupRejoinWaitTime;
System.out.println(host.getHost().getId() + " | "+Time.getFormattedTime()
+" | Wait for:" +Time.getFormattedTime(t) + ", req is " + Time.getFormattedTime(groupRejoinWaitTime) );
boolean dec = t >= groupRejoinWaitTime;
return dec;
} }
/** /**
...@@ -374,8 +361,6 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior { ...@@ -374,8 +361,6 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
* *
* @param SimLocacationActuator The host to be checked. * @param SimLocacationActuator The host to be checked.
* @return Boolean * @return Boolean
*
* @author Marcel Verst
*/ */
protected boolean beenInGroup(SimLocationActuator host) { protected boolean beenInGroup(SimLocationActuator host) {
return groupCon.hostWasGroupMember(host); return groupCon.hostWasGroupMember(host);
...@@ -391,13 +376,12 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior { ...@@ -391,13 +376,12 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
* the group members first have to meet at the meeting point. * the group members first have to meet at the meeting point.
* *
* @param SocialMovementGroup The group to set the meeting point. * @param SocialMovementGroup The group to set the meeting point.
*
* @author Marcel Verst, Julian Zobel
*/ */
protected void setGroupMeetingPoint(SocialMovementGroup group) { protected void setGroupMeetingPoint(SocialMovementGroup group) {
PositionVector leaderPos = group.getLeader().getRealPosition(); PositionVector leaderPos = group.getLeader().getRealPosition();
BasicAttractionPoint meetingPoint = new BasicAttractionPoint("Group Movement Meeting Point of Leader #"+group.getLeader().getHost().getId(), leaderPos); BasicAttractionPoint meetingPoint =
new BasicAttractionPoint("Group Movement Meeting Point of Leader #"+group.getLeader().getHost().getId(), leaderPos);
group.setMeetingPoint(meetingPoint); group.setMeetingPoint(meetingPoint);
...@@ -405,7 +389,7 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior { ...@@ -405,7 +389,7 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
for(SimLocationActuator participant : group.getMembers()) { for(SimLocationActuator participant : group.getMembers()) {
movementModel.getAttractionAssignmentStrategy().updateTargetAttractionPoint(participant, meetingPoint); movementModel.getAttractionAssignmentStrategy().updateTargetAttractionPoint(participant, meetingPoint);
} }
} }
@Override @Override
public int getMinGroupSize() { public int getMinGroupSize() {
......
...@@ -20,12 +20,13 @@ ...@@ -20,12 +20,13 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupforming; package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupforming;
import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Set; import java.util.Set;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.movement.local.LocalMovementStrategy; import de.tud.kom.p2psim.api.topology.movement.local.LocalMovementStrategy;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup; import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.IAttractionAssigmentStrategy; import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.IAttractionAssigmentStrategy;
import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tud.kom.p2psim.impl.topology.util.PositionVector;
...@@ -36,7 +37,6 @@ import de.tudarmstadt.maki.simonstrator.api.EventHandler; ...@@ -36,7 +37,6 @@ import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID; import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/** /**
...@@ -103,43 +103,45 @@ public class DefaultGroupForming extends AbstractGroupForming { ...@@ -103,43 +103,45 @@ public class DefaultGroupForming extends AbstractGroupForming {
int numberOfHostsInAttractionPoint = hostCounter.getHostCountOfAttractionPoint(apCandidate); int numberOfHostsInAttractionPoint = hostCounter.getHostCountOfAttractionPoint(apCandidate);
int groupSize = this.rndGroupSize(numberOfHostsInAttractionPoint); int groupSize = this.rndGroupSize(numberOfHostsInAttractionPoint);
Set<SimLocationActuator> groupCandidates = new LinkedHashSet<>(); Set<SimLocationActuator> groupCandidates = new LinkedHashSet<>();
Set<SimLocationActuator> hostsOfPoi = hostCounter.getHostsOfAttractionPoint(apCandidate); // shuffle the hosts at the attraction point (more randomness ftw!)
LinkedList<SimLocationActuator> randomShuffledHostsAtAttractionPoint = new LinkedList<>(hostCounter.getHostsOfAttractionPoint(apCandidate));
Collections.shuffle(randomShuffledHostsAtAttractionPoint, rand);
for (SimLocationActuator m : hostsOfPoi) { for (SimLocationActuator m : randomShuffledHostsAtAttractionPoint) {
// skip already added hosts (should never happen)
if(groupCandidates.contains(m)) { if(groupCandidates.contains(m)) {
System.err.println("Cannot be???");
continue; continue;
} }
// skip single hosts
if(movementModel.getSingleHosts().contains(m)) { if(movementModel.getSingleHosts().contains(m)) {
System.out.println("ACM Single Host is not added");
continue; continue;
} }
// skip hosts that are already part of a group
if(groupCon.isGroupMember(m)) { if(groupCon.isGroupMember(m)) {
System.out.println("No members allowed");
continue; continue;
} }
// test if the host wants and also is allowed to join this group
if(wantsToJoin()) { if(wantsToJoin()) {
if(!beenInGroup(m) || groupRejoinTimerExpired(m)) { if(!beenInGroup(m) || groupRejoinTimerExpired(m)) {
groupCandidates.add(m); groupCandidates.add(m);
} }
} }
// do not continue if enough group members are gathered
if(groupCandidates.size() == groupSize) { if(groupCandidates.size() == groupSize) {
System.out.println("Group full, now go!");
break; break;
} }
} }
if(groupCandidates.isEmpty() || groupCandidates == null) { // if there are no candidates, wait a minute until asking again
System.out.println("--no cands"); if(groupCandidates.isEmpty() || groupCandidates == null) {
Event.scheduleWithDelay(Time.MINUTE, new EventHandler() { Event.scheduleWithDelay(Time.MINUTE, new EventHandler() {
@Override @Override
public void eventOccurred(Object content, int type) { public void eventOccurred(Object content, int type) {
...@@ -149,13 +151,12 @@ public class DefaultGroupForming extends AbstractGroupForming { ...@@ -149,13 +151,12 @@ public class DefaultGroupForming extends AbstractGroupForming {
break; break;
} }
System.out.println("Group creation: " + groupCandidates.size() + " => " + apCandidate);
for(SimLocationActuator candidate : groupCandidates) { for(SimLocationActuator candidate : groupCandidates) {
INodeID id = candidate.getHost().getId(); INodeID id = candidate.getHost().getId();
stayDuration.put(id, new Tuple<Long, Long>(0L, Time.getCurrentTime())); // FIXME why? stayDuration.put(id, new Tuple<Long, Long>(0L, Time.getCurrentTime())); // FIXME why?
} }
createGroup(groupCandidates); createGroup(groupCandidates);
} }
} }
...@@ -214,18 +215,8 @@ public class DefaultGroupForming extends AbstractGroupForming { ...@@ -214,18 +215,8 @@ public class DefaultGroupForming extends AbstractGroupForming {
for(SimLocationActuator component : movementModel.getAllLocationActuators()) { for(SimLocationActuator component : movementModel.getAllLocationActuators()) {
INodeID id = component.getHost().getId(); INodeID id = component.getHost().getId();
// Check if host is in an AP area
boolean isInAp = false;
for(AttractionPoint ap : IAttractionGenerator.attractionPoints) {
Location hostLocation = component.getLastLocation();
if(ap.distanceTo(hostLocation) <= ap.getRadius()) {
isInAp = true;
break;
}
}
// In AP, increase stayDuration // In AP, increase stayDuration
if(isInAp) { if(movementModel.getAttractionAssignmentStrategy().hostInAttractionPointArea(component)) {
Tuple<Long, Long> timeInfo = stayDuration.get(id); Tuple<Long, Long> timeInfo = stayDuration.get(id);
long delta = Time.getCurrentTime() - timeInfo.getB(); long delta = Time.getCurrentTime() - timeInfo.getB();
...@@ -242,4 +233,6 @@ public class DefaultGroupForming extends AbstractGroupForming { ...@@ -242,4 +233,6 @@ public class DefaultGroupForming extends AbstractGroupForming {
} }
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupforming; package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupforming;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.SocialGroupMovementModel; import de.tud.kom.p2psim.impl.topology.movement.modularosm.SocialGroupMovementModel;
/** /**
...@@ -59,7 +60,7 @@ public interface IGroupFormingBehavior { ...@@ -59,7 +60,7 @@ public interface IGroupFormingBehavior {
* @author Marcel Verst * @author Marcel Verst
*/ */
void runGroupDeletionProcess(); void runGroupDeletionProcess();
public int getMinGroupSize(); public int getMinGroupSize();
public int getMaxGroupSize(); public int getMaxGroupSize();
} }
\ No newline at end of file
...@@ -128,4 +128,16 @@ public abstract class AbstractAttractionBasedAssignmentStrategy implements IAttr ...@@ -128,4 +128,16 @@ public abstract class AbstractAttractionBasedAssignmentStrategy implements IAttr
AttractionPoint assignment = candidates.get(rnd.nextInt(candidates.size())); AttractionPoint assignment = candidates.get(rnd.nextInt(candidates.size()));
return assignment; return assignment;
} }
@Override
public boolean hostInAttractionPointArea(SimLocationActuator host) {
for(AttractionPoint ap : IAttractionGenerator.attractionPoints) {
if(ap.distanceTo(host.getRealPosition()) <= ap.getRadius()) {
return true;
}
}
return false;
}
} }
...@@ -84,5 +84,6 @@ public interface IAttractionAssigmentStrategy { ...@@ -84,5 +84,6 @@ public interface IAttractionAssigmentStrategy {
AttractionPoint newAssignment); AttractionPoint newAssignment);
} }
public boolean hostInAttractionPointArea(SimLocationActuator host);
} }
package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition; package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import java.util.*; import java.util.*;
...@@ -68,4 +69,15 @@ public class ManualAssignmentStrategy implements IAttractionAssigmentStrategy ...@@ -68,4 +69,15 @@ public class ManualAssignmentStrategy implements IAttractionAssigmentStrategy
assignments.put(comp, attractionPoint); assignments.put(comp, attractionPoint);
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint)); listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
} }
@Override
public boolean hostInAttractionPointArea(SimLocationActuator host) {
for(AttractionPoint ap : IAttractionGenerator.attractionPoints) {
if(ap.distanceTo(host.getRealPosition()) <= ap.getRadius()) {
return true;
}
}
return false;
}
} }
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