Commit 3f83db48 authored by Julian Zobel's avatar Julian Zobel
Browse files

Now multiple groups can meet each other and wait (+smart merge). Wait Time is...

Now multiple groups can meet each other and wait (+smart merge). Wait Time is adapted to the encountered group and not reset to full time (prevents single group waiting).

Problems in Routing?
parent 4b8eaefe
...@@ -190,7 +190,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac ...@@ -190,7 +190,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
attractionAssigment.updateTargetAttractionPoint(actuator, ap); attractionAssigment.updateTargetAttractionPoint(actuator, ap);
} }
private void checkConfiguration() { protected void checkConfiguration() {
if (localMovementStrategy == null) { if (localMovementStrategy == null) {
throw new ConfigurationException( throw new ConfigurationException(
"LocalMovementStrategy is missing in ModularMovementModel!"); "LocalMovementStrategy is missing in ModularMovementModel!");
......
...@@ -28,6 +28,7 @@ import java.util.Set; ...@@ -28,6 +28,7 @@ import java.util.Set;
import java.util.Vector; import java.util.Vector;
import de.tud.kom.p2psim.api.scenario.ConfigurationException; import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.Topology;
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.attraction.IAttractionGenerator;
...@@ -38,7 +39,10 @@ import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounter ...@@ -38,7 +39,10 @@ import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounter
import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupforming.IGroupFormingBehavior; import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupforming.IGroupFormingBehavior;
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;
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.Event;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
...@@ -55,10 +59,16 @@ public class SocialGroupMovementModel extends ModularMovementModel { ...@@ -55,10 +59,16 @@ public class SocialGroupMovementModel extends ModularMovementModel {
private Set<SimLocationActuator> singleHosts = new LinkedHashSet<SimLocationActuator>(); private Set<SimLocationActuator> singleHosts = new LinkedHashSet<SimLocationActuator>();
private int numberOfSingleHosts; private int numberOfSingleHosts;
private boolean placeNodesAtAP = false;
public void setPlaceNodes(boolean placeNodes) {
this.placeNodesAtAP = placeNodes;
}
@Override @Override
public void initialize() { public void initialize() {
if (!initialized) { if (!initialized) {
groupContainer = MovementGroupContainer.getInstance(); groupContainer = MovementGroupContainer.getInstance();
attractionPointHostCounter.initialize(this); attractionPointHostCounter.initialize(this);
...@@ -72,10 +82,53 @@ public class SocialGroupMovementModel extends ModularMovementModel { ...@@ -72,10 +82,53 @@ public class SocialGroupMovementModel extends ModularMovementModel {
} while(singleHosts.size() < numberOfSingleHosts); } while(singleHosts.size() < numberOfSingleHosts);
} }
super.initialize(); if (modelVisualisation == null) {
modelVisualisation = new ModularMovementModelViz(this);
}
VisualizationInjector.injectComponent(modelVisualisation);
if (mapVisualization != null) {
VisualizationInjector.injectComponent(mapVisualization);
}
checkConfiguration();
// setWayPointModel
localMovementStrategy.setObstacleModel(Binder
.getComponentOrNull(Topology.class).getObstacleModel());
localMovementStrategy.setWaypointModel(Binder
.getComponentOrNull(Topology.class).getWaypointModel());
/*
* Scale depending on calculation interval, if interval != 1 Second.
*/
localMovementStrategy
.setScaleFactor(timeBetweenMoveOperation / (double) Time.SECOND);
attractionAssigment.addAttractionAssignmentListener(this);
// This adds the mobile hosts (smartphones/users) to the transition
// strategy
for (SimLocationActuator ms : moveableHosts) {
attractionAssigment.addComponent(ms);
if(placeNodesAtAP)
ms.updateCurrentLocation(attractionAssigment.getAssignment(ms));
}
setTimeBetweenMoveOperations(timeBetweenMoveOperation);
// initial move
move();
initialized = true;
} }
} }
/** /**
* Returns a random SimLocationActuator component from the set of moveable hosts. * Returns a random SimLocationActuator component from the set of moveable hosts.
* *
...@@ -119,6 +172,18 @@ public class SocialGroupMovementModel extends ModularMovementModel { ...@@ -119,6 +172,18 @@ public class SocialGroupMovementModel extends ModularMovementModel {
*/ */
for (SimLocationActuator component : moveableHosts) { for (SimLocationActuator component : moveableHosts) {
assert currentTargets.containsKey(component); assert currentTargets.containsKey(component);
if(component.getHost().getId().value() == 74) {
if(component.getCurrentTargetAttractionPoint().distanceTo(component.getRealPosition())
> component.getCurrentTargetAttractionPoint().getRadius()) {
System.out.println(currentTargets.get(component));
System.out.println(component.getRealPosition());
System.out.println(component.getCurrentTargetAttractionPoint());
System.out.println(component.getCurrentTargetAttractionPoint().distanceTo(component.getRealPosition()));
System.out.println("==");
}
}
doGroupMovement(component, currentTargets.get(component)); doGroupMovement(component, currentTargets.get(component));
} }
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null, EVENT_MOVE); Event.scheduleWithDelay(timeBetweenMoveOperation, this, null, EVENT_MOVE);
......
...@@ -105,6 +105,7 @@ public class MovementGroupContainer { ...@@ -105,6 +105,7 @@ public class MovementGroupContainer {
for(SimLocationActuator participant : group.getMembers()) { for(SimLocationActuator participant : group.getMembers()) {
leftGroupAtTime.put(participant, Time.getCurrentTime()); leftGroupAtTime.put(participant, Time.getCurrentTime());
} }
waitingGroups.remove(group);
groups.remove(group); groups.remove(group);
} }
...@@ -233,13 +234,18 @@ public class MovementGroupContainer { ...@@ -233,13 +234,18 @@ public class MovementGroupContainer {
* @param SocialMovementGroup The first group. * @param SocialMovementGroup The first group.
* @param SocialMovementGroup The second group. * @param SocialMovementGroup The second group.
* *
* @author Marcel Verst
*/ */
public void updateMergeVars(SocialMovementGroup group1, SocialMovementGroup group2) { public void updateMergeVars(SocialMovementGroup group1, SocialMovementGroup group2) {
Set<SimLocationActuator> all = new LinkedHashSet<>(); updateMergeVars(group1);
all.addAll(group1.getMembers()); updateMergeVars(group2);
all.addAll(group2.getMembers()); }
for(SimLocationActuator host : all) {
public void updateMergeVars(SocialMovementGroup group) {
if(group == null || group.getMembers().isEmpty()) {
return;
}
for(SimLocationActuator host : group.getMembers()) {
addHasMergedEntry(host, true); addHasMergedEntry(host, true);
addMergedAtTimeEntry(host, Time.getCurrentTime()); addMergedAtTimeEntry(host, Time.getCurrentTime());
} }
......
...@@ -135,6 +135,12 @@ public class SocialMovementGroup { ...@@ -135,6 +135,12 @@ public class SocialMovementGroup {
return leader.getRealPosition(); return leader.getRealPosition();
} }
@Override
public String toString() {
return "Social Group of #" + leader.getHost().getId() + " ("+ members.size() +")";
}
// =================== // ===================
// Getters and Setters // Getters and Setters
// =================== // ===================
......
...@@ -31,6 +31,8 @@ import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.MovementGroupC ...@@ -31,6 +31,8 @@ import de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.MovementGroupC
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.util.PositionVector; import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.util.Tuple; 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.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.common.datastructures.Pair;
...@@ -253,11 +255,12 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior ...@@ -253,11 +255,12 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
* @param SocialMovementGroup The first group. * @param SocialMovementGroup The first group.
* @param SocialMovementGroup The second group. * @param SocialMovementGroup The second group.
* *
* @return Returns the merged group
*/ */
protected void mergeGroupsFully(SocialMovementGroup group1, SocialMovementGroup group2) { protected SocialMovementGroup mergeGroupsFully(SocialMovementGroup group1, SocialMovementGroup group2) {
groupCon.updateMergeVars(group1, group2); groupCon.updateMergeVars(group1, group2);
System.out.println("merge groups!"); System.out.println("merge groups | " + group1 + "| " + group2 );
SocialMovementGroup large = getLargerGroup(group1, group2); SocialMovementGroup large = getLargerGroup(group1, group2);
SocialMovementGroup small = getSmallerGroup(group1, group2); SocialMovementGroup small = getSmallerGroup(group1, group2);
...@@ -271,6 +274,8 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior ...@@ -271,6 +274,8 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
} }
movementModel.getGroupFormingBehavior().removeGroup(small); movementModel.getGroupFormingBehavior().removeGroup(small);
return large;
} }
/** /**
...@@ -302,45 +307,50 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior ...@@ -302,45 +307,50 @@ public abstract class AbstractGroupEncounter implements IGroupEncounterBehavior
} }
} }
/**
* Assigns two groups the role to wait for a specified amount of time. After waiting for this time,
* the groups are released from the waiting role and can continue their trip.
*
* @param SocialMovementGroup The first group.
* @param SocialMovementGroup The second group.
*/
protected void wait(SocialMovementGroup group1, SocialMovementGroup group2, long timeToWait) {
// Do not apply waiting process if one of both groups is already waiting
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(!groupCon.waitingGroups.containsKey(group1) && !groupCon.waitingGroups.containsKey(group2)) {
groupCon.waitingGroups.put(group1, new Tuple<Long, Long>(timeToWait, Time.getCurrentTime()));
groupCon.waitingGroups.put(group2, new Tuple<Long, Long>(timeToWait, Time.getCurrentTime()));
}
// If both groups are already waiting protected void wait(SocialMovementGroup group, long timeToWait) {
if(groupCon.waitingGroups.containsKey(group1) && groupCon.waitingGroups.containsKey(group2)) { // Do not apply waiting process if one of both groups is already waiting
long timerGroup1 = groupCon.waitingGroups.get(group1).getA(); if(!groupCon.waitingGroups.containsKey(group)) {
long timerGroup2 = groupCon.waitingGroups.get(group2).getA(); // long timer = groupCon.waitingGroups.get(group).getA();
// long delta = Time.getCurrentTime() - groupCon.waitingGroups.get(group).getB();
// Remove groups if they have waited long enough // System.out.println("Group " + group.getLeader().getHost().getId());
if(timerGroup1 <= 0 && timerGroup2 <= 0) { // System.out.println(Time.getFormattedTime(timer) + " TTW");
groupCon.updateMergeVars(group1, group2); // System.out.println(Time.getFormattedTime(delta) + " delta");
groupCon.waitingGroups.remove(group1); //
groupCon.waitingGroups.remove(group2); // // Remove groups if they have waited long enough
} // if(delta >= timer) {
// Decrement timer of both groups if they have to wait more // System.out.println(" Delta >= Timer --- remove...");
else { // groupCon.updateMergeVars(group);
long deltaGroup1 = Time.getCurrentTime() - groupCon.waitingGroups.get(group1).getB(); // groupCon.waitingGroups.remove(group);
groupCon.waitingGroups.put(group1, new Tuple<Long, Long>(timerGroup1 - deltaGroup1, Time.getCurrentTime())); // }
// else {
// System.out.println(" wait more... ");
// }
//
// System.out.println(" == ");
// }
// else {
System.out.println("new Waiting group : " + group.getLeader().getHost().getId() );
groupCon.waitingGroups.put(group, new Tuple<Long, Long>(timeToWait, Time.getCurrentTime()));
Event.scheduleWithDelay(timeToWait, new EventHandler() {
long deltaGroup2 = Time.getCurrentTime() - groupCon.waitingGroups.get(group2).getB(); @Override
groupCon.waitingGroups.put(group2, new Tuple<Long, Long>(timerGroup2 - deltaGroup2, Time.getCurrentTime())); public void eventOccurred(Object content, int type) {
}
SocialMovementGroup g = (SocialMovementGroup) content;
if(!groupCon.hasGroup(g)) {
System.out.println("group NULL");
return;
}
System.out.println(" Timer expired for " + g);
groupCon.updateMergeVars(g);
groupCon.waitingGroups.remove(g);
}
}, group, 0);
} }
} }
......
...@@ -22,6 +22,7 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounte ...@@ -22,6 +22,7 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounte
import de.tud.kom.p2psim.api.scenario.ConfigurationException; import de.tud.kom.p2psim.api.scenario.ConfigurationException;
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.Time;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
...@@ -34,8 +35,8 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; ...@@ -34,8 +35,8 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
*/ */
public class Wait extends AbstractGroupEncounter{ public class Wait extends AbstractGroupEncounter{
//--- VARIABLES TO BE DECLARED IN CONFIG --- //--- VARIABLES TO BE DECLARED IN CONFIG ---
private double probabilityToWait; protected double probabilityToWait;
private long timeToWait; protected long timeToWait;
//------------------------------------------ //------------------------------------------
@XMLConfigurableConstructor({"enableGroupEncounters","groupEncounterMeetingDistance","groupReencounterWaitTime"}) @XMLConfigurableConstructor({"enableGroupEncounters","groupEncounterMeetingDistance","groupReencounterWaitTime"})
...@@ -49,10 +50,15 @@ public class Wait extends AbstractGroupEncounter{ ...@@ -49,10 +50,15 @@ public class Wait extends AbstractGroupEncounter{
@Override @Override
public void handleGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2) { public void handleGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2) {
if(rand.nextDouble() <= probabilityToWait) { if(rand.nextDouble() <= probabilityToWait) {
wait(group1, group2, timeToWait); long waittime = getRandomWaitTime();
wait(group1, waittime);
wait(group2, waittime);
} }
} }
protected long getRandomWaitTime() {
return (long) Math.max(Time.MINUTE, (rand.nextDouble() + 0.5) * timeToWait);
}
/* /*
* GETTERS AND SETTERS * GETTERS AND SETTERS
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounter; package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups.groupencounter;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
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.Time;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
...@@ -30,11 +30,7 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; ...@@ -30,11 +30,7 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
* @author Julian Zobel * @author Julian Zobel
* @version 1.0, 04.02.2020 * @version 1.0, 04.02.2020
*/ */
public class WaitSmartMerge extends AbstractGroupEncounter{ public class WaitSmartMerge extends Wait{
//--- VARIABLES TO BE DECLARED IN CONFIG ---
private double probabilityToWait;
private long timeToWait;
//------------------------------------------
@XMLConfigurableConstructor({"enableGroupEncounters","groupEncounterMeetingDistance","groupReencounterWaitTime"}) @XMLConfigurableConstructor({"enableGroupEncounters","groupEncounterMeetingDistance","groupReencounterWaitTime"})
public WaitSmartMerge(boolean enableGroupEncounters, public WaitSmartMerge(boolean enableGroupEncounters,
...@@ -47,31 +43,42 @@ public class WaitSmartMerge extends AbstractGroupEncounter{ ...@@ -47,31 +43,42 @@ public class WaitSmartMerge extends AbstractGroupEncounter{
@Override @Override
public void handleGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2) { public void handleGroupEncounter(SocialMovementGroup group1, SocialMovementGroup group2) {
long pauseTime = getRandomWaitTime();
if(groupCon.waitingGroups.containsKey(group1) && !groupCon.waitingGroups.containsKey(group2)) {
pauseTime =getRemainingGroupWaitTime(group1);
}
else if(!groupCon.waitingGroups.containsKey(group1) && groupCon.waitingGroups.containsKey(group2)) {
pauseTime =getRemainingGroupWaitTime(group2);
}
if(group1.getLeader().getCurrentTargetAttractionPoint() == group2.getLeader().getCurrentTargetAttractionPoint()) { if(group1.getLeader().getCurrentTargetAttractionPoint() == group2.getLeader().getCurrentTargetAttractionPoint()) {
mergeGroupsFully(group1, group2); SocialMovementGroup merged = mergeGroupsFully(group1, group2);
wait(merged, getRandomWaitTime());
} }
else if(rand.nextDouble() <= probabilityToWait) { else if(rand.nextDouble() <= probabilityToWait) {
wait(group1, group2, timeToWait); long time = getRandomWaitTime();
wait(group1, time);
wait(group2, time);
} }
} }
/* private long getRemainingGroupWaitTime(SocialMovementGroup group) {
* GETTERS AND SETTERS
*/ long pausetime = groupCon.waitingGroups.get(group).getA();
public void setProbabilityToWait(double probabilityToWait) {
if (probabilityToWait < 0 || probabilityToWait > 1.0) { long issueTime = groupCon.waitingGroups.get(group).getB();
throw new ConfigurationException(
"probabilityToWait should be between 0.0 and 1.0!"); long remaining = issueTime + pausetime - Time.getCurrentTime();
}
this.probabilityToWait = probabilityToWait; System.out.println(Time.getFormattedTime(remaining) + " remaining of " + group);
}
return remaining;
public void setTimeToWait(long timeToWait) {
if(timeToWait < 0) {
throw new ConfigurationException(
"timeToWait should be greater or equal than 0!");
}
this.timeToWait = timeToWait;
} }
} }
...@@ -26,7 +26,6 @@ import java.io.IOException; ...@@ -26,7 +26,6 @@ import java.io.IOException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Vector;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.json.JSONArray; import org.json.JSONArray;
...@@ -130,9 +129,7 @@ public class JSONPlacement implements PlacementModel { ...@@ -130,9 +129,7 @@ public class JSONPlacement implements PlacementModel {
} }
public void setPlacementJsonFile(String placementJsonFile) { public void setPlacementJsonFile(String placementJsonFile) {
this.placementJsonFile = placementJsonFile; this.placementJsonFile = placementJsonFile;
} }
......
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