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;
}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值