Commit dce6451f authored by Julian Zobel's avatar Julian Zobel
Browse files

Attraction Analyzer and Social Group Movement ANalyzer

parent 7b723ca7
......@@ -333,6 +333,6 @@ public abstract class AbstractTopologyComponent implements TopologyComponent {
@Override
public String toString() {
return "TopoComp: " + getHost().getId() + " at " + position.toString();
return "Topology Component #" + getHost().getId() + " at pos " + position.toString();
}
}
......@@ -23,9 +23,10 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm;
import java.util.Set;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Analyzer;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
public interface IAttractionBasedMovementMonitor {
public interface IAttractionBasedMovementAnalyzer extends Analyzer {
public void onAllNodeMovementCompleted(Set<SimLocationActuator> nodes);
......@@ -36,5 +37,6 @@ public interface IAttractionBasedMovementMonitor {
public void onUpdateAttractionAssignment(SimLocationActuator node, IAttractionPoint attractionpoint);
public void onNodeReachedAttractionPoint(SimLocationActuator node, IAttractionPoint attractionpoint);
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modularosm;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup;
public interface ISocialGroupMovementAnalyzer extends IAttractionBasedMovementAnalyzer {
public void onGroupForming(SocialMovementGroup group);
public void onGroupDisbanding(SocialMovementGroup group);
public void onGroupMerge(SocialMovementGroup group1, SocialMovementGroup group2);
public void onGroupWait(SocialMovementGroup group);
public void onGroupMovesToAttractionPoint(SocialMovementGroup group);
public void onMoveToMeetingPoint(SocialMovementGroup group, SimLocationActuator node);
public void onMemberWaitAtMeetingPoint(SocialMovementGroup group, SimLocationActuator node);
public void onGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2);
}
......@@ -46,6 +46,7 @@ import de.tud.kom.p2psim.impl.util.Either;
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.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
......@@ -173,6 +174,12 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
move();
initialized = true;
// Inform analyzer of resolved movement
if(Monitor.hasAnalyzer(IAttractionBasedMovementAnalyzer.class)) {
Monitor.getOrNull(IAttractionBasedMovementAnalyzer.class).onAllNodeMovementCompleted(moveableHosts);
}
}
}
......@@ -249,6 +256,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
assert currentTargets.containsKey(component);
doLocalMovement(component, currentTargets.get(component));
}
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null,
EVENT_MOVE);
}
......
......@@ -20,8 +20,6 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm;
import java.net.UnknownHostException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
......@@ -42,6 +40,7 @@ import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
......@@ -52,6 +51,9 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractio
*/
public class SocialGroupMovementModel extends ModularMovementModel {
private final double MEETING_POINT_DISTANCE = 5;
private final double LEADER_GROUP_DISTANCE = 10;
protected MovementGroupContainer groupContainer;
protected IGroupFormingBehavior groupFormingBehavior;
protected IGroupEncounterBehavior groupEncounterBehavior;
......@@ -69,6 +71,7 @@ public class SocialGroupMovementModel extends ModularMovementModel {
public void initialize() {
if (!initialized) {
groupContainer = MovementGroupContainer.getInstance();
groupFormingBehavior.initialize(this);
groupEncounterBehavior.initialize(this);
......@@ -116,6 +119,8 @@ public class SocialGroupMovementModel extends ModularMovementModel {
}
}
setTimeBetweenMoveOperations(timeBetweenMoveOperation);
// initial move
......@@ -123,6 +128,11 @@ public class SocialGroupMovementModel extends ModularMovementModel {
initialized = true;
// Inform analyzer of resolved movement
if(Monitor.hasAnalyzer(IAttractionBasedMovementAnalyzer.class)) {
Monitor.getOrNull(IAttractionBasedMovementAnalyzer.class).onAllNodeMovementCompleted(moveableHosts);
}
}
}
......@@ -167,7 +177,7 @@ public class SocialGroupMovementModel extends ModularMovementModel {
*/
for (SimLocationActuator host : moveableHosts) {
assert currentTargets.containsKey(host);
// Single Host Movement
if(singleHosts.contains(host) || !groupContainer.isGroupMember(host)) {
doLocalMovement(host, currentTargets.get(host));
......@@ -178,9 +188,12 @@ public class SocialGroupMovementModel extends ModularMovementModel {
else {
throw new UnsupportedOperationException("SimLocationActuator " + host + " is neither in a group nor a single node");
}
// TODO maybe remodel the group movement to do a whole group?
}
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null, EVENT_MOVE);
}
......@@ -195,34 +208,58 @@ public class SocialGroupMovementModel extends ModularMovementModel {
* @param PositionVector Destination of the host.
*/
protected void doGroupMovement(SimLocationActuator host, PositionVector destination) {
// This host is a member of a group, thus...
SocialMovementGroup group = groupContainer.getGroupOfHost(host);
// if the group is currently gathering at a meeting point...
if(movesToGroupMeetingPoint(host)) {
// if this host has already arrived at the group meeting point..
if(hostIsAtMeetingPoint(host)) {
if(groupAtMP(host)) {
SocialMovementGroup group = groupContainer.getGroupOfHost(host);
IAttractionPoint currAp = group.getLeader().getCurrentTargetAttractionPoint();
PositionVector currDest = group.getDestination();
group.setMeetingPoint(currDest);
for(SimLocationActuator participant : group.getMembers()) {
attractionAssigment.updateTargetAttractionPoint(participant, currAp);
}
// ... and if the whole group is also at the meeting point...
if(groupGatheredAtMeetingPoint(group)) {
// remove the meeting point and thus, start moving towards the actual destination
group.setMeetingPoint(null);
}
// ... but the group is not gathered at the meeting point, do nothing and wait for the rest.
else {
// inform analyzer of waiting group members
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onMemberWaitAtMeetingPoint(group, host);
}
}
}
// MP not reached. Move to MP.
else {
// if the host has not reached the group meeting point, move towards it.
else {
PositionVector mp = groupContainer.getGroupOfHost(host).getMeetingPoint();
doLocalMovement(host, mp);
// inform analyzer group member moves to meeting point
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onMoveToMeetingPoint(group, host);
}
}
}
// MP reached. Move to destination.
// ... but if the group is currently on their way to the destination
else {
// the leader does a local movement
if(groupContainer.isLeader(host)) {
if(!groupContainer.isWaiting(groupContainer.getGroupOfHost(host))) {
doLocalMovement(host, destination);
// inform analyzer of movement to attraction point
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupMovesToAttractionPoint(group);
}
}
else {
// inform analyzer of waiting group
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupWait(group);
}
}
}
else {
// while other nodes just follow the group leader
followLeader(host);
}
}
......@@ -242,12 +279,14 @@ public class SocialGroupMovementModel extends ModularMovementModel {
* @return Boolean
*/
private boolean movesToGroupMeetingPoint(SimLocationActuator host) {
PositionVector mp = groupContainer.getGroupOfHost(host).getMeetingPoint();
PositionVector dest = groupContainer.getGroupOfHost(host).getDestination();
if(mp != dest) {
PositionVector meetingpoint = groupContainer.getGroupOfHost(host).getMeetingPoint();
if(meetingpoint == null)
return false;
else if(meetingpoint != groupContainer.getGroupOfHost(host).getDestination())
return true;
}
return false;
else
return false;
}
/**
......@@ -256,18 +295,15 @@ public class SocialGroupMovementModel extends ModularMovementModel {
* @param SimLocationActuator The host to be checked.
* @return Boolean
*/
private boolean groupAtMP(SimLocationActuator host) {
Set<SimLocationActuator> participants = groupContainer.getGroupMembers(host);
int counter = 0;
for(SimLocationActuator participant : participants) {
if(hostIsAtMeetingPoint(participant)) {
counter++;
private boolean groupGatheredAtMeetingPoint(SocialMovementGroup group) {
for(SimLocationActuator participant : group.getMembers()) {
if(!hostIsAtMeetingPoint(participant)) {
return false;
}
}
if(counter == participants.size()) {
return true;
}
return false;
return true;
}
/**
......@@ -278,16 +314,12 @@ public class SocialGroupMovementModel extends ModularMovementModel {
*
*/
private boolean hostIsAtMeetingPoint(SimLocationActuator host) {
PositionVector currMP = groupContainer.getGroupOfHost(host).getMeetingPoint();
// Setting the required distance to the meeting point to maximum of 2 meters
// This is equivalent to a distance of group members in real life
double distance = host.getLastLocation().distanceTo(currMP);
if(distance <= 5) {
PositionVector meetingpoint = groupContainer.getGroupOfHost(host).getMeetingPoint();
if(host.getLastLocation().distanceTo(meetingpoint) <= MEETING_POINT_DISTANCE)
return true;
}
return false;
else
return false;
}
/*
......@@ -304,24 +336,10 @@ public class SocialGroupMovementModel extends ModularMovementModel {
*/
private void followLeader(SimLocationActuator host) {
SimLocationActuator leader = groupContainer.getGroupOfHost(host).getLeader();
if(leader.getCurrentTargetAttractionPoint() == null) {
System.out.println();
}
IAttractionPoint leaderDestination = leader.getCurrentTargetAttractionPoint();
IAttractionPoint hostDestination = host.getCurrentTargetAttractionPoint();
// Update target attraction point if not already done
if(leaderDestination != null && hostDestination != leaderDestination) {
attractionAssigment.updateTargetAttractionPoint(host, leaderDestination);
}
int o = 10;
// Assign small offset to the host depending on the leaders position.
PositionVector leaderPos = leader.getRealPosition();
PositionVector offset = new PositionVector(rand.nextInt(o), rand.nextInt(o));
PositionVector offset = new PositionVector(rand.nextDouble() * LEADER_GROUP_DISTANCE, rand.nextDouble() * LEADER_GROUP_DISTANCE);
PositionVector newPos = leaderPos.plus(offset);
// Update location of host, which will be around the leaders location.
......
......@@ -24,7 +24,10 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.IAttractionBasedMovementAnalyzer;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.ISocialGroupMovementAnalyzer;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
......@@ -55,6 +58,10 @@ public class AttractionPointImpl extends BasicAttractionPoint {
throw new AssertionError("Name "+name+" already in use for an attraction point.");
}
instances.put(name, this);
if(Monitor.hasAnalyzer(IAttractionBasedMovementAnalyzer.class)) {
Monitor.getOrNull(IAttractionBasedMovementAnalyzer.class).onAttractionPointAdded(this);
}
}
public AttractionPointImpl(String name, PositionVector posVec, double weight, double radius, long pauseTimeMin, long pauseTimeMax) {
......@@ -168,4 +175,9 @@ public class AttractionPointImpl extends BasicAttractionPoint {
public boolean hasRadius() {
return true;
}
@Override
public String toString() {
return getName();
}
}
......@@ -26,7 +26,9 @@ import java.util.Map;
import java.util.Set;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.ISocialGroupMovementAnalyzer;
import de.tud.kom.p2psim.impl.util.Tuple;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
......@@ -103,10 +105,10 @@ public class MovementGroupContainer {
*/
public void removeGroup(SocialMovementGroup group) {
for(SimLocationActuator participant : group.getMembers()) {
leftGroupAtTime.put(participant, Time.getCurrentTime());
leftGroupAtTime.put(participant, Time.getCurrentTime());
}
waitingGroups.remove(group);
groups.remove(group);
groups.remove(group);
}
/**
......
......@@ -26,6 +26,7 @@ import java.util.Set;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.ISocialGroupMovementAnalyzer;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.SocialGroupMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.MovementGroupContainer;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.SocialMovementGroup;
......@@ -33,6 +34,7 @@ import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.util.Tuple;
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.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.common.datastructures.Pair;
......@@ -91,8 +93,13 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
}
}
@Override
public Set<Pair<SocialMovementGroup>> getEncounteringGroups() {
/**
* 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.
*
* @return
*/
private Set<Pair<SocialMovementGroup>> getEncounteringGroups() {
if(!enableGroupEncounters)
return null;
......@@ -147,7 +154,13 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
}
for(Pair<SocialMovementGroup> encounter : encounteringGroups) {
if(groupCon.hasGroup(encounter.getFirst()) && groupCon.hasGroup(encounter.getSecond())) {
if(groupCon.hasGroup(encounter.getFirst()) && groupCon.hasGroup(encounter.getSecond())) {
// Inform analyzer of resolved movement
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupEncounter(encounter.getFirst(), encounter.getSecond());
}
handleGroupEncounter(encounter.getFirst(), encounter.getSecond());
}
}
......@@ -230,21 +243,13 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
*
*/
protected void dissolveGroups(SocialMovementGroup group1, SocialMovementGroup group2) {
groupCon.updateMergeVars(group1, group2);
if(groupCon.getGroups().contains(group1) && groupCon.getGroups().contains(group2)) {
for(SimLocationActuator participant : group1.getMembers()) {
groupCon.addLeftGroupAtTimeEntry(participant, Time.getCurrentTime());
movementModel.getAttractionAssignmentStrategy().addComponent(participant);
}
for(SimLocationActuator participant : group2.getMembers()) {
groupCon.addLeftGroupAtTimeEntry(participant, Time.getCurrentTime());
movementModel.getAttractionAssignmentStrategy().addComponent(participant);
}
groupCon.updateMergeVars(group1, group2);
if(groupCon.getGroups().contains(group1)) {
movementModel.getGroupFormingBehavior().removeGroup(group1);
}
if(groupCon.getGroups().contains(group2)) {
movementModel.getGroupFormingBehavior().removeGroup(group2);
}
}
......@@ -260,6 +265,11 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
protected SocialMovementGroup mergeGroupsFully(SocialMovementGroup group1, SocialMovementGroup group2) {
groupCon.updateMergeVars(group1, group2);
// Inform analyzer of resolved movement
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupMerge(group1, group2);
}
SocialMovementGroup large = getLargerGroup(group1, group2);
SocialMovementGroup small = getSmallerGroup(group1, group2);
......@@ -272,7 +282,7 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
}
movementModel.getGroupFormingBehavior().removeGroup(small);
return large;
}
......@@ -302,13 +312,24 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
groupCon.updateGroupEntry(small);
groupCon.updateGroupEntry(large);
}
// Inform analyzer of resolved movement
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupMerge(group1, group2);
}
}
}
protected void wait(SocialMovementGroup group, long timeToWait) {
// only start the waiting process if not already waiting (duh!)
if(!groupCon.waitingGroups.containsKey(group)) {
if(!groupCon.waitingGroups.containsKey(group)) {
// Inform analyzer of resolved movement
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupWait(group);
}
groupCon.waitingGroups.put(group, new Tuple<Long, Long>(timeToWait, Time.getCurrentTime()));
Event.scheduleWithDelay(timeToWait, new EventHandler() {
@Override
......
......@@ -39,14 +39,7 @@ public interface IGroupEncounterBehavior {
*
*/
void initialize(SocialGroupMovementModel movementModel);
/**
* 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.
*
* @return
*/
Set<Pair<SocialMovementGroup>> getEncounteringGroups();
/**
* Applies an encountering action to each detected encountering groups.
......
......@@ -27,6 +27,7 @@ import java.util.Set;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.ISocialGroupMovementAnalyzer;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.SocialGroupMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.BasicAttractionPoint;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
......@@ -37,6 +38,7 @@ import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.util.Tuple;
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.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
......@@ -183,8 +185,8 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
protected void createGroup(Set<SimLocationActuator> members) {
SocialMovementGroup group = new SocialMovementGroup(members);
movementModel.getAttractionAssignmentStrategy().addComponent(group.getLeader());
// FIXME move to movement model
movementModel.getAttractionAssignmentStrategy().addComponent(group.getLeader());
IAttractionPoint nextDestination = movementModel.getAttractionAssignmentStrategy().getAssignment(group.getLeader());
// Add Offset to group destination
......@@ -202,6 +204,11 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
}
groupCon.addGroup(group);
// Inform analyzer of new group
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupForming(group);
}
}
/**
......@@ -212,6 +219,22 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
*/
@Override
public void removeGroup(SocialMovementGroup group) {
// Inform analyzer of group removal
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onGroupDisbanding(group);
}
// If this group is removed, reassign the group target attraction point as new target attraction point
// for each former group member (prevents errors when routing was not reset correctly)
if(group.getGroupSize() > 0 || group.getLeader() != null) {
IAttractionPoint currentAP = group.getLeader().getCurrentTargetAttractionPoint();
for (SimLocationActuator host : group.getMembers()) {
movementModel.updatedAttractionAssignment(host, currentAP);
}
}
groupCon.removeGroup(group);
long delay = 0;
......@@ -227,17 +250,7 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
else {
delay = rndGroupFormationDelay();
}
if(group.getGroupSize() > 0 || group.getLeader() != null) {
IAttractionPoint currentAP = group.getLeader().getCurrentTargetAttractionPoint();
for (SimLocationActuator host : group.getMembers()) {
movementModel.updatedAttractionAssignment(host, currentAP);
}
}
Event.scheduleWithDelay(delay, new EventHandler() {
@Override
public void eventOccurred(Object content, int type) {
......@@ -339,7 +352,7 @@ public abstract class AbstractGroupForming implements IGroupFormingBehavior {
// Update target for all group members to meeting point
for(SimLocationActuator participant : group.getMembers()) {
movementModel.getAttractionAssignmentStrategy().updateTargetAttractionPoint(participant, meetingPoint);
//movementModel.getAttractionAssignmentStrategy().updateTargetAttractionPoint(participant, meetingPoint);
}
}
......
......@@ -149,7 +149,8 @@ public class DefaultGroupForming extends AbstractGroupForming {
}
// if there are no candidates, wait a minute until asking again
if(groupCandidates.isEmpty() || groupCandidates == null) {
if(groupCandidates.isEmpty() || groupCandidates == null || groupCandidates.size() < minGroupSize) {
Event.scheduleWithDelay(Time.MINUTE, new EventHandler() {
@Override
public void eventOccurred(Object content, int type) {
......
......@@ -27,7 +27,9 @@ import java.util.Map;
import java.util.Random;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.IAttractionBasedMovementAnalyzer;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
......@@ -86,6 +88,11 @@ public abstract class AbstractAttractionBasedAssignmentStrategy implements IAttr
protected void notifyListenersOfAssignmentUpdate(SimLocationActuator comp,
IAttractionPoint attractionPoint) {
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
// also iInform analyzer of assigment update
if(Monitor.hasAnalyzer(IAttractionBasedMovementAnalyzer.class)) {
Monitor.getOrNull(IAttractionBasedMovementAnalyzer.class).onUpdateAttractionAssignment(comp, attractionPoint);
}
}
@Override
......@@ -95,7 +102,7 @@ public abstract class AbstractAttractionBasedAssignmentStrategy implements IAttr
this.lastAssignments.put(comp, this.assignments.remove(comp));
}
this.assignments.put(comp, attractionPoint);
notifyListenersOfAssignmentUpdate(comp, attractionPoint);
notifyListenersOfAssignmentUpdate(comp, attractionPoint);
}
private long getRandomUniformDistributionPauseTime(IAttractionPoint attractionPoint) {
......
......@@ -23,10 +23,12 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;
import java.util.LinkedHashMap;
import java.util.Map;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
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.attraction.IAttractionGenerator;
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.component.sensor.location.IAttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
......@@ -66,10 +68,13 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig
return;
}
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onNodeReachedAttractionPoint(comp, attractionPoint);
}
this.roamingStates.put(comp, roamingTransitionState.PAUSE);
// schedule roaming
Event.scheduleWithDelay(Math.max(Time.MINUTE, gaussianDistributionPauseTime(5 * Time.MINUTE, 1 * Time.MINUTE)), this, comp, 0);
}
/**
......@@ -87,8 +92,7 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig
if(roamingStates.get(comp) == roamingTransitionState.PAUSE) {
IAttractionPoint currentAttractionPoint = this.assignments.get(comp);
this.roamingStates.put(comp, roamingTransitionState.ROAMING);
notifyListenersOfAssignmentUpdate(comp, currentAttractionPoint);
notifyListenersOfAssignmentUpdate(comp, currentAttractionPoint);
}
}
......@@ -106,7 +110,4 @@ public class AttractionPointRoamingStrategy extends AbstractAttractionBasedAssig
this.roamAroundAttractionPoint(comp);
}
}
}
}
\ No newline at end of file
......@@ -23,10 +23,12 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;
import java.util.LinkedHashMap;
import java.util.Map;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
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.attraction.IAttractionGenerator;
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.component.sensor.location.IAttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
......@@ -71,6 +73,11 @@ public class InAreaRoamingTransitionStrategy extends AbstractAttractionBasedAssi
return;
}
if(Monitor.hasAnalyzer(ISocialGroupMovementAnalyzer.class)) {
Monitor.getOrNull(ISocialGroupMovementAnalyzer.class).onNodeReachedAttractionPoint(comp, attractionPoint);
}
// start roaming if the AP was reached
if(roamingStates.get(comp) == roamingTransitionState.TRANSITION) {
// schedule the end of the roaming phase, which will make a new transition
......
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