通过更改参数

时间:2015-06-09 11:20:08

标签: c++ omnet++ inet

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

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()?。

是否还有其他方法可以通过其他子模块实例化模块。

感谢您的帮助。

2 个答案:

答案 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函数中定义。