wifi: Fix SNR computations for MIMO

This commit is contained in:
Sébastien Deronne
2020-06-08 21:49:19 +02:00
parent 4b138220fa
commit 376d5d62fa
2 changed files with 19 additions and 19 deletions

View File

@@ -238,10 +238,11 @@ InterferenceHelper::AppendEvent (Ptr<Event> 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<double>(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<uint64_t> (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<const Event> 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<const Event> 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<const Event> 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> event, std::pair<Time, Ti
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
double snr = CalculateSnr (event->GetRxPowerW (),
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> 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> 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> 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.

View File

@@ -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.