1 Introduction
2 Overview
3 The NED Language
4 Simple Modules
5 Messages
6 The Simulation Library
7 Building Simulation Programs
8 Configuring Simulations
9 Running Simulations
10 Network Graphics And Animation
11 Analyzing Simulation Results
12 Eventlog
13 Documenting NED and Messages
14 Parallel Distributed Simulation
15 Plug-in Extensions
16 Embedding the Simulation Kernel
17 Appendix: NED Reference
18 Appendix: NED Language Grammar
19 Appendix: NED XML Binding
20 Appendix: NED Functions
21 Appendix: Message Definitions Grammar
22 Appendix: Display String Tags
23 Appendix: Configuration Options
24 Appendix: Result File Formats
25 Appendix: Eventlog File Format
1 Introduction
1.1 What is OMNeT++?
1.2 Organization of this manual
1.3 Credits
2 Overview
2.1 Modeling concepts
2.1.1 Hierarchical modules
2.1.2 Module types
2.1.3 Messages, gates, links
2.1.4 Modeling of packet transmissions
2.1.5 Parameters
2.1.6 Topology description method
2.2 Programming the algorithms
2.3 Using OMNeT++
2.3.1 Building and running simulations
2.3.2 What is in the distribution
3 The NED Language
3.1 NED overview
3.2 Warmup
3.2.1 The network
3.2.2 Introducing a channel
3.2.3 The App, Routing and Queue simple modules
3.2.4 The Node compound module
3.2.5 Putting it together
3.3 Simple modules
3.4 Compound modules
3.5 Channels
3.6 Parameters
3.7 Gates
3.8 Submodules
3.9 Connections
3.10 Multiple connections
3.10.1 Connection patterns
3.11 Submodule type as parameter
3.12 Properties (metadata annotations)
3.13 Inheritance
3.14 Packages
4 Simple Modules
4.1 Simulation concepts
4.1.1 Discrete Event Simulation
4.1.2 The event loop
4.1.3 Simple modules in OMNeT++
4.1.4 Events in OMNeT++
4.1.5 Simulation time
4.1.6 FES implementation
4.2 Defining simple module types
4.2.1 Overview
4.2.2 Constructor
4.2.3 Constructor and destructor vs initialize() and finish()
4.2.4 An example
4.2.5 Using global variables
4.3 Adding functionality to cSimpleModule
4.3.1 handleMessage()
4.3.2 activity()
4.3.3 initialize() and finish()
4.3.4 handleParameterChange()
4.3.5 Reusing module code via subclassing
4.4 Accessing module parameters
4.4.1 Volatile and non-volatile parameters
4.4.2 Changing a parameter's value
4.4.3 Further cPar methods
4.4.4 Emulating parameter arrays
4.5 Accessing gates and connections
4.5.1 Gate objects
4.5.2 Connections
4.5.3 The connection's channel
4.6 Sending and receiving messages
4.6.1 Sending messages
4.6.2 Packet transmissions
4.6.3 Delay, data rate, bit error rate, packet error rate
4.6.4 Broadcasts and retransmissions
4.6.5 Delayed sending
4.6.6 Direct message sending
4.6.7 Receiving messages
4.6.8 The wait() function
4.6.9 Modeling events using self-messages
4.7 Stopping the simulation
4.7.1 Normal termination
4.7.2 Raising errors
4.8 Finite State Machines in OMNeT++
4.9 Walking the module hierarchy
4.10 Direct method calls between modules
4.11 Dynamic module creation
4.11.1 When do you need dynamic module creation
4.11.2 Overview
4.11.3 Creating modules
4.11.4 Deleting modules
4.11.5 Module deletion and finish()
4.11.6 Creating connections
4.11.7 Removing connections
5 Messages
5.1 Messages and packets
5.1.1 The cMessage class
5.1.2 Self-messages
5.1.3 Modelling packets
5.1.4 Encapsulation
5.1.5 Attaching parameters and objects
5.2 Message definitions
5.2.1 Introduction
5.2.2 Declaring enums
5.2.3 Message declarations
5.2.4 Inheritance, composition
5.2.5 Using existing C++ types
5.2.6 Customizing the generated class
5.2.7 Using STL in message classes
5.2.8 Summary
5.2.9 What else is there in the generated code?
6 The Simulation Library
6.1 Class library conventions
6.1.1 Base class
6.1.2 Setting and getting attributes
6.1.3 getClassName()
6.1.4 Name attribute
6.1.5 getFullName() and getFullPath()
6.1.6 Copying and duplicating objects
6.1.7 Iterators
6.1.8 Error handling
6.2 Logging from modules
6.3 Simulation time conversion
6.4 Generating random numbers
6.4.1 Random number generators
6.4.2 Random number streams, RNG mapping
6.4.3 Accessing the RNGs
6.4.4 Random variates
6.4.5 Random numbers from histograms
6.5 Container classes
6.5.1 Queue class: cQueue
6.5.2 Expandable array: cArray
6.6 Routing support: cTopology
6.6.1 Overview
6.6.2 Basic usage
6.6.3 Shortest paths
6.7 Statistics and distribution estimation
6.7.1 cStatistic and descendants
6.7.2 Distribution estimation
6.7.3 The k-split algorithm
6.7.4 Transient detection and result accuracy
6.8 Recording simulation results
6.8.1 Output vectors: cOutVector
6.8.2 Output scalars
6.8.3 Precision
6.9 Watches and snapshots
6.9.1 Basic watches
6.9.2 Read-write watches
6.9.3 Structured watches
6.9.4 STL watches
6.9.5 Snapshots
6.9.6 Getting coroutine stack usage
6.10 Deriving new classes
6.10.1 cOwnedObject or not?
6.10.2 cOwnedObject virtual methods
6.10.3 Class registration
6.10.4 Details
6.11 Object ownership management
6.11.1 The ownership tree
6.11.2 Managing ownership
7 Building Simulation Programs
7.1 Overview
7.2 Using gcc
7.2.1 The opp_makemake tool
7.2.2 Basic use
7.2.3 Debug and release builds
7.2.4 Using external C/C++ libraries
7.2.5 Building directory trees
7.2.6 Automatic include dirs
7.2.7 Dependency handling
7.2.8 Out-of-directory build
7.2.9 Building shared and static libraries
7.2.10 Recursive builds
7.2.11 Customizing the Makefile
7.2.12 Projects with multiple source trees
7.2.13 A multi-directory example
8 Configuring Simulations
8.1 Configuring simulations
8.2 The configuration file: omnetpp.ini
8.2.1 An example
8.2.2 File syntax
8.2.3 File inclusion
8.3 Sections
8.3.1 The [General] section
8.3.2 Named configurations
8.3.3 Section inheritance
8.4 Setting module parameters
8.4.1 Using wildcard patterns
8.4.2 Using the default values
8.5 Parameter studies
8.5.1 Basic use
8.5.2 Named iteration variables
8.5.3 Repeating runs with different seeds
8.6 Parameter Studies and Result Analysis
8.6.1 Output vectors and scalars
8.6.2 Configuring output vectors
8.6.3 Saving parameters as scalars
8.6.4 Experiment-Measurement-Replication
8.7 Configuring the random number generators
8.7.1 Number of RNGs
8.7.2 RNG choice
8.7.3 RNG mapping
8.7.4 Automatic seed selection
8.7.5 Manual seed configuration
9 Running Simulations
9.1 Introduction
9.1.1 Running a simulation executable
9.1.2 Running a shared library
9.1.3 Controlling the run
9.2 Cmdenv: the command-line interface
9.2.1 Example run
9.2.2 Command-line switches
9.2.3 Cmdenv ini file options
9.2.4 Interpreting Cmdenv output
9.3 Tkenv: the graphical user interface
9.3.1 Command-line switches
9.4 Batch execution
9.4.1 Using Cmdenv
9.4.2 Using shell scripts
9.4.3 Using opp_runall
9.5 Akaroa support: Multiple Replications in Parallel
9.5.1 Introduction
9.5.2 What is Akaroa
9.5.3 Using Akaroa with OMNeT++
9.6 Troubleshooting
9.6.1 Unrecognized configuration option
9.6.2 Stack problems
9.6.3 Memory leaks and crashes
9.6.4 Simulation executes slowly
10 Network Graphics And Animation
10.1 Display strings
10.1.1 Display string syntax
10.1.2 Display string placement
10.1.3 Display string inheritance
10.1.4 Display string tags used in submodule context
10.1.5 Display string tags used in module background context
10.1.6 Connection display strings
10.1.7 Message display strings
10.2 Parameter substitution
10.3 Colors
10.3.1 Color names
10.3.2 Icon colorization
10.4 The icons
10.4.1 The image path
10.4.2 Categorized icons
10.4.3 Icon size
10.5 Layouting
10.6 Enhancing animation
10.6.1 Changing display strings at runtime
10.6.2 Bubbles
11 Analyzing Simulation Results
11.1 Result files
11.1.1 Results
11.1.2 Output vectors
11.1.3 Format of output vector files
11.1.4 Scalar results
11.2 The Analysis Tool in the Simulation IDE
11.3 Scave Tool
11.3.1 Filter command
11.3.2 Index command
11.3.3 Summary command
11.4 Alternative statistical analysis and plotting tools
11.4.1 Spreadsheet programs
11.4.2 GNU R
11.4.3 MATLAB or Octave
11.4.4 NumPy and MatPlotLib
11.4.5 ROOT
11.4.6 Gnuplot
11.4.7 Grace
12 Eventlog
12.1 Introduction
12.2 Configuration
12.2.1 File Name
12.2.2 Recording Intervals
12.2.3 Recording Modules
12.2.4 Recording Message Data
12.3 Eventlog Tool
12.3.1 Filter
12.3.2 Echo
13 Documenting NED and Messages
13.1 Overview
13.2 Documentation comments
13.2.1 Private comments
13.2.2 More on comment placement
13.3 Text layout and formatting
13.3.1 Paragraphs and lists
13.3.2 Special tags
13.3.3 Text formatting using HTML
13.3.4 Escaping HTML tags
13.4 Customizing and adding pages
13.4.1 Adding a custom title page
13.4.2 Adding extra pages
13.4.3 Incorporating externally created pages
14 Parallel Distributed Simulation
14.1 Introduction to Parallel Discrete Event Simulation
14.2 Assessing available parallelism in a simulation model
14.3 Parallel distributed simulation support in OMNeT++
14.3.1 Overview
14.3.2 Parallel Simulation Example
14.3.3 Placeholder modules, proxy gates
14.3.4 Configuration
14.3.5 Design of PDES Support in OMNeT++
15 Plug-in Extensions
15.1 Overview
15.2 Plug-in descriptions
15.2.1 Defining a new random number generator
15.2.2 Defining a new scheduler
15.2.3 Defining a new configuration provider
15.2.4 Defining a new output scalar manager
15.2.5 Defining a new output vector manager
15.2.6 Defining a new snapshot manager
15.3 Accessing the configuration
15.3.1 Defining new configuration options
15.3.2 Reading values from the configuration
15.4 Implementing a new user interface
16 Embedding the Simulation Kernel
16.1 Architecture
16.2 Embedding the OMNeT++ simulation kernel
16.2.1 The main() function
16.2.2 The simulate() function
16.2.3 Providing an environment object
16.2.4 Providing a configuration object
16.2.5 Loading NED files
16.2.6 How to eliminate NED files
16.2.7 Assigning module parameters
16.2.8 Extracting statistics from the model
16.2.9 The simulation loop
16.2.10 Multiple, coexisting simulations
16.2.11 Installing a custom scheduler
16.2.12 Multi-threaded programs
17 Appendix: NED Reference
17.1 Syntax
17.1.1 NED file extension
17.1.2 NED file encoding
17.1.3 Reserved words
17.1.4 Identifiers
17.1.5 Case sensitivity
17.1.6 Literals
17.1.7 Comments
17.1.8 Grammar
17.2 Built-in definitions
17.3 Packages
17.3.1 Package declaration
17.3.2 Directory structure, package.ned
17.4 Components
17.4.1 Simple modules
17.4.2 Compound modules
17.4.3 Networks
17.4.4 Channels
17.4.5 Module interfaces
17.4.6 Channel interfaces
17.4.7 Resolving the implementation C++ class
17.4.8 Properties
17.4.9 Parameters
17.4.10 Gates
17.4.11 Submodules
17.4.12 Connections
17.4.13 Inner types
17.4.14 Name uniqueness
17.4.15 Type name resolution
17.4.16 Implementing an interface
17.4.17 Inheritance
17.4.18 Network build order
17.5 Expressions
17.5.1 Operators
17.5.2 Referencing parameters and loop variables
17.5.3 The index operator
17.5.4 The sizeof() operator
17.5.5 The xmldoc() operator
17.5.6 Functions
17.5.7 Units of measurement
18 Appendix: NED Language Grammar
19 Appendix: NED XML Binding
20 Appendix: NED Functions
21 Appendix: Message Definitions Grammar
22 Appendix: Display String Tags
22.1 Module and connection display string tags
22.2 Message display string tags
23 Appendix: Configuration Options
23.1 Configuration Options
23.2 Predefined Configuration Variables
24 Appendix: Result File Formats
24.1 Version
24.2 Run Declaration
24.3 Attributes
24.4 Module Parameters
24.5 Scalar Data
24.6 Vector Declaration
24.7 Vector Data
24.8 Index Header
24.9 Index Data
24.10 Statistics Object
24.11 Field
24.12 Histogram Bin
25 Appendix: Eventlog File Format
OMNeT++ is an object-oriented modular discrete event network simulation framework. It has a generic architecture, so it can be (and has been) used in various problem domains:
OMNeT++ itself is not a simulator of anything concrete, but it rather provides infrastructure and tools for writing simulations. One of the fundamental ingredients of this infrastructure is a component architecture for simulation models. Models are assembled from reusable components termed modules. Well-written modules are truly reusable, and can be combined in various ways like LEGO blocks.
Modules can be connected with each other via gates (other systems would call them ports), and combined to form compound modules. The depth of module nesting is not limited. Modules communicate through message passing, where messages may carry arbitrary data structures. Modules can may messages along predefined paths via gates and connections, or directly to their destination; the latter is useful for wireless simulations, for example. Modules may have parameters, which can be used to customize module behaviour, and/or to parameterize the model's topology. Modules at the lowest level of the module hierarchy are called simple modules, and they encapsulate behaviour. Simple modules are programmed in C++, and make use of the simulation library.
OMNeT++ simulations can be run under various user interfaces. Graphical, animating user interfaces are highly useful for demonstration and debugging purposes, and command-line user interfaces are best for batch execution.
The simulator as well as user interfaces and tools are highly portable. They are tested on the most common operating systems (Linux, Mac OS/X, Windows), and they can be compiled out of the box or after trivial modifications on most Unix-like operating systems.
OMNeT++ also supports parallel distributed simulation. OMNeT++ can use several mechanisms for communication between partitions of a parallel distributed simulation, for example MPI or named pipes. The parallel simulation algorithm can easily be extended or new ones plugged in. Models do not need any special instrumentation to be run in parallel -- it is just a matter of configuration. OMNeT++ can even be used for classroom presentation of parallel simulation algorithms, because simulations can be run in parallel even under the GUI which provides detailed feedback on what is going on.
OMNEST is the commercially supported version of OMNeT++. OMNeT++ is only free for academic and non-profit use -- for commercial purposes one needs to obtain OMNEST licenses from Simulcraft Inc.
The manual is organized the following way:
OMNeT++ has been developed by András Varga (andras@omnetpp.org, andras.varga@omnest.com).
In the early stage of the project, several people have contributed to OMNeT++. Although most contributed code is no longer part of the OMNeT++, nevertheless I'd like to acknowledge the work of the following people. First of all, I'd like thank Dr György Pongor (pongor@hit.bme.hu), my advisor at the Technical University of Budapest who initiated the OMNeT++ as a student project.
My fellow student Ákos Kun started to program the first NED parser in 1992-93, but it was abandoned after a few months. The first version of nedc was finally developed in summer 1995, by three exchange students from TU Delft: Jan Heijmans, Alex Paalvast and Robert van der Leij. nedc was first called JAR after their initials until it got renamed to nedc. nedc was further developed and refactored several times until it finally retired and got replaced by nedtool in OMNeT++ 3.0. The second group of Delft exchange students (Maurits André, George van Montfort, Gerard van de Weerd) arrived in fall 1995. They performed some testing of the simulation library, and wrote some example simulations, for example the original version of Token Ring, and simulation of the NIM game which survived until OMNeT++ 3.0. These student exchanges were organized by Dr. Leon Rothkranz at TU Delft, and György Pongor at TU Budapest.
The diploma thesis of Zoltán Vass (spring 1996) was to prepare OMNeT++ for parallel execution over PVM to OMNeT++. This code has been replaced with the new Parallel Simulation Architecture in OMNeT++ 3.0. Gábor Lencse (lencse@hit.bme.hu) was also interested in parallel simulation, namely a method called Statistical Synchronization (SSM). He implemented the FDDI model (practically unchanged until now), and added some extensions into NED for SSM. These extensions have been removed since then (OMNeT++ 3.0 does parallel execution on different principles).
The P2 algorithm and the original implementation of the k-split algorithm was programmed in fall 1996 by Babak Fakhamzadeh from TU Delft. k-split was later reimplemented by András.
Several bugfixes and valuable suggestions for improvements came from the user community of OMNeT++. It would be impossible to mention everyone here, and the list is constantly growing -- instead, the README and ChangeLog files contain acknowledgements.
Between summer 2001 and fall 2004, the OMNeT++ CVS was hosted at the University of Karlsruhe. Credit for setting up and maintaining the CVS server goes to Ulrich Kaage. Ulrich can also be credited with converting the User Manual from Microsoft Word format to LaTeX, which was a huge undertaking and great help.