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

时间:2015-06-08 18:17:45

标签: c++ omnet++ inet

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

  • Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}

我在ini的{​​{1}}文件中给出了一些初始参数:

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 startTimestopTime模块的udpAPP[0]CNPCBeacon。因此我将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);

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

1 个答案:

答案 0 :(得分:1)

将参数声明为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

我在这里解释了参数研究的工作原理:https://stackoverflow.com/a/30572095/4786271以及如何通过约束等来实现:https://stackoverflow.com/a/29622426/4786271

如果我建议的方法都不符合您的情况,那么完全回答这个问题可能会解决您的问题:How to change configuration of network during simulation in OMNeT++?

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

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

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

从本质上讲,它的目的是:

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

moduleB::handleParameterChange(parB);

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