在其他模块中通过 cPar 更改模型参数
Changing model parameters by cPar in other module
我正在使用这个模块层次结构:
Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}
我在 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]
更改 startTime
和 stopTime
。因此,我将 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");
并且我能够成功接收 startTime
和 stopTime
的值。但是我想在当前模块中更改这些值,这会导致以下代码出错:
udpmod->par("startTime").setDoubleValue(4.2);
任何人都可以建议我在 运行 时间更改它的方法。
将您的参数声明为 volatile
应该可以解决您的问题。但为了将来参考,我将在下面提供进一步的解释
这里取决于你想如何使用这个参数。主要通过 .ini
文件,您有两种类型的参数:volatile
和 non-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);
。
本质上它似乎在做以下事情:
假设我们有两个模块 moduleA
和 moduleB
,并且 moduleB
有参数 parB
。 moduleA
更改了 parB
,当发生这种情况时,moduleB
根据以下定义的行为对此更改做出反应:
moduleB::handleParameterChange(parB);
行为可能是从 .ini
等中重新读取 parB
的原始值
我正在使用这个模块层次结构:
Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}
我在 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]
更改 startTime
和 stopTime
。因此,我将 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");
并且我能够成功接收 startTime
和 stopTime
的值。但是我想在当前模块中更改这些值,这会导致以下代码出错:
udpmod->par("startTime").setDoubleValue(4.2);
任何人都可以建议我在 运行 时间更改它的方法。
将您的参数声明为 volatile
应该可以解决您的问题。但为了将来参考,我将在下面提供进一步的解释
这里取决于你想如何使用这个参数。主要通过 .ini
文件,您有两种类型的参数:volatile
和 non-volatile
.
volatile
参数在您的 运行 期间每次都会被读取。如果您希望此参数由内置函数生成,例如 uniform(0,10)
每次此 volatile 参数将获得不同的值,那将很有帮助。
另一方面,non-volatile
参数只读取一个,因为它们不会从 运行 运行.
使用 volatile
类型参数不会给您充分的灵活性,因为您的参数值将始终落在 .ini
动态变量(参数)重新赋值:
相反,您可以使用更稳健的方法,并在每次必须这样做时重新定义存储该模块参数值的变量。
例如,在您的情况下,您可以执行以下操作:
varHoldingStartTime = par("startTime").doubleValue();
varHoldingStartTime = 4.2;
这样,实际值将在内部发生变化,而不会反映到您的 运行。
参数研究:
或者,如果您希望将此参数更改应用于多个 运行,您可以使用 OMNeT++ 提供的高级内置方法,它允许您执行 Parameter Studies。
我在这里解释了参数研究的工作原理:
如果我建议的 none 方法适合您的情况,那么完全回答这个问题可能会解决您的问题:
编辑: 扩展答案以粗略解释 handleParameterChange()
我之前也没有使用过handleParameterChange()
,但是从我可以看出这个函数为使用它的模块提供了watchdog功能。
要激活此功能,首先必须重新定义 void handleParameterChange(const char *parameterName);
。
本质上它似乎在做以下事情:
假设我们有两个模块 moduleA
和 moduleB
,并且 moduleB
有参数 parB
。 moduleA
更改了 parB
,当发生这种情况时,moduleB
根据以下定义的行为对此更改做出反应:
moduleB::handleParameterChange(parB);
行为可能是从 .ini
等中重新读取 parB
的原始值