## RNGs in OMNeT++

This entry was posted by on Saturday, 17 April, 2010 at

In order to mimic realistic behaviour the simulation should not be truly deterministic. Real life circumstances always introduce some randomness to many properties. In simulation this can be modelled by using Random variables (within a certain range) to cater for the varying circumstances in real life.

Choosing a contention window size for the Mac layer backoff, for instance, is influenced by a random variable obtained from a Random Number Generator.

Randomness in Communication
OMNeT++ offers the choice between three different Random Generators (or pseudo-random actually). The default is the Mersenne Twister which uses the MT19937 RNG by Makoto Matsumoto (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html) which has a cycle length of 2^19937-1. LCG32, with a cycle length of 2^31-2, is the legacy RNG used in OMNeT++ versions prior to version 3.0 alpha 9. When using Akaroa a third RNG exists, which we will not further discuss.

A RNG is used by adding the following to omnetpp.ini’s General section:
``` [General] rng-class="cLCG32" # default is "cMersenneTwister" num-rngs=2 ```

A nice thing about these random generators is that they are predictable – they always provide the same stream of output with the same seed. This may appear counter-intuitive—the values are supposed to be random!—but aids in repeating the same simulation run over and over with the exact same random values. By choosing a different seed (or starting at a different point in the stream) a different set of random variates can be used in the simulation run.
A way to seed the RNG is to use the application ‘seedtool’ which comes with OMNeT++:
`seedtool g 1 10000000 8`

Gives 8 seeds 10000000 apart starting at position 1. A RNG can be seeded in omnetpp.ini:
``` seed-0-mt = 1389532321 seed-1-mt = 56577561 ```
And, depending on the number of RNGs used in the simulation, we can now register the RNGs with the model:
``` **.rng-0 = 1 **.rng-1 = 2 ```
What this does: every (hence the **) module’s rng-0 is RNG number 1 and rng-1 is RNG number 2. This allows for great flexibility: for every module we can make different RNGs. For instance, we might use seperate RNGs for the MAC and the Network layer.

The RNGs are ‘automatically’ used. OMNeT++ has a class cRNG from which the different RNG implementations are derived. By using methods from the cRNG interface the registered RNGs are used:
``` /** * Random integer in [0,n), n < intRandMax() */ virtual unsigned long intRand(unsigned long n) = 0; ```
(from cRNG.h)

This gives a random number between 0 and n (excluding n).

Randomness in Mobility
In order to prevent periodicity in the results due to equidistant placement of nodes it would be good to randomly place vehicles on the road. With enough runs we can take mean results giving a view free of periodicity observed in the runs performed met equidistant placement.
The Mobility Framework allows a hosts position to be set in omnetpp.ini:
``` TFSim.host.mobility.x = 100 TFSim.host.mobility.y = 100 ```
This effectively positions host 0 at position (100,100). Supplying a '-1' in stead of a positive value tells the BasicMobility layer to randomly place the host. MF does show some unexpected behaviour here, though:
``` TFSim.host.mobility.x = -1 TFSim.host.mobility.y = 100 ```
Does not position host 0 at a random x position along y=100. This can easily circumvented by altering the implementation of BasicMobility.cc and then recompiling the framework. The changes made are quite straight-forward. By default, BasicMobility.cc chooses a completely random position if either x or y is -1. By adding a few lines a random value is only chosen for the component which is configured with '-1'. This behaves as intended: position host 0 somewhere on the line y = 100.
BasicMobility will use one of the RNGs provided to it in omnetpp.ini:
``` num-rngs = 3 ... seed-2-mt = 23525221 *.mobility.rng-0 = 3 ```
Then in BasicMobility the lines
``` Coord p; p.x = genk_uniform(0, 0, cc->getPgs()->x); p.y = genk_uniform(0, 0, cc->getPgs()->y); return p; ```
Will choose random value from a uniform distribution between 0 and the playground size. The random variables will be provided by the RNG supplied in omnetpp.ini.

One drawback of this approach; if we choose a density to have at least one vehicle in every other vehicle's transmission range the randomness can cause clusters and - more important - gaps. These gaps can be larger than the transmission range, resulting in incorrect end-to-end propagation. For evaluation of the flooding scheme we would like to use a fully connected network.

Solution: do place every vehicle at a certain distance from the previous (like with equidistant placement) but apply a random variation of approx 20% of the inter-vehicle space. This randomness is enough to cause vehicles to sometimes be in one slot and sometimes in the other while not creating gaps in the network. This is implemented in IDMMobilityModel, which also gets information on the desired spacing through the omnetpp.ini file:
``` if(!mobEnabled){ move.startPos.x+= intrand(0.4*spacing)-0.2*spacing; } ```
If mobility is not enabled (e.g. we use a static network for testing the flooding scheme) we apply some randomness to the x position.