Movement models代碼分析1--MovementModel,Path

movement.MovementModel
1.所有移動模型都是對其擴展
2.爲一個節點請求新路徑提供接口,並詢問何時可獲得下一條路徑

新的移動模型可以通過擴展MovementModel類來創建,覆寫至少getInitialLocation和getPath這兩種方法。
  • getInitialLocation方法:在模擬開始時,節點獲得初始位置
  • getPath方法:詢問節點將使用的新的路徑
   路徑是路標序列,節點以移動模型決定的速度從一個路標移動到另一個路標。MovementModel類也提供配置和產生統一速度和等待時間分配的能力。



最重要的是聲明中的三個條件
1.在子類中,至少有一個構造方法中含有{@link Settings}的參數和一個複製建構
2.在子類中,必須實現{@link #replicate()}方法,用來返回移動模型類的實例,此實例的參數與對象的參數相同
3.爲了使移動模型有用,至少要覆寫{@link #getInitialLocation()} 和 {@link #getPath()}這兩個方法
        public abstract Path getPath();
        public abstract Coord getInitialLocation();


在movement包中相關的類:
ActivenessHandler: 此類的對象告訴移動模型,屬於某個組的節點什麼時候是激活的,什麼時候不是。
Path:   多座標間的路徑


關鍵詞protected 被protected修飾的變量,可以被本類,本包中的其他類,和它的子類訪問。




*************************************************************************************************************

代碼分析

package movement;

import java.util.Random;
public static double random()
返回帶正號的 double 值,該值大於等於 0.0 且小於 1.0。返回值是一個僞隨機選擇的數,在該範圍內(近似)均勻分佈。

import core.Coord;

//Class to hold 2D coordinates and perform simple arithmetics and transformations

import core.DTNSim;
//Simulator's main class
import core.ModuleCommunicationBus;
//Intermodule communication bus. Works as a blackboard where modules can post data, subscribe to data changes and also poll for data values. This is fairly similar to Message class' property interface, but these values are shared for a node instead of message
import core.Settings;
//Interface for simulation settings stored in setting file(s).
import core.SimClock;
/ /Wall clock for checking the simulation time
import core.SimError; 

//Error in the simulation

/**
 * <P> Superclass for all movement models
 *  滿足三個條件:
 * 1.  All subclasses must contain at least a constructor(構造函數) with one {@link Settings} parameter and also a copy-constructor.
 * 2.   They must also implement the { @link #replicate()} method, which should return
 * an instance of the movement model class with same parameters as the object
 * (immutable fields can be shared, but mutable fields must be copied).</P>
 * 3.   To make a new movement model do something useful, also at least
 * { @link #getInitialLocation()} and { @link #getPath()} are worthwhile to 
 * override.</P>
 */
public abstract class MovementModel {
/** node's speed CSV (min, max) -setting id ({@value})*/
public static final String SPEED = "speed";
/** node's wait time CSV (min, max) -setting id ({@value})*/
public static final String WAIT_TIME = "waitTime";
/** default setting for speed distribution */
public static final double[] DEF_SPEEDS = {1,1};
/** default setting for wait time distribution */
public static final double[] DEF_WAIT_TIMES = {0,0};
/** MovementModel namespace (where world size and rng seed settings 
* are looked from ({@value})*/
public static final String MOVEMENT_MODEL_NS = "MovementModel";
/** world's size CSV (width, height) -setting id ({@value})*/
public static final String WORLD_SIZE = "worldSize";
/** movement models' rng seed -setting id ({@value})*/
public static final String RNG_SEED = "rngSeed";
/** common rng for all movement models in the simulation */
protected static Random rng; 
// 被protected修飾的變量,可以被本類,本包中的其他類,和它的子類訪問。rng是一個隨機產生的值 
private ActivenessHandler ah;
// Object of this class tell the movement models when a node belonging to a certain group is active and when not.
protected double minSpeed;
protected double maxSpeed;
protected double minWaitTime;
protected double maxWaitTime;

private int maxX;
private int maxY;
protected ModuleCommunicationBus comBus;


//前部分首先對變量進行初始化

// static initialization of all movement models' random number generator
static {
DTNSim.registerForReset(MovementModel.class. getCanonicalName());
reset();
}
//String java.lang.Class.getCanonicalName():Returns the canonical name of the underlying class as defined by the Java Language Specification
//以上對移動模型初始化

/**
* Checks that the minimum setting is not bigger than the maximum and
* that both are positive
* @param name Name of the setting
* @param min The minimum setting
* @param max The maximum setting
*/
private static void checkMinAndMaxSetting(String name,
double min, double max) {
if (min < 0 || max < 0) {
throw new SimError("MovementModel." + name + " (in Settings)" + 
" has a value less than zero ("+min+", "+max+")");
}
if (min > max) {
throw new SimError("MovementModel." + name + " (in Settings)" + 
" min is bigger than max ("+min+", "+max+")");
}
}
/** 
* Empty constructor for testing purposes.
*/
public MovementModel() {
super();
}
//MovementModel方法的重載
/**
* Creates a new MovementModel based on a Settings object's settings.
* @param settings The Settings object where the settings are read from
*/
public MovementModel( Settings settings) {
double[] speeds;
double[] times;
ah = new ActivenessHandler(settings);
if (settings.contains(SPEED)) {
speeds = settings.getCsvDoubles(SPEED, 2);
}
else {
speeds = DEF_SPEEDS;
}
minSpeed = speeds[0];
maxSpeed = speeds[1];
checkMinAndMaxSetting(SPEED,minSpeed,maxSpeed);

if(settings.contains(WAIT_TIME)) {
times = settings.getCsvDoubles(WAIT_TIME, 2);
}
else {
times = DEF_WAIT_TIMES;
}
minWaitTime = times[0];
maxWaitTime = times[1];
checkMinAndMaxSetting(WAIT_TIME,minWaitTime,maxWaitTime);
settings.setNameSpace(MOVEMENT_MODEL_NS);
int [] worldSize = settings.getCsvInts(WORLD_SIZE,2);
this.maxX = worldSize[0];
this.maxY = worldSize[1];

settings.restoreNameSpace();
}
//以上將setting中的參數取出:速度最大最小值,等待時間最大最小, 和仿真空間x,y軸最大值(注意檢查)
//滿足了條件1

/**
* Copyconstructor. Creates a new MovementModel based on the given
* prototype.
* @param mm The MovementModel prototype to base the new object to 
*/
public MovementModel(MovementModel mm) {
this.maxSpeed = mm.maxSpeed;
this.minSpeed = mm.minSpeed;
this.maxWaitTime = mm.maxWaitTime;
this.minWaitTime = mm.minWaitTime;
this.maxX = mm.maxX;
this.maxY = mm.maxY;
this.ah = mm.ah;
this.comBus = null;
}

/**
* Returns the largest X coordinate value this model uses
* @return Maximum of X coordinate values
*/
public int getMaxX() {
return this.maxX;
}

/**
* Returns the largest Y coordinate value this model uses
* @return Maximum of Y coordinate values
*/
public int getMaxY() {
return this.maxY;
}
//以上創建新的移動模型 (複製建構)
//條件1

/**
* Generates and returns a speed value between min and max of the 
* {@link #WAIT_TIME} setting.
* @return A new speed between min and max values 
*/
protected double generateSpeed() {
if (rng == null) {
return 1;
}
return (maxSpeed - minSpeed) * rng.nextDouble() + minSpeed;
}
//public double nextDouble()
返回下一個僞隨機數,它是取自此隨機數生成器序列的、在 0.01.0 之間均勻分佈的 double
/**
* Generates and returns a suitable waiting time at the end of a path.
* (i.e. random variable whose value is between min and max of the 
* {@link #WAIT_TIME} setting).
* @return The time as a double
*/
protected double generateWaitTime() {
if (rng == null) {
return 0;
}
return (maxWaitTime - minWaitTime) * rng.nextDouble() + 
minWaitTime;
}

//以上利用隨機數產生速度和等待時間

/**
* Returns a new path by this movement model or null if no new path could
* be constructed at the moment (node should wait where it is). A new
* path should not be requested before the destination of the previous
* path has been reached.
* @return A new path or null
*/
public abstract Path getPath();
/**
* Returns a new initial placement for a node
* @return The initial coordinates for a node
*/
public abstract Coord getInitialLocation();

// 以上兩種方法需要在子類中覆寫
//條件3
 
/**
* Returns true if this node is active at the moment (false if not)
* @return true if this node is active (false if not)
*/
public boolean isActive() {
return  ah.isActive();
}
//節點當前是否激活
/**
* Returns a sim time when the next path is available. This implementation
* returns a random time in future that is {@link #WAIT_TIME} from now.
* @return The sim time when node should ask the next time for a path
*/
public double nextPathAvailable() {
return SimClock.getTime() + generateWaitTime();
}
//返回允許下一條路徑的時間
/**
* Sets the module communication bus for this movement model
* @param comBus The communications bus to set
*/
public void setComBus(ModuleCommunicationBus comBus) {
this.comBus = comBus;
}
// 爲這個移動模型設置模塊通信總線
/**
* Returns the module communication bus of this movement model (if any)
* @return The communications bus or null if one is not set
*/
public ModuleCommunicationBus getComBus() {
return this.comBus;
}
//  返回
/**
* Returns simply the name of the movement model class
* @return the name of the movement model class
*/
public String toString() {
return this.getClass().getSimpleName();
}
//返回移動模型類的簡單名字 Returns the simple name of the underlying class as given in the source code. Returns an empty string if the underlying class is anonymous
         /**
* Creates a replicate of the movement model.
* @return A new movement model with the same settings as this model
*/
public abstract MovementModel replicate();

//建立一個移動模型的複製
條件2
/**
* Resets all static fields to default values
*/
public static void reset() {
Settings s = new Settings(MOVEMENT_MODEL_NS);
if (s.contains(RNG_SEED)) {
int seed = s.getInt(RNG_SEED);
rng = new Random(seed);
}
else {
rng = new Random(0);
}
}
}
//重置

小結:
最重要的是聲明中的三個條件
1.在子類中,至少有一個構造方法中含有{@link Settings}的參數和一個複製建構
2.在子類中,必須實現{@link #replicate()}方法,用來返回移動模型類的實例,此實例的參數與對象的參數相同
3.爲了使移動模型有用,至少要覆寫{@link #getInitialLocation()} 和 {@link #getPath()}這兩個方法

由於沒有看core中的代碼,有些類的功能不是很清楚,列出來,有空了看
ModuleCommunicationBus
ActivenessHandler
DTNSim
Coord



movement.Path.java


import java.util.ArrayList;
//ArrayList() 構造一個初始容量爲 10 的空列表。
import java.util.List ;
// List 組件爲用戶提供了一個可滾動的文本項列表。
import core.Coord ;

/**
 * A Path between multiple Coordinates.
 */
public class Path  {
/** coordinates of the path */
private List<Coord> coords;   
/** speeds in the path legs */
private List<Double> speeds;
private int nextWpIndex;
/**
* Creates a path with zero speed.
*/
public Path() {
this.nextWpIndex = 0;
this.coords = new ArrayList <Coord>();
this.speeds = new ArrayList<Double>(1);     //Constructs an empty list with the specified initial capacity.
}
//
/**
* Copy constructor. Creates a copy of this path with a shallow copy of
* the coordinates and speeds.
* @param path The path to create the copy from
*/
public Path(Path path) {
this.nextWpIndex = path.nextWpIndex;
this.coords = new ArrayList<Coord>((ArrayList<Coord>)path.coords);
this.speeds = new ArrayList<Double>((ArrayList<Double>)path.speeds);
}
/**
* Creates a path with constant speed
* @param speed The speed on the path
*/
public Path(double speed) {
this();       //Creates a path with zero speed
setSpeed(speed);
}
/**
* Sets a constant speed for the whole path. Any previously set speed(s)
* is discarded.
*/
public void setSpeed(double speed) {
this.speeds = new ArrayList<Double>(1);
speeds.add(speed);   //Appends the specified element to the end of this list (optional operation)
}
/**
* Returns a reference to the coordinates of this path 
* @return coordinates of the path
*/
public List<Coord> getCoords() {
return this.coords;
}
/**
* Adds a new waypoint to the end of the path.
* @param wp The waypoint to add
*/
public void addWaypoint(Coord wp) {
assert this.speeds.size() <= 1 : "This method should be used only for" +
" paths with constant speed";
this.coords.add(wp);
}
/**
* Adds a new waypoint with a speed towards that waypoint
* @param wp The waypoint
* @param speed The speed towards that waypoint
*/
public void addWaypoint(Coord wp, double speed) {
this.coords.add(wp);
this.speeds.add(speed);
}
/**
* Returns the next waypoint on this path
* @return the next waypoint
*/
public Coord getNextWaypoint() {
assert hasNext() : "Path didn't have " + (nextWpIndex+1) + ". waypoint";
return coords.get(nextWpIndex++);
}
/**
* Returns true if the path has more waypoints, false if not
* @return true if the path has more waypoints, false if not
*/
public boolean hasNext() {
return nextWpIndex < this.coords.size();
}
/**
* Returns the speed towards the next waypoint (asked with
* {@link #getNextWaypoint()}. 
* @return the speed towards the next waypoint
*/
public double getSpeed() {
assert speeds.size() != 0 : "No speed set"; 
assert nextWpIndex != 0 : "No waypoint asked";
if (speeds.size() == 1) {
return speeds.get(0);
}
else {
return speeds.get(nextWpIndex-1);
}
}
/**
* Returns a string presentation of the path's coordinates
* @return Path as a string
*/
public String toString() {
String s ="";
for (int i=0, n=coords.size(); i<n; i++) {
Coord c = coords.get(i);
s+= "->" + c;
if (speeds.size() > 1) {
s += String.format("@%.2f ",speeds.get(i));  //Returns a formatted string using the specified format string and arguments
}
}
return s;
}
public List<Double> getSpeeds() {
return this.speeds;
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章