在其他模块中通过 cPar 更改模型参数

Changing model parameters by cPar in other module

我正在使用这个模块层次结构:

我在 ini 文件中为 udpApp 提供了一些初始参数:

**.host*.numUdpApps = 2
**.host*.udpApp[0].typename = "UDPBasicApp" 
**.host*.udpApp[0].chooseDestAddrMode = "perBurst"
**.host*.udpApp[0].destAddresses = "gw1"
**.host*.udpApp[0].startTime = 1.32s
**.host*.udpApp[0].stopTime = 1.48s

但在 运行 时,我想通过 CNPCBeacon 模块为 udpAPP[0] 更改 startTimestopTime。因此,我将 CNPCBeacon.cc 更改为:-

cModule* parentmod = getParentModule();
cModule* grantParentmod = parentmod->getParentModule();
cModule* udpmod;
for (cSubModIterator iter(*grantParentmod); !iter.end(); iter++)
{
    //EV<<"get the modulde "<< iter()->getFullName()<<endl;
    if (strcmp(iter()->getFullName(), "udpApp[0]") == 0)
    {
        udpmod = iter();
        break;
    }
}
cPar& startTime = udpmod->par("startTime");
cPar& stopTime = udpmod->par("stopTime");

并且我能够成功接收 startTimestopTime 的值。但是我想在当前模块中更改这些值,这会导致以下代码出错:

udpmod->par("startTime").setDoubleValue(4.2);

任何人都可以建议我在 运行 时间更改它的方法。

将您的参数声明为 volatile 应该可以解决您的问题。但为了将来参考,我将在下面提供进一步的解释


Volatile vs. non-volatile:

这里取决于你想如何使用这个参数。主要通过 .ini 文件,您有两种类型的参数:volatilenon-volatile.

volatile 参数在您的 运行 期间每次都会被读取。如果您希望此参数由内置函数生成,例如 uniform(0,10) 每次此 volatile 参数将获得不同的值,那将很有帮助。

另一方面,non-volatile 参数只读取一个,因为它们不会从 运行 运行.

改变

使用 volatile 类型参数不会给您充分的灵活性,因为您的参数值将始终落在 .ini

中预定义的范围内

动态变量(参数)重新赋值:

相反,您可以使用更稳健的方法,并在每次必须这样做时重新定义存储该模块参数值的变量。

例如,在您的情况下,您可以执行以下操作:

varHoldingStartTime = par("startTime").doubleValue();
varHoldingStartTime = 4.2;

这样,实际值将在内部发生变化,而不会反映到您的 运行。


参数研究:

或者,如果您希望将此参数更改应用于多个 运行,您可以使用 OMNeT++ 提供的高级内置方法,它允许您执行 Parameter Studies

我在这里解释了参数研究的工作原理: and also here how it can be achieved with constraints etc:

如果我建议的 none 方法适合您的情况,那么完全回答这个问题可能会解决您的问题:


编辑: 扩展答案以粗略解释 handleParameterChange()

我之前也没有使用过handleParameterChange(),但是从我可以看出这个函数为使用它的模块提供了watchdog功能。

要激活此功能,首先必须重新定义 void handleParameterChange(const char *parameterName);

本质上它似乎在做以下事情:

假设我们有两个模块 moduleAmoduleB,并且 moduleB 有参数 parBmoduleA 更改了 parB,当发生这种情况时,moduleB 根据以下定义的行为对此更改做出反应:

moduleB::handleParameterChange(parB);

行为可能是从 .ini 等中重新读取 parB 的原始值