Tictoc Example Simulation-OMNeT

Tictoc Example Simulation-OMNeTCSE 247BlockedUnblockFollowFollowingJan 2IntroductionWe assume that you have good C++ knowledge, and you are in general familiar with C/C++ development (editing source files, compiling, debugging etc.

)Part 1 — Getting Started1.

1 The modelFor a start, let us begin with a “network” that consists of two nodes.

The nodes will do something simple: one of the nodes will create a packet, and the two nodes will keep passing the same packet back and forth.

We’ll call the nodes tic and toc.


2 Setting up the projectchoose New -> OMNeT++ Project from the menu.

Enter tictoc as project name, choose Empty project when asked about the initial content of the project, then click Finish.


3 Adding the NED fileOMNeT++ uses NED files to define components and to assemble them into larger units like networks.

We start implementing our model by adding a NED file.

To add the file to the project, right-click the project directory in the Project Explorer panel on the left, and choose New -> Network Description File (NED) from the menu.

Enter tictoc1.

ned when prompted for the file name.

Once created, the file can be edited in the Editor area of the OMNeT++ IDE.

The OMNeT++ IDE’s NED editor has two modes, Design and Source; one can switch between them using the tabs at the bottom of the editor.

In Design mode, the topology can be edited graphically, using the mouse and the palette on the right.

In Source mode, the NED source code can be directly edited as text.

Changes done in one mode will be immediately reflected in the other, so you can freely switch between modes during editing, and do each change in whichever mode it is more convenient.

Switch into Source mode, and enter the following:simple Txc1{ gates: input in; output out;}network Tictoc1{ submodules: tic: Txc1; toc: Txc1; connections: tic.

out –> { delay = 100ms; } –> toc.

in; tic.

in <– { delay = 100ms; } <– toc.

out;}When you’re done, switch back to Design mode.

You should see something like this:The first block in the file declares Txc1 as a simple module type.

Simple modules are atomic on NED level.

They are also active components, and their behavior is implemented in C++.

The declaration also says that Txc1 has an input gate named in, and an output gate named out.

The second block declares Tictoc1 as a network.

Tictoc1 is assembled from two submodules, tic and toc, both instances of the module type Txc1.

tic's output gate is connected to toc's input gate, and vica versa.

There will be a 100ms propagation delay both ways.


4 Adding the C++ filesWe now need to implement the functionality of the Txc1 simple module in C++.

Create a file named txc1.

cc by choosing New -> Source File from the project's context menu (or File -> New -> File from the IDE's main menu), and enter the following content:#include <string.

h>#include <omnetpp.

h>using namespace omnetpp;class Txc1 : public cSimpleModule{ protected: virtual void initialize() override; virtual void handleMessage(cMessage *msg) override;};Define_Module(Txc1);void Txc1::initialize(){ if (strcmp("tic", getName()) == 0) { cMessage *msg = new cMessage("tictocMsg"); send(msg, "out"); }}void Txc1::handleMessage(cMessage *msg){ send(msg, "out");}The Txc1 simple module type is represented by the C++ class Txc1.

The Txc1 class needs to subclass from OMNeT++'s cSimpleModule class, and needs to be registered in OMNeT++ with the Define_Module() macro.

We redefine two methods from cSimpleModule: initialize() and handleMessage().

They are invoked from the simulation kernel: the first one only once, and the second one whenever a message arrives at the module.

In initialize() we create a message object (cMessage), and send it out on gate out.

Since this gate is connected to the other module's input gate, the simulation kernel will deliver this message to the other module in the argument to handleMessage() — after a 100ms propagation delay assigned to the link in the NED file.

The other module just sends it back (another 100ms delay), so it will result in a continuous ping-pong.

Messages (packets, frames, jobs, etc) and events (timers, timeouts) are all represented by cMessage objects (or its subclasses) in OMNeT++.

After you send or schedule them, they will be held by the simulation kernel in the “scheduled events” or “future events” list until their time comes and they are delivered to the modules via handleMessage().

Note that there is no stopping condition built into this simulation: it would continue forever.

You will be able to stop it from the GUI.

(You could also specify a simulation time limit or CPU time limit in the configuration file)1.

5 Adding omnetpp.

iniTo be able to run the simulation, we need to create an omnetpp.

ini file.


ini tells the simulation program which network you want to simulate (as NED files may contain several networks), you can pass parameters to the model, explicitly specify seeds for the random number generators, etc.

Create an omnetpp.

ini file using the File -> New -> Initialization file (INI) menu item.

The new file will open in an Inifile Editor.

As the NED Editor, the Inifile Editor also has two modes, Form and Source, which edit the same content.

For now, just switch to Source mode and enter the following:[General]network = Tictoc1You can verify the result in Form mode:tictoc2 and further steps will all share a common omnetpp.

ini file.

Part 2 — Running the Simulation2.

1 Launching the simulation programOnce you complete the above steps, you can launch the simulation by selecting %omnetpp.

ini (in either the editor area or the Project Explorer), and pressing the Run button.

The IDE will build your project automatically.

If there are compilation errors, you need to rectify those until you get an error-free compilation and linking.

You can manually trigger a build by hitting choosing Project -> Build All from the menu, or hitting Ctrl+B.


2 Running the simulationAfter successfully building and launching your simulation, you should see a new GUI window appear, similar to the one in the screenshot below.

The window belongs to Qtenv, the main OMNeT++ simulation runtime GUI.

You should also see the network containing tic and toc displayed graphically in the main area.

Press the Run button on the toolbar to start the simulation.

What you should see is that tic and toc are exchanging messages with each other.

The main window toolbar displays the current simulation time.

This is virtual time, it has nothing to do with the actual (or wall-clock) time that the program takes to execute.

Actually, how many seconds you can simulate in one real-world second depends highly on the speed of your hardware and even more on the nature and complexity of the simulation model itself.

You can play with slowing down the animation or making it faster with the slider at the top of the graphics window.

You can stop the simulation by hitting F8 (equivalent to the STOP button on the toolbar), single-step through it (F4), run it with (F5) or without (F6) animation.

F7 (express mode) completely turns off tracing features for maximum speed.


3 DebuggingThe simulation is just a C++ program, and as such, it often needs to be debugged while it is being developed.

The simulation can be started in debug mode by clicking the Debug button on the IDE’s main toolbar.

This will cause the simulation program to be launched under a debugger (usually gdb).

The IDE will also switch into “Debug perspective”, i.


rearrange its various panes and views to a layout which is better suited to debugging.

You can end the debugging session with the Terminate button (a red square) on the toolbar.

Runtime errorsDebugging is most often needed to track down runtime errors.

Let’s try it!.First, deliberately introduce an error into the program.

In txc1.

cc, duplicate the send() line insidehandleMessage(), so that the code looks like this:void Txc1::handleMessage(cMessage *msg){ //.

send(msg, "out"); // send out the message send(msg, "out"); // THIS SHOULD CAUSE AN ERROR}When you launch the simulation in normal mode (Run button) and try to run it, you’ll get an error message like this:Now, run the simulation in Debug mode.

Due to a debug-on-errors option being enabled by default, the simulation program will stop in the debugger.

You can locate the error by examining the stack trace (the list of nested function calls) in the Debug view:You can see that it was OMNeT++’s breakIntoDebuggerIfRequested() method that activated the debugger.

From then on, you need to search for a function that looks familiar, i.


for one that is part of the model.

In our case, that is the "Txc1::handleMessage() at txc1.

cc:54" line.

Selecting that line will show you the corresponding source code in the editor area, and lets you examine the values of variables in the Variables view.

This information will help you determine the cause of the error and fix it.

CrashesTracking down crashes i.


segfaults is similar, let’s try that as well.

Undo the previous source code edit (remove the duplicate send() line), and introduce another error.

Let's pretend we forgot to create the message before sending it, and change the following lines in initialize()cMessage *msg = new cMessage("tictocMsg"); send(msg, "out");to simplycMessage *msg; // no initialization!.send(msg, "out");When you run the simulation, it will crash.

(You will get an error message similar to “Simulation terminated with exit code: 139”).

If you launch the simulation again, this time in Debug mode, the crash will bring you into the debugger.

Once there, you’ll be able to locate the error in the Debugview and examine variables, which will help you identify and fix the bug.

BreakpointsYou can also manually place breakpoints into the code.

Breakpoints will stop execution, and let you examine variables, execute the code line-by-line, or resume execution (until the next breakpint).

A breakpoint can be placed at a specific line in the source code by double-clicking on the left gutter in the editor, or choosing Toggle Breakpoint from the context menu.

The list of active (and inactive) breakpoints can be examined in the Breakpoints view.

Debug next eventIf you did the previous exercise, you must have noticed that the breakpoint was triggered at each and every event in the Txc1 simple module.

In real life it often occurs that an error only surfaces at, say, the 357th event in that module, so ideally that’s when you’d want to start debugging.

It is not very convenient to have to hit Resume 356 times just to get to the place of the error.

A possible solution is to add a condition or an ignore-count to the breakpoint (see Breakpoint Properties in its context menu).

However, there is a potentially more convenient solution.

In Qtenv, use Run Until to get to the event to be debugged.

Then, choose Simulation -> Debug Next Event from the menu.

This will trigger a breakpoint in the debugger at the beginning of handleMessage() of the next event, and you can start debugging that event.


4 The Debug/Run dialogLet us return to launching simulations once more.

When you launch the simulation program with the Run or Debug buttons on the IDE toolbar, settings associated with the launch are saved in a launch configuration.

Launch configurations can be viewed in the Run/Debug Configurations dialog which can be opened e.


by clicking the little down arrow next to the Run (Debug) toolbar button to open a menu, and choosing Run (Debug) Configurations… in it.

In the same menu, you can also click the name of a launch configuration (e.


tictoc) while holding down the Ctrl key to open the dialog with the corresponding configuration.

The dialog allows you activate various settings for the launch.


5 Visualizing on a Sequence ChartThe OMNeT++ simulation kernel can record the message exchanges during the simulation into an event log file.

use the Record button in the Qtenv graphical runtime environment after launching.

The log file can be analyzed later with the Sequence Chart tool in the IDE.

The results directory in the project folder contains the .

elog file.

Double-clicking on it in the OMNeT++ IDE opens the Sequence Chart tool and the event log tab at the bottom of the window.

The following figure has been created with the Sequence Chart tool and shows how the message is routed between the different nodes in the network.

In this instance, the chart is very simple, but when you have a complex model, sequence charts can be very valuable in debugging, exploring or documenting the model’s behaviour.


. More details

Leave a Reply