/* * 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 . * */ package de.tud.kom.p2psim.impl.topology.movement; import java.util.HashMap; import java.util.Map; import java.util.Set; import de.tud.kom.p2psim.api.topology.movement.MovementInformation; import de.tud.kom.p2psim.api.topology.movement.MovementSupported; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tud.kom.p2psim.impl.util.stat.distributions.NormalDistribution; import de.tudarmstadt.maki.simonstrator.api.Randoms; import de.tudarmstadt.maki.simonstrator.api.Time; import de.tudarmstadt.maki.simonstrator.api.util.Distribution; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; /** * A movement Model that produces more realistic paths for mobile users, without * sharp edges or sudden motion changes. It is described in A Survey of * Mobility Models for Ad Hoc Network Research by Tracy Camp et al. * * The notation used in this class is the same as in the paper * * @author Bjoern Richerzhagen * @version 1.0, 05/31/2011 */ public class GaussMarkovMovement extends AbstractMovementModel { private double alpha; private double edgeThreshold = 20; private Distribution distribution_s = null; private Distribution distribution_d = null; private Map stateInfos; /** * * @param alpha */ @XMLConfigurableConstructor({ "alpha", "edgeThreshold" }) public GaussMarkovMovement(double alpha, double edgeThreshold) { this.alpha = alpha; if (alpha > 1 || alpha < 0) { throw new AssertionError( "For GaussMarkovMovement alpha has to be set between zero and one."); } this.edgeThreshold = edgeThreshold; this.stateInfos = new HashMap(); } @Override public void move() { if (distribution_s == null) { distribution_s = new NormalDistribution(0, 1); } if (distribution_d == null) { distribution_d = new NormalDistribution(0, 1); } Set comps = getComponents(); for (SimLocationActuator comp : comps) { // get old x and y PositionVector pos = comp.getRealPosition(); GaussMarkovMovementInfo inf = stateInfos.get(comp); double x_old = pos.getEntry(0); double y_old = pos.getEntry(1); // position within threshold? if (x_old < edgeThreshold || x_old > getWorldDimension(0) - edgeThreshold || y_old < edgeThreshold || y_old > getWorldDimension(1) - edgeThreshold) { if (x_old < edgeThreshold && y_old > getWorldDimension(1) - edgeThreshold) { // System.err.println(inf.d_bar + " bl to 45"); // inf.d_bar = 45; inf.d_bar = Math.PI * 0.25; } else if (x_old < edgeThreshold && y_old < edgeThreshold) { // System.err.println(inf.d_bar + " tl to 315"); // inf.d_bar = 315; inf.d_bar = Math.PI * 1.75; } else if (x_old < edgeThreshold) { // System.err.println(inf.d_bar + " l to 0"); // inf.d_bar = 0; inf.d_bar = 0; } else if (x_old > getWorldDimension(0) - edgeThreshold && y_old > getWorldDimension(1) - edgeThreshold) { // System.err.println(inf.d_bar + " br to 135"); // inf.d_bar = 135; inf.d_bar = Math.PI * 0.75; } else if (x_old > getWorldDimension(0) - edgeThreshold && y_old < edgeThreshold) { // System.err.println(inf.d_bar + " tr to 225"); // inf.d_bar = 225; inf.d_bar = Math.PI * 1.25; } else if (x_old > getWorldDimension(0) - edgeThreshold) { // System.err.println(inf.d_bar + " r to 180"); // inf.d_bar = 180; inf.d_bar = Math.PI; } else if (y_old < edgeThreshold) { // System.err.println(inf.d_bar + " t to 270"); // inf.d_bar = 270; inf.d_bar = Math.PI * 1.5; } else if (y_old > getWorldDimension(1) - edgeThreshold) { // System.err.println(inf.d_bar + " b to 90"); // inf.d_bar = 90; inf.d_bar = Math.PI * 0.5; } inf.d_old = inf.d_bar; } double s_n = alpha * inf.s_old + (1 - alpha) * inf.s_bar + Math.sqrt(1 - (alpha * alpha)) * distribution_s.returnValue(); if (s_n > comp.getMaxMovementSpeed() * getTimeBetweenMoveOperations() / Time.SECOND) { // Maximum speed s_n = comp.getMaxMovementSpeed() * getTimeBetweenMoveOperations() / Time.SECOND; } if (s_n < 0) { s_n = 0; } //System.out.println(inf.d_old + " " + inf.d_bar); double d_n = (alpha * inf.d_old + (1 - alpha) * inf.d_bar + Math .sqrt(1 - (alpha * alpha)) * distribution_d.returnValue()); // if (d_n < 0) { // d_n += 2 * Math.PI; // } // if (d_n >= 2 * Math.PI) { // d_n -= 2 * Math.PI; // } double x_n = x_old + inf.s_old * Math.cos(inf.d_old); double y_n = y_old - inf.s_old * Math.sin(inf.d_old); /* minus, because origin is in the upper left */ inf.d_old = d_n; inf.s_old = s_n; PositionVector newPos = new PositionVector(x_n, y_n); if (isValidPosition(newPos)) { updatePosition(comp, newPos); } } } @Override public void addComponent(SimLocationActuator component) { super.addComponent(component); GaussMarkovMovementInfo info = new GaussMarkovMovementInfo(); double rand = Randoms.getRandom(GaussMarkovMovement.class).nextDouble(); info.d_bar = rand * 2 * Math.PI; info.d_old = info.d_bar; info.s_bar = component.getMaxMovementSpeed() * rand * getTimeBetweenMoveOperations() / Time.SECOND; info.s_old = rand * component.getMaxMovementSpeed() * getTimeBetweenMoveOperations() / Time.SECOND; stateInfos.put(component, info); } /** * This allows to overwrite the distribution for directions * * @param distribution */ public void setDirectionDistribution(Distribution distribution) { this.distribution_d = distribution; } /** * This allows to overwrite the distribution for speed * * @param distribution */ public void setSpeedDistribution(Distribution distribution) { this.distribution_s = distribution; } /** * Movement State Information for this movement model * * @author Bjoern Richerzhagen * @version 1.0, 05/31/2011 */ private class GaussMarkovMovementInfo implements MovementInformation { public GaussMarkovMovementInfo() { // ntd } public double s_old = 0; public double d_old = 0; public double d_bar; public double s_bar; } }