OMNeT++ 基础知识:仿真过程和配置文件

仿真过程

OMNeT++ 的源代码通常包括以下文件:

  • C++ 文件(.h.cc):包含简单模块的实现和其他代码;
  • 消息文件(.msg):包含要转换为 C++ 类的消息定义;
  • 带有组件声明和拓扑描述的 NED 文件(.ned);
  • 具有模型参数分配和其他设置的配置文件(.ini)。

简单地说,OMNeT++ 将源代码转换为可执行文件的过程如下:

  1. 使用消息编译器 opp_msgc.msg 文件翻译为 C++ 文件;
  2. 将 C++ 文件编译为对象形式(.o 文件);
  3. 目标文件与仿真内核和其他库连接以得到可执行文件或共享库

需要注意的是,NED 文件与 .ini 文件是由仿真程序在运行时加载的。

配置文件

仿真的配置文件和输入数据通常放置在 .ini 文件中。

配置文件语法

OMNeT++ 配置文件是一个面向行的文本文件。编码主要是 ASCII,但在注释和字符串文字中允许使用非 ASCII 字符。

注释以 # 开头,程序也允许并在执行时忽略空行。可以通过尾随反斜杠的方式将很长的一行代码拆分为多行。即使在名称、数字或字符串常量的中间,这也允许换行。

配置文件中共有三种类型的行:节标题行、 键值行和指令行:

  • 节标题行是用方括号括起来的节名称。

  • 键值行表现形式为 <key>=<value>;如果一行包含多个等号,则最左边的一个等号作为键值分隔符。

  • 指令行以 include 开头,后跟要包含的文件的名称。

键可以仅根据语法进一步分类:

  1. 不包含点的键代表全局或每次都要运行的配置选项。
  2. 如果键包含一个点,则考虑其最后一个组件(最后一个点之后的子字符串)。如果最后一个组件包含连字符或等于 typename,则该键表示每个对象的配置选项。
  3. 否则,键代表参数赋值。因此,参数分配键包含一个点,并且在最后一个点之后没有连字符。

例如:

1
2
3
4
5
6
7
8
9
10
11
# 注释行
[General] # 节标题行
network = Foo # 配置选项
debug-on-errors = false # 配置选项

**.vector-recording = false # 每个对象的配置选项
**.app*.typename = "HttpClient" # 每个对象的配置选项

**.app*.interval = 3s # 参数值
**.app*.requestURL = "http://www.example.com/this-is-a-very-very-very-very\
-very-long-url?q=123456789" # 一个两行的参数值

文件包含

OMNeT++ 通过 include 关键词在配置文件中引入另一个 .ini 文件,使得大型 .ini 文件可以被划分为逻辑单元、固定单元和可变单元等。例如:

1
2
3
4
5
6
# omnetpp.ini
...
include params1.ini
include params2.ini
include ../common/config.ini
...

节标题

一个 .ini 文件可以包含一个 [general] 部分和多个 [<configname>][Config <configname>] 部分。也就是说,[Foo][Config Foo] 等价。各部分的顺序并不重要。

分配模块参数

模拟通过模块参数获取输入,这些参数可以在 NED 文件或 omnetpp.ini 中按顺序分配值。由于在 NED 文件中分配的参数不能在 omnetpp.ini 中被覆盖,因此可以将 NED 文件中的参数分配视为“硬编码”。相比之下,在 omnetpp.ini 中维护模块参数设置更容易、更灵活。

omnetpp.ini中,模块参数由它们的完整路径(分层名称)引用。该名称由以点分隔的模块名称列表(从顶级模块到包含参数的模块)以及参数名称组成。

模型可以有大量的参数需要配置,在omnetpp.ini中一一设置会很繁琐。OMNeT++ 支持通配符模式,允许一次设置多个模型参数。通配规则最明显的区别是***之间的区别。此外,表示字符范围时应该用大括号而不是方括号,因为方括号是为模块向量索引的表示法保留的。

模式语法:

  • ?: 匹配除点 (.) 以外的任何字符
  • * : 匹配零个或多个字符,除了点 (.)
  • **:匹配零个或多个字符(任何字符)
  • {af} : 集合: 匹配 af 范围内的字符
  • {^af} :否定集: 匹配不在 af 范围内的字符
  • {38..150}:数字范围:38..150 范围内的任何数字(即数字序列),包括在内;两个限制都是可选的
  • [38..150]:索引范围:方括号中的任何数字,范围为 38..150,包括 38..150;两个限制都是可选的
  • 反斜杠(\):去掉后面字符的特殊含义

使用通配符时,条目的顺序非常重要。当一个键匹配多个通配符模式时,将使用第一个匹配项,即需要先列出特定设置,然后再列出更一般的设置。示例如下:

1
2
3
4
[General] 
*.*.queue[3..5].bufSize = 10
*.*.queue[12..].bufSize = 18
*.*.queue[*].bufSize = 6 # 这只会影响队列0,1,26..11

* 通配符用于匹配路径名中的单个模块或参数名称,而 ** 可用于匹配路径中的多个组件。例如,**.queue*.bufSize 匹配模型中名称以 queue 开头的所有模块的 bufSize 参数,而 *.queue*.bufSizenet.queue*.bufSize 仅选择网络级别的队列。此外,**.queue**.bufSize 也会匹配如 net.queue1.foo.bar.bufSize 的参数。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 lgc0208@foxmail.com
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信