OMNET 学习

OMNET 学习

1 OMNET 下载[1]

  1. 官网下载OMNET,OMNeT++ Older Versions,这里下载6.0.3版本。

  2. 进入OMNET解压缩文件根目录,双击运行mingwenv.cmd,等待运行完成。

    image-20250707142727303
  3. 输入命令,等待大概1分钟:

    ./configure
    
    image-20250707145027819
  4. 接着输入,等待5-40分钟。

    make
    或 make -j8
    
    image-20250707145050680

    完成后,测试一下,在命令行输入:

    cd samples/aloha
    ./aloha
    
    image-20250707154421470

    出现以下界面:

    image-20250707154452583
  5. 编辑环境变量,首先新建系统变量:

    OMNET_HOME
    F:\apps\omnetpp-6.0.3-windows-x86_64\omnetpp-6.0.3
    
    image-20250707154839896

    然后在Path路径,新建以下路径:

    %OMNET_HOME%\bin
    %OMNET_HOME%\tools\win64\usr\bin
    %OMNET_HOME%\tools\win64\mingw64\bin
    %OMNET_HOME%\tools\win64\opt\mingw64\bin
    
    image-20250707155057564
  6. 重启电脑。安装完成。

2 OMNET 打开方式

  1. OMNET 6.x可以直接通过IDE快捷方式打开,等待加载,片刻后自动打开。

    image-20250707171639452

    或者打开mingwenv.cmd,输入omnest或者omnetpp,即可打开可视化IDE(推荐)。

    或者在ide文件夹下,将opp_ide.exe创建快捷方式。

  2. OMNET 5.X,没有快捷方式。Win+R输入cmd,然后输入omnest或者omnetpp;

    或者打开mingwenv.cmd,输入omnetpp。

  3. OMNET 4.X,Win+R,输入cmd,然后输入omnet。

3 OMNET 使用[2]

3.1 开始项目

3.1.1 模型

一个网络由两个节点组成。一个节点创造数据包,然后这两个节点会继续来回传递这个相同的数据包。这里叫节点为”tic“和”toc“。

3.1.2 Project 初始设定

在终端输入omnetpp打开OMNeT++ IDE,新建一个Project,在向导对话框输入项目名字,在initial content 选择空项目,点击finish。

image-20250707174918159

该项目将保存所有仿真文件。在这个例子中,项目由单个文件组成。对于较大仿真,项目的内容通常分到srcsimulation文件夹,并且可能在他们下面的子文件夹中。

3.1.3 添加NED文件

OMNET++使用NED文件来定义组件,并把他们汇编为更大的单位,比如网络。通过添加一个NED文件执行模型。右键单击左侧Project Explorer面板中的项目文件夹,选择New -> Network Description File(NED),输入文件名.ned。在IDE的NED编辑器中有两个模块,DesignSource,Design能图形化编辑拓扑,可以使用鼠标和右侧选项板。在Source模块,能直接以文本形式编辑NED源代码。在一种模式中做出的更改能立即反映到另一个,所以在编辑中能自由切换两种模式,在更方便的模式中做出更改。

在Source输入以下代码:

simple Txc1
{
    gates:
        input in;
        output out;
}

//
// Two instances (tic and toc) of Txc1 connected both ways.
// Tic and toc will pass messages to one another.
//
network Tictoc1
{
    submodules:
        tic: Txc1;
        toc: Txc1;
    connections:
        tic.out --> {  delay = 100ms; } --> toc.in;
        tic.in <-- {  delay = 100ms; } <-- toc.out;
}

Design模块中,出现以下拓扑网络:

image-20250708132741778

第一个模块Txc0是一个简单模块类型。简单模块在NED级别上是原子的。他们也是活动组件,由C++实现。在声明中说明了Txc0有一个输入门是in,有一个输出门是out

第二个模块Tictoc0是一个网络。它由两个子模块组成,tictoc,他们都是Txc0类型。tic的输出门连接toc的输入门,反之亦然。两个通路都有100ms的传播延迟。

3.1.4 添加C++文件

需要在C++执行Tcx0简单模块的功能。项目菜单New -> Source File或者主菜单 File -> New -> File

#include <string.h>
#include <omnetpp.h>

using namespace omnetpp;

class Txc0 : public cSimpleModule
{
protected:
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
};

Define_Module(Txc0);

void Txc0::initialize()
{
    // Am I Tic or Toc?
    if (strcmp("tic", getName()) == 0) {
        cMessage *msg = new cMessage("tictocMsg");
        send(msg, "out");
    }
}

void Txc0::handleMessage(cMesssage *msg)
{
    send(msg, "out");
}

Txc0类是OMNET++的cSimpleModule类的子类,并且需要用Define_Module()宏注册在OMNET++。

忘记宏注册就会报错:

"Error: Class 'Txc1' not found -- perhapsits code was not linked in, or the class wasn't registered with Register_Class(), or inthe case of modules and channels, with Define_Module()/Define_Channel()".

重新定义 cSimpleModule: initialize() and handleMessage()这两个方法,他们从仿真内核调用:第一个仅调用一次,第二个是当信息到达模块时调用。

initialize(),创建一个消息对象cMessage,然后发送到输出门outout连接其他模块的输入门,仿真内核会传送这个消息到其他模块的handleMessage()的参数,在100ms的传输延迟后,其他模块也送回消息,所以会产生连续的ping-pong

Messages (packets, frames, jobs, etc),即 消息(数据包,帧,作业等)和 events (timers, timeouts),即 事件(计时器,超时)都由omnet++中的cMessage对象(或其子类)表示。在发送或调度它们之后,它们将被模拟内核保存在“计划事件”或“未来事件”列表中,直到它们的时间到来,然后通过handleMessage()将它们传递给模块。

请注意,这个模拟中没有内置停止条件:它将永远持续下去。您将能够在GUI中停止它。(您也可以在配置文件中指定模拟时间限制或CPU时间限制,但我们不会在教程中这样做。)

3.1.5 添加omnetpp.ini

ini文件告诉仿真程序需要仿真的网络(NED文件可以包含数个网络),能向模型传递参数,显性指定随机数生成器的种子等等。

编辑器有两个模块,Form和Source,编辑的是相同内容,但前者更适合配置仿真内核,后者更适合输入模块参数。不同部分共享同一个ini文件

image-20250707173340994

3.1.6 总结

一个项目由三个部分,NED文件,两个界面,一个是Design,图形化编辑网络,一个是Source,C++编辑,功能就是定义节点,包含两个东西,一个是simple Txc2,一个是network tictoc2;c++文件定义节点的功能,对节点行为的描述,即对那一类的描述;ini文件与仿真系统相连,调配参数信息等。

  1. 加参数:可以往两个地方加参数,一个是ned文件,加的参数就叫参数parameters,另一个是c++文件,加的参数就叫私有变量private variable;
  2. @display是给某个东西加图标,OMNET的语法的一种——在@后加xx,构成一个结构

3.2 运行仿真

3.2.1 启动仿真程序

3.3 加强两节点tictoc

3.3.1 添加图标

分配block/routing(块/路由)图标,tic是cyan(青色),toc是黄色,通过在ned文件中添加展示字符串,i=标签指定了图标。

simple Txc2
{
    parameters:
    	@display("i=block/routing");
   gates:
    	input in;
    	output out;
}

network Tictoc2
{
    submodules:
    	tic: Txc2 {
            parameters:
            	@display("i=,cyan");
        }
        toc: Txc2 {
            parameters:
                @display("i=,gold");
   		}
    connections:
    	tic.out --> (	delay = 100ms; ) --> toc.in;
    	tic.in <-- (	delay = 100ms; ) <-- toc.out;
}

3.3.2 添加日志功能

修改C++文件,

4 OMNET++ 实例

4.1 官方实例 tictoc

4.1.1 Txc1 添加两个简单节点

简单的添加一个网络,两个节点,以100ms延迟相互传输。

image-20250712164700808

4.1.2 Txc2 添加图标颜色和日志

ned文件添加一个默认图标,加上颜色:

image-20250712164929674

并在c++文件添加日志状态打印功能:

image-20250712165130989

结果:

image-20250712165158164

还可以右键单击部件,查看其部件日志,也可直接双击在底部监控面板查看。

image-20250712165351460

4.1.3 Txc3 添加计数器,事件数量归零停止运行

添加一个计数器,并在归零后删除消息,停止程序。

image-20250712165535078

在c++文件的initialize函数中添加counter,定义次数,在handleMessage中添加次数衰减,每当消息到达,counter-1,直到为0,事件走完,程序停止。

initialize中添加WATCH(counter);,使counter次数可视化,单击部件,在左下角监控面板的顶部工具栏,选择Children模块能查看部件的详细信息,其中就有counter监控。

image-20250712170922255

程序运行结果:

image-20250712171224042

4.1.4 Txc4 添加参数,决定事件数和是否发送初始信息

添加一个默认值参数,决定发送次数,以及布尔参数来决定模块是否要发送第一条信息

image-20250712171657782

在c++文件中同步修改,将limit作为counter的值,布尔参数sendMsgOnInit来决定是否发送初始信息:

image-20250712172044691

用ned文件或者ini来设定参数值,ned可以使用default()来初始化,这里定义tic作为发送初始信息的部件。

image-20250712172441194

也可以使用ini,ini文件支持通配符,所以也可以使用Tictoc4.t*c.limit=5Tictoc.*.limit=5**.limit=5

image-20250712173031018

注意,ini文件设定的参数会覆盖ned文件的初始参数。

4.1.5 Txc5 派生模块

从简单模块中派生子模块,可以直接添加到网络中,而无需再次初始化参数信息等,使网络定义更加简短。

image-20250712173913891image-20250712173927571

image-20250712174021705

4.1.6 Txc6 添加处理延迟

tictoc接到消息后有处理时间,1模拟s延迟后才会发回消息。这个延迟是通过向自身发送消息实现的。这样的消息被称为自消息【其实就是模拟显示网络处理消息】。在class中添加两个cMessage变量,event用来计时,tictocMsg记住我们延迟发送的变量。

修改cc文件,添加变量

image-20250713231140149

如果发送普通消息,使用send()函数,如果发送自消息,使用scheduleAt()函数。

image-20250713231645297

4.1.7 修改延迟为随机数和参数

通过修改延迟为随机数

image-20250714001534101 image-20250714001936001

无论重复运行程序多少次结果一样,因为使用RNG 0,seed相同。

4.1.8 发出消息开启计时,到时重发消息

tictoc分成两个不同class,toc有概率丢失消息,显示一个丢失消息弹窗,tic在发送消息的同时会开启一个计时器,当计时器结束,会假定消息丢失,重发消息,如果toc的响应到达,计时器会被取消。

image-20250714002704201 image-20250714002950787

4.1.9 重新传输相同消息

传输消息的副本,保存消息的原始数据包,当toc的确认消息到达才删除原始数据包。为了更直观地验证模型,在消息名字中加入一个消息序列数字。为了避免消息接收函数太大,引入两个新函数。

image-20250714004044722 image-20250714004904962

4.1.10 增加网络节点数量

网络中,消息被随机传输,直到传到预先确定的目标节点停止,核心代码在接收消息函数中调用:

image-20250714005947404 image-20250714010025163

4.1.11 创建channel内部类型定义,简化网络定义

image-20250714010405882

4.1.12 使用双向连接

OMNeT++支持双向连接,可以替换原来的单向连接定义,用inout门代替in/out

image-20250714010813634

同时修改C++文件,只需要随机选择一个门。

image-20250714011054889

4.1.13 定义消息类

目的地不再是固定tic[3],随机选择目的地并加入到消息中。最好的方法是创建cMessage的子类,添加目的地作为一个数据成员。最好的方法是创建cMessage的子类,并将destination添加为数据成员。手工编码消息类通常很乏味,因为它包含大量样板代码,所以我们让omnet++为我们生成类。消息类规范在tictoc13.msg中:

image-20250714011622527

文件生成后,编译器opp_msgc被调用,从消息声明中生成tictoc13_m.htictoc13_m.cc,它们将包含一个生成的TicTocMsg13类,从cMessage子类化而来,该类将会为每个字段提供getter和setter方法。

tictoc13_m.h包含进C++代码,可以使用TicTocMsg13作为其他类。例如,z在generateMessage()中创建消息并填充字段:

image-20250714221614403

4.1.14 展示发送/接收到的数据包的数量

为了在运行时大致了解每个节点发出或者接收到的消息数量,我们增加两个计数器,能够在Inspect菜单使用Find/inspect objects对话框,查看具体数量

image-20250714222024572 image-20250714222455031

也可以在模块图标的上方展示这个信息:

image-20250714222857796 image-20250714222821328

4.1.15 添加统计信息

比如一个消息到达目的地必须经过的平均跳数

image-20250714224004054

4.1.16 不修改模型的情况下统计信息

5 INET

5.1 安装

INET Framework - Download

选择与omnet匹配版本,输入以下代码,等待编译完成

source setenv
make makefiles
make

image-20250722192815388

image-20250722192912644


  1. 参考OMNeT学习之OMNeT安装与运行-CSDN博客 ↩︎

  2. 根据OMNET++的官方教程Getting Started - OMNeT++ Technical Articles ↩︎

posted @ 2025-07-22 20:04  波伏鲸  阅读(199)  评论(0)    收藏  举报