split the error rate model from the yans phy
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 12 Jun 2008 12:28:36 -0700
changeset 3902 9e048e073cf0
parent 3901 46153af8a08e
child 3903 714f93024a37
split the error rate model from the yans phy
src/devices/wifi/error-rate-model.cc
src/devices/wifi/error-rate-model.h
src/devices/wifi/wscript
src/devices/wifi/yans-wifi-phy.cc
src/devices/wifi/yans-wifi-phy.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/error-rate-model.cc	Thu Jun 12 12:28:36 2008 -0700
@@ -0,0 +1,249 @@
+#include "error-rate-model.h"
+#include "wifi-phy.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("ErrorRateModel");
+
+namespace ns3 {
+
+TypeId 
+ErrorRateModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ErrorRateModel")
+    .SetParent<Object> ()
+    .AddConstructor<ErrorRateModel> ()
+    ;
+  return tid;
+}
+
+ErrorRateModel::ErrorRateModel ()
+{}
+
+
+double 
+ErrorRateModel::Log2 (double val) const
+{
+  return log(val) / log(2.0);
+}
+double 
+ErrorRateModel::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
+{
+  double EbNo = snr * signalSpread / phyRate;
+  double z = sqrt(EbNo);
+  double ber = 0.5 * erfc(z);
+  NS_LOG_INFO ("bpsk snr="<<snr<<" ber="<<ber);
+  return ber;
+}
+double 
+ErrorRateModel::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
+{
+  double EbNo = snr * signalSpread / phyRate;
+  double z = sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
+  double z1 = ((1.0 - 1.0 / sqrt (m)) * erfc (z)) ;
+  double z2 = 1 - pow ((1-z1), 2.0);
+  double ber = z2 / Log2 (m);
+  NS_LOG_INFO ("Qam m="<<m<<" rate=" << phyRate << " snr="<<snr<<" ber="<<ber);
+  return ber;
+}
+uint32_t
+ErrorRateModel::Factorial (uint32_t k) const
+{
+  uint32_t fact = 1;
+  while (k > 0) 
+    {
+      fact *= k;
+      k--;
+    }
+  return fact;
+}
+double 
+ErrorRateModel::Binomial (uint32_t k, double p, uint32_t n) const
+{
+  double retval = Factorial (n) / (Factorial (k) * Factorial (n-k)) * pow (p, k) * pow (1-p, n-k);
+  return retval;
+}
+double 
+ErrorRateModel::CalculatePdOdd (double ber, unsigned int d) const
+{
+  NS_ASSERT ((d % 2) == 1);
+  unsigned int dstart = (d + 1) / 2;
+  unsigned int dend = d;
+  double pd = 0;
+
+  for (unsigned int i = dstart; i < dend; i++) 
+    {
+      pd += Binomial (i, ber, d);
+    }
+  return pd;
+}
+double 
+ErrorRateModel::CalculatePdEven (double ber, unsigned int d) const
+{
+  NS_ASSERT ((d % 2) == 0);
+  unsigned int dstart = d / 2 + 1;
+  unsigned int dend = d;
+  double pd = 0;
+
+  for (unsigned int i = dstart; i < dend; i++)
+    {
+      pd +=  Binomial (i, ber, d);
+    }
+  pd += 0.5 * Binomial (d / 2, ber, d);
+
+  return pd;
+}
+
+double 
+ErrorRateModel::CalculatePd (double ber, unsigned int d) const
+{
+  double pd;
+  if ((d % 2) == 0) 
+    {
+      pd = CalculatePdEven (ber, d);
+    } 
+  else 
+    {
+      pd = CalculatePdOdd (ber, d);
+    }
+  return pd;
+}
+
+double
+ErrorRateModel::GetFecBpskBer (double snr, double nbits, 
+                         uint32_t signalSpread, uint32_t phyRate,
+                         uint32_t dFree, uint32_t adFree) const
+{
+  double ber = GetBpskBer (snr, signalSpread, phyRate);
+  if (ber == 0.0) 
+    {
+      return 1.0;
+    }
+  double pd = CalculatePd (ber, dFree);
+  double pmu = adFree * pd;
+  pmu = std::min (pmu, 1.0);
+  double pms = pow (1 - pmu, nbits);
+  return pms;
+}
+
+double
+ErrorRateModel::GetFecQamBer (double snr, uint32_t nbits, 
+                       uint32_t signalSpread,
+                       uint32_t phyRate,
+                       uint32_t m, uint32_t dFree,
+                       uint32_t adFree, uint32_t adFreePlusOne) const
+{
+  double ber = GetQamBer (snr, m, signalSpread, phyRate);
+  if (ber == 0.0) 
+    {
+      return 1.0;
+    }
+  /* first term */
+  double pd = CalculatePd (ber, dFree);
+  double pmu = adFree * pd;
+  /* second term */
+  pd = CalculatePd (ber, dFree + 1);
+  pmu += adFreePlusOne * pd;
+  pmu = std::min (pmu, 1.0);
+  double pms = pow (1 - pmu, nbits);
+  return pms;
+}
+
+double 
+ErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
+{
+  if (mode == WifiPhy::g_6mba)
+    {
+      return GetFecBpskBer (snr, 
+                            nbits,
+                            mode.GetBandwidth (), // signal spread
+                            mode.GetPhyRate (), // phy rate
+                            10, // dFree
+                            11 // adFree
+                            );      
+    }
+  else if (mode == WifiPhy::g_9mba)
+    {
+      return GetFecBpskBer (snr, 
+                            nbits,
+                            mode.GetBandwidth (), // signal spread
+                            mode.GetPhyRate (), // phy rate
+                            5, // dFree
+                            8 // adFree
+                            );
+    }
+  else if (mode == WifiPhy::g_12mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           4,  // m 
+                           10, // dFree
+                           11, // adFree
+                           0   // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_18mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           4, // m
+                           5, // dFree
+                           8, // adFree
+                           31 // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_24mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           16, // m
+                           10, // dFree
+                           11, // adFree
+                           0   // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_36mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           16, // m
+                           5,  // dFree
+                           8,  // adFree
+                           31  // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_48mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           64, // m
+                           6,  // dFree
+                           1,  // adFree
+                           16  // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_54mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           64, // m
+                           5,  // dFree
+                           8,  // adFree
+                           31  // adFreePlusOne
+                           );
+    }
+  return 0;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/error-rate-model.h	Thu Jun 12 12:28:36 2008 -0700
@@ -0,0 +1,41 @@
+#ifndef ERROR_RATE_MODEL_H
+#define ERROR_RATE_MODEL_H
+
+#include <stdint.h>
+#include "wifi-mode.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class ErrorRateModel : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  ErrorRateModel ();
+
+  double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
+
+private:
+  double Log2 (double val) const;
+  double GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const;
+  double GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const;
+  uint32_t Factorial (uint32_t k) const;
+  double Binomial (uint32_t k, double p, uint32_t n) const;
+  double CalculatePdOdd (double ber, unsigned int d) const;
+  double CalculatePdEven (double ber, unsigned int d) const;
+  double CalculatePd (double ber, unsigned int d) const;
+  double GetFecBpskBer (double snr, double nbits, 
+                        uint32_t signalSpread, uint32_t phyRate,
+                        uint32_t dFree, uint32_t adFree) const;
+  double GetFecQamBer (double snr, uint32_t nbits, 
+                       uint32_t signalSpread,
+                       uint32_t phyRate,
+                       uint32_t m, uint32_t dfree,
+                       uint32_t adFree, uint32_t adFreePlusOne) const;
+};
+
+
+} // namespace ns3
+
+#endif /* ERROR_RATE_MODEL_H */
--- a/src/devices/wifi/wscript	Thu Jun 12 12:07:50 2008 -0700
+++ b/src/devices/wifi/wscript	Thu Jun 12 12:28:36 2008 -0700
@@ -12,6 +12,7 @@
         'ssid.cc',
         'wifi-phy.cc',
         'wifi-phy-state-helper.cc',
+        'error-rate-model.cc',
         'yans-wifi-phy.cc',
         'yans-wifi-channel.cc',
         'wifi-mac-header.cc',
--- a/src/devices/wifi/yans-wifi-phy.cc	Thu Jun 12 12:07:50 2008 -0700
+++ b/src/devices/wifi/yans-wifi-phy.cc	Thu Jun 12 12:28:36 2008 -0700
@@ -23,6 +23,7 @@
 #include "wifi-mode.h"
 #include "wifi-preamble.h"
 #include "wifi-phy-state-helper.h"
+#include "error-rate-model.h"
 #include "ns3/simulator.h"
 #include "ns3/packet.h"
 #include "ns3/random-variable.h"
@@ -212,6 +213,7 @@
 {
   NS_LOG_FUNCTION (this);
   m_state = CreateObject<WifiPhyStateHelper> ();
+  m_errorRateModel = Create<ErrorRateModel> ();
 }
 
 YansWifiPhy::~YansWifiPhy ()
@@ -484,7 +486,7 @@
     {
       NS_ASSERT (high >= low);
       double middle = low + (high - low) / 2;
-      if ((1 - GetChunkSuccessRate (txMode, middle, 1)) > ber) 
+      if ((1 - m_errorRateModel->GetChunkSuccessRate (txMode, middle, 1)) > ber) 
         {
           low = middle;
         } 
@@ -518,7 +520,7 @@
     std::cout <<snr<<" ";
     for (uint8_t i = 0; i < GetNModes (); i++) {
       WifiMode mode = GetMode (i);
-      double ber = 1-GetChunkSuccessRate (mode,snr, 2000*8);
+      double ber = 1-m_errorRateModel->GetChunkSuccessRate (mode,snr, 2000*8);
       std::cout <<ber<< " ";
     }
     std::cout << std::endl;
@@ -701,236 +703,6 @@
 }
 
 
-
-/**
- * Stuff specific to the BER model here.
- */
-double 
-YansWifiPhy::Log2 (double val) const
-{
-  return log(val) / log(2.0);
-}
-double 
-YansWifiPhy::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
-{
-  double EbNo = snr * signalSpread / phyRate;
-  double z = sqrt(EbNo);
-  double ber = 0.5 * erfc(z);
-  NS_LOG_INFO ("bpsk snr="<<snr<<" ber="<<ber);
-  return ber;
-}
-double 
-YansWifiPhy::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
-{
-  double EbNo = snr * signalSpread / phyRate;
-  double z = sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
-  double z1 = ((1.0 - 1.0 / sqrt (m)) * erfc (z)) ;
-  double z2 = 1 - pow ((1-z1), 2.0);
-  double ber = z2 / Log2 (m);
-  NS_LOG_INFO ("Qam m="<<m<<" rate=" << phyRate << " snr="<<snr<<" ber="<<ber);
-  return ber;
-}
-uint32_t
-YansWifiPhy::Factorial (uint32_t k) const
-{
-  uint32_t fact = 1;
-  while (k > 0) 
-    {
-      fact *= k;
-      k--;
-    }
-  return fact;
-}
-double 
-YansWifiPhy::Binomial (uint32_t k, double p, uint32_t n) const
-{
-  double retval = Factorial (n) / (Factorial (k) * Factorial (n-k)) * pow (p, k) * pow (1-p, n-k);
-  return retval;
-}
-double 
-YansWifiPhy::CalculatePdOdd (double ber, unsigned int d) const
-{
-  NS_ASSERT ((d % 2) == 1);
-  unsigned int dstart = (d + 1) / 2;
-  unsigned int dend = d;
-  double pd = 0;
-
-  for (unsigned int i = dstart; i < dend; i++) 
-    {
-      pd += Binomial (i, ber, d);
-    }
-  return pd;
-}
-double 
-YansWifiPhy::CalculatePdEven (double ber, unsigned int d) const
-{
-  NS_ASSERT ((d % 2) == 0);
-  unsigned int dstart = d / 2 + 1;
-  unsigned int dend = d;
-  double pd = 0;
-
-  for (unsigned int i = dstart; i < dend; i++)
-    {
-      pd +=  Binomial (i, ber, d);
-    }
-  pd += 0.5 * Binomial (d / 2, ber, d);
-
-  return pd;
-}
-
-double 
-YansWifiPhy::CalculatePd (double ber, unsigned int d) const
-{
-  double pd;
-  if ((d % 2) == 0) 
-    {
-      pd = CalculatePdEven (ber, d);
-    } 
-  else 
-    {
-      pd = CalculatePdOdd (ber, d);
-    }
-  return pd;
-}
-
-double
-YansWifiPhy::GetFecBpskBer (double snr, double nbits, 
-                         uint32_t signalSpread, uint32_t phyRate,
-                         uint32_t dFree, uint32_t adFree) const
-{
-  double ber = GetBpskBer (snr, signalSpread, phyRate);
-  if (ber == 0.0) 
-    {
-      return 1.0;
-    }
-  double pd = CalculatePd (ber, dFree);
-  double pmu = adFree * pd;
-  pmu = std::min (pmu, 1.0);
-  double pms = pow (1 - pmu, nbits);
-  return pms;
-}
-
-double
-YansWifiPhy::GetFecQamBer (double snr, uint32_t nbits, 
-                       uint32_t signalSpread,
-                       uint32_t phyRate,
-                       uint32_t m, uint32_t dFree,
-                       uint32_t adFree, uint32_t adFreePlusOne) const
-{
-  double ber = GetQamBer (snr, m, signalSpread, phyRate);
-  if (ber == 0.0) 
-    {
-      return 1.0;
-    }
-  /* first term */
-  double pd = CalculatePd (ber, dFree);
-  double pmu = adFree * pd;
-  /* second term */
-  pd = CalculatePd (ber, dFree + 1);
-  pmu += adFreePlusOne * pd;
-  pmu = std::min (pmu, 1.0);
-  double pms = pow (1 - pmu, nbits);
-  return pms;
-}
-
-double 
-YansWifiPhy::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
-{
-  if (mode.GetUid () == g_6mba.GetUid ())
-    {
-      return GetFecBpskBer (snr, 
-                            nbits,
-                            mode.GetBandwidth (), // signal spread
-                            mode.GetPhyRate (), // phy rate
-                            10, // dFree
-                            11 // adFree
-                            );      
-    }
-  else if (mode.GetUid () == g_9mba.GetUid ())
-    {
-      return GetFecBpskBer (snr, 
-                            nbits,
-                            mode.GetBandwidth (), // signal spread
-                            mode.GetPhyRate (), // phy rate
-                            5, // dFree
-                            8 // adFree
-                            );
-    }
-  else if (mode.GetUid () == g_12mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           4,  // m 
-                           10, // dFree
-                           11, // adFree
-                           0   // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_18mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           4, // m
-                           5, // dFree
-                           8, // adFree
-                           31 // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_24mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           16, // m
-                           10, // dFree
-                           11, // adFree
-                           0   // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_36mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           16, // m
-                           5,  // dFree
-                           8,  // adFree
-                           31  // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_48mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           64, // m
-                           6,  // dFree
-                           1,  // adFree
-                           16  // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_54mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           64, // m
-                           5,  // dFree
-                           8,  // adFree
-                           31  // adFreePlusOne
-                           );
-    }
-  return 0;
-}
-
 double
 YansWifiPhy::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
 {
@@ -987,7 +759,7 @@
   }
   uint32_t rate = mode.GetPhyRate ();
   uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
-  double csr = GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
+  double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
   return csr;
 }
 
@@ -1114,7 +886,7 @@
    */
   double per = CalculatePer (event, &ni);
   NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
-                ", ber="<<(1-GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<<
+                ", ber="<<(1-m_errorRateModel->GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<<
                 ", snr="<<snr<<", per="<<per<<", size="<<packet->GetSize ());
   
   if (m_random.GetValue () > per) 
--- a/src/devices/wifi/yans-wifi-phy.h	Thu Jun 12 12:07:50 2008 -0700
+++ b/src/devices/wifi/yans-wifi-phy.h	Thu Jun 12 12:28:36 2008 -0700
@@ -44,6 +44,7 @@
 class RxEvent;
 class YansWifiChannel;
 class WifiPhyStateHelper;
+class ErrorRateModel;
 
 
 /**
@@ -146,23 +147,6 @@
   double CalculateChunkSuccessRate (double snir, Time delay, WifiMode mode) const;
   double CalculatePer (Ptr<const RxEvent> event, NiChanges *ni) const;
   void EndSync (Ptr<Packet> packet, Ptr<RxEvent> event);
-  double Log2 (double val) const;
-  double GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const;
-  double GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const;
-  uint32_t Factorial (uint32_t k) const;
-  double Binomial (uint32_t k, double p, uint32_t n) const;
-  double CalculatePdOdd (double ber, unsigned int d) const;
-  double CalculatePdEven (double ber, unsigned int d) const;
-  double CalculatePd (double ber, unsigned int d) const;
-  double GetFecBpskBer (double snr, double nbits, 
-                        uint32_t signalSpread, uint32_t phyRate,
-                        uint32_t dFree, uint32_t adFree) const;
-  double GetFecQamBer (double snr, uint32_t nbits, 
-                       uint32_t signalSpread,
-                       uint32_t phyRate,
-                       uint32_t m, uint32_t dfree,
-                       uint32_t adFree, uint32_t adFreePlusOne) const;
-  double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
 private:
   uint64_t m_txPrepareDelayUs;
   uint64_t m_plcpLongPreambleDelayUs;
@@ -187,6 +171,7 @@
   UniformVariable m_random;
   WifiPhyStandard m_standard;
   Ptr<WifiPhyStateHelper> m_state;
+  Ptr<ErrorRateModel> m_errorRateModel;
 };
 
 } // namespace ns3