Search code examples
vectorsimulationomnet++

Vectors defined in .cc file do not appear in .vec output file


I am using OMNET++ to implement a WBAN network. The network is defined in the WBAN.ned file. There are multiple sensors that I have used and they are defined by Sensor module that extend ApplicationLayerNodeBase and is defined in Sensor.ned. Now the issue is that I have defined some vectors in Sensor.cc to calculate delay, remaining energy and throughput, but they do not appear in the output .vec file. Can you please help me to guide where I went wrong? what could be the possible reason? I did not get any errors in build process. Thanks for your help.

WBAN.ned

package wban;
import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator;
import inet.networklayer.diffserv.BehaviorAggregateClassifier;
import inet.node.ethernet.Eth100M;
import inet.node.ethernet.Eth1G;
import inet.node.ethernet.EthernetSwitch;
import inet.node.inet.SensorNode;
import inet.node.inet.StandardHost;
import inet.physicallayer.wireless.apsk.packetlevel.ApskScalarRadioMedium;
import inet.routing.contract.IManetRouting;
import inet.tutorials.protocol.ServerHost1;
import inet.visualizer.common.IntegratedVisualizer;


network wban
{
    @display("bgb=2294.056,2104.26;i=maps/man;is=l;bgi=maps/italy,s");
    @statistic[residualEnergyCapacity](source="energyStorage"; record=count);
    @statistic[remainingEnergy](source="remainingEnergyVector"; record=vector);
    @statistic[remainingEnergyVector](title="Remaining Energy"; source=remainingEnergyVector; record=vector);

    submodules:
        configurator: Ipv4NetworkConfigurator {
            @display("p=2246.4,111.6");
        }
        visualizer: IntegratedVisualizer {
            @display("p=1873.204,111.402");
        }
        radioMedium: ApskScalarRadioMedium {
            @display("p=2096.008,416.72598");
        }
        temp: Sensor {
            @display("p=878.83795,1877.33;i=misc/node");
        
        }
        om: SensorNode {
            @display("p=590.39996,982.7999;i=misc/node");
        }
        bp: SensorNode {
            @display("p=1712.2899,981.988;i=misc/node");
        }
        ecg: SensorNode {
            @display("p=1213.044,577.63995;i=misc/node");
        }
        gateway: SensorNode {
            @display("p=1006.74396,981.988;i=block/classifier;is=s");
        }
        doctor: StandardHost {
            @display("p=155.144,147.928;i=misc/person3;is=l");
        }
        glo: SensorNode {
            @display("p=1373.958,1877.33;i=misc/node");
        }

        //LVQ: EthernetSwitch {
        //    @display("p=321.828,602.396");
        // }

        MS: SensorNode {
            @display("p=1373.958,1563.7539;i=misc/node");
        }
        EEG: SensorNode {
            @display("p=878.83795,1563.7539;i=misc/node");
        }
        EMG: SensorNode {
            @display("p=920.09796,1320.32;i=misc/node");
        }
        VOICE: SensorNode {
            @display("p=1373.958,1233.674;i=misc/node");
        }
        CE: SensorNode {
            @display("p=1254.304,903.594;i=misc/node");
        }
        //EMERGENCY: StandardHost {
          //  @display("p=717.92395,272.31598;i=device/server,red");
      //  }
    //        ambulance: StandardHost {
    //          @display("p=429.10397,144.40999;i=misc/truck;is=s");
    //    }
    connections:
//        gateway.ethg++ <--> Eth1G <--> LVQ.ethg++;
 //       LVQ.ethg++ <--> Eth1G <--> doctor.ethg++;
  //      LVQ.ethg++ <--> Eth1G <--> EMERGENCY.ethg++;
   //     LVQ.ethg++ <--> Eth1G <--> ambulance.ethg++;

        gateway.ethg++ <--> Eth1G <--> doctor.ethg++;
      //  gateway.ethg++ <--> Eth1G <--> EMERGENCY.ethg++;
        //gateway.ethg++ <--> Eth1G <--> ambulance.ethg++;
}

Sensor.ned

package wban;
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
//

import inet.node.base.ApplicationLayerNodeBase;
module Sensor extends ApplicationLayerNodeBase
{
    parameters:
        double energy;
        double remainingEnergy;
        double transmissionEnergyPerPacket;
        double receptionEnergyPerPacket;
        double distance;
        int numNodes;
        double distanceToBaseStation;
        double sensorDensity;
        double degreeCentrality;
        double betweennessCentrality;
        double distanceToOtherSensors;
        numWlanInterfaces = default(1);
        energyStorage.typename = default("IdealEpEnergyStorage");
        wlan[*].typename = default("Ieee802154NarrowbandInterface");
        wlan[*].radio.energyConsumer.typename = default("SensorStateBasedEpEnergyConsumer");
        
     @class(Sensor);
     @statistic[remainingEnergyVector](title="Remaining Energy"; source=remainingEnergyVector; record=vector);
     @statistic[delayVector](title="Delay"; source=delayVector; record=vector);
  
}

Sensor.cc

#include <omnetpp.h>

#include <vector>



using namespace omnetpp;
class Sensor : public cSimpleModule
{
  private:
    double energy;
    double distance;
    int numNodes;
    double remainingEnergy;
    double distanceToBaseStation;
    double sensorDensity;
    double degreeCentrality;
    double betweennessCentrality;
    double distanceToOtherSensors;
    double threshold1;
    double threshold2;
    double threshold3;
    double threshold4;
    double threshold5;
    double threshold6;
    double threshold7;
    bool isClusterHead;

    double transmissionEnergyPerPacket; //added it for packet transmission energy
    double receptionEnergyPerPacket; //added it for packet reception energy

    int numPacketsSent;
    int numPacketsReceived;
    double throughput;

    simtime_t lastTimestamp; //added this for delay calculation

    cOutVector remainingEnergyVector;
    cOutVector delayVector;


    void energyAwareClustering();
    void distanceBasedClustering();
    void centralityBasedClustering();
    void calculateThroughput();



  public:
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
    virtual void updateEnergyConsumption(double energyConsumed);
    //void calculateEndToEndDelay(simtime_t timestamp);
    virtual void finish() override;


};

Define_Module(Sensor);

void Sensor::initialize()
{
    energy = par("energy").doubleValue();
    distance = par("distance").doubleValue();
    int numNodes = par("numNodes");


    numPacketsSent = 0;
    numPacketsReceived = 0;
    throughput = 0;
    lastTimestamp = simTime();

    remainingEnergy = energy;
    distanceToBaseStation = par("distanceToBaseStation").doubleValue();
    sensorDensity = par("sensorDensity").doubleValue();
    degreeCentrality = par("degreeCentrality").doubleValue();
    betweennessCentrality = par("betweennessCentrality").doubleValue();
    isClusterHead = false;


    // Here I have added the energy consumption parameters considering basic energy model
    transmissionEnergyPerPacket = 0.01;  // Energy per packet transmission
    receptionEnergyPerPacket = 0.005;    // Energy per packet reception


    energyAwareClustering();
    distanceBasedClustering();
    centralityBasedClustering();

    lastTimestamp = simTime();
}

void Sensor::handleMessage(cMessage *msg)
{
    // Handle messages and update remaining energy, distance to base station, sensor density, degree centrality, and betweenness centrality
    energyAwareClustering();
    distanceBasedClustering();
    centralityBasedClustering();


    // Energy consumption calculations
        int packetSize = 50;  // Set the packet size here

        if (isClusterHead) {
                double transmissionEnergy = transmissionEnergyPerPacket * packetSize;
                updateEnergyConsumption(transmissionEnergy);

                simtime_t currentTimestamp = simTime();
                simtime_t delay = currentTimestamp - lastTimestamp; //
                delayVector.record(delay.dbl()); // Record the delay value
                lastTimestamp = currentTimestamp; // Update the lastTimestamp
                numPacketsReceived++;
            }
            else {
                double receptionEnergy = receptionEnergyPerPacket * packetSize;
                updateEnergyConsumption(receptionEnergy);
                numPacketsReceived++;
            }

        remainingEnergyVector.record(remainingEnergy); // Record the remainingEnergy value

    delete msg;
}

void Sensor::updateEnergyConsumption(double energyConsumed)
{
    remainingEnergy -= energyConsumed;

    // Perform any other necessary actions related to energy consumption
}


void Sensor::energyAwareClustering()
{
    // Check if remaining energy, distance to base station, and sensor density meet the criteria for being a cluster head
    if (remainingEnergy > threshold1 && distanceToBaseStation < threshold2 && sensorDensity > threshold3)
        isClusterHead = true;
    else
        isClusterHead = false;
}

void Sensor::distanceBasedClustering()
{
    // Check if distance to other sensors and distance to base station meet the criteria for being a cluster head
    if (distanceToOtherSensors < threshold4 && distanceToBaseStation < threshold5)
        isClusterHead = true;
    else
        isClusterHead = false;
}

void Sensor::centralityBasedClustering()
{
    // Check if degree centrality and betweenness centrality meet the criteria for being a cluster head
    if (degreeCentrality > threshold6 && betweennessCentrality > threshold7)
        isClusterHead = true;
    else
        isClusterHead = false;
}

//void Sensor::calculateEndToEndDelay(simtime_t timestamp)
//{
 //   simtime_t delay = timestamp - lastPacketTimestamp;
  //  lastPacketTimestamp = timestamp;

//}

void Sensor::calculateThroughput()
{
    simtime_t currentTime = simTime();
    simtime_t duration = currentTime - lastTimestamp;
    if (duration > 0) {
        double receivedData = numPacketsReceived * 8 * 50; // Calculate received data in bits
        throughput = receivedData / duration.dbl(); // Calculate throughput in bits per second
    }
}



void Sensor::finish()
{
    calculateThroughput();

        EV << "Remaining energy: " << remainingEnergy << " J" << endl;
        EV << "End-to-End Delay: " << delayVector << endl;
        EV << "Throughput: " << throughput << " bps" << endl;
}

wban.ini

[General]
network = wban

#abstract-config = true (requires omnet 6)
**.vector-recording = true
**.scalar-recording = true
record-eventlog = true
**.sensor*.remainingEnergyVector.record = true
**.sensor*.delayVector.record = true

wban.temp.distanceToBaseStation = 10
wban.temp.sensorDensity = 1
wban.temp.degreeCentrality = 90
wban.temp.betweennessCentrality = 60
wban.temp.distanceToOtherSensors = 10

# data link visualizer
*.visualizer.*.numDataLinkVisualizers = 5
*.visualizer.*.dataLinkVisualizer[*].activityLevel = "peer"
*.visualizer.*.dataLinkVisualizer[*].displayLinks = true
*.visualizer.*.dataLinkVisualizer[0].packetFilter = "UdpBasicApp"
*.visualizer.*.dataLinkVisualizer[1].packetFilter = "ping* or UDP*"
*.visualizer.*.dataLinkVisualizer[1].*Color = "black"
*.visualizer.*.dataLinkVisualizer[2].packetFilter = "aodv::Rrep"
*.visualizer.*.dataLinkVisualizer[2].*Color = "darkslategray"
*.visualizer.*.dataLinkVisualizer[3].packetFilter = "aodv::Rerr"
*.visualizer.*.dataLinkVisualizer[3].*Color = "red"
*.visualizer.*.dataLinkVisualizer[4].packetFilter = "Hello"
*.visualizer.*.dataLinkVisualizer[4].*Color = "green"
# wireless interface
**.wlan[*].typename = "WirelessInterface"
**.wlan[*].radio.typename = "ApskScalarRadio"
**.wlan[*].mac.typename = "XMac"
**.ap1.wlan[*].mgmt.beaconInterval = 100ms


**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 20

# misc
**.arp.typename = "GlobalArp"
*.gateway.forwarding = true
**.maxTransmissionDuration = 100ms

# configurator
*.configurator.addStaticRoutes = false
*.configurator.config = xmldoc("config.xml")

# radio and radioMedium
**.radio.centerFrequency = 2.45GHz
**.radio.bandwidth = 2.8MHz
**.radio.transmitter.bitrate = 19200 bps
**.radio.transmitter.headerLength = 8b
**.radio.transmitter.preambleDuration = 0.0001s
**.radio.transmitter.power = 2.24mW
**.radio.receiver.energyDetection = -90dBm
**.radio.receiver.sensitivity = -100dBm
**.radio.receiver.snirThreshold = -8dB
*.radioMedium.backgroundNoise.power = -110dBm
**.mac.headerLength = 8b
## Temp wireless configuration


# app all sensors
*.sensor*.numApps = 1

*.sensor*.app[0].typename = "UdpBasicApp"
*.Sensor*.app[0].destAddresses = "doctor"
#*.Sensor*.app[1].destAddresses = "EMERGENCY"
#*.Sensor*.app[2].destAddresses = "ambulance"
*.sensor*.app[0].destPort = 1000
*.sensor*.app[0].sendInterval = 1s
*.sensor*.app[0].startTime = exponential(1s)
*.sensor*.app[0].messageLength = 10Byte

# app temp
*.temp*.numApps = 1
*.temp*.app[0].typename = "UdpBasicApp"

*.temp*.remainingEnergyVector.record = true

*.temp*.app[0].destAddresses = "doctor"
#*.temp*.app[1].destAddresses = "EMERGENCY"
#*.temp*.app[2].destAddresses = "ambulance"
*.temp*.app[0].destPort = 1000
*.temp*.app[0].sendInterval = 1s
*.temp*.app[0].startTime = exponential(1s)
*.temp*.app[0].messageLength = 10Byte
*.temp*.energy = 50.0
*.temp*.distance = 20.0
*.temp*.numNodes = 100

####
# app temp
*.CE*.numApps = 1
*.CE*.app[0].typename = "UdpBasicApp"
*.CE*.app[0].destAddresses = "doctor"
#*.CE*.app[1].destAddresses = "EMERGENCY"
#*.CE*.app[2].destAddresses = "ambulance"
*.CE*.app[0].destPort = 1000
*.CE*.app[0].sendInterval = 1s
*.CE*.app[0].startTime = exponential(1s)
*.CE*.app[0].messageLength = 10Byte
*.CE*.energy = 50.0
*.CE*.distance = 20.0
*.CE*.numNodes = 100

####

# app bp
*.bp*.numApps = 1
*.bp*.app[0].typename = "UdpBasicApp"
#*.bp*.app[0].destAddresses = "EMERGENCY"
*.bp*.app[1].destAddresses = "doctor"
#*.bp*.app[2].destAddresses = "ambulance"
*.bp*.app[0].destPort = 1000
*.bp*.app[0].sendInterval = 1s
*.bp*.app[0].startTime = exponential(1s)
*.bp*.app[0].messageLength = 11Byte
*.bp*.energy = 50.0
####
# app glo
*.glo*.numApps = 1
*.glo*.app[0].typename = "UdpBasicApp"
#*.glo*.app[0].destAddresses = "ambulance"
#*.glo*.app[1].destAddresses = "EMERGENCY"
*.glo*.app[2].destAddresses = "doctor"
*.glo*.app[0].destPort = 1000
*.glo*.app[0].sendInterval = 1s
*.glo*.app[0].startTime = exponential(1s)
*.glo*.app[0].messageLength = 12Byte
####
# app OM
*.om*.numApps = 1
*.om*.app[0].typename = "UdpBasicApp"
*.om*.app[0].destAddresses = "doctor"
#*.om*.app[1].destAddresses = "EMERGENCY"
#*.om*.app[2].destAddresses = "ambulance"
*.om*.app[0].destPort = 1000
*.om*.app[0].sendInterval = 1s
*.om*.app[0].startTime = exponential(1s)
*.om*.app[0].messageLength = 13Byte
####

# app ECG
*.ecg*.numApps = 1
*.ecg*.app[0].typename = "UdpBasicApp"
#*.ecg*.app[0].destAddresses = "ambulance"
#*.ecg*.app[1].destAddresses = "EMERGENCY"
*.ecg*.app[2].destAddresses = "doctor"
*.ecg*.app[0].destPort = 1000
*.ecg*.app[0].sendInterval = 1s
*.ecg*.app[0].startTime = exponential(1s)
*.ecg*.app[0].messageLength = 14Byte
####

# app ECG
*.EEG*.numApps = 1
*.EEG*.app[0].typename = "UdpBasicApp"
#*.EEG*.app[0].destAddresses = "EMERGENCY"
*.EEG*.app[1].destAddresses = "doctor"
#*.EEG*.app[2].destAddresses = "ambulance"
*.EEG*.app[0].destPort = 1000
*.EEG*.app[0].sendInterval = 1s
*.EEG*.app[0].startTime = exponential(1s)
*.EEG*.app[0].messageLength = 14Byte
####
# app ECG
*.MS*.numApps = 1
*.MS*.app[0].typename = "UdpBasicApp"
#*.MS*.app[0].destAddresses = "ambulance"
#*.MS*.app[1].destAddresses = "EMERGENCY"
*.MS*.app[2].destAddresses = "doctor"
*.MS*.app[0].destPort = 1000
*.MS*.app[0].sendInterval = 1s
*.MS*.app[0].startTime = exponential(1s)
*.MS*.app[0].messageLength = 14Byte
####

*.EMERGENCY.numApps = 1
*.EMERGENCY.app[0].typename = "UdpSink"
*.EMERGENCY.app[0].localPort = 1000

*.EMERGENCY.numApps = 1
*.EMERGENCY.app[0].typename = "UdpSink"
*.EMERGENCY.app[0].localPort = 1000

# visualizer
*.visualizer.*.routingTableVisualizer.displayRoutingTables = false
*.visualizer.*.routingTableVisualizer.displayRoutesIndividually = true
*.visualizer.*.routingTableVisualizer.lineShift = 0
*.visualizer.*.routingTableVisualizer.displayLabels = false

*.visualizer.*.infoVisualizer.modules = "*.EMERGENCY.app[0]"
*.visualizer.*.infoVisualizer.format = "%t"
*.visualizer.*.infoVisualizer.modules = "*.EMERGENCY.app[1]"
*.visualizer.*.infoVisualizer.format = "%t"
*.visualizer.*.networkRouteVisualizer.displayRoutes = true
*.visualizer.*.physicalLinkVisualizer.displayLinks = false
[Config XMac]
network = wban
wban.temp.distanceToBaseStation = 10
wban.temp.sensorDensity = 1
wban.temp.degreeCentrality = 90
wban.temp.betweennessCentrality = 60
wban.temp.distanceToOtherSensors = 10
**.wlan[*].mac.typename = "XMac"
**.wlan[*].mac.headerLength = 24B
*.gateway.wlan[*].mac.slotDuration = 0.1s
*.sensor*.wlan[*].mac.slotDuration = 0.25s
*.temp*.wlan[*].mac.slotDuration = 0.25s
*.om*.wlan[*].mac.slotDuration = 0.25s
*.bp*.wlan[*].mac.slotDuration = 0.25s
*.glo*.wlan[*].mac.slotDuration = 0.25s
*.ecg*.wlan[*].mac.slotDuration = 0.25s
**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 20


[Config BMac]
network = wban

**.wlan[*].mac.typename = "BMac"
**.wlan[*].mac.headerLength = 1B
**.wlan[*].mac.slotDuration = 0.025s
**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 20

# Ethernet interface and queueing
*.*.eth[*].typename = "LayeredEthernetInterface"
*.*.eth[*].bitrate = 1000Mbps
*.switch1.eth[0].macLayer.queue.typename = "GatingPriorityQueue"
*.switch1.eth[0].macLayer.queue.numQueues = 2
*.switch1.eth[0].macLayer.queue.classifier.typename = "ContentBasedClassifier"
*.switch1.eth[0].macLayer.queue.classifier.packetFilters = ["UdpBasicApp*", "source2*"]
*.switch1.eth[0].macLayer.queue.queue[*].typename = "DropTailQueue"
*.switch1.eth[0].macLayer.queue.gate[*].initiallyOpen = false
*.switch1.eth[0].macLayer.queue.gate[*].durations = [10us, 10us]
*.switch1.eth[0].macLayer.queue.gate[1].offset = 10us


[Config LMac]
network = wban

**.wlan[*].mac.typename = "LMac"
**.mac.slotDuration = 50ms
**.mac.numSlots = 8
**.mac.reservedMobileSlots = 0
**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 10

[Config StatisticBase]
network = wban
#abstract-config = true (requires omnet 6)

**.vector-recording = false
sim-time-limit = 100s
repeat = 10

[Config StatisticBMac]
extends = StatisticBase

**.wlan[*].mac.typename = "BMac"
**.wlan[*].mac.headerLength = 1B
**.wlan[*].mac.slotDuration = ${slotDuration=0.01..1 step 0.01}s
**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 20

[Config StatisticXMac]
extends = StatisticBase

**.wlan[*].mac.typename = "XMac"
**.wlan[*].mac.headerLength = 24B
*.gateway.wlan[*].mac.slotDuration = ${gwSlotDuration=0.01..1 step 0.01}s
*.temp*.wlan[*].mac.slotDuration = ${snSlotDuration=2.5*$gwSlotDuration}s
#*.sensor*.wlan[*].mac.slotDuration = ${snSlotDuration=2.5*$gwSlotDuration}s
**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 20

[Config StatisticLMac]
extends = StatisticBase

**.wlan[*].mac.typename = "LMac"
**.mac.slotDuration = ${slotDuration=0.01..1 step 0.01}s
**.mac.numSlots = 8
**.mac.reservedMobileSlots = 0
**.wlan[*].queue.typename = "DropTailQueue"
**.wlan[*].queue.packetCapacity = 10

I tried using statistic, cOutVector, to measure the energy go sensor nodes over time but when I access the .vec file after running simulation, there are no vectors for delay and energy as I defined in the Sensor.cc file


Solution

  • You have created and added to the network a new simple module - Sensor type. However, your module does not contain any radio interface so it cannot receive any messages. As a consequence, handleMessage() from Sensor is never called. Therefore recording of vector is never called too.
    Take a look how SensorNode is build - see for example /inet4.5/src/inet/node/inet/SensorNode.ned as well as in INET Documentation.