Veins教程04 - Veins介绍
Intro to Veins
有了对SUMO和OMNet++的基础了解,接下来主要学习使用Veins。
VANETs
使用Veins需要对车联网有一定了解
在纯V2V网络中,由于通信距离有限(离车300米范围内),路广车少的地方难以有效果;并且要实现长距离的通信必须实现车车之间的多跳路由。参见Collision-Avoidance-in-VANETs第2页
而在V2V和V2I的混合网络中,有RSU(Roadside Unit)的帮助,车车之间可以实现长距离通信。工作模式为:(事故)车辆同时发送warning message给范围内其他车辆以及RSU,如果其他车辆先收到来自事故车辆的warning message而不是来自RSU的,则将该message发送范围内的RSU转发。换句话说,RSU的覆盖范围不是100%,所以没有覆盖的区域由V2V传递信息。参见Collision-Avoidance-in-VANETs第33页
Why Veins
Veins用于V2V的仿真,并且由于Veins也提供RSU的框架,Veins也用V2I的仿真。可以说Veins侧重V2V/V2I hybrid。
Learn From The Example
对Veins内置例子进行深入理解
Run the simulation
开始仿真后,可以发现小车源源不断的从地图右下角某处生成并沿固定路线行进。某一时刻突然停顿并出现很多蓝线,蓝线代表消息传输;同时有一辆小车变成红色,红色代表改小车已经十秒钟没有移动了,即堵塞了;然后随着蓝线上的蓝色圆形移动,逐渐有小车变成绿色,蓝色圆形为消息,绿色小车为收到消息(准确说是确认)。
随着蓝线不断的生成,消息不断传输。如果仔细观察右上角的时间,消息传输的过程只持续了几毫秒。然后所有小车短暂的移动了,紧接着又开始传输信息。这是因为src/veins/modules/application/traci/TraCIDemo11p.cc
定义了小车收到消息后大约两秒将此消息转发给其他小车
,也就是V2V消息多跳传播。
随着以上过程不管重复,越来越多小车变绿,但仍有些小车是白色,是因为V2V传播消息无法穿透建筑,所以被建筑挡住的小车无法收到消息。不过随着多跳传播的深入,白色小车也收到消息。
默认的RSU只有转发转发信息的功能
Files
接下来了解examples文件夹内各个文件的作用。
- antenna.xml 车辆天线配置,可以不修改
- config.xml 物理层无线电传播相关参数。默认的配置是信号穿过建筑有衰减,前期如果不需要这个配置,可以将
db-per-cut
和db-per-meter
都改成0 - erlangen.launchd.xml 与SUMO的通信,不可更改
- erlangen.net.xml 通过之前对SUMO的学习知道,
.net.xml
是地图文件,在项目中需要自定义 - erlangen.poly.xml
poly.xml
文件记录地图中建筑信息的文件 - erlangen.rou.xml
.rou.xml
是交通文件,在项目中需要自定义 - erlangen.sumo.cfg
sumo.cfg
是SUMO的配置文件,在项目中需要自定义;与之前学习SUMO中的.sumocfg
文件一样 - RSUExampleScenario.ned 网络拓扑结构的文件,通过这个文件逐渐深入学习
- omnetpp.ini 配置文件,用于修改参数
主体的源文件比即.ned
和.cc
文件在同级的src
目录下。
omnetpp.ini
通过对OMNet++的学习,可以知晓omnetpp.ini
文件中配置项的生效位置,参看注释可知
- TraCIScenarioManager parameters 与SUMO的通信配置
- RSU SETTINGS 总体参数
- App Layer 应用层相关参数
- NIC-Settings MAC层相关参数
- Mobility 移动驱动层相关参数
- Annotation 注解参数,注解就是建筑图形,draw改为false则不画出图形
- Obstacle 障碍物(建筑)配置的文件位置
参数调整暂不做深入介绍
Dig into Files
Veins的Q&A中提到可以生成NED文档来查看模块及用法,但是实际过程中会出错。不过文档本质就是注释和函数名,直接查看文件效果一样。定义功能的cpp文件直接看.h
即可了解接口。
从RSUExampleScenario.ned
开始逐级往上,读懂代码并了解其用法。
点开RSUExampleScenario.ned
可知网络主要继承于Scenario
除了继承的Scenario
,RSUExampleScenario
还定义了一个RSU
,也就是前文说的路侧件。
后文分别从这两个方向网上逐级深入
Scenario
Scenario
提供预制的Annotations
,World
,Manager
,Obstacles
,ConnectionManager
和Node
模块。其中Node
就是车辆模块。
Annotations
标注注解,暂不深入
World
提供一些整个项目可用的函数,暂不深入
Manager
这个是与sumo-launchd.py
脚本交互的类,实现与SUMO通信。主要是对小车的仿真。主要的的函数实现在src/veins/modules/mobility/traci/TraCICommandInterface.cc
文件内;与SUMO交互的接口函数在同目录下的TraCIConnection.cc
内。
如果想要小车实现与Example一致的源源不断生成的效果,在
netedit
中添加vehicles
时需要选择flow
。
Obstacles
ObstacleControl即障碍的控制类。障碍会阻碍信号传播,均为多边形(polygon)。相关类文件在src/veins/modules/obstacle/
内,障碍的位置通过前文提到的erlangen.poly.xml
定义。
config.xml
中的obstacles
标签下定义了信号传输的衰减,默认的设置会导致信号穿过建筑后衰减为0,这解释了为什么前文运行例子的时候有些小车没有及时收到信息。
Obstacles就是建筑,因此需要
.pol.xml
。
Node (Car)
Node是一个元素类型为Car的数组,也就是仿真需要的所有车辆。
这里的Node和
src/veins/nodes
不是一个概念,后者是拓扑网络中的各个模块
Car有三个模块分别是
- appl 应用层
- nic MAC层
- veinsmobility 移动驱动层
其中nic定义了上下层的接口,可以不作修改
而veinsmobility定义了底层,包括位置速度参数等,定义函数比如获取速度,前往下一个坐标等,可以修改/替换,至少需要实现IMobility
这个接口
例子中的apply应用层是TraCIDemo11p.cc
只是定义了几个简单的消息处理函数,开发中需要自己添加其他功能
RSU
打开RSU.ned
可知RSU也分为
- appl 应用层,通过默认参数定义成
TraCIDemoRSU11p
,其cpp文件为src/veins/modules/application/traci/TraCIDemoRSU11.cc
,也只是定义了简单的消息处理函数 - nic MAC层,与Car一致
- mobility 移动驱动层,通过
BaseMobility
定义成静态非移动物件
Your Own Project
推荐通过修改而非新建来实现自己的项目。而通过上文的学习可知,主要需要修改的三个地方
- 地图/道路/障碍文件
- 小车的应用层
- RSU的应用层
逐步实现
SUMO Related XML files
修改道路等文件,可以手动创建xml文件,参考连接
导入真实地图更为常用,可以快速获取xml文件,参看之前的SUMO教程。注意,.rou.xml
文件需要手动通过netedit生成;.sumocfg
也需要参考erlangen.sumo.cfg
编写。
记得修改
omnetpp.ini
中的启动文件
Hints
记录以下要点
- 地图中的左上角(也就是
world
等模块的位置)对应netedit打开时的左上角。而地图的显示范围由omnetpp.ini
中的playgroundSize
来定义,因此如果真实地图范围太大而路线离左上角太远,需要手动调整playgroundSize
(增大)。小车的生成位置必须在playgraound内。 - 必须把
.pol.xml
中的additional
标签手动调整为shapes
才可以正确显示建筑,参考例子中erlangen.pol.xml
。 - 例子提供的
config.xml
定义了最基础的Obstacles
模块,只支持building
这个类型的障碍。因此要么修改config.xml
使其支持OSMWebWizard
自动生成的.pol.xml
中的各种建筑类型,要么手动把所有建筑(poly
标签)修改为building
。 - 如果真实地图太大,建筑过多,TraCI连接会中断,无法仿真,因此尽量避免过大的地图范围,或者在
.pol.xml
中手动删掉不重要区域的建筑。 - 即使建筑数量不多,有些异常建筑无法导入,需要排查删除。
- 这里可以借助
netedit
快捷查看异常建筑:打开netedit
后导入道路文件.net.xml
和建筑文件.pol.xml
,进入delete
模式删除大型,覆盖其他建筑的建筑。最后记得导出保存。
- 这里可以借助
Appl - Cars
下章讲