Changing model parameters by cPar in other module

695 views Asked by At

I am using this module hierarchy :

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

I have given some initial parameter in the ini file for udpApp as :

**.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

But at run time I want to change the startTime and stopTime for udpAPP[0] through CNPCBeacon module. Hence I changed CNPCBeacon.cc as:-

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");

And I am successfully able to receive the values of startTime and stopTime. However I want to change these value in current module, which is resulting in an error by following code:

udpmod->par("startTime").setDoubleValue(4.2);

Can anybody please suggest me a way to change it at run time.

1

There are 1 answers

4
user4786271 On BEST ANSWER

Declaring your parameter as volatile should solve your problem. But for future reference I'll provide further explanation below


Volatile vs. non-volatile:

Here it depends how you want to use this parameter. Mainly via the .ini file you have two types of parameters: volatile and non-volatile.

volatile parameters are read every time during your run. That woule be helpful if you want this parameter to be generated by a built-in function, for example, uniform(0,10) each time this volatile parameter will get a different value.

On the other hand non-volatile parameters are read just one, as they don't change from run to run.

Using the volatile type parameter does not give you full flexibility, in the sense that your parameter value will always fall with in a range predefined in the .ini


Dynamic Variable (parameter) Reassignment:

Instead what you could do is use a more robust approach, and re-define the variable which stores the value from that module parameter each time you have to do so.

For example in your case you could do the following:

varHoldingStartTime = par("startTime").doubleValue();
varHoldingStartTime = 4.2;

This way the actual value will change internally without reflecting to your run.


Parameter Studies:

Alternatively if you want this change of the parameter to be applied to multiple runs you could use the advanced built-in approach provided by OMNeT++ which allows you to perform Parameter Studies.

I have explained here how Parameter Studies work: https://stackoverflow.com/a/30572095/4786271 and also here how it can be achieved with constraints etc: https://stackoverflow.com/a/29622426/4786271

If none of the approaches suggested by me fit your case, answers to this question altogether might solve your problem: How to change configuration of network during simulation in OMNeT++?


EDIT: extending the answer to roughly explain handleParameterChange()

I have not used handleParameterChange() before as well, but from what can I see this function provides a watchdog functionality to the module which utilizes it.

To activate this functionality first the void handleParameterChange(const char *parameterName); has to be re-defined.

In essence what it seems to do is the following:

Assume we have two modules moduleA and moduleB and moduleB has parameter parB. moduleA changes the parB and when that happens, moduleB reacts to this change based on the behaviour defined in:

moduleB::handleParameterChange(parB);

The behaviour could be re-reading the original value for parB from the .ini etc.