Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ doc/package-list
.project
/target/
.settings/org.eclipse.*
/bin/
161 changes: 161 additions & 0 deletions example_settings/communitybasedmovement_settings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#
# Default settings for the simulation
#

## Scenario settings
Scenario.name = default_scenario

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scenario name should be changed to something else than the default.

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]$
Binary file added lib/junit-4.12.jar
Binary file not shown.
227 changes: 227 additions & 0 deletions src/movement/CommunityBasedMovement.java
Original file line number Diff line number Diff line change
@@ -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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be on top of the class header, not the package line.

* 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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there need to recompile?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dear akeranen,
What i wrote is the source file .java not just a configuration file. So, you have to recompile the new movement model source file into the project. But there is not any conflicts against previous source code and no any modification in previous source code. I just added the new movement model file and explained how to configure the configuration file to test it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The settings file should be written so that it can just be passed as a command line argument, rather than replacing default_settings.txt. And the instructions for replacing the default_settings.txt should be removed.

*
* @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";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static fields that identify settings to be read from the settings file should be identified clearly as such. E.g., add an _S or _SETTING suffix. The javadoc for settings names should include ({@value}) so that it shows up in the compiled javadoc. If the setting has a default value (like the map size, the javadoc of the setting should state what it is). The ONE also uses camelCase in most places, including setting names.


/* 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;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure about this. It feels like it might be better to have explicit configuration for the home community of each group in the settings file. Or at least an option to do it explicitly.


/* Communities' attributes include the community_id and the coordinates */
private static Map<String, double[]> community_attribute = new HashMap<String, double[]>();

/* 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);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would replace array_counter with i * this.community_x_number + j.


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<String, double[]> 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<PATH_LENGTH; i++) {
c = local_roaming_selection();
p.addWaypoint(c);
}

this.lastWaypoint = c;
return p;
}

@Override
public CommunityBasedMovement replicate() {
return new CommunityBasedMovement(this);
}

/**
* Generate a random coordinates in the given community area.
* @param community_area
* @return

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete javadoc.

*/
protected Coord randomCoord(double[] community_area) {
assert community_area.length == 4 : "Community's coordinates have errors!";

double x = (rng.nextDouble()) * (community_area[2] - community_area[0])
+ community_area[0];
double y = (rng.nextDouble()) * (community_area[3] - community_area[1])
+ community_area[1];

return new Coord(x,y);
}

/**
* Decide the states of the node by the probabilities: local or roaming epoch
* @return Final destination
*/
protected Coord local_roaming_selection() {
if (((rng.nextDouble()) * 100) < (pi_l * 100)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why * 100?

return randomCoord(selected_community);
} else {

do {
rnd_i = rng.nextInt(community_attribute.size());
not_selected_community = community_attribute.get(community_id[rnd_i]);

}while((selected_community.equals(not_selected_community)));

return randomCoord(not_selected_community);
}

}

}