omnet++ 快速入门 | 计算机网络仿真 | omnet++ 入门教程

omnet

具体实现官方有很多, 主要是一些概念比较不太好懂

1 网络仿真软件综述

01 wsn仿真软件

看博客: wsn simulator

02 为什么使用omnet

  1. 简单易用
  2. 提供强大的GUI
  3. 有支持团队不断在更新维护

03 学习资料

omnet++:https://omnetpp.org/documentation/
C++: CPrimer 中文版

04 目标

  1. 讲omnet的基本使用
    1. 使用ned进行仿真网络结构的定义
    2. omnet中模块的概念
  2. 从头带大家实现一个有线的tictoc 和 一个无线的tictoc

2 omnet介绍

1 omnet安装与启动

  1. 安装必须进行的步骤
    1. 下载OMNeT : 下载地址
    2. 将存档解压缩到新文件夹中。
    3. 打开mingw.cmd 键入./configure和后make (这步可能要30分钟左右)
    4. 将path/to/OMNeT/build添加path/to/OMNeT/build目录到PATH环境变量中。
    5. 输入omnetpp确保安装正常。预计OMNeT ++开发环境将启动。

注: (原则上不需要下载任何东西, 都是包括在安装包中的, 包括Qt环境,编译器mingw等)
有关更多安装说明, 请访问omnet installGuide

  1. 安装完成后, 打开mingwenv.cmd, 输出omnetpp, 即可打开omnetIDE
    在这里插入图片描述
  2. 选择工作目录, 打开后界面如下所示
    在这里插入图片描述

2 使用omnet仿真的一般步骤

使用omnet仿真

主要有三步:

  1. 使用ned(network description)定义网络拓扑结构
  2. 利用C++编写实现网络的各种行为
  3. 编写配置文件指定网络参数, 利用配置文件启动项目

3 新建项目

File->New-Project->Omnet++Project 来新建项目, 项目新建后, 我们可以看到src, simulation文件夹

  • simulation: 存放项目配置文件

    我们在配置文件中指定想模拟的网络, 网络中节点的位置等

  • src: 存放所有源代码, 包括ned文件, C++源文件等

关于所有文件夹的作用看: https://doc.omnetpp.org/omnetpp/manual/#cha:ned-lang

3 定义仿真网络的拓扑结构

使用omnet进行仿真, 我们首先需要去定义网络的拓扑结构

01 新建一个空的 network

src目录下, 我们新建一个network , 选择one item , 此时我们就有了一个网络,当然现在里面什么也没有, 点击Design标签, 可以以GUI的形式查看ned文件当前的内容

02 Module的概念

01-Module的概念

逻辑上, omnet++中的module就相当于C++中的类,并且在模块中可以定义属性,我们用module实例化出来的模块对象, 又可以放到其他的模块中

代码上, omnet++中的module最终就是一个C++中的类,在定义网络的行为时, 我们需要用到他的属性,参数等等

  1. 在omnet中, 网络中的所有东西(如一个节点, 服务器等)都以module形式定义
  • 最低层的模块称为 简单模块(simple Module)
  • 模块可以添加到复合模块(compound module)
  • 模块之间可以相互嵌套, 嵌套的层级没有限制
  • 模块之间可以定义继承关系

一个节点, 很多个节点, 一块网络, 都可以是一个模块
network本质上就是一个复合模块

在这里插入图片描述

02-Module Type的定义步骤

一个模块的定义分为3个步骤

  1. 在ned文件中定义
  2. 使用C++继承omnet的cModule类cSimpleModule类, 定义一个Module类
  3. 将ned文件中定义的Module与C++中定义的Module联系起来
1. ned文件中定义

定义一个复合模块的一般语法如下, 所有的sections都为可选的

module Host
{
   types:  //定义模块类型(在submodules中使用),信道类型(在connections中使用)等
       ...
   parameters:  //定义该模块的参数, 如传输速率,节点个数等
       ...
   gates:   // 定义该模块的输入和输出口及个数
       ...
   submodules: // 定义子模块实例
       ...
   connections: // 定义子模块间的链接方式
       ...
}

定义一个简单模块的语法如下:

simple Host
{
       ...
   parameters:  //定义该模块的参数, 如传输速率等
       ...
   gates:   // 定义该模块的输入和输出口及个数
       ...
  }
2. C++文件定义

对于简单模块我们继承cSimpleModule
对于复合模块我们继承cModule类, 来定义一个C++ Module类

#include <omnetpp/csimplemodule.h>

class ExampleModule: public omnetpp::cSimpleModule {
public:
    ExampleModule();
    virtual ~ExampleModule();
};

Define_Module(ExampleModule);
3. 将C++文件与ned文件联系起来

在类定义的后面, 添加Define_Module(模块名);, 将模块与指定的C++类联系起来

#include <omnetpp/csimplemodule.h>

class ExampleModule: public omnetpp::cSimpleModule {
public:
    ExampleModule();
    virtual ~ExampleModule();
};

Define_Module(ExampleModule);
03-元数据注释 (属性)

NED properties are metadata annotations that can be added to modules, parameters, gates, connections, NED files, packages, and virtually anything in NED. @display, @class, @namespace, @unit, @prompt, @loose, @directIn are all properties that have been mentioned in previous sections, but those examples only scratch the surface of what properties are used for.

Using properties, one can attach extra information to NED elements. Some properties are interpreted by NED, by the simulation kernel; other properties may be read and used from within the simulation model, or provide hints for NED editing tools.

Properties are attached to the type, so one cannot have different properties defined per-instance. All instances of modules, connections, parameters, etc. created from any particular location in the NED files have identical properties.

下面是一个使用元数据注解的例子

@namespace(foo);  // file property

module Example
{
    parameters:
       @node;   // module property
       @display("i=device/pc");   // module property
       int a @unit(s) = default(1); // parameter property
    gates:
       output out @loose @labels(pk);  // gate properties
    submodules:
       src: Source {
           parameters:
              @display("p=150,100");  // submodule property
              count @prompt("Enter count:"); // adding a property to a parameter
           gates:
              out[] @loose;  // adding a property to a gate
       }
       ...
    connections:
       src.out++ --> { @display("ls=green,2"); } --> sink1.in; // connection prop.
       src.out++ --> Channel { @display("ls=green,2"); } --> sink2.in;
}
04-Channel(信道)

在ned文件中, 我们可以定义信道, 定义的一般语法如下

channel 信道名 extends 要继承的信道   // requires a CustomChannel C++ class
{
...信道属性...
}

大多数情况下我们不用去定义信道, omnet++自带了三个信道ned.IdealChannel, ned.DelayChannelned.DatarateChannel
详细请看:https://doc.omnetpp.org/omnetpp/manual/#sec:ned-lang:channels

我们也可以直接在connections中直接写出信道的属性, 省去了定义信道的步骤
在定义不同

05-配置文件

定义在parameters 中的属性, 在配置文件.ini中指定

03 几个例子

omnet++根目录的sample目录下官方提供了许多例子供我们参考, 这里挑选几个较为典型的例子

01 AHOLA
02 tictoc
03 SimpleNode 和 Sink

我们先来看一个模块, 这是我做RIMAC时定义的一个节点, SimpleNode

//Simple Node 模块
//定义普通节点拥有的参数
package RIMAC.simplenode;


simple SimpleNode
{
    parameters:
    	 double x @unit(m);  
    	 double y @unit(m);
    	double txRange @unit(m);    //数据传输距离
    	double senRange @unit(m);   //数据感知距离 
		double Twait @unit(s);    //事件等待时间
//    	double bitRate; //传输速率
		double animationHoldTimeOnCollision @unit(s);  //碰撞时动画持续时间
		volatile double frameTime = uniform(0.5s, 1.5s) @unit(s); //一帧的时间
		double sleepTime @unit(s);  //睡眠时间
		double sendConsumption   @unit(W);   //发送能耗
        double recvConsumption  @unit(W);  //接受能耗
        double sleepConsumption  @unit(W);  //睡眠能耗
        double idleConsumption   @unit(W);  //空闲能耗
		double energy @unit(J);  //初始能量
		int packetSize @unit(B);
    	@display("p=$x,$y");
    	@class(RIMAC::simpleNode);
	    @signal[energyLeft](type="double");
    	@statistic[energyLeftStat](title="energyLeft"; source="energyLeft"; record=vector,stats);

    	
    gates:
        input in @directIn;
}

Sink定义

package RIMAC;
import RIMAC.simplenode.SimpleNode;
simple Sink extends SimpleNode
{
    parameters:
     	@class(RIMAC::Sink);
        @display("p=$x,$y;i=device/terminal;r=$txRange");

    	@signal[e2etd](type="double");
		@statistic[e2etdStat](title="e2etd"; source="e2etd"; record=vector,stats);
    	@signal[ae2etd](type="double");
		@statistic[ae2etdStat](title="ae2etd"; source="ae2etd"; record=vector,stats);

}

4 控制网络仿真时的行为

01 omnet仿真原理

01-离散事件模拟
  1. 离散事件系统(Discrete Event System)是指事件发生在时间线中离散的部分, 对于计算机网络而言正像是如此

  2. 离散事件模拟系统通过在称为FES (Future Event Set) or FEL (Future Event List) 的 数据结构中保存未来事件的集合来实现

  3. omnet++底层使用了 二叉堆实现的优先级队列事件循环(Eventloop) 来实现了这一套模拟机制
    在这里插入图片描述

02-omnet事件循环

启动仿真后, 事件执行的伪代码如下

初始化(initialize) -- 包括构建模型,添加初始化事件到FES中

while (FES不为空 && 仿真未结束)
{
    从FES中取出事件
    t := 该事件发生时间
    执行事件
    (事件执行过程中,可能往FES中添加事件, 也可能往FES中删除事件)
}
结束仿真 (写入统计数据, etc.)

02 网络的初始化和结束原理

omnet网络的整个过程如下

perform simulation run:
    build network
      (i.e. the system module and its submodules recursively)
    insert starter messages for all submodules using activity()
    do callInitialize() on system module
        enter event loop // (described earlier)
    if (event loop terminated normally) // i.e. no errors
        do callFinish() on system module
    clean up

callInitialize和callFinish的伪代码如下


callInitialize()
{
    call to user-defined initialize() function
    if (module is compound)
        for (each submodule)
            do callInitialize() on submodule
}

callFinish()
{
    if (module is compound)
        for (each submodule)
            do callFinish() on submodule
    call to user-defined finish() function
}
01-模块的初始化

从上面的执行过程可知, 模块是有初始化事件的, 我们通过父类cSimpleModuleinitialize()方法来进行初始化,

1.window–>
2.preferrence–>
3.general–>
4.keys–>
来添加重载快捷键
在这里插入图片描述

模块调试:
EV<<“initialize!!!”<<"("<<x<<","<<y<<")"<<endl;

02-模块的多阶段初始化

可以重写两个方法来进行多阶段的初始化,在numInitStages 中返回阶段的个数
一般来说,我们在第一个初始化阶段进行变量赋值等操作, 后面的阶段可以进行周期计算等

virtual void initialize(int stage);
virtual int numInitStages() const;
03-模块的结束

模块通过调用finish()来进行仿真结束的工作

03 消息的发送与接收

消息的发送由 sendXXX 系列函数完成, 消息的接收基本都由handleMessage完成

1. 默认的消息cMessage类

cMessage类是所有消息类的父类, 我们可以自定义一个消息类(当然必须继承cMessage类), 也可以直接使用这个类

  1. 构造函数:
    1.  cMessage (const char *name=nullptr, short kind=0) 
      

cMessage API reference

1. sendXXX(-)

Message sending.
virtual void send (cMessage *msg, int gateid)
virtual void send (cMessage *msg, const char *gatename, int gateindex=-1)
virtual void send (cMessage *msg, cGate *outputgate)
virtual void sendDelayed (cMessage *msg, simtime_t delay, int gateid)
virtual void sendDelayed (cMessage *msg, simtime_t delay, const char *gatename, int gateindex=-1)
virtual void sendDelayed (cMessage *msg, simtime_t delay, cGate *outputgate)
virtual void sendDirect (cMessage *msg, cModule *mod, const char *inputGateName, int gateIndex=-1)
virtual void sendDirect (cMessage *msg, cModule *mod, int inputGateId)
virtual void sendDirect (cMessage *msg, cGate *inputGate)
virtual void sendDirect (cMessage *msg, simtime_t propagationDelay, simtime_t duration, cModule *mod, const char *inputGateName, int gateIndex=-1)
virtual void sendDirect (cMessage *msg, simtime_t propagationDelay, simtime_t duration, cModule *mod, int inputGateId)
virtual void sendDirect (cMessage *msg, simtime_t propagationDelay, simtime_t duration, cGate *inputGate)

2. handleMessage(Msg *)

handleMessage()
在这里插入图片描述

3. ScheduelAt() 自消息的发送

scheduelAt()
在这里插入图片描述

例子阅读

官方 19 个 tictoc

仿真主要参考的资料

  1. 我们不知道一个函数的作用的时候, 绝大多数情况下, 都是去查cSimpleModulle
    cSimpleModule

  2. 其次会去 SimulationManual 中查, 里面会有一些实际应用的例子

5 状态的定义(如果有时间的话)

01 睡眠实现

  • 42
    点赞
  • 352
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
目 录 第一章 无线传感器网络概述 6 概述 6 1.1 NS-2 6 1.2 OPNET 6 1.3 SensorSim 7 1.4 EmStar 7 1.5 GloMoSim 7 1.6 TOSSIM 7 1.7 PowerTOSSIM 8 第二章 OMNET++简介 9 概述 9 2.1 OMNeT++框架 9 2.1.1 OMNeT++组成 9 2.1.2 OMNeT++结构 10 2.2 OMNeT++的安装 11 2.3 OMNeT++语法 12 2.3.1 NED语言 12 2.3.1.1 NED总概述 12 2.3.1.2 Ned描述的组件 13 2.3.1.3函数 15 2.3.2 简单模块 17 2.3.2.1 OMNET++中离散事件 17 2.3.2.2 包传输模型 17 2.3.2.3定义简单模块 18 2.3.2.4 简单模块中的主要成员函数 20 2.3.3 消息 21 2.3.3.1 cMessage类 21 2.3.3.2 消息定义 21 2.3.3.3 消息的收发 22 2.3.4 模块参数、门及连接的访问 23 2.3.4.1消息参数的访问 23 2.3.4.2门和连接的访问 24 2.3.4.3门的传输状态 26 2.3.3.4连接的状态 26 2.4 仿真过程 27 2.5 配置文件omnetpp.ini 28 2.6 结果分析工具 29 2.6.1 矢量描绘工具Plove 29 2.6.2 标量工具Scalar 29 27、结束语 30 第三章 物理层仿真(信道) 32 3.1 UWB的基础知识 32 3.1.1 UWB信号的应用背景 32 3.1.2 UWB信号的定义 32 3.1.3 UWB的脉冲生成方式(高斯脉冲,非高斯脉冲) 34 3.1.4 UWB的调制方式 34 3.1.5 用功率控制多址接入方法来进行链路的建立控制 36 3.2 用OMNeT++对UWB进行仿真 37 3.2.1 算法仿真的概述 37 3.2.2 算法的具体流程 39 3.2.3 算法的主要代码 41 3.2.4 仿真结果分析 58 3.2.5 应用前景 58 参考文献 59 第四章 MAC层仿真 60 概述 60 4.1 无线传感器网络MAC层特性及分类 60 4.1.1 无线信道特性 60 4.1.2 MAC 设计特性分析 61 4.1.3 无线传感器网络典型MAC协议的分类 61 4.2 基于随机竞争的MAC协议 62 4.2.1 S-MAC协议[12] 62 4.2.2 T-MAC协议 64 4.2.3 AC-MAC协议 65 4.3 基于时分复用的MAC协议 65 4.3.1 D-MAC协议 65 4.3.2 TRAMA协议 66 4.3.3 AI-LMAC协议 66 4.4 其他类型的MAC协议 67 4.4.1 SMACS/EAR协议 67 4.4.2 基于CDMA技术的MAC协议 67 4.4.3 DCC-MAC 68 4.5 基于OMNeT++的MAC层协议仿真 69 4.5.1 S-MAC协议的仿真 69 4.5.2 S-MAC协议流程图 70 4.5.3 S-MAC协议的分析 71 4.6 小结 86 参考文献 86 第五章 网络层仿真 88 概述 88 5.1 无线传感器网络路由协议研究 88 5.1.1 无线传感器网络协议分类 88 5.1.2无线传感器网络中平面路由 90 5.1.3无线传感器网络中层次化路由 91 5.1.4 经典算法的OMNET仿真 93 5.2 无线传感器网络路由协议研究的发展趋势 104 5.3 无线传感器网络层路由协议与OMNET++仿真 104 5.3.1 无线传感器网络层路由与OMNET++仿真的基本概念[19] 104 5.3.1.1 传感器网络的体系结构 105 5.3.1.1.1 传感节点的物理结构 105 5.3.1.1.2 传感器网络的体系结构与网络模型 106 5.3.2 传感器网络层路由协议的基本概念 106 5.3.2.1 网络通信模式[28] 106 5.3.2.1.1 单播: 107 5.3.2.1.2 广播: 107 5.3.2.1.3 组播: 108 5.3.2.2传感器网络层设计[29] 108 5.3.3 OMNET++仿真软件的基本概念 109 5.4 无线传感器网络路由协议介绍 110 5.4.1 泛洪法(Flooding)[32] 111 5.4.2 定向扩散(Directed Diffusion:DD)[33] 112 5.4.3 LEACH( Energy Adaptive Clustering Hierarchy)[34] 113 5.5. OMNET++仿真实例 114 5.5.1 泛洪法 114 5.5.2 gossiping协议 119 5.6 本章总结 121 参考文献 121 第六章 应用层仿真 125 6.1 无线传感器网络节点定位 125 6.1.1 节点定位的基本概念 125 6.1.1.1 节点定位的定义 125 6.1.1.2 节点定位的重要性 126 6.1.2 节点定位的研究 126 6.1.2.1 测距方法 126 6.1.2.2 节点定位原理 127 6.1.2.3 节点定位算法分类 128 6.1.2.3.1 锚节点分类 128 6.1.2.3.2 计算方式分类 129 6.1.2.3.3 测距分类 130 6.1.2.3.4 节点移动性分类 130 6.1.2.4 节点定位性能评价[37] 130 6.1.3基于OMNET++的DV—Hop定位算法仿真 132 6.1.3.1 DV—Hop定位算法的基本思想 132 6.1.3.2 DV—Hop定位算法仿真 133 6.2 网络管理 141 6.2.1概叙 141 6.2.1.1 wsn网络管理的定义及范畴 142 6.2.1.2 wsn网络管理系统的分类 143 6.2.1.3 wsn网络管理系统的设计标准 144 6.2.2 wsn网络管理系统 145 6.2.2.1 能量管理系统 145 6.2.2.1.1 SenOs[5] 145 6.2.2.2 拓扑控制系统 146 6.2.2.2.1 TopDisc 算法 146 6.2.2.3 可调试、可配置、可编程系统 148 6.2.2.2.1 sympathy 系统[42] 148 6.2.2.2.2 Agilla系统[7] 149 6.2.3典型网络管理算法的Omnet 模拟 150 6.2.3.1 基于Wsn的一个简单拓扑查找算法算法模拟 150 6.2.4 结论 155 6.3 基于路由层安全协议的OMNeT++仿真 156 6.3.1 基础知识介绍 156 6.3.1.1无线传感器网络安全性的重要性和必要性 156 6.3.1.2 无线传感器网络的安全目标 156 6.3.1.3无线传感器网络中的路由协议概述 157 6.3.1.4无线传感器网络路由协议的攻击方法 157 6.3.1.5无线传感器网络中经典路由协议安全性分析 160 6.3.1.6 安全路由技术分析 162 6.3.1.6.1 密钥管理技术[20, 23, 24, 25] 162 6.3.1.6.2 安全路由协议 162 6.3.2 在OMNeT++ 中的仿真 163 6.3.3 总结 172 参考文献 172 第七章 实例(无线传感器网络移动节点定位仿真) 179 概述 179 7.1 移动定位算法介绍 179 7.1.1 室内移动节点定位算法 179 7.1.1.1 Active Badge系统 180 7.1.1.2 RADAR系统 180 7.1.1.3 Cricket系统 180 7.1.2 室外移动节点定位算法 181 7.1.2.1 基于静态定位的移动定位算法 181 7.1.2.2 纯移动定位算法 182 7.2 移动定位算法的OMNeT++仿真 183 7.2.1 MCL(Monte Carlo Localization)定位算法简介 183 7.2.2 MCL(Monte Carlo Localization)的OMNeT++仿真 185 7.2.2.1 建立网络拓扑 185 7.2.2.2 编码阶段 190 7.3.总结和发展趋势 195 参考文献 195
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值