http://www.paper.edu.cn
基于 OMNeT++的传感器网络仿真1
操敏 1,李文锋 1,袁兵 1
1 武汉理工大学物流工程学院,湖北武汉 (430063)
E-mail:cm_991221@163.com
摘 要:本文介绍了 OMNeT++的组成和体系结构,详细论述了 OMNeT++编程的语法,并对
OMNeT++的建模过程作了较为深入的阐述。我们实现了在界面程序中为仿真配置运行参数,
并在 OMNeT++平台上对 LEACH 协议进行了仿真。
关键词:网络仿真 用户接口 无线传感器网络
中图分类号:TP391.9 A
1.引言
OMNeT++是 Objective Modular Network TestBed in C++的英文缩写,它是开源的基于
组件的模块化的开放网络仿真平台,是近年来在科学和工业领域里逐渐流行的一种优秀的网
络仿真平台。OMNeT++作为离散事件仿真器,具备强大完善的图形界面接口和可嵌入式仿真
内核,同 NS2,OPNET 和 JavaSim 等仿真平台相比,OMNeT++可运行于多个操作系统平台,可
以简便定义网络拓扑结构,具备编程,调试和跟踪支持等功能。OMNeT++主要用于通信网络
和分布式系统的仿真,目前最高版本为 OMNeT3.2p1 ]1[ 。
2.OMNeT++框架
2.1 OMNeT++组成
OMNeT++主要由六个部分组成:仿真内核库(simulation kernel library,简称Sim),
网络描述语言的编译器(network description compiler, nedc),图形化的网络编辑器
(graphical network description editor,GNED),仿真程序的图形化用户接口-Tkenv,
仿真程序的命令行用户接口-Cmdenv,图形化的向量输出工具-Plove。
Sim是仿真内核和类库,用户编写的仿真程序要同Sim连接,Sim在OMNeT++中占据最为核
心重要的地位。下面详细介绍的另外两重要组成部分。
1.网络描述(NED)语言
NED是模块化的网络描述语言。网络描述包括大量的对组件的描述,如通道,简单和复
合模块的类型。这些组件描述可用于各种不同的网络描述中。NED语言用来定义模型中的网
络拓扑结构,较为简单的网络拓扑可以使用GNED,但复杂网络的拓扑描述还应该用NED源文
件方式书写。
2.用户接口
OMNeT++的用户接口用于实现仿真程序的人机交互,OMNeT++允许模型内部机制对用户可
视化,也允许用户启动和终止仿真,并更改模型内部的变量。OMNeT++中的图形化接口是一
个用户工具,可方便用户了解模型内部的运行机制。
用户接口和仿真内核的交互是通过一个已定义的接口实现的。无需改变仿真内核,就可
以实现不同类型的用户接口。同样无需更改模型文件,仿真模型可在不同接口下运行。用户
可以在强大图形化用户接口下测试和调试仿真程序,并最后可在简单快速的用户接口中运
行,而且该接口支持批处理。
1 本课题得到国家自然科学基金项目(60475031)和湖北省青年杰出人才基金项目(2005ABB021)的资助
- 1 -
http://www.paper.edu.cn
目前OMNeT++支持两种用户接口,即Tkenv和Cmdenv。对仿真进行的测试和调试可以在
Tkenv接口下进行,Tkenv是一个简便易用的图形窗口化的用户接口,Tkenv支持跟踪,调试
和执行仿真的功能。它在执行仿真过程中的任意时刻都能够提供详细的状态信息。Tkenv的
主要特征有:各模块的文本输出有其独立的窗口,仿真过程中可以在Tkenv窗口中看到自传
消息,支持仿真动画,标记断点,具有检查窗口,可以检查和改变模型中的变量,执行过程
中仿真结果的图形化显示并且结果可以用柱状图和时间序列图显示,仿真可重新进行,快照
文件用于显示模型的详细信息。
Cmdenv接口用于实际的仿真实验,因为Cmdenv支持批处理。Cmdenv是一个简便的小型命
令行接口,执行速度快。它可以在所有操作系统平台上运行。Cmdenv可以一次批处理配置文
件中所有的仿真。
2.2 OMNeT++框架
OMNeT++具有模块化的结构,图1是OMNeT++仿真的高层体系结构 ]1[ 。
图1 OMNeT++仿真程序的体系结构
图1的箭头表示两组件之间的交互,图中共有5个箭头,表示了组件间的5种关系。
①执行模型和Sim:仿真内核管理将来的事件,当有事件发生时,仿真内核就调用执行模型
中的模块。执行模型的模块存储在Sim的main对象中。执行模型依次调用仿真内核的函数并
使用Sim库中的类。
②Sim和模型组件库:当仿真开始运行创建了仿真模型的时候,仿真内核就实例化简单模块
和其它的组件。当创建动态模块时,仿真内核也要引用组件库。实现在模型组件库中注册和
查寻组件也是Sim的功能。
③执行模型和Envir:ev对象作为Envir的一部分,是面向执行模型的用户接口。仿真模型使
用ev对象来记录调试信息。
④Sim和Envir:由Envir决定创建何种模型,Envir包含主要的仿真循环,并调用仿真内核以
实现必须的功能。Envir捕捉并处理执行过程中发生在仿真内核和或类库中的错误和异常。
⑤Envir和Tkenv,Cmdenv:Envir定义了表示用户接口的TOmnetApp基类,Tkenv和Cmdenv都
是TOmnetApp的派生类。main()函数是Envir的一部分,为仿真决定选用合适的用户接口类,
创建用户接口类的实例并执行。Sim和模型对ev对象的调用通过实例化TOmnetApp类进行。
Envir通过TOmnetApp和其它类的方法实现Tkenv和Cmdenv的框架和基本功能。
3.OMNeT++语法
OMNet++是面向对象的离散事件模拟工具,为基于进程式和事件驱动两种方式的仿
真提供了支持。OMNet++采用了混合式的建模方式,同时使用了 OMNet++特有的 ned(NEtwork
Discription,网络描述)语言和 C++进行建模。
3.1 NED 语言 ]1[
- 2 -
http://www.paper.edu.cn
NED 语言包含的组件:import 指令,通道定义,简单和复合模块定义,网络定义。此外,
NED 语言还可以定义自己的 message 格式。
1.import 指令:用于从其它的网络描述文件引入声明。在引入了一个网络描述之后,可以
使用该网络的组件,如通道,简单和复合模块等。
2.通道定义:定义通道有三个可选的参数,即 delay,error 和 datarate,这三个参数必
须是常量。delay 是传播延时,单位为秒。error 是位误码率,即错误传输一位的概率。
datarate 是通道的传输速率,单位为位/秒,用于计算包的传输时间。
3.简单和复合模块定义:在 ned 中,主要的实体是模块(module)。模块分为两种,一种是
普通模块(simple module),一种为复合模块(compound module)。模块有 gates,模块之
间通过门(gates)进行消息(message)传输。
⑴简单模块是其它模块的基础,它的定义需要声明其参数和门。简单模块名的首字母应当大
写,而参数和门的名称应当小写。
简单模块的算法可以访问其声明的参数,参数类型可以定义成 numeric,numeric
const(简写为 const),bool,sring 或者 xml。也可以不定义参数类型,缺省的参数类型为
numeric。
模块间连接的开始和终止点就是门。有两种门,即输入门和输出门。还可以使用门向量,
一个门向量包含多个门。
⑵复合模块是由一个和多个自模块组成的。子模块可以是简单模块,也可以是复合模块。同
简单模块一样,复合模块也有参数和门,除此之外,复合模块中还需声明个复合模块的子模
块和连接。
OMNeT++具有层次化的模块化结构 ]1[
]2[ ,最高层的模块称为系统模块或网络,该模块包
含一个或多个子模块,而子模块也可以有自己的子模块,因此可以在 OMNeT++用构建复杂的
系统模型,见图 2。
图 2 层次化模块结构
4.网络定义:网络定义声明仿真模型,模型是预先定义的模块类型的实例。在 NED 文件中
定义网络模型,可以定义多个网络并在配置文件中选择要仿真执行的网络。
3.2 简单模块算法实现
]1[
简单模块的算法通过 C++语言编写,OMNeT++使用 CSinpleModule 来直接或间接定义简
单模块,再用 Define_Module() 或 Define_Module_Like()宏来注册该简单模块。每个简单
模块都必须手动添加该宏,复合模块则由 OMNeT++自动添加。
CSimpleModule 有四个预先定义的成员函数:initialize()函数,handleMessage()函
数,activity()函数和 finish()函数。用户可以对该四个函数重新进行定义,一个简单模
块中不能同时有 handleMessage()和 activity()函数。
1) Initialize()函数:在初始化消息放入 FES(Future Event Set,未来事件集)后,
在执行前被调用,初始化成员变量。复合模块的初始化先于其子模块。
2) handleMessage()函数:handleMessage()的主要应用于:大规模的模拟环境,比如
说几千个 Simple Module,用户需要用 handleMessage()以省下用 activity()为每个模块划
分的栈空间;函数调用比协同程序切换快得多;对于需要维持较大的状态信息的模块或者是
- 3 -
http://www.paper.edu.cn
多状态的复杂的通信协议,handleMessage()较适用。采用 handleMessage()的优势有:占
用内存少,无需为简单模块分配独立的栈空间;执行速度快,采用 handleMessage()的劣势
有:本地变量无法存储状态信息;需要重载 initialize();模块设计时不太方便。
3) activity()函数:它使得用户可以象编写一个进程、线程一样编写一个简单模块。
等待消息、延缓执行时间等等。拥有这个函数的多个简单模块作为一系列协同程序协同执行,
又称之为协同多任务。手动设置模块栈空间,一般为 16k,如果模块存在递归或本地变量占
空 间 较 大 的 话 , 可 以 设 置 为 更 大 的 栈 空 间 。 采 用 activity() 的 优 势 有 : 无 需 重 载
initialize();可以将模块作为进程描述。采用 activity()的劣势有:有内存分配问题,
主要由于栈的手动分配,成千上万个 Simple Module 的分配造成内存不堪重负;运行时负载
过重,协同程序间的切换比普通函数调用慢了很多;不是一种较好的编程方式,使用
activity()会导致代码不可靠。
4) Finish()函数:循环结束后正常中止时被调用,模块的调用顺序刚好与 initialize()
相反。
在 OMNeT++中,事件在简单模块内部产生。初始化阶段,OMNeT++以 NED 构建网络,调
用所有模块的 initialize()函数。activity()和 handleMessage()用以实现模块的行为,在
事件处理时被调用。模拟成功结束时调用 finish()函数,它最典型的应用就是记录下一些
模拟时的统计信息。OMNeT 用 message 表示事件,有事件发生的模块就是收到消息的模块。
4.OMNeT++建模
4.1 建模流程
在完成消息格式、ned 和 c++代码以后,使用 opp_nmakemake 就可以直接生成 VC 的
makefile 文件。如果是类 unix 平台,用 opp_makemake 即可。使用命令 nmake –f Makefile.vc
编译完成后,得到一个可执行文件。为这个可执行文件添加一个配置文件交 omnetpp.ini,
就可以在任意机器上执行仿真过程,完全脱离仿真平台了。
OMNeT++仿真程序可在各种平台上运行:具备 GNU 工具的 Solaris, Linux(或其它类 Unix)
操作系统;Win32 操作系统和 CygWin32;Win32 操作系统和 Microsoft Visual C++。其中
CygWin 是 gcc 在 Win32 操作系统中的接口。同 NS2 等其它网络仿真工具相比, OMNeT++可
在 Win32 操作系统下安装和运行,使用方便,大大简化了 Linux 下的工作。
OMNeT++建模的流程见图 3 ]1[ :
图 3 OMNeT 仿真建模流程
- 4 -
http://www.paper.edu.cn
为了方便在 omnetpp.ini 文件中改动参数,我们用 VC6.0 编写了一个界面程序 ]5[ ,见
图 4。该界面程序可以直接修改 omnetpp.ini 配置文件的参数,可以简化仿真操作。
图 4 界面程序
该界面程序简化了 omnetpp.ini 文件的参数配置过程,从配置运行参数到编译、连接、
运行以及查看仿真结果都可以在一个界面上完成,大大简化了仿真工作。该界面输入各个参
数值后,点击“写 INI 文件”按钮,可以将输入的各个参数值写入 omnetpp.ini 文件。再点
击“编译与连接”按钮,可以执行 opp_nmakemake -f 和 nmake –f Makefile.vc 两个命
令,这样将生成 Makefile.vc 和相应的可执行文件。编译连接完成之后,点击“运行”按钮,
将直接调用生成的 exe 文件,同时打开 Tkenv 界面。程序运行完成之后,点击“仿真结果分
析按钮”,将打开 omnetpp.sca 这个标量文件,以显示仿真分析结果数据。
4.2 仿真实现
在 OMNeT++平台上,我们对无线传感器网络(wireless sensor networks,简称 WSNs)
的 LEACH(low energy adaptive clustering hierarchy)协议进行了仿真。LEACH 算法 ]4][3[
的核心思想是减少与基站直接通信的节点数量来达到节能的目。LEACH 协议按轮(round)
运行,每轮分为簇形成和簇稳定两个阶段。为了提高能量的利用率,应保证簇稳定阶段维持
较长的时间。
在簇形成阶段,首先随机选出部分传感器节点作为簇头,接着选出的簇头以 CDMA/CA
方式向其它普通节点发送广播消息,普通节点根据接收信号的强弱来选择自己的簇头加入,并
同该簇头一起形成簇,簇中的普通节点称为该簇的成员节点。
在稳定阶段中, 成为簇头节点的节点向其成员节点发送 TDMA(时分复用)帧,即将传输
时槽分配给其成员节点。簇中的成员节点在所分配的时隙内,把采集得到的数据传送给簇头,
簇头将簇内所有成员节点收集的数据进行数据融合后再发给 Sink 节点。图 5 是 LEACH 算
法描述的 WSNs 的工作原理。
- 5 -
http://www.paper.edu.cn
图 5 LEACH 算法下 WSNs 的工作模式
我们在 50×50 的仿真区域内布撒 50 个节点,在 OMNeT++平台上仿真实现了 LEACH
协议,见图 6。
图 6 LEACH 的仿真实现
5.结束语
本文详细介绍了 OMNeT++这个优秀的网络仿真平台,它主要用于离散事件的模拟。
OMNeT++相对其它网络模拟器来说,使用是较为简单的,但其使用方法仍然尤其特殊性和
复杂性。本文详细介绍了如何使用 OMNeT++,对其体系结构,编程语法以及建模过程都作了
详细介绍与深入剖析。然后我们还介绍了一个用于更改配置参数的界面程序,使用该界面程
序可以有效减少用 OMNeT++进行仿真的工作量,最后进行了 LEACH 协议的仿真实现。
- 6 -
http://www.paper.edu.cn
参考文献
[1] Andras Varga. OMNeT++ User Manual[EB/OL]. http://www.omnetpp.org/index.php
[2] C.Mallanda 等. Simulating Wireless Sensor Networks with OMNeT++[EB/OL].
http://csc.lsu.edu/sensor_web/simulator.html
[3] Wendi B.Heinzelman 等. Energy Efficient Communication Protocol for Wireless Microsensor Networks[A].
Proceedings of the 33rd Hawaii International Conference on System Sciences[C]. Jan, 2000.
[4] Wendi B.Heinzelman 等 . An Application Specific Protocol Architecture for Wireless Microsensor
Networks[J]. IEEE Transactions on Wireless Communications. 2002, 1 (4) : 660 - 670.
[5] 刘惊雷.Visual C++实用教程.北京:电子工业出版社,2005 年
Sensor Network Simulation based on OMNeT++
Min Cao WenFeng Li Bing Yuan
School of Logistics Engineering,
Wuhan University of Technology, Wuhan, HuBei China (430063)
1. Abstract
This paper introduces components and the architecture of OMNeT++, discusses the grammar of
OMNeT++ programming in detail, and demonstrates deeply the model creation in OMNeT++. We
implement an interface of configuring parameters for simulation with OMNeT++,and simulate the
LEACH protocol on OMNeT++ platform.
Keywords: Network Simulation User Interface Wireless SensorNetwork
- 7 -