I want to modify some parameters of element's .ini file in OMNeT++, say a node's transmission rate, during the simulation run, e.g. when a node receives some control message.
I found information saying that it's possible to somehow loop the configuration stated as: some_variable = ${several values}, but there are no conditional clauses in .ini files and no way to pass to those files any data from C++ functions (as far as I'm concerned).
I use INET, but maybe some other models' users already bothered with such a problem.
While you can certainly manually change volatile parameters, OMNeT++ (as far as I am aware) offers no integrated support for automatic changing of parameters at runtime.
You can, however, write some model code that changes volatile parameters programatically.
I found information saying that it's possible to somehow loop the configuration stated as: some_variable = ${several values}, but there are no conditional clauses in .ini files and no way to pass to those files any data from C++ functions (as far as I'm concerned).
In fact you can use the built-in constraint expression in the INI file. This will allow you to create runs for the given configuration while respecting the specified constraint (condition).
However, this constraint will only apply to the parameters that are specified in the .ini file, i.e. this won't help you if the variable which you are trying to change is computed dynamically as part of the code
Below, I give you a rather complicated "code-snippet" from the .ini file which uses many of the built-in functions that you have mentioned (variable iteration, conditionals etc.)
# Parameter assignment using iteration loops and constrains #
# first define the static values on which the others depend #
scenario.node[*].application.ADVlowerBound = ${t0= 0.1}s
scenario.node[*].application.aggToServerUpperBound = ${t3= 0.9}s
#
## assign values to "dependent" parameters using variable names and loop iterations #
scenario.node[*].application.ADVupperBound = ${t1= ${t0}..${t3} step 0.1}s # ADVupperBound == t1; t1 will take values starting from t0 to t3 (0.1 - 0.9) iterating 0.1
scenario.node[*].application.CMtoCHupperBound = ${t2= ${t0}..${t3} step 0.1}s
#
## connect "dependent" parameters to their "copies" -- this part of the snippet is only variable assignment.
scenario.node[*].application.CMtoCHlowerBound = ${t11 = ${t1}}s
scenario.node[*].application.joinToServerLowerBound = ${t12 = ${t1}}s
#
scenario.node[*].application.aggToServerLowerBound = ${t21 = ${t2}}s
scenario.node[*].application.joinToServerUpperBound = ${t22 = ${t2}}s
#
constraint = ($t0) < ($t1) && ($t1) < ($t2) && ($t2) < ($t3)
# END END END #
The code above creates all the possible combinations of time values for t0
to t3
, where they can take values between 0.1
and 0.9
.
t0
and t3
are the beginning and the end points, respectively. t1
and t2
take values based on them.
t1
will take values between t0
and t3
each time being incremented by 0.1
(see the syntax above). The same is true for t2
too.
However, I want t0
to always be smaller than t1
, t1
smaller than t2
, and t2
smaller than t3
. I specify these conditions in the constraint
section.
I am sure, a thorough read through this section of the manual, will help you find the solution.
If you want to change some value during the simulation you can just do that in your C++ code. Something like:
handleMessage(cMessage *msg){
if(msg->getKind() == yourKind){ // replace yourKind with the one you are using for these messages
transmission_rate = new_value;
}
What you are refering to as some_variable = ${several values} can be used to perform multiple runs with different parameters. For example one run with a rate of 1s, one with 2s and one with 10s. That would then be:
transsmission_rate = ${1, 2, 10}s
For more detailed information how to use such values (like to do loops) see the relevant section in the OMNeT++ User Manual