diff --git a/.gitignore b/.gitignore index 2d302dcd8..b8ccd69e9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ doc/package-list .project /target/ .settings/org.eclipse.* +/bin/ diff --git a/example_settings/communitybasedmovement_settings.txt b/example_settings/communitybasedmovement_settings.txt new file mode 100644 index 000000000..0eb6a9a4c --- /dev/null +++ b/example_settings/communitybasedmovement_settings.txt @@ -0,0 +1,161 @@ +# +# Default settings for the simulation +# + +## Scenario settings +Scenario.name = default_scenario +Scenario.simulateConnections = true +Scenario.updateInterval = 0.1 +# 43200s == 12h +Scenario.endTime = 10000000 +Scenario.endTime = 43200 + +## Interface-specific settings: +# type : which interface class the interface belongs to +# For different types, the sub-parameters are interface-specific +# For SimpleBroadcastInterface, the parameters are: +# transmitSpeed : transmit speed of the interface (bytes per second) +# transmitRange : range of the interface (meters) + +# "Bluetooth" interface for all nodes +btInterface.type = SimpleBroadcastInterface +# Transmit speed of 2 Mbps = 250kBps +btInterface.transmitSpeed = 250k +btInterface.transmitRange = 20 + +# High speed, long range, interface for group 4 +highspeedInterface.type = SimpleBroadcastInterface +highspeedInterface.transmitSpeed = 10M +highspeedInterface.transmitRange = 10 + +# Define 4 different node groups +Scenario.nrofHostGroups = 4 + +## Group-specific settings: +# groupID : Group's identifier. Used as the prefix of host names +# nrofHosts: number of hosts in the group +# movementModel: movement model of the hosts (valid class name from movement package) +# waitTime: minimum and maximum wait times (seconds) after reaching destination +# speed: minimum and maximum speeds (m/s) when moving on a path +# bufferSize: size of the message buffer (bytes) +# router: router used to route messages (valid class name from routing package) +# activeTimes: Time intervals when the nodes in the group are active (start1, end1, start2, end2, ...) +# msgTtl : TTL (minutes) of the messages created by this host group, default=infinite + +## Group and movement model specific settings +# pois: Points Of Interest indexes and probabilities (poiIndex1, poiProb1, poiIndex2, poiProb2, ... ) +# for ShortestPathMapBasedMovement +# okMaps : which map nodes are OK for the group (map file indexes), default=all +# for all MapBasedMovent models +# routeFile: route's file path - for MapRouteMovement +# routeType: route's type - for MapRouteMovement + + +# Common settings for all groups +Group.movementModel = CommunityBasedMovement +#Group.movementModel = MapBasedMovement +Group.router = ProphetRouter +#Group.router = E3PRouter + +Group.bufferSize = 5M +Group.waitTime = 0, 120 +# All nodes have the bluetooth interface +Group.nrofInterfaces = 1 +Group.interface1 = btInterface +# Walking speeds +#Group.speed = 0.5, 1.5 +Group.speed = 3, 6 +# Message TTL of 300 minutes (5 hours) +Group.msgTtl = 300 + +Group.nrofHosts = 9 + +# group1 (players) specific settings +Group1.groupID = a +# 10-50 km/h +#Group1.speed = 2.7, 13.9 + +# group2 (players) specific settings +Group2.groupID = b +# 10-50 km/h +#Group2.speed = 2.7, 13.9 + +Group3.groupID = c + +Group4.groupID = d + +## Message creation parameters +# How many event generators +Events.nrof = 1 +# Class of the first event generator +Events1.class = MessageEventGenerator +# (following settings are specific for the MessageEventGenerator class) +# Creation interval in seconds (one new message every 25 to 35 seconds) +Events1.interval = 25,35 +# Message sizes (500kB - 1MB) +Events1.size = 500k,1M +# range of message source/destination addresses +Events1.hosts = 0,36 +# Message ID prefix +Events1.prefix = M + + +## Movement model settings +# seed for movement models' pseudo random number generator (default = 0) +MovementModel.rngSeed = 1 +# World's size for Movement Models without implicit size (width, height; meters) +MovementModel.worldSize = 2000,1500 +# How long time to move hosts in the world before real simulation +MovementModel.warmup = 0 + +## Community based movement -movement model specific settings +CommunityBasedMovement.communityNumber = 2,2 +CommunityBasedMovement.mapSize = 2000, 1500 +CommunityBasedMovement.communityID = a,b,c,d +#CommunityBasedMovement.probabilities_local_roaming = 1,0 +CommunityBasedMovement.probabilities_local_roaming = 0.8,0.2 + +## Map based movement -movement model specific settings +MapBasedMovement.nrofMapFiles = 1 +MapBasedMovement.mapFile1 = data/map.osm.wkt + + +## Reports - all report names have to be valid report classes + +# how many reports to load +Report.nrofReports = 2 +# length of the warm up period (simulated seconds) +Report.warmup = 0 +# default directory of reports (can be overridden per Report with output setting) +Report.reportDir = reports/ +# Report classes to load +Report.report1 = ContactTimesReport +Report.report2 = ConnectivityONEReport + +## Default settings for some routers settings +ProphetRouter.secondsInTimeUnit = 30 +E3PRouter.secondsInTimeUnit = 30 +SprayAndWaitRouter.nrofCopies = 6 +SprayAndWaitRouter.binaryMode = true + +## Optimization settings -- these affect the speed of the simulation +## see World class for details. +Optimization.cellSizeMult = 5 +Optimization.randomizeUpdateOrder = true + + +## GUI settings + +# GUI underlay image settings +GUI.UnderlayImage.fileName = data/helsinki_underlay.png +# Image offset in pixels (x, y) +GUI.UnderlayImage.offset = 64, 20 +# Scaling factor for the image +GUI.UnderlayImage.scale = 4.75 +# Image rotation (radians) +GUI.UnderlayImage.rotate = -0.015 + +# how many events to show in the log panel (default = 30) +GUI.EventLogPanel.nrofEvents = 30 +# Regular Expression log filter (see Pattern-class from the Java API for RE-matching details) +#GUI.EventLogPanel.REfilter = .*p[1-9]<->p[1-9]$ diff --git a/lib/junit-4.12.jar b/lib/junit-4.12.jar new file mode 100644 index 000000000..3a7fc266c Binary files /dev/null and b/lib/junit-4.12.jar differ diff --git a/src/movement/CommunityBasedMovement.java b/src/movement/CommunityBasedMovement.java new file mode 100644 index 000000000..a05ec98d5 --- /dev/null +++ b/src/movement/CommunityBasedMovement.java @@ -0,0 +1,227 @@ +/* + * Copyright 2010 Aalto University, ComNet + * Released under GPLv3. See LICENSE.txt for details. + */ + +/** + * CommunityBasedMovement where the coordinates are restricted to rectangle + * area defined by two coordinates in the entire map. + * + * Four parameters for configuration file: + * CommunityBasedMovement.communityNumber: the number of rectangle community + * e.g. if you have 12 communities, you could set the value to 3,4 or 4,3 + * CommunityBasedMovement.mapSize: the size of map should be identical to worldSize + * e.g. CommunityBasedMovement.mapSize = x,y : x,y are the maximum coordinates + * in X-Axis and Y-Axis respectively + * CommunityBasedMovement.communityID = a,b,c,d: all community identity + * CommunityBasedMovement.probabilities_local_roaming: probabilities for p_local and + * p_roaming + * + * Note: To run this movement model: + * 1. Move the configuration file "communitybasedmovement_settings.txt" from + * the directory "example_settings" to root directory + * 2.rename the configuration to "default_settings.txt" to replace the original + * one + * 3. recompile the code + * + * @author Xiaoyang Zhu + * @email xiaoyang.zhu@hotmail.com + */ +package movement; + +import java.util.HashMap; +import java.util.Map; + +import core.Coord; +import core.Settings; + +public class CommunityBasedMovement extends MovementModel { + /* Number of the Community: + e.g. if you have 12 communities, you could set the value to 3,4 or 4,3 */ + public static final String COMMUNITY_NUMBER = "communityNumber"; + /* Size of the map */ + public static final String MAP_SIZE = "mapSize"; + /* Community identifier that should be identical to the Group ID in configuration file */ + public static final String COMMUNITY_ID = "communityID"; + + public static final String COMMUNITY_BASED_MOVEMENT_MODEL_NS = "CommunityBasedMovement"; + + + /* Probabilities of local or roaming epoch */ + public static final String PROBABILITIES_LOCAL_ROAMING = "probabilities_local_roaming"; + + /* Size of the map */ + private int map_x_max = 100, map_y_max = 100; + /* Number of the Community */ + private int community_x_number = 1, community_y_number = 1; + + /* Community identifier that should be identical to the Group ID in configuration file */ + private static String[] community_id; + + /* Communities' attributes include the community_id and the coordinates */ + private static Map community_attribute = new HashMap(); + + /* Minimum unit of community */ + private double x_unit, y_unit; + + /* Selected destination */ + private Coord lastWaypoint; + + /* Selected community */ + private double [] selected_community = null; + + /* Probabilities of local or roaming epoch */ + private static double p_l = 0.8, p_r = 0.2; + + /* Probability that a give epoch of node is a local one */ + private static double pi_l; + + /* Selecting not the current community */ + private int rnd_i; + private double [] not_selected_community = null; + + /** how many waypoints should there be per path */ + private static final int PATH_LENGTH = 1; + + public CommunityBasedMovement(Settings s) { + super(s); + + /* Loading the parameters in configuration file */ + s.setNameSpace(COMMUNITY_BASED_MOVEMENT_MODEL_NS); + + if (s.contains(COMMUNITY_NUMBER)){ + int[] cn = s.getCsvInts(COMMUNITY_NUMBER,2); + this.community_x_number = cn[0]; + this.community_y_number = cn[1]; + } + if (s.contains(MAP_SIZE)){ + int[] ms = s.getCsvInts(MAP_SIZE,2); + this.map_x_max = ms[0]; + this.map_y_max = ms[1]; + } + if (s.contains(COMMUNITY_ID)){ + community_id = s.getSetting(COMMUNITY_ID).split(","); + } + if (s.contains(PROBABILITIES_LOCAL_ROAMING)){ + double[] plr = s.getCsvDoubles(PROBABILITIES_LOCAL_ROAMING,2); + p_l = plr[0]; + p_r = plr[1]; + } + + /* Calculate the probability according to Markov Chain */ + pi_l = (1 - p_r)/(2 - p_l - p_r); + + /* According to the setting parameters to initiate the coordinates information of each community */ + assert (community_id.length == (this.community_x_number) * + (this.community_y_number)) : "the number of communityID is not correct!"; + + x_unit = map_x_max/community_x_number; + y_unit = map_y_max/community_y_number; + + double community_x_min = 0, community_y_min = 0; + double community_x_max = x_unit, community_y_max = y_unit; + int array_counter = 0; + for (int i = 0; i < this.community_y_number; i++) { + for (int j = 0; j < this.community_x_number; j++) { + double[] community_attribute_coordinates = {community_x_min, community_y_min, + community_x_max, community_y_max}; + + community_attribute.put(community_id[array_counter++], community_attribute_coordinates); + + community_x_min = community_x_max; + community_x_max = community_x_max + x_unit; + } + community_x_min = 0; + community_y_min += y_unit; + community_x_max = x_unit; + community_y_max += y_unit; + } + + } + + private CommunityBasedMovement(CommunityBasedMovement cmv) { + super(cmv); + this.community_x_number = cmv.community_x_number; + this.community_y_number = cmv.community_y_number; + this.map_x_max = cmv.map_x_max; + this.map_y_max = cmv.map_y_max; + } + + /** + * Returns a possible (random) placement for a host + * @return Random position on the map + */ + @Override + public Coord getInitialLocation() { + assert rng != null : "MovementModel not initialized!"; + for (Map.Entry ca : community_attribute.entrySet()) { + if (getHost().toString().startsWith(ca.getKey())) { + selected_community = ca.getValue(); + Coord c = randomCoord(selected_community); + this.lastWaypoint = c; + return c; + } + + } + assert selected_community != null : "The node's id is not idential with the community's"; + return null; + } + + @Override + public Path getPath() { + Path p; + p = new Path(generateSpeed()); + p.addWaypoint(lastWaypoint.clone()); + Coord c = lastWaypoint; + + for (int i=0; i