在其他模块中通过cPar更改模型参数 [英] Changing model parameters by cPar in other module

查看:298
本文介绍了在其他模块中通过cPar更改模型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用这个模块层次结构:




  • 节点:{udpApp [0]< udp→networkLayer→wlan [0]}和wlan [0]:{CNPCBeacon→mac→radio}



    • 我在 ini 文件中给出了一些初始参数,用于 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

      但是在运行时我想改变 startTime stopTime udpAPP [0] 通过 CNPCBeacon 模块。因此,我将 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 应该可以解决您的问题。






      易失性与非易失性 / p>

      这里它取决于你想如何使用这个参数。主要通过 .ini 文件有两种类型的参数: volatile 非易失性



      volatile 参数在运行期间每次都会被读取。如果您希望通过内置函数生成此参数,例如 uniform(0,10),每次此volatile参数将获得不同的值值。



      另一方面,非易失性参数只读取一个,因为它们不会从运行更改为



      使用 volatile 类型参数不能提供完全的灵活性,总是落在 .ini

      中预定义的范围内。




      动态变量(参数)重新分配:



      您可以做的是使用更稳健的方法,并重新定义存储



      例如,在您的情况下,您可以执行以下操作:

        varHoldingStartTime = par(startTime)。doubleValue(); 
      varHoldingStartTime = 4.2;

      这样,实际值将在内部更改,而不会反映到您的运行中。






      参数研究:



      的参数应用于多个运行,您可以使用OMNeT ++提供的高级内置方法,它允许您执行参数研究



      我在这里解释了参数研究的工作原理: http:// stackoverflow。 com / a / 30572095/4786271 ,以及在这里如何使用约束等实现它: http://stackoverflow.com / a / 29622426/4786271



      如果我建议的方法都不适合您的情况,这个问题的答案完全可能解决您的问题:如何在OMNeT ++中模拟期间更改网络配置?






      EDIT:扩展答案,大致解释 handleParameterChange()



      我有没有使用 handleParameterChange()之前,但从我可以看到这个功能提供了一个看门狗功能的模块使用它。



      要激活此功能,首先必须重新定义 void handleParameterChange(const char * parameterName);



      本质上它似乎是做以下事情:



      假设我们有两个模块 moduleA moduleB moduleB 有参数 / code>。 moduleA 更改 parB ,当发生这种情况时, moduleB 基于在

        moduleB :: handleParameterChange(parB); 

      行为可能是重新读取 parB 来自 .ini 等。


      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.

      解决方案

      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: http://stackoverflow.com/a/30572095/4786271 and also here how it can be achieved with constraints etc: http://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.

      这篇关于在其他模块中通过cPar更改模型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆