Download presentation
Presentation is loading. Please wait.
Published byHomer Reeves Modified over 8 years ago
1
Introduction to Omnet++ By: Mahsa Soheil Shamaee
2
TicToc Tutorial for OMNeT++ Step 15: Adding statistics collection The OMNeT++ simulation kernel can record a detailed log about your message exchanges automatically by setting the [Config Tictoc15] network = Tictoc15 record-eventlog = true The previous simulation model does something interesting enough so that we can collect some statistics For example, you may be interested in the average hop count a message has to travel before reaching its destination We'll record in the hop count of every message upon arrival into an output vector (a sequence of (time,value) pairs, sort of a time series) We also calculate mean, standard deviation, minimum, maximum values per node, and write them into a file at the end of the simulation Then we'll use tools from the OMNeT++ IDE to analyse the output files For that, we add an output vector object (which will record the data into Tictoc15-0.vec) and a histogram object (which also calculates mean, etc) to the class
3
TicToc Tutorial for OMNeT++ message TicTocMsg15 { int source; int destination; int hopCount = 0;} simple Txc15{ parameters: @display("i=block/routing"); gates: inout gate[];} network Tictoc15 { types: channel Channel extends ned.DelayChannel { delay = 100ms; } submodules: tic[6]: Txc15; connections: tic[0].gate++ Channel tic[1].gate++; tic[1].gate++ Channel tic[2].gate++; tic[1].gate++ Channel tic[4].gate++; tic[3].gate++ Channel tic[4].gate++; tic[4].gate++ Channel tic[5].gate++;} class Txc15 : public cSimpleModule { private: long numSent; long numReceived; cLongHistogram hopCountStats; cOutVector hopCountVector; protected: virtual TicTocMsg15 *generateMessage(); virtual void forwardMessage(TicTocMsg15 *msg); virtual void initialize(); virtual void handleMessage(cMessage *msg); // The finish() function is called by OMNeT++ at the end of the simulation: virtual void finish(); };
4
TicToc Tutorial for OMNeT++ Define_Module(Txc15); void Txc15::initialize() { // Initialize variables numSent = 0; numReceived = 0; WATCH(numSent); WATCH(numReceived); hopCountStats.setName("hopCountStats"); hopCountStats.setRangeAutoUpper(0, 10, 1.5); hopCountVector.setName("HopCount"); // Module 0 sends the first message if (getIndex()==0) { // Boot the process scheduling the initial message as a self-message. TicTocMsg15 *msg = generateMessage(); scheduleAt(0.0, msg); } void Txc15::handleMessage(cMessage *msg) { TicTocMsg15 *ttmsg = check_and_cast (msg); if (ttmsg->getDestination()==getIndex()) { // Message arrived int hopcount = ttmsg->getHopCount(); EV << "Message " << ttmsg << " arrived after " << hopcount << " hops.\n"; bubble("ARRIVED, starting new one!"); // update statistics. numReceived++; hopCountVector.record(hopcount); hopCountStats.collect(hopcount); delete ttmsg;. }
5
TicToc Tutorial for OMNeT++ void Txc15::finish() { // This function is called by OMNeT++ at the end of the simulation. EV << "Sent: " << numSent << endl; EV << "Received: " << numReceived << endl; EV << "Hop count, min: " << hopCountStats.getMin() << endl; EV << "Hop count, max: " << hopCountStats.getMax() << endl; EV << "Hop count, mean: " << hopCountStats.getMean() << endl; EV << "Hop count, stddev: " << hopCountStats.getStddev() << endl; recordScalar("#sent", numSent); recordScalar("#received", numReceived); hopCountStats.recordAs("hop count"); } hopCountVector.record() call writes the data into Tictoc15-0.vec With a large simulation model or long execution time, the Tictoc15-0.vec file may grow very large To handle this situation, you can specifically disable/enable vector in omnetpp.ini, and you can also specify a simulation time interval in which you're interested (data recorded outside this interval will be discarded) When you begin a new simulation, the existing Tictoc15- 0.vec/sca file gets deleted Scalar data (collected by the histogram object in this simulation) have to be recorded manually, in the finish() function finish() gets invoked on successful completion of the simulation, i.e. not when it's stopped with an error The recordScalar() calls in the code below write into the Tictoc15-0.sca file The files are stored in the results/ subdirectory.
6
TicToc Tutorial for OMNeT++. Step 16: Statistic collection without modifying your model In the previous step we have added statistic collection to our model While we can compute and save any value we wish, usually it is not known at the time of writing the model, what data the enduser will need OMNeT++ 4.1 provides an additional mechanism to record values and events Any model can emit 'signals' that can carry a value or an object The model writer just have to decide what signals to emit, what data to attach to them and when to emit them The enduser can attach 'listeners' to these signals that can process or record these data items This way the model code does not have to contain any code that is specific to the statistics collection and the enduser can freely add additional statistics without even looking into the C++ code We will re-write the statistic collection introduced in the last step to use signals First of all, we can safely remove all statistic related variables from our module. There is no need for the cOutVector and cLongHistogram classes eithercOutVectorcLongHistogram We will need only a single signal that carries the hopCount of the message at the time of message arrival at the destination First we need to define our signal. The arrivalSignal is just an identifier that can be used later to easily refer to our signal
7
TicToc Tutorial for OMNeT++. class Txc16 : public cSimpleModule { private: simsignal_t arrivalSignal; protected: virtual TicTocMsg16 *generateMessage(); virtual void forwardMessage(TicTocMsg16 *msg); virtual void initialize(); virtual void handleMessage(cMessage *msg); }; Define_Module(Txc16); void Txc16::initialize() { arrivalSignal = registerSignal("arrival"); // Module 0 sends the first message if (getIndex()==0) { // Boot the process scheduling the initial message as a self-message. TicTocMsg16 *msg = generateMessage(); scheduleAt(0.0, msg); } We must register all signals before using them The best place to do this is the initialize() method of the module void Txc16::handleMessage(cMessage *msg) { TicTocMsg16 *ttmsg = check_and_cast (msg); if (ttmsg->getDestination()==getIndex()) { // Message arrived int hopcount = ttmsg->getHopCount(); // send a signal emit(arrivalSignal, hopcount); EV << "Message " << ttmsg << " arrived after " << hopcount << " hops.\n"; bubble("ARRIVED, starting new one!"); delete ttmsg; Now we can emit our signal, when the message has arrived to the destination node As we do not have to save or store anything manually, the finish() method can be deleted. We no longer need it
8
TicToc Tutorial for OMNeT++. simple Txc16 { parameters: @signal[arrival](type="long"); @statistic[hopCount](title="hop count"; source="arrival"; record=vector,stats; interpolationmode=none); @display("i=block/routing"); gates: inout gate[]; } network Tictoc16 { types: channel Channel extends ned.DelayChannel { delay = 100ms; } submodules: tic[6]: Txc16; connections: tic[0].gate++ Channel tic[1].gate++; tic[1].gate++ Channel tic[2].gate++; tic[1].gate++ Channel tic[4].gate++; tic[3].gate++ Channel tic[4].gate++; tic[4].gate++ Channel tic[5].gate++; } Define the emitted signal also in the NED file Declaring signals in the NED file allows you to have all information about your module in one place You will see the parameters it takes, its input and output gates, and also the signals and statistics it provides
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.