Skip to content
This repository has been archived by the owner on Feb 20, 2024. It is now read-only.

Gilbert Elliot Channel Model #38

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .cproject
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@
<project id="lte.org.omnetpp.cdt.omnetppProjectType.2046274091" name="OMNeT++ Simulation" projectType="org.omnetpp.cdt.omnetppProjectType"/>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="msvc-debug">
<configuration configurationName="gcc-release">
<resource resourceType="PROJECT" workspacePath="/lte"/>
</configuration>
<configuration configurationName="gcc-release">
<configuration configurationName="msvc-debug">
<resource resourceType="PROJECT" workspacePath="/lte"/>
</configuration>
<configuration configurationName="gcc-debug">
Expand Down
42 changes: 0 additions & 42 deletions src/corenetwork/binder/PhyPisaData.cc

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/corenetwork/binder/PhyPisaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PhyPisaData
public:
PhyPisaData();
virtual ~PhyPisaData();
double getBler(int i, int j, int k){if (j==0) return 1; else return blerCurves_[i][j][k-1];}
double getBler(int i, int j, int k){return blerCurves_[i][j][k-1];}
double getLambda(int i, int j){return lambdaTable_[i][j];}
int nTxMode(){return 3;}
int nMcs(){return 15;}
Expand Down
22 changes: 18 additions & 4 deletions src/stack/mac/LteMac.ned
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,32 @@ simple LteMacBase like LteMac {
//#
//# Statistics recording
//#
@signal[macThroughputIntervalDl];
@statistic[macThroughputIntervalDl](title="Throughput at the MAC layer DL"; unit="Bps"; source="macThroughputIntervalDl"; record=mean,vector,timeavg);
@signal[macThroughputIntervalUl];
@statistic[macThroughputIntervalUl](title="Throughput at the MAC layer UL"; unit="Bps"; source="macThroughputIntervalUl"; record=mean,vector,timeavg);
@signal[macCellThroughputIntervalUl];
@statistic[macCellThroughputIntervalUl](title="Cell Throughput at the MAC layer UL"; unit="Bps"; source="macCellThroughputIntervalUl"; record=mean,vector,timeavg);
@signal[macCellThroughputIntervalDl];
@statistic[macCellThroughputIntervalDl](title="Cell Throughput at the MAC layer DL"; unit="Bps"; source="macCellThroughputIntervalDl"; record=mean,vector,timeavg);

@signal[macPacketSizeDl];
@statistic[macPacketSizeDl](title="Packet size at the MAC layer DL"; unit="Bps"; source="macPacketSizeDl"; record=sum,mean,vector,timeavg);
@signal[macPacketSizeUl];
@statistic[macPacketSizeUl](title="Packet size at the MAC layer UL"; unit="Bps"; source="macPacketSizeUl"; record=sum,mean,vector,timeavg);

@signal[macDelayDl];
@statistic[macDelayDl](title="Delay at the MAC layer UL"; unit="s"; source="macDelayDl"; record=mean,vector);
@signal[macThroughputDl];
@statistic[macThroughputDl](title="Throughput at the MAC layer DL"; unit="Bps"; source="macThroughputDl"; record=mean);
@statistic[macThroughputDl](title="Throughput at the MAC layer DL"; unit="Bps"; source="macThroughputDl"; record=mean,vector,timeavg,last);
@signal[macDelayUl];
@statistic[macDelayUl](title="Delay at the MAC layer UL"; unit="s"; source="macDelayUl"; record=mean,vector);
@signal[macThroughputUl];
@statistic[macThroughputUl](title="Throughput at the MAC layer UL"; unit="Bps"; source="macThroughputUl"; record=mean);
@statistic[macThroughputUl](title="Throughput at the MAC layer UL"; unit="Bps"; source="macThroughputUl"; record=mean,vector,timeavg,last);
@signal[macCellThroughputUl];
@statistic[macCellThroughputUl](title="Cell Throughput at the MAC layer UL"; unit="Bps"; source="macCellThroughputUl"; record=mean);
@statistic[macCellThroughputUl](title="Cell Throughput at the MAC layer UL"; unit="Bps"; source="macCellThroughputUl"; record=mean,vector,timeavg,last);
@signal[macCellThroughputDl];
@statistic[macCellThroughputDl](title="Cell Throughput at the MAC layer DL"; unit="Bps"; source="macCellThroughputDl"; record=mean);
@statistic[macCellThroughputDl](title="Cell Throughput at the MAC layer DL"; unit="Bps"; source="macCellThroughputDl"; record=mean,vector,timeavg,last);
@signal[macCellPacketLossDl];
@statistic[macCellPacketLossDl](title="Mac Cell Packet Loss Dl"; unit=""; source="macCellPacketLossDl"; record=mean);
@signal[macCellPacketLossUl];
Expand Down
65 changes: 53 additions & 12 deletions src/stack/mac/buffer/harq/LteHarqBufferRx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include "stack/mac/layer/LteMacBase.h"
#include "stack/mac/layer/LteMacEnb.h"

unsigned int LteHarqBufferRx::totalCellRcvdBytes_ = 0;
unsigned int LteHarqBufferRx::totalCellRcvdBytesDl_ = 0;
unsigned int LteHarqBufferRx::totalCellRcvdBytesUl_ = 0;

LteHarqBufferRx::LteHarqBufferRx(unsigned int num, LteMacBase *owner,
MacNodeId nodeId)
Expand All @@ -38,13 +39,19 @@ LteHarqBufferRx::LteHarqBufferRx(unsigned int num, LteMacBase *owner,
nodeB_ = macOwner_;
macDelay_ = macUe_->registerSignal("macDelayUl");
macThroughput_ = getMacByMacNodeId(nodeId_)->registerSignal("macThroughputUl");
macThroughputInterval_ = getMacByMacNodeId(nodeId_)->registerSignal("macThroughputIntervalUl");
macPacketSize_ = getMacByMacNodeId(nodeId_)->registerSignal("macPacketSizeUl");
macCellThroughput_ = macOwner_->registerSignal("macCellThroughputUl");
macCellThroughputInterval_ = macOwner_->registerSignal("macCellThroughputIntervalUl");
}
else if (macOwner_->getNodeType() == UE)
{
nodeB_ = getMacByMacNodeId(macOwner_->getMacCellId());
macThroughput_ = macOwner_->registerSignal("macThroughputDl");
macThroughputInterval_ = macOwner_->registerSignal("macThroughputIntervalDl");
macPacketSize_ = macOwner_->registerSignal("macPacketSizeDl");
macCellThroughput_ = nodeB_->registerSignal("macCellThroughputDl");
macCellThroughputInterval_ = nodeB_->registerSignal("macCellThroughputIntervalDl");
macDelay_ = macOwner_->registerSignal("macDelayDl");
}
}
Expand Down Expand Up @@ -135,22 +142,56 @@ std::list<LteMacPdu *> LteHarqBufferRx::extractCorrectPdus()
macUe_->emit(macDelay_, (NOW - temp->getCreationTime()).dbl());

// Calculate Throughput by sending the number of bits for this packet
totalCellRcvdBytes_ += size;
totalRcvdBytes_ += size;
double tputSample = (double)totalRcvdBytes_ / (NOW - getSimulation()->getWarmupPeriod());
double cellTputSample = (double)totalCellRcvdBytes_ / (NOW - getSimulation()->getWarmupPeriod());

// emit throughput statistics
nodeB_->emit(macCellThroughput_, cellTputSample);
if (uInfo->getDirection() == DL)
if (NOW > getSimulation()->getWarmupPeriod())
{
macOwner_->emit(macThroughput_, tputSample);
totalRcvdBytes_ += size;
intervalRcvdBytes_ += size;

double tputSample = (double)totalRcvdBytes_ / (NOW - getSimulation()->getWarmupPeriod());

// emit throughput statistics
if (uInfo->getDirection() == DL)
{
totalCellRcvdBytesDl_ += size;
double cellTputSample = (double)totalCellRcvdBytesDl_ / (NOW - getSimulation()->getWarmupPeriod());
nodeB_->emit(macCellThroughput_, cellTputSample);
macOwner_->emit(macThroughput_, tputSample);
macOwner_->emit(macPacketSize_, size);
}
else // UL
{
totalCellRcvdBytesUl_ += size;
double cellTputSample = (double)totalCellRcvdBytesUl_ / (NOW - getSimulation()->getWarmupPeriod());
nodeB_->emit(macCellThroughput_, cellTputSample);
macUe_->emit(macThroughput_, tputSample);
macUe_->emit(macPacketSize_, size);
}
}
else // UL

if (NOW > getSimulation()->getWarmupPeriod() && NOW > tpIntervalStart + tpIntervalLength_)
{
macUe_->emit(macThroughput_, tputSample);
double tputSample = (double)intervalRcvdBytes_ / (NOW - tpIntervalStart);

// emit throughput statistics
if (uInfo->getDirection() == DL)
{
double cellTputSample = (double) (totalCellRcvdBytesDl_ - intervalStartCellRcvdBytesDl_) / (NOW - tpIntervalStart);
nodeB_->emit(macCellThroughputInterval_, cellTputSample);
macOwner_->emit(macThroughputInterval_, tputSample);
}
else // UL
{
double cellTputSample = (double) (totalCellRcvdBytesUl_ - intervalStartCellRcvdBytesUl_) / (NOW - tpIntervalStart);
nodeB_->emit(macCellThroughputInterval_, cellTputSample);
macUe_->emit(macThroughputInterval_, tputSample);
}
intervalStartCellRcvdBytesDl_ = totalCellRcvdBytesDl_;
intervalStartCellRcvdBytesUl_ = totalCellRcvdBytesUl_;
intervalRcvdBytes_ = 0;
tpIntervalStart = NOW;
}


macOwner_->dropObj(temp);
ret.push_back(temp);
acid = i;
Expand Down
11 changes: 10 additions & 1 deletion src/stack/mac/buffer/harq/LteHarqBufferRx.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,20 @@ class LteHarqBufferRx
bool isMulticast_;

//Statistics
static unsigned int totalCellRcvdBytes_;
static unsigned int totalCellRcvdBytesDl_;
static unsigned int totalCellRcvdBytesUl_;
unsigned int totalRcvdBytes_ = 0;
unsigned int intervalStartCellRcvdBytesDl_ = 0;
unsigned int intervalStartCellRcvdBytesUl_ = 0;
unsigned int intervalRcvdBytes_ = 0;
simtime_t tpIntervalStart = 0;
simtime_t tpIntervalLength_ = SimTime(1000, SIMTIME_MS);
simsignal_t macDelay_;
simsignal_t macCellThroughput_;
simsignal_t macThroughput_;
simsignal_t macCellThroughputInterval_;
simsignal_t macThroughputInterval_;
simsignal_t macPacketSize_;

// reference to the eNB module
cModule* nodeB_;
Expand Down
78 changes: 63 additions & 15 deletions src/stack/mac/buffer/harq_d2d/LteHarqBufferRxD2D.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "stack/mac/layer/LteMacUeD2D.h"
#include "stack/mac/layer/LteMacEnbD2D.h"

unsigned int LteHarqBufferRxD2D::totalCellRcvdBytesD2D_ = 0;

LteHarqBufferRxD2D::LteHarqBufferRxD2D(unsigned int num, LteMacBase *owner, MacNodeId nodeId, bool isMulticast)
{
macOwner_ = owner;
Expand Down Expand Up @@ -146,28 +148,74 @@ std::list<LteMacPdu *> LteHarqBufferRxD2D::extractCorrectPdus()
}

// Calculate Throughput by sending the number of bits for this packet
totalRcvdBytes_ += size;
totalCellRcvdBytes_ += size;
double tputSample = (double)totalRcvdBytes_ / (NOW - getSimulation()->getWarmupPeriod());
double cellTputSample = (double)totalCellRcvdBytes_ / (NOW - getSimulation()->getWarmupPeriod());

// emit throughput statistics
if (info->getDirection() == D2D)
if (NOW > getSimulation()->getWarmupPeriod())
{
check_and_cast<LteMacEnbD2D*>(nodeB_)->emit(macCellThroughputD2D_, cellTputSample);
check_and_cast<LteMacUeD2D*>(macOwner_)->emit(macThroughputD2D_, tputSample);
totalRcvdBytes_ += size;
intervalRcvdBytes_ += size;

double tputSample = (double)totalRcvdBytes_ / (NOW - getSimulation()->getWarmupPeriod());

// emit throughput statistics
if (info->getDirection() == D2D)
{
totalCellRcvdBytesD2D_ += size;
double cellTputSample = (double)totalCellRcvdBytesD2D_ / (NOW - getSimulation()->getWarmupPeriod());
check_and_cast<LteMacEnbD2D*>(nodeB_)->emit(macCellThroughputD2D_, cellTputSample);
check_and_cast<LteMacUeD2D*>(macOwner_)->emit(macThroughputD2D_, tputSample);
check_and_cast<LteMacUeD2D*>(macOwner_)->emit(macPacketSize_, size);
}
else
{
if (info->getDirection() == DL)
{
totalCellRcvdBytesDl_ += size;
double cellTputSample = (double)totalCellRcvdBytesDl_ / (NOW - getSimulation()->getWarmupPeriod());
nodeB_->emit(macCellThroughput_, cellTputSample);
macOwner_->emit(macThroughput_, tputSample);
macOwner_->emit(macPacketSize_, size);
}
else // UL
{
totalCellRcvdBytesUl_ += size;
double cellTputSample = (double)totalCellRcvdBytesUl_ / (NOW - getSimulation()->getWarmupPeriod());
nodeB_->emit(macCellThroughput_, cellTputSample);
macUe_->emit(macThroughput_, tputSample);
macUe_->emit(macPacketSize_, size);
}
}
}
else

if (NOW > getSimulation()->getWarmupPeriod() && NOW > tpIntervalStart + tpIntervalLength_)
{
nodeB_->emit(macCellThroughput_, cellTputSample);
if (info->getDirection() == DL)
double tputSample = (double)intervalRcvdBytes_ / (NOW - tpIntervalStart);

// emit throughput statistics
if (info->getDirection() == D2D)
{
macOwner_->emit(macThroughput_, tputSample);
double cellTputSample = (double) (totalCellRcvdBytesD2D_ - intervalStartCellRcvdBytesD2D_) / (NOW - tpIntervalStart);
check_and_cast<LteMacEnbD2D*>(nodeB_)->emit(macCellThroughputD2D_, cellTputSample);
check_and_cast<LteMacUeD2D*>(macOwner_)->emit(macThroughputD2D_, tputSample);
}
else // UL
else
{
macUe_->emit(macThroughput_, tputSample);
if (info->getDirection() == DL)
{
double cellTputSample = (double) (totalCellRcvdBytesDl_ - intervalStartCellRcvdBytesDl_) / (NOW - tpIntervalStart);
nodeB_->emit(macCellThroughputInterval_, cellTputSample);
macOwner_->emit(macThroughputInterval_, tputSample);
}
else // UL
{
double cellTputSample = (double) (totalCellRcvdBytesUl_ - intervalStartCellRcvdBytesUl_) / (NOW - tpIntervalStart);
nodeB_->emit(macCellThroughputInterval_, cellTputSample);
macUe_->emit(macThroughputInterval_, tputSample);
}
}
intervalStartCellRcvdBytesD2D_ = totalCellRcvdBytesD2D_;
intervalStartCellRcvdBytesDl_ = totalCellRcvdBytesDl_;
intervalStartCellRcvdBytesUl_ = totalCellRcvdBytesUl_;
intervalRcvdBytes_ = 0;
tpIntervalStart = NOW;
}

ret.push_back(temp);
Expand Down
2 changes: 2 additions & 0 deletions src/stack/mac/buffer/harq_d2d/LteHarqBufferRxD2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class LteHarqBufferRxD2D : public LteHarqBufferRx
protected:

// D2D Statistics
static unsigned int totalCellRcvdBytesD2D_;
unsigned int intervalStartCellRcvdBytesD2D_ = 0;
simsignal_t macDelayD2D_;
simsignal_t macCellThroughputD2D_;
simsignal_t macThroughputD2D_;
Expand Down
96 changes: 96 additions & 0 deletions src/stack/phy/ChannelModel/GilbertElliotModel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// Created by seba on 09.07.19.
//

#include <stdexcept>
#include <iostream>
#include "GilbertElliotModel.h"
#include "stack/phy/ChannelModel/LteGilbertElliotChannelModel.h"

GilbertElliotModel::GilbertElliotModel() {}

void GilbertElliotModel::setStartingState() {
double steady_state_good = getSteadyStateProbability(ChannelState::good);
double random_number = parent->getRandomNumber();
if (random_number <= steady_state_good)
current_channel_state = ChannelState::good;
else
current_channel_state = ChannelState::bad;
}

double GilbertElliotModel::update() {
double random_number = parent->getRandomNumber();
double current_transition_probability = current_channel_state == ChannelState::good ? good_state_transition_prob : bad_state_transition_prob;
if (random_number <= current_transition_probability)
current_channel_state = current_channel_state == ChannelState::good ? ChannelState::bad : ChannelState::good;
current_channel_state == ChannelState::good ? num_times_good_state_visited++ : num_times_bad_state_visited++;
return getCurrentErrorProbability();
}

void GilbertElliotModel::setErrorProbability(const int channel_state, double error_probability) {
if (channel_state == ChannelState::good)
this->good_state_packet_error_prob = error_probability;
else if (channel_state == ChannelState::bad)
this->bad_state_packet_error_prob = error_probability;
else
throw std::invalid_argument("Channel state is neither good nor bad.");
}

void GilbertElliotModel::setTransitionProbability(const int channel_state, double transition_probability) {
if (channel_state == ChannelState::good)
this->good_state_transition_prob = transition_probability;
else if (channel_state == ChannelState::bad)
this->bad_state_transition_prob = transition_probability;
else
throw std::invalid_argument("Channel state is neither good nor bad.");
}

double GilbertElliotModel::getErrorProbability(const int channel_state) const {
if (channel_state == ChannelState::good)
return this->good_state_packet_error_prob;
else if (channel_state == ChannelState::bad)
return this->bad_state_packet_error_prob;
else
throw std::invalid_argument("Channel state is neither good nor bad.");
}

double GilbertElliotModel::getTransitionProbability(const int channel_state) const {
if (channel_state == ChannelState::good)
return this->good_state_transition_prob;
else if (channel_state == ChannelState::bad)
return this->bad_state_transition_prob;
else
throw std::invalid_argument("Channel state is neither good nor bad.");
}

double GilbertElliotModel::getCurrentErrorProbability() const {
return current_channel_state == ChannelState::good ? good_state_packet_error_prob : bad_state_packet_error_prob;
}

double GilbertElliotModel::getSteadyStateProbability(const int channel_state) const {
const double& p12 = good_state_transition_prob;
const double& p21 = bad_state_transition_prob;
if (channel_state == ChannelState::good)
return p21 / (p12 + p21);
else if (channel_state == ChannelState::bad)
return p12 / (p21 + p12);
else
throw std::invalid_argument("Channel state is neither good nor bad.");
}

const GilbertElliotModel::ChannelState& GilbertElliotModel::getCurrentChannelState() const {
return this->current_channel_state;
}

void GilbertElliotModel::setParent(LteGilbertElliotChannelModel* parent) {
this->parent = parent;
}

unsigned long GilbertElliotModel::getNumTimesStateVisited(const int channel_state) const {
if (channel_state == ChannelState::good)
return num_times_good_state_visited;
else if (channel_state == ChannelState::bad)
return num_times_bad_state_visited;
else
throw std::invalid_argument("Channel state is neither good nor bad.");
}
Loading