Я использую эту иерархию модулей:
Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}
С некоторым параметром ini для udpApp как:
Я дал некоторый начальный параметр в INI-файле для udpApp как:
**.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
Но во время выполнения я хочу изменить startTime и stopTime для udpAPP [0] через модуль CNPCBeacon.
Поэтому я изменил 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 () ?.
Есть ли также какой-либо другой способ создания экземпляра модуля через другой субмодуль.
Спасибо за эту помощь.
Я немного растерялся в иерархии и отношениях между вашими модулями и подмодулями, однако я думаю, что если вы хотите динамически создавать (или заново создавать) модуль, вы можете использовать встроенный подход, предложенный 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 ++, чтобы увидеть, что это значит.
Странно то, что вы получаете эту ошибку для scheduleAt()
метод, который является методом, который принадлежит к фундаментальному классу OMNeT ++ cSimpleModule
, Это означает, что для использования этого метода в вашем классе вам придется наследовать от cSimpleModule
в вашем определении класса.
Может быть, просто сделать что-то вроде:
class MyCurrentClass: public cSimpleModule
{
/* further class definition */
};
… может решить вашу проблему.
Решением для повторной инициализации модуля (целевого модуля) через другой модуль (запрашивающий модуль) является создание функции handleParamterChange () в целевом модуле. handleParameterChange () используется для перечитывания измененного параметра во время настройки. Однако он не запустит событие 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 определен в функции инициализации UdpBasciApp.cc в среде INET.