wifi: (merges !642) Extend ErrorRateModel API for link-to-system models
Incorporates improvements from Rediet's code review.
This commit is contained in:
committed by
Tom Henderson
parent
f0b7deab3d
commit
4d7983d4e0
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "error-rate-model.h"
|
||||
#include "non-ht/dsss-error-rate-model.h"
|
||||
#include "ns3/dsss-error-rate-model.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -60,7 +60,7 @@ ErrorRateModel::CalculateSnr (const WifiTxVector& txVector, double ber) const
|
||||
}
|
||||
|
||||
double
|
||||
ErrorRateModel::GetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const
|
||||
ErrorRateModel::GetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
|
||||
{
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS || mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)
|
||||
{
|
||||
@@ -80,9 +80,22 @@ ErrorRateModel::GetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector
|
||||
}
|
||||
else
|
||||
{
|
||||
return DoGetChunkSuccessRate (mode, txVector, snr, nbits, staId);
|
||||
return DoGetChunkSuccessRate (mode, txVector, snr, nbits, numRxAntennas, field, staId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
ErrorRateModel::IsAwgn (void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t
|
||||
ErrorRateModel::AssignStreams (int64_t stream)
|
||||
{
|
||||
// Override this method if the error model uses random variables
|
||||
return 0;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -48,6 +48,12 @@ public:
|
||||
*/
|
||||
double CalculateSnr (const WifiTxVector& txVector, double ber) const;
|
||||
|
||||
/**
|
||||
* \return true if the model is for AWGN channels,
|
||||
* false otherwise
|
||||
*/
|
||||
virtual bool IsAwgn (void) const;
|
||||
|
||||
/**
|
||||
* This method returns the probability that the given 'chunk' of the
|
||||
* packet will be successfully received by the PHY.
|
||||
@@ -70,11 +76,25 @@ public:
|
||||
* \param txVector TXVECTOR of the overall transmission
|
||||
* \param snr the SNR of the chunk
|
||||
* \param nbits the number of bits in this chunk
|
||||
* \param numRxAntennas the number of active RX antennas (1 if not provided)
|
||||
* \param field the PPDU field to which the chunk belongs to (assumes this is for the payload part if not provided)
|
||||
* \param staId the station ID for MU
|
||||
*
|
||||
* \return probability of successfully receiving the chunk
|
||||
*/
|
||||
double GetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId = SU_STA_ID) const;
|
||||
double GetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits,
|
||||
uint8_t numRxAntennas = 1, WifiPpduField field = WIFI_PPDU_FIELD_DATA,
|
||||
uint16_t staId = SU_STA_ID) const;
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned.
|
||||
*
|
||||
* \param stream first stream index to use
|
||||
* \return the number of stream indices assigned by this model
|
||||
*/
|
||||
virtual int64_t AssignStreams (int64_t stream);
|
||||
|
||||
|
||||
private:
|
||||
@@ -85,11 +105,14 @@ private:
|
||||
* \param txVector TXVECTOR of the overall transmission
|
||||
* \param snr the SNR of the chunk
|
||||
* \param nbits the number of bits in this chunk
|
||||
* \param numRxAntennas the number of active RX antennas
|
||||
* \param field the PPDU field to which the chunk belongs to
|
||||
* \param staId the station ID for MU
|
||||
*
|
||||
* \return probability of successfully receiving the chunk
|
||||
*/
|
||||
virtual double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const = 0;
|
||||
virtual double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits,
|
||||
uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const = 0;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -344,13 +344,16 @@ InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint1
|
||||
double noise = noiseFloor + noiseInterference;
|
||||
double snr = signal / noise; //linear scale
|
||||
NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB");
|
||||
double gain = 1;
|
||||
if (m_numRxAntennas > nss)
|
||||
if (m_errorRateModel->IsAwgn ())
|
||||
{
|
||||
gain = static_cast<double>(m_numRxAntennas) / nss; //compute gain offered by diversity for AWGN
|
||||
double gain = 1;
|
||||
if (m_numRxAntennas > nss)
|
||||
{
|
||||
gain = static_cast<double> (m_numRxAntennas) / nss; //compute gain offered by diversity for AWGN
|
||||
}
|
||||
NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB");
|
||||
snr *= gain;
|
||||
}
|
||||
NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB");
|
||||
snr *= gain;
|
||||
return snr;
|
||||
}
|
||||
|
||||
@@ -384,7 +387,7 @@ InterferenceHelper::CalculateNoiseInterferenceW (Ptr<Event> event, NiChangesPerB
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector) const
|
||||
InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector, WifiPpduField field) const
|
||||
{
|
||||
if (duration.IsZero ())
|
||||
{
|
||||
@@ -392,7 +395,7 @@ InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiM
|
||||
}
|
||||
uint64_t rate = mode.GetDataRate (txVector.GetChannelWidth ());
|
||||
uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
|
||||
double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
|
||||
double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits, m_numRxAntennas, field);
|
||||
return csr;
|
||||
}
|
||||
|
||||
@@ -407,7 +410,7 @@ InterferenceHelper::CalculatePayloadChunkSuccessRate (double snir, Time duration
|
||||
uint64_t rate = mode.GetDataRate (txVector, staId);
|
||||
uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
|
||||
nbits /= txVector.GetNss (staId); //divide effective number of bits by NSS to achieve same chunk error rate as SISO for AWGN
|
||||
double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits, staId);
|
||||
double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits, m_numRxAntennas, WIFI_PPDU_FIELD_DATA, staId);
|
||||
return csr;
|
||||
}
|
||||
|
||||
@@ -417,7 +420,7 @@ InterferenceHelper::CalculatePayloadPer (Ptr<const Event> event, uint16_t channe
|
||||
uint16_t staId, std::pair<Time, Time> window) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << window.first << window.second);
|
||||
const WifiTxVector& txVector = event->GetTxVector ();
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
@@ -468,7 +471,7 @@ InterferenceHelper::CalculatePhyHeaderSectionPsr (Ptr<const Event> event, NiChan
|
||||
PhyEntity::PhyHeaderSections phyHeaderSections) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
const WifiTxVector& txVector = event->GetTxVector ();
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
@@ -500,7 +503,15 @@ InterferenceHelper::CalculatePhyHeaderSectionPsr (Ptr<const Event> event, NiChan
|
||||
if (duration.IsStrictlyPositive ())
|
||||
{
|
||||
WifiMode mode = section.second.second;
|
||||
psr *= CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
if (mode.GetModulationClass () < WIFI_MOD_CLASS_OFDM)
|
||||
{
|
||||
psr *= CalculateChunkSuccessRate (snr, duration, mode, txVector, WIFI_PPDU_FIELD_NON_HT_HEADER);
|
||||
}
|
||||
else
|
||||
{
|
||||
//FIXME: this will be directly available with PHY refactoring, hence assume HT-SIG for now since error rate model do not differentiate these non-HT PHY headers yet
|
||||
psr *= CalculateChunkSuccessRate (snr, duration, mode, txVector, WIFI_PPDU_FIELD_HT_SIG);
|
||||
}
|
||||
NS_LOG_DEBUG ("Current NI change in " << section.first << " [" << start << ", " << stop << "] for "
|
||||
<< duration.As (Time::NS) << ": mode=" << mode << ", psr=" << psr);
|
||||
}
|
||||
@@ -523,7 +534,7 @@ InterferenceHelper::CalculatePhyHeaderPer (Ptr<const Event> event, NiChangesPerB
|
||||
WifiPpduField header) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second << header);
|
||||
const WifiTxVector& txVector = event->GetTxVector ();
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto phyEntity = WifiPhy::GetStaticPhyEntity (txVector.GetModulationClass ());
|
||||
|
||||
|
||||
@@ -281,18 +281,30 @@ protected:
|
||||
*/
|
||||
double CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const;
|
||||
/**
|
||||
* Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode.
|
||||
* The duration and mode are used to calculate how many bits are present in the chunk.
|
||||
* Calculate the success rate of the chunk given the SINR, duration, and TXVECTOR.
|
||||
* The duration and TXVECTOR are used to calculate how many bits are present in the chunk.
|
||||
*
|
||||
* \param snir the SINR
|
||||
* \param duration the duration of the chunk
|
||||
* \param mode the WifiMode
|
||||
* \param txVector the TXVECTOR
|
||||
* \param field the PPDU field to which the chunk belongs to
|
||||
*
|
||||
* \return the success rate
|
||||
*/
|
||||
double CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector) const;
|
||||
|
||||
double CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector, WifiPpduField field) const;
|
||||
/**
|
||||
* Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR.
|
||||
* The duration and TXVECTOR are used to calculate how many bits are present in the payload chunk.
|
||||
*
|
||||
* \param snir the SINR
|
||||
* \param duration the duration of the chunk
|
||||
* \param txVector the TXVECTOR
|
||||
* \param staId the station ID of the PSDU (only used for MU)
|
||||
*
|
||||
* \return the success rate
|
||||
*/
|
||||
double CalculatePayloadChunkSuccessRate (double snir, Time duration, const WifiTxVector& txVector, uint16_t staId = SU_STA_ID) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -362,18 +374,6 @@ private:
|
||||
* \return noise and interference power
|
||||
*/
|
||||
double CalculateNoiseInterferenceW (Ptr<Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the success rate of the payload chunk given the SINR, duration, and Wi-Fi mode.
|
||||
* The duration and mode are used to calculate how many bits are present in the chunk.
|
||||
*
|
||||
* \param snir the SINR
|
||||
* \param duration the duration of the chunk
|
||||
* \param txVector the TXVECTOR
|
||||
* \param staId the station ID of the PSDU (only used for MU)
|
||||
*
|
||||
* \return the success rate
|
||||
*/
|
||||
double CalculatePayloadChunkSuccessRate (double snir, Time duration, const WifiTxVector& txVector, uint16_t staId) const;
|
||||
/**
|
||||
* Calculate the error rate of the given PHY payload only in the provided time
|
||||
* window (thus enabling per MPDU PER information). The PHY payload can be divided into
|
||||
|
||||
@@ -217,9 +217,9 @@ NistErrorRateModel::GetBValue (WifiCodeRate codeRate) const
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const
|
||||
NistErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode << snr << nbits << staId);
|
||||
NS_LOG_FUNCTION (this << mode << snr << nbits << +numRxAntennas << field << staId);
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
|
||||
|| mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
|
||||
|| mode.GetModulationClass () == WIFI_MOD_CLASS_HT
|
||||
|
||||
@@ -47,7 +47,8 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const override;
|
||||
double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits,
|
||||
uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const override;
|
||||
/**
|
||||
* Return the bValue such that coding rate = bValue / (bValue + 1).
|
||||
*
|
||||
|
||||
@@ -141,9 +141,9 @@ TableBasedErrorRateModel::GetMcsForMode (WifiMode mode)
|
||||
}
|
||||
|
||||
double
|
||||
TableBasedErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const
|
||||
TableBasedErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode << txVector << snr << nbits << staId);
|
||||
NS_LOG_FUNCTION (this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
|
||||
uint64_t size = std::max<uint64_t> (1, (nbits / 8));
|
||||
double roundedSnr = RoundSnr (RatioToDb (snr), SNR_PRECISION);
|
||||
uint8_t mcs = GetMcsForMode (mode);
|
||||
|
||||
@@ -47,8 +47,6 @@ public:
|
||||
TableBasedErrorRateModel ();
|
||||
~TableBasedErrorRateModel ();
|
||||
|
||||
double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const override;
|
||||
|
||||
/**
|
||||
* \brief Utility function to convert WifiMode to an MCS value
|
||||
* \param mode the WifiMode
|
||||
@@ -58,6 +56,9 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits,
|
||||
uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const override;
|
||||
|
||||
/**
|
||||
* Round SNR (in dB) to the specified precision
|
||||
*
|
||||
|
||||
@@ -2294,8 +2294,10 @@ int64_t
|
||||
WifiPhy::AssignStreams (int64_t stream)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << stream);
|
||||
m_random->SetStream (stream);
|
||||
return 1;
|
||||
int64_t currentStream = stream;
|
||||
m_random->SetStream (currentStream++);
|
||||
currentStream += m_interference.GetErrorRateModel ()->AssignStreams (currentStream);
|
||||
return (currentStream - stream);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, RxSignalInfo rxSignalInfo)
|
||||
|
||||
@@ -179,9 +179,9 @@ YansErrorRateModel::GetFecQamBer (double snr, uint64_t nbits,
|
||||
}
|
||||
|
||||
double
|
||||
YansErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const
|
||||
YansErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits << staId);
|
||||
NS_LOG_FUNCTION (this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
|
||||
|| mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
|
||||
|| mode.GetModulationClass () == WIFI_MOD_CLASS_HT
|
||||
|
||||
@@ -63,7 +63,8 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint16_t staId) const override;
|
||||
double DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits,
|
||||
uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const override;
|
||||
/**
|
||||
* Return BER of BPSK with the given parameters.
|
||||
*
|
||||
|
||||
@@ -300,7 +300,7 @@ class TestInterferenceHelper : public InterferenceHelper
|
||||
{
|
||||
public:
|
||||
using InterferenceHelper::InterferenceHelper;
|
||||
using InterferenceHelper::CalculateChunkSuccessRate;
|
||||
using InterferenceHelper::CalculatePayloadChunkSuccessRate;
|
||||
using InterferenceHelper::CalculateSnr;
|
||||
};
|
||||
|
||||
@@ -352,7 +352,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
double snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "Attempt to set initial SNR to known value failed");
|
||||
Time duration = MilliSeconds (2);
|
||||
double chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
double chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, 0.905685, 0.000001, "CSR not within tolerance for SISO");
|
||||
double sisoChunkSuccess = chunkSuccess;
|
||||
|
||||
@@ -361,7 +361,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNTx (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 2x1:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, 0.905685, 0.000001, "CSR not within tolerance for SISO");
|
||||
|
||||
// MIMO 1x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO thanks to RX diversity
|
||||
@@ -370,7 +370,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not within tolerance for 1x2:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 1x2:1 MIMO");
|
||||
|
||||
// MIMO 2x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO thanks to RX diversity
|
||||
@@ -379,7 +379,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not equal within tolerance for 2x2:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 2x2:1 MIMO");
|
||||
|
||||
// MIMO 2x2:2: expect no SNR gain in AWGN channel
|
||||
@@ -388,7 +388,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not equal within tolerance for 2x2:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not within tolerance for 2x2:2 MIMO");
|
||||
|
||||
// MIMO 3x3:1: expect that SNR is increased by a factor of 4.8 dB (10 log 3/1) compared to SISO thanks to RX diversity
|
||||
@@ -397,7 +397,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (3);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 4.8, 0.1, "SNR not within tolerance for 3x3:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 3x3:1 MIMO");
|
||||
|
||||
// MIMO 3x3:2: expect that SNR is increased by a factor of 1.8 dB (10 log 3/2) compared to SISO thanks to RX diversity
|
||||
@@ -406,7 +406,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (3);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 1.8, 0.1, "SNR not within tolerance for 3x3:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 3x3:2 MIMO");
|
||||
|
||||
// MIMO 3x3:3: expect no SNR gain in AWGN channel
|
||||
@@ -415,7 +415,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (3);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 3x3:3 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not equal within tolerance for 3x3:3 MIMO");
|
||||
|
||||
// MIMO 4x4:1: expect that SNR is increased by a factor of 6 dB (10 log 4/1) compared to SISO thanks to RX diversity
|
||||
@@ -424,7 +424,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 6, 0.1, "SNR not within tolerance for 4x4:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:1 MIMO");
|
||||
|
||||
// MIMO 4x4:2: expect that SNR is increased by a factor of 3 dB (10 log 4/2) compared to SISO thanks to RX diversity
|
||||
@@ -433,7 +433,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not within tolerance for 4x4:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:2 MIMO");
|
||||
|
||||
// MIMO 4x4:3: expect that SNR is increased by a factor of 1.2 dB (10 log 4/3) compared to SISO thanks to RX diversity
|
||||
@@ -442,7 +442,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 1.2, 0.1, "SNR not within tolerance for 4x4:3 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:1 MIMO");
|
||||
|
||||
// MIMO 4x4:4: expect no SNR gain in AWGN channel
|
||||
@@ -451,7 +451,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 4x4:4 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
chunkSuccess = interference.CalculatePayloadChunkSuccessRate (snr, duration, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not within tolerance for 4x4:4 MIMO");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user