From 376d5d62fa711b3033bcd20e6edf1d78b3cfe3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Mon, 8 Jun 2020 21:49:19 +0200 Subject: [PATCH] wifi: Fix SNR computations for MIMO --- src/wifi/model/interference-helper.cc | 34 +++++++++++++-------------- src/wifi/model/interference-helper.h | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/wifi/model/interference-helper.cc b/src/wifi/model/interference-helper.cc index 5ba10675b..38eddb1a1 100644 --- a/src/wifi/model/interference-helper.cc +++ b/src/wifi/model/interference-helper.cc @@ -238,10 +238,11 @@ InterferenceHelper::AppendEvent (Ptr event) } double -InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth) const +InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiTxVector txVector) const { //thermal noise at 290K in J/s = W static const double BOLTZMANN = 1.3803e-23; + uint16_t channelWidth = txVector.GetChannelWidth (); //Nt is the power of thermal noise in W double Nt = BOLTZMANN * 290 * channelWidth * 1e6; //receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver @@ -249,6 +250,13 @@ 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 > txVector.GetNss ()) + { + gain = static_cast(m_numRxAntennas) / txVector.GetNss (); //compute gain offered by diversity for AWGN + } + NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB"); + snr *= gain; return snr; } @@ -296,15 +304,7 @@ InterferenceHelper::CalculatePayloadChunkSuccessRate (double snir, Time duration WifiMode mode = txVector.GetMode (); uint64_t rate = mode.GetDataRate (txVector); uint64_t nbits = static_cast (rate * duration.GetSeconds ()); - if (txVector.GetMode ().GetModulationClass () >= WIFI_MOD_CLASS_HT) - { - nbits /= txVector.GetNss (); //divide effective number of bits by NSS to achieve same chunk error rate as SISO for AWGN - double gain = (txVector.GetNTx () * m_numRxAntennas); //compute gain offered by MIMO, SIMO or MISO compared to SISO for AWGN - NS_LOG_DEBUG ("TX=" << +txVector.GetNTx () << - ", RX=" << +m_numRxAntennas << - ", SNIR improvement=+" << 10 * std::log10 (gain) << "dB"); - snir *= gain; - } + nbits /= txVector.GetNss (); //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); return csr; } @@ -332,7 +332,7 @@ InterferenceHelper::CalculatePayloadPer (Ptr event, NiChanges *ni, Time current = j->first; NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); NS_ASSERT (current >= previous); - double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth ()); + double snr = CalculateSnr (powerW, noiseInterferenceW, txVector); //Case 1: Both previous and current point to the windowed payload if (previous >= windowStart) { @@ -378,7 +378,7 @@ InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr event, NiChange Time current = j->first; NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); NS_ASSERT (current >= previous); - double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth ()); + double snr = CalculateSnr (powerW, noiseInterferenceW, txVector); //Case 1: previous and current after payload start if (previous >= phyPayloadStart) { @@ -507,7 +507,7 @@ InterferenceHelper::CalculateHtPhyHeaderPer (Ptr event, NiChanges * Time current = j->first; NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); NS_ASSERT (current >= previous); - double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth ()); + double snr = CalculateSnr (powerW, noiseInterferenceW, txVector); //Case 1: previous and current after payload start: nothing to do if (previous >= phyPayloadStart) { @@ -743,7 +743,7 @@ InterferenceHelper::CalculatePayloadSnrPer (Ptr event, std::pairGetRxPowerW (), noiseInterferenceW, - event->GetTxVector ().GetChannelWidth ()); + event->GetTxVector ()); /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate * all SNIR changes in the SNIR vector. @@ -763,7 +763,7 @@ InterferenceHelper::CalculateSnr (Ptr event) const double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); double snr = CalculateSnr (event->GetRxPowerW (), noiseInterferenceW, - event->GetTxVector ().GetChannelWidth ()); + event->GetTxVector ()); return snr; } @@ -774,7 +774,7 @@ InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr event) const double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); double snr = CalculateSnr (event->GetRxPowerW (), noiseInterferenceW, - event->GetTxVector ().GetChannelWidth ()); + event->GetTxVector ()); /* calculate the SNIR at the start of the PHY header and accumulate * all SNIR changes in the SNIR vector. @@ -794,7 +794,7 @@ InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr event) const double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); double snr = CalculateSnr (event->GetRxPowerW (), noiseInterferenceW, - event->GetTxVector ().GetChannelWidth ()); + event->GetTxVector ()); /* calculate the SNIR at the start of the PHY header and accumulate * all SNIR changes in the SNIR vector. diff --git a/src/wifi/model/interference-helper.h b/src/wifi/model/interference-helper.h index aa846d5d6..c30a7f0cc 100644 --- a/src/wifi/model/interference-helper.h +++ b/src/wifi/model/interference-helper.h @@ -306,11 +306,11 @@ private: * * \param signal signal power, W * \param noiseInterference noise and interference power, W - * \param channelWidth signal width in MHz + * \param txVector the TXVECTOR * * \return SNR in linear scale */ - double CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth) const; + double CalculateSnr (double signal, double noiseInterference, WifiTxVector txVector) 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.