我正在使用此模块层次结构:
Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}
使用udpApp的一些ini参数: 我在udpApp的ini文件中给出了一些初始参数:
**.host*.numUdpApps = 2
**.host*.udpApp[0].typename = "UDPBasicApp"
**.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 = grantParentmod->getSubmodule("udpApp",0);
double varHoldingStartTime = udpmod->par("startTime").doubleValue();
double varGoldingStopTime = udpmod->par("stopTime").doubleValue();
varHoldingStartTime = SIMTIME_DBL(4.2);
varGoldingStopTime = SIMTIME_DBL(4.5);
udpmod->par("startTime").setDoubleValue(varHoldingStartTime);
udpmod->par("stopTime").setDoubleValue(varGoldingStopTime);
EV<<"New start and stop time is "<<udpmod->par("startTime").str()<<"\t"<<udpmod->par("stopTime").str()<<endl;`
哪个成功更改了参数。但是,它不会再次启动udpApp[0]
模块。所以我尝试将此模块的动态转换用作:
UDPBasicApp* udpBasicMod = dynamic_cast<UDPBasicApp*>(udpmod);
sendTimer = new cMessage("sendTimer");
scheduleAt(iniSchduleTime, sendTimer);
导致以下错误: -
模块中的错误(CNPCBeacon)BSoneNode.gw1.wlan [0] .CNPCBeacon(id = 23)在事件#1496,t = 4:scheduleAt()模块(UDPBasicApp)BSoneNode.gw1.udpApp [0]调用在模块(CNPCBeacon)的上下文中BSoneNode.gw1.wlan [0] .CNPCBeacon:从后一个模块调用的方法缺少Enter_Method()或Enter_Method_Silent()?。
是否还有其他方法可以通过其他子模块实例化模块。
感谢您的帮助。
答案 0 :(得分:0)
我在模块和子模块之间的层次结构和关系上有点迷失,但是我认为如果你想动态创建(或重新创建)模块,你可以使用OMNeT ++建议的内置方法: https://omnetpp.org/doc/omnetpp/manual/usman.html#sec186
一旦你(重新)定义了参数值,也许你可以直接使用单行代码:
cModuleType *moduleType = cModuleType::get("foo.nodes.WirelessNode");
cModule *mod = moduleType->createScheduleInit("node", this);
另一方面,您错误消息抱怨:Enter_Method()
和/或Enter_Method_Silent()
如果您尝试从另一个模块中调用模块的函数(示例X::get()
),则应使用这些宏:
Y::doSmthWithXsGet()
{
x->get();
}
为了实现这一目标,Enter_Method()
(或Enter_Method_Silent()
)必须在X::get()
X::get()
{
Enter_Method();
/* rest of the code */
}
您可以阅读OMNeT ++ userman的Direct Method Calls部分,了解其含义。
奇怪的是你得到scheduleAt()
方法的这个错误,这是一个属于基本OMNeT ++类cSimpleModule
的方法。这意味着,要在您的课程中使用此方法,您必须在类定义中继承cSimpleModule
。
可能只是做了类似的事情:
class MyCurrentClass: public cSimpleModule
{
/* further class definition */
};
......可以解决你的问题。
答案 1 :(得分:0)
通过另一个模块(请求模块)重新初始化模块(目标模块)的解决方案是在目标模块中创建handleParamterChange()函数。 handleParameterChange()用于在tun时重读已更改的参数。但是,它不会启动scheduleAt()事件来重新初始化目标模块的事件。所以我只是在这个函数中添加了scheduleAt()事件:
void UDPBasicApp:: handleParameterChange(const char* parname)
{
if(parname)
{
if((strcmp(parname, "startTime")==0) &&
(startTime != par("startTime").doubleValue())
startTime = par("startTime").doubleValue();
if(strcmp(parname,"stopTime")==0)&&
(stopTime != par("stopTime").doubleValue())
{
stopTime = par("stopTime").doubleValue();
selfMsg->setKind(START);
scheduleAt((simtime_t)(startTime), selfMsg);
}
}
请注意,selfMsg在INET框架中的UdpBasciApp.cc的initialize函数中定义。