ONE源代码分析——movement2之MapBasedMovement

本文介绍了一种基于地图的移动模型(MapBasedMovement),该模型利用SimMap类定义地图边界及节点,Path类描述路径,MapNode类表示地图上的节点。文章详细分析了MapBasedMovement类的实现,包括路径生成算法、节点选择机制等。

MapBasedMovement是继承MovementModel基类的一个子类,同时也是很多子类的基类,我们先来看一下一个辅助类SimMap类。

SimMap类:

数据域:

Coord minBound,maxBound:标示最大最小的边界范围

ArrayList<MaoNode> nodes:地图上节点的列表返回

Map<Coord, MapNode> nodesMap:地图上节点对应的坐标

Coord offset:地图整体位置

函数域:

构造函数SimMap(Map<Coord, MapNode> nodes):this.offset = new Coord(0, 0),this.nodes = new ArrayList<MapNode>(nodes.values());

void translate(double dx, double dy):函数用于将nodes表中的节点、minBound、maxBound以及offset转换成(x, y)坐标值。


void setBound():根据nodes表中节点位置设置最大最小的边界范围。


接下来看一下另一个辅助类Path类。

Path类:

数据域:

List<Coord> coords:path的坐标

List<Double> speeds:各段路上的速度值

int nextWpIndex:下一个路径节点的序号


函数域:

构造函数Path()创建一个速度为0的path,Path(Path path)复制构造,Path(double speed)创建一个特定速度的path。


void setSpeed(double speed):为整个路径设置速度。


void addWaypoint(Coord wp):添加一个路径终点。


Coord getNextWaypoint():获取下一个路径节点。


接下来看一下辅助类MapNode。

MapNode类:

数据域:

Coord location:表示节点位置

Vector<MapNode> neighbors:表示邻居节点列表

int type:表示节点类型,可取值1~31


函数域:

构造函数MapNode(Coord location)以一个位置创建一个MapNode。


void addToList(MapNode node):如果node不存在于neighbors表,且不是该节点本身,将其加入邻居表。


好,现在我们来分析MapBasedMovement类。

MapBasedMovement类:

数据域:

SimMap Map:移动模型所使用的SimMap

MapNode lastMapNode:上一段path的终点或下一个初始点

int maxPathLength:可寻路的最多的map节点

int minPathLength:可寻路的最少的map节点

boolean backAllowed:当网络节点来到一个路口,是否可以选择原路返回

static final String MAP_SELECT_S = "okMaps":表示每个节点组选择的地图节点类型是可以满足节点组通过的。如果配置没有设置,所有地图节点考虑成可以的

int[] okMapNodeTypes:OK的地图文件的序号

int nrofMapFilesRead:已经读取的地图文件数量

static SimMap cachedMapFiles:防止上一个移动模型读取了相同的地图,没有加载就使用

static List<String> cachedMapFiles:之前已经被缓存的地图文件的名字(用于比较)


函数域:

构造函数MapBasedMovement(Settings settings)基于配置文件创建移动模型对象

MapBasedMovement(Settings settings, SimMap newMap, int nrofMaps)基于配置文件和不同的SimMap创建移动模型对象


void readOkMapNodeTypes(Settings settings):从配置文件中读取OK的地图节点类型


Coord getInitialLocation():随机返回一个在两个相邻地图节点之间的坐标


Path getPath():获取路径

详解:

Path p = new Path(generateSpeed()); //创建一条新的路径
MapNode curNode = lastMapNode; //当前地图节点
MapNode prevNode = lastMapNode; //前一个地图节点
MapNode nextNode = null; //下一个地图节点
List<MapNode> neighbors; //邻居表
Coord nextCoord; //下一个坐标

assert lastMapNode != null: "Tried to get a path before placement";

// start paths from current node 
p.addWaypoint(curNode.getLocation()); //为路径添加一个节点——当前地图点

int pathLength = rng.nextInt(maxPathLength-minPathLength) + 
minPathLength; //定义路径长度


for (int i=0; i<pathLength; i++) {
neighbors = curNode.getNeighbors();
Vector<MapNode> n2 = new Vector<MapNode>(neighbors);
if (!this.backAllowed) {
n2.remove(prevNode); // to prevent going back
}

if (okMapNodeTypes != null) { //remove neighbor nodes that aren't ok
for (int j=0; j < n2.size(); ){
if (!n2.get(j).isType(okMapNodeTypes)) {
n2.remove(j);
}
else {
j++;
}
}
}

if (n2.size() == 0) { // only option is to go back
nextNode = prevNode;
}
else { // choose a random node from remaining neighbors
nextNode = n2.get(rng.nextInt(n2.size())); //随机选择一个邻居作为下一路径点 
}

prevNode = curNode; //当前节点变成前一节点

nextCoord = nextNode.getLocation();
curNode = nextNode; //下一节点成为当前节点

p.addWaypoint(nextCoord);
}

lastMapNode = curNode;


return p;


MapNode selectRandomOkNode(List<MapNode> nodes)从OK的节点列表中随机选择并返回一个节点(如果okMapNodetypes被定义,那么必须保证参数列表中至少有一个OK的节点,防止无限循环)


SimMap readMap()从配置文件指定的位置读取仿真地图,将地图镜像,并移动地图的左上角到起点位置。


void checkMapConnectedness(List<MapNode> nodes)检查地图所有点是否可达。


void checkCoordValidity(List<MapNode> nodes)检查地图所有节点坐标在移动模型规定的最大最小值之内。


SimMap checkCache(Settings settings)检查地图缓存是否满足所需的地图文件。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ymaym

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值