通过Omnet++官网tictoc教程学习在Omnet++中构建和运行仿真 Part1Part2

news2025/1/18 13:50:45

    • introduce
    • 开始
      • 模型介绍
      • 构建项目
      • 添加 NED 文件
      • 添加C++ 文件
      • 添加 omnetpp.ini
      • 总结
    • 运行仿真
      • 启动仿真程序
      • 运行仿真
      • 调试
        • 运行时错误
        • 崩溃
        • 断点
        • 调试下一事件
      • 调试/运行 日志
      • 序列图可视化

Omnet++官网 TicToc教学

introduce

在 Omnet++安装完成后,samples/tictoc 中有该例子的完整文件,你可以立刻运行该文件看他是怎么工作的,不过更推荐按接下来的步骤一步步完成该项目的构建。
在这里插入图片描述
需求:

  1. 安装好了Omnet++
  2. 拥有良好的C++知识、C++开发经验
  3. To make the examples easier to follow, all source code in here is cross-linked to the OMNeT++ API documentation.

开始

模型介绍

创建一个有两个节点的网络,其中一个节点会创建一个数据包,两个节点会来回传递相同的数据包,这两个节点分别叫做 tic和toc ,接着我们会逐渐拓展这个模型,在这个过程中介绍Omnet++的特征。

构建项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果有一些版本生成了 package.ned 文件,要将其删除

本项目所有文件都包含在一个文件夹中,对于一些更大规模的文件,可能会创建多个子文件夹。

添加 NED 文件

OMNeT++ 使用 NED 文件来定义组件并将它们组装成更大的单元 就像网络一样。
创建名为 tictoc1.ned的ned文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建后,可以在 OMNeT++ IDE 的 “Editor”(编辑器)区域中编辑该文件。 OMNeT++ IDE 的 NED 编辑器有两种模式: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模式,可以看到如下类似的图像
在这里插入图片描述
文件中的第一个块声明 Txc1作为简单的模块类型。 简单模块在NED级别上是原子的。它们也是有源成分, 他们的行为是在 C++ 中实现的。该声明还说,Txc1有一个名为 in 的输入门和一个名为 out 的输出门。

第二个块 Tictoc1 声明为网络。 Tictoc1由两个子模块 tic和 toc 组装而成 ,两者都是模块 Txc1的实例。tic的输出门连接到toc的输入门,反之亦然。 双向传播延迟为 100 毫秒。

注:ned语言更详细的介绍见ned语言 ,在安装完Omnet++后再 doc文件夹下也可以找到这些文档

添加C++ 文件

现在通过添加C++文件来编程Txc1模块的功能,创建一个名为 txc1.cc的文件
在这里插入图片描述

在这里插入图片描述
将如下代码输入到 Txc.cc中

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

using namespace omnetpp;

/**
 * Derive the Txc1 class from cSimpleModule. In the Tictoc1 network,
 * both the `tic' and `toc' modules are Txc1 objects, created by OMNeT++
 * at the beginning of the simulation.
 */
class Txc1 : public cSimpleModule
{
  protected:
    // The following redefined virtual function holds the algorithm.
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
};

// The module class needs to be registered with OMNeT++
Define_Module(Txc1);

void Txc1::initialize()
{
    // Initialize is called at the beginning of the simulation.
    // To bootstrap the tic-toc-tic-toc process, one of the modules needs
    // to send the first message. Let this be `tic'.

    // Am I Tic or Toc?
    if (strcmp("tic", getName()) == 0) {
        // create and send first message on gate "out". "tictocMsg" is an
        // arbitrary string which will be the name of the message object.
        cMessage *msg = new cMessage("tictocMsg");
        send(msg, "out");
    }
}

void Txc1::handleMessage(cMessage *msg)
{
    // The handleMessage() method is called whenever a message arrives
    // at the module. Here, we just send it to the other module, through
    // gate `out'. Because both `tic' and `toc' does the same, the message
    // will bounce between the two.
    send(msg, "out"); // send out the message
}

类Txc1 代表了基础模块 Txc1 ,Txc1是 Omnet++中 cSimpleModule 的子类,并且使用Define_Module() 函数宏注册到 Omner++中 。

如果忘记使用 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()”

在Txc1中重定义了函数 initialize() 和handleMessage() ,他们从仿真内核调用 ,第一个函数仅仿真开始时调用一次,第二个函数当有一个消息到达该模块时就会进行调用。

在 initialize() 函数中,创建了一个消息对象 cMessage ,并通过门 out 发送出去. 如果这个门连接到其他模块的 input门 ,仿真内核将传输这个消息到另一个模块的 handleMessage() ,根据 NED文件中的链接有100ms的传播时延。另一个模块将会将其传回,构成一个乒乓一般的传播。

消息(数据包、帧、作业等)和事件(计时器、超时)都是由 OMNeT++ 中的 cMessage 对象(或其子类)表示。 发送或调度它们后,它们将保持在仿真内核的“计划事件”或“未来事件”列表中,直到时间到了,他们才会通过 handleMessage()传输到模块。

注意:这个仿真没有内置停止条件,但可以哦那个GUI中停止。

添加 omnetpp.ini

为了运行这个仿真,我们要创建一个 omnetpp.ini文件,该文件告诉仿真程序想要仿真的网络是哪一个(NED文件可能包括多个网络),通过该文件还可以传递参数到模型中,显式的为随机数生成器指明seeds等。
在这里插入图片描述

在这里插入图片描述
与 NED的编辑器类似,ini文件的编辑器也有两个模式,Form和Source ,前者适合配置仿真内核,后者适合输入仿真参数。

现在选择Source,输入如下代码:

[General]
network = Tictoc1

现在已经完成了第一个模型的创建,接下来准备编译和运行该模型。

总结

通过该流程的学习,我们了解到一个模型的创建包含了三类主要文件 : ned 、cpp和ini 。 ned文件构建模块和网络,可以通过图形化界面或文本输入构建 ,cpp文件编程各个模块的具体功能 ,ini文件确定运行那个网络或传递参数等。

除了学习到创建各个文件的用途、创建方式、命名规则等。还学习到cMessage 、initialize()函数、handleMessage()函数相关的知识。进一步学习ned语言可以通过官方文档。在cpp文件中使用 omnetpp.h头文件和 omnetpp命名空间,可以进一步学习。

运行仿真

启动仿真程序

选择 omnetpp.ini文件 ,点击 Run按钮即可开始仿真
在这里插入图片描述

运行仿真

构建并启动仿真后,会弹出一个新界面
在这里插入图片描述
该窗口属于 Qtenv,是OMNeT++仿真运行时主要的 GUI。
在图形化窗口中,可以看见 tic和toc

点击最上面一栏的Run可以运行仿真,可以看见tic和toc相互交换信息的过程。
在这里插入图片描述
主窗口工具栏显示当前仿真时间。这是虚拟时间, 它与程序所需的实际(或挂钟)执行时间无关 。 实际上,在现实世界的一秒钟内可以模拟多少秒 很大程度上取决于硬件的速度,甚至更多地取决于硬件的性质和 仿真模型本身的复杂性。
在这里插入图片描述

比如硬件较差的情况下,仿真中只过去了一秒而实际时间耗费了五分钟。

请注意,节点处理消息所需的模拟时间为零。 在这个模型中,唯一使仿真时间流逝的是 连接上的传播延迟。

通过顶部的滑块,可以减慢或加速动画的速度。
在这里插入图片描述
F8 :停止仿真
F4:单步执行
F5:有动画仿真
F6:无动画仿真
F7:快速模式 ,将完全关闭追踪特征

可以多次运行该仿真来探索各个按钮的功能,直接点X可以退出该仿真

调试

模拟只是一个 C++ 程序,因此,它通常需要 在开发过程中进行调试。在本节中,我们将了解 调试的基础知识,以帮助您完成这项重要任务。

点击调试按钮开始进行调试
在这里插入图片描述
这将导致仿真程序在调试器下启动 (通常为 gdb)。IDE 也将切换到 “Debug perspective”, 即将其各种窗格和视图重新排列为更好的布局 适合调试。您可以使用工具栏上的“终止”按钮(红色方块)结束调试会话。

运行时错误

最常见的debug是在运行时出错,我们现在模拟一个错误,在txc1.cc的handleMessage()函数中的 多加一个send()函数,如下所示:

void Txc1::handleMessage(cMessage *msg)
{
    //...
    send(msg, "out"); // send out the message
    send(msg, "out"); // THIS SHOULD CAUSE AN ERROR
}

此时再运行会报如下的错:
在这里插入图片描述
现在,在调试模式下运行仿真。由于debug-on-errors选项 默认情况下启用,仿真程序将在调试器中停止。
在这里插入图片描述
可以通过检查堆栈跟踪(嵌套的列表)来定位错误
在这里插入图片描述
注:右上角的两个小按钮可以切换debug和普通模式
在这里插入图片描述
你可以看到是omnet++的breakIntoDebuggerIfRequested()方法激活了调试器。然后,你需要搜索一个看起来熟悉的函数,即模型的一部分。在我们的例子中,这就是Txc1::handleMessage()。选择这一行将在编辑器区域中显示相应的源代码,并允许您在variables视图中检查变量的值。这些信息将帮助您确定错误的原因并修复它。

崩溃

让我们来制造一个崩溃,先恢复之前对handleMessage()函数的编辑,假装我们在发送消息之前忘记创建它,在initialize()函数中修改原来的行为:

        cMessage *msg; // no initialization!
        send(msg, "out");

此时运行该仿真,将会造成崩溃。
在这里插入图片描述
该报错也可能是:Simulation terminated with exit code: 139

然后在debug模式下运行该代码,然后就可以定位到出错的位置,同时可以查看变量窗口中的变量,帮助进一步修复错误
在这里插入图片描述

断点

您还可以手动在代码中放置断点。断点将停止执行,并允许您检查变量、逐行执行代码或恢复执行(直到下一个断点)。

双击编辑器中左侧的gutter,或者从上下文菜单中选择Toggle breakpoint,可以将断点置于源代码中的特定行。可以在breakpoints视图中检查活动(和不活动)断点的列表。

调试下一事件

如果您做过前面的练习,您一定已经注意到,在Txc1简单模块中的每个事件上都触发了断点。在现实生活中,通常只有在模块的第357个事件时才会出现错误,所以理想情况下,应该从这个时候开始调试。要点击简历356次才能找到错误的位置是很不方便的。一种可能的解决方案是向断点添加条件或忽略计数(请参阅上下文菜单中的断点属性)。然而,可能有一个更方便的解决方案。

在Qtenv中,使用Run Until获取要调试的事件。然后,从菜单中选择“模拟->调试下一个事件”。这将在调试器中在下一个事件的handleMessage()开始处触发一个断点,你可以开始调试该事件。

在这里插入图片描述

调试/运行 日志

重新启动仿真

当你用IDE工具栏上的Run或Debug按钮启动模拟程序时,与启动相关的设置会保存在启动配置中。启动配置可以在运行/调试配置对话框中查看,可以通过单击运行(调试)工具栏按钮旁边的向下小箭头来打开菜单,并选择运行(调试)配置…在里面。在相同的菜单中,您还可以单击启动配置的名称(例如tictoc),同时按住Ctrl键打开相应配置的对话框。

该对话框允许您激活各种启动设置。
在这里插入图片描述

在这里插入图片描述

序列图可视化

omnet++仿真内核可以将仿真过程中的消息交换记录到事件日志文件中。要启用记录事件日志,请在启动配置对话框中选中Record eventlog复选框。或者,您可以在omnetpp.ini中指定Record -eventlog = true,甚至在启动后在Qtenv图形运行时环境中使用Record按钮,
在这里插入图片描述

稍后可以使用IDE中的序列图工具分析日志文件。项目文件夹下的results目录中包含 .elog 文件。在omnet++ IDE中双击它会打开序列图工具,以及窗口底部的event log选项卡。
在这里插入图片描述
在这里插入图片描述

注意:产生的日志文件可能会非常大,所以最好只在特别需要时使用该功能

下图是使用序列图工具创建的,显示了消息如何在网络中的不同节点之间路由。在这种情况下,图表非常简单,但当你有一个复杂的模型时,序列图在调试、探索或记录模型的行为方面非常有价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1572201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows部署Jenkins并远程部署tomcat

目录 1、Jenkins官网下载Jenkins 2、安装Jenkins 3、修改Home directory 4、插件安装及系统配置 5、Tomcat安装及配置 5.1、修改配置文件,屏蔽以下代码 5.2、新增登录用户 5.3、编码格式修改 5.4、启动tomcat 6、Jenkins远程部署war包 6.1、General配置 6.2、Sourc…

基于卷积神经网络的大米品种分类系统(pytorch框架)【python源码+UI界面+前端界面+功能源码详解】

功能演示&#xff1a; 大米品种分类系统&#xff0c;基于vgg16&#xff0c;resnet50卷积神经网络&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神经网络的大米品种分类系统是在pytorch框架下实现的&#xff0c;系统中有两…

Redis中的持久化

持久化 .RDB手动触发save命令bgsave命令 自动触发bgsave的具体流程RDB的处理保存压缩校验 RDB的优缺点 AOF命令写入文件同步重写机制启动时恢复数据 本章重点回顾 . RDB RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发 手动触发…

电子积木方案开发商

东莞市酷得智能科技有限公司电子积木方案开发商 提供消费电子解决方案、提供IC技术支持&#xff0c;全国线上线下服务 积木小车底层驱动开发过程主要涉及到以下几个方面&#xff1a; 首先&#xff0c;需要对小车底盘结构、硬件、模块等有深入的了解。底盘承载着机器人定位、导…

nvm保姆级安装使用教程

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 开发环境篇 ✨特色专栏&#xff1a; M…

数据采集与整理:知识图谱的根基

数据采集与整理&#xff1a;知识图谱的根基 一、 引言 在今天的数据驱动的世界中&#xff0c;知识图谱已经成为了连接复杂信息的关键工具。它们不仅推动了人工智能的发展&#xff0c;还改变了我们管理和利用知识的方式。然而&#xff0c;任何优秀的知识图谱都离不开一个核心的…

武汉星起航:跨境电商领域的领航者,助力全球贸易新篇章

自2017年以来&#xff0c;武汉星起航一直专注于亚马逊自营店铺&#xff0c;积累了宝贵的经验。2020年正式成立后&#xff0c;公司以跨境电商为核心&#xff0c;致力于为合作伙伴提供深入的合作模式。武汉星起航凭借其卓越的服务和实战经验&#xff0c;已成功助力众多创业者实现…

C# 分布式自增ID算法snowflake(雪花算法)

文章目录 1. 概述2. 结构3. 代码3.1 IdWorker.cs3.2 IdWorkerTest.cs (测试) 1. 概述 分布式系统中&#xff0c;有一些需要使用全局唯一ID的场景&#xff0c;这种时候为了防止ID冲突可以使用36位的UUID&#xff0c;但是UUID有一些缺点&#xff0c;首先他相对比较长&#xff0c…

画图理解JVM相关内容

文章目录 1. JVM视角下&#xff0c;内存划分2. 类内存分布硬核详解1. 获取堆内存参数2. 扫描堆内存&#xff0c;定位实例3. 查看实例所在地址的数据4. 找到实例所指向的类信息的地址5. 查看class信息6. 结论 3. Java的对象创建流程4. 垃圾判别算法4.1 引用计数法4.2 可达性分析…

DRF:认证(单视图或全局设置认证方案和源码分析、设置多个认证方案、如何设置不允许匿名访问)

概念&#xff1a;request.user、request.auth、认证方案authentication_classes 官网原文&#xff1a; 验证始终在视图的最开始进行&#xff0c;在执行权限和限制检查之前以及允许任何其他代码继续执行之前。 request.user 属性通常被设置为contrib.auth 包中 User 类的一个…

数学知识--(欧拉函数,快速幂,扩展欧几里得算法)

本文用于记录个人算法竞赛学习&#xff0c;仅供参考 目录 一.欧拉函数 二.欧拉函数模板 三.用筛法求每个数的欧拉函数 四.快速幂 五.扩展欧几里得算法 六.用扩展欧几里得算法求线性同余方程 一.欧拉函数 即有一个数n&#xff0c; n通过质因数分解得到 通过欧拉函数有 证明&…

Java 程式 main 方法传参数

Java 程式运行时如果需要传递参数时&#xff0c;常用的方法有两种&#xff1a; 使用 Program Arguments 来传递值使用 VM Arguments 来传递值 1、使用 Program Arguments 来传递值 使用 Program Arguments 来传递值时&#xff0c;main 方法的写法如下&#xff1a; public st…

Linux 常用命令(持续更新中...)

1. ls 查看文件列表命令 语法&#xff1a; ls [-a -l -h] [Linux路径] -a -l -h 是可选的选项 &#xff08;-h需配合-l命令一起使用&#xff09;Linux路径是此命令可选的参数 ls #查看当前目录所有非隐藏文件(平铺方式显示) ls -a #查看当前目录下所有文件 …

Web 后台项目,权限如何定义、设置、使用:菜单权限、按钮权限 ts element-ui-Plus

Web 后台项目&#xff0c;权限如何定义、设置、使用&#xff1a;菜单权限、按钮权限 ts element-ui-Plus 做一个后台管理项目&#xff0c;里面需要用到权限管理。这里说一下权限定义的大概&#xff0c;代码不多&#xff0c;主要讲原理和如何实现它。 一、权限管理的原理 权限…

Polardb MySQL 产品架构及特性

一、产品概述; 1、产品族 参考&#xff1a;https://edu.aliyun.com/course/3121700/lesson/341900000?spma2cwt.28120015.3121700.6.166d71c1wwp2px 2、polardb mysql架构优势 1&#xff09;大容量高弹性&#xff1a;最大支持存储100T&#xff0c;最高超1000核CPU&#xff0…

55、美国德克萨斯大学奥斯汀分校、钱德拉家族电气与计算机工程系:通过迁移学习解决BCI个体差异性[不得不说,看技术还得是老美]

2024年2月5日跨被试最新文章&#xff1a; 德州州立大学奥斯汀分校研究团队最近的一项研究成果&#xff0c;通过非侵入式的脑机接口&#xff0c;可以让被试不需要任何校准就可以使用脑机接口设备&#xff0c;这意味着脑机接口具备了大规模被使用的潜力。 一般来说&#xff0c;…

哈希-字母异位词分组

字母异位词&#xff0c;词频一样&#xff0c;但是顺序不一样&#xff0c;可以进行排序&#xff0c;获取一个key&#xff0c;放在map中即可。 class Solution {public List<List<String>> groupAnagrams(String[] strs) {Map<String, List<String>> ma…

彩虹聚合DNS管理系统v1.0全新发布

聚合DNS管理系统&#xff08;https://github.com/netcccyun/dnsmgr&#xff09;可以实现在一个网站内管理多个平台的域名解析&#xff0c;目前已支持的域名平台有&#xff1a;阿里云、腾讯云、华为云、西部数码、CloudFlare。本系统支持多用户&#xff0c;每个用户可分配不同的…

STM32CubeIDE基础学习-舵机控制实验

STM32CubeIDE基础学习-舵机控制实验 文章目录 STM32CubeIDE基础学习-舵机控制实验前言第1章 硬件介绍第2章 工程配置2.1 基础工程配置部分2.2 生成工程代码部分 第3章 代码编写第4章 实验现象总结 前言 SG90、MG996舵机在机器人领域用得非常多&#xff0c;因为舵机有内置控制电…

利用nginx-http-flv-module实现三种直播

目录 一、说明 二、目标 三、实现 四、直播地址 一、说明 此文在《流媒体服务器的搭建(支持hls)》《搭建nginx-http-flv-module直播系统》之后编写,很多详细内容需要参考它。 流媒体服务器的搭建(支持hls)