Add testcase for DL control channels (PCFICH+PDCCH) to lte-phy-error-model test suite
authorMarco Miozzo <marco.miozzo@cttc.es>
Fri, 06 Jul 2012 13:08:22 +0200
changeset 9044 e8595c3ac95b
parent 9043 9130e2dbe601
child 9045 9786bf474ea1
Add testcase for DL control channels (PCFICH+PDCCH) to lte-phy-error-model test suite
src/lte/model/lte-enb-phy.cc
src/lte/model/lte-mi-error-model.cc
src/lte/model/rr-ff-mac-scheduler.cc
src/lte/test/lte-test-phy-error-model.cc
src/lte/test/lte-test-phy-error-model.h
--- a/src/lte/model/lte-enb-phy.cc	Thu Jul 05 16:42:48 2012 +0200
+++ b/src/lte/model/lte-enb-phy.cc	Fri Jul 06 13:08:22 2012 +0200
@@ -400,7 +400,11 @@
   NS_LOG_FUNCTION (this);
 
   ++m_nrSubFrames;
-  m_currentSrsOffset = (m_currentSrsOffset + 1) % m_srsPeriodicity;
+  if (m_srsPeriodicity>0)
+    { 
+      // might be 0 in case the eNB has no UEs attached
+      m_currentSrsOffset = (m_currentSrsOffset + 1) % m_srsPeriodicity;
+    }
   NS_LOG_INFO ("-----sub frame " << m_nrSubFrames << "-----");
   
   
--- a/src/lte/model/lte-mi-error-model.cc	Thu Jul 05 16:42:48 2012 +0200
+++ b/src/lte/model/lte-mi-error-model.cc	Fri Jul 06 13:08:22 2012 +0200
@@ -541,7 +541,22 @@
   else 
     {
       NS_ASSERT_MSG (j<MI_MAP_QPSK_SIZE, "MI map out of data");
-      esinr = MI_map_qpsk_axis[j];
+      // take the closest value (when possible)  
+      if (j>0)
+        {
+          if ((MI_map_qpsk[j]-MI)<(MI-MI_map_qpsk[j-1]))
+            {
+              esinr = MI_map_qpsk_axis[j];
+            }
+          else
+            {
+              esinr = MI_map_qpsk_axis[j-1];
+            }
+        }
+      else
+        {
+          esinr = MI_map_qpsk_axis[0];
+        }
     }
 
   double esirnDb = 10*log10 (esinr); 
--- a/src/lte/model/rr-ff-mac-scheduler.cc	Thu Jul 05 16:42:48 2012 +0200
+++ b/src/lte/model/rr-ff-mac-scheduler.cc	Fri Jul 06 13:08:22 2012 +0200
@@ -536,7 +536,7 @@
 //       int totRbg = lcNum * rbgPerFlow;
 //       totRbg = rbgNum / nTbs;
       int tbSize = (m_amc->GetTbSizeFromMcs (newDci.m_mcs.at (0), rbgPerTb * rbgSize) / 8);
-      NS_LOG_DEBUG (this << "Allocate user " << newEl.m_rnti << " LCs " << (uint16_t)(*itLcRnti).second << " bytes " << tbSize << " PRBs " <<  rbgAllocated * rbgSize << "..." << (rbgAllocated* rbgSize) + (rbgPerTb * rbgSize) - 1 << " mcs " << (uint16_t) newDci.m_mcs.at (0) << " layers " << nLayer);
+      NS_LOG_DEBUG (this << " DL - Allocate user " << newEl.m_rnti << " LCs " << (uint16_t)(*itLcRnti).second << " bytes " << tbSize << " PRBs " <<  rbgAllocated * rbgSize << "..." << (rbgAllocated* rbgSize) + (rbgPerTb * rbgSize) - 1 << " mcs " << (uint16_t) newDci.m_mcs.at (0) << " layers " << nLayer);
       uint16_t rlcPduSize = tbSize / lcNum;
       for (int i = 0; i < lcNum ; i++)
         {
--- a/src/lte/test/lte-test-phy-error-model.cc	Thu Jul 05 16:42:48 2012 +0200
+++ b/src/lte/test/lte-test-phy-error-model.cc	Fri Jul 06 13:08:22 2012 +0200
@@ -59,20 +59,32 @@
   : TestSuite ("lte-phy-error-model", SYSTEM)
 {
   NS_LOG_INFO ("creating LenaTestPhyErrorModelTestCase");
+  
+  
+  // Tests on DL Control Channels (PCFICH+PDDCH)
+  // 1 interfering eNB SINR -2.0 BER 0.007 TB size 217
+  AddTestCase (new LenaDlCtrlPhyErrorModelTestCase (2, 1078, 217, 0.007));
+  // 2 interfering eNBs SINR -4.0 BER 0.037 TB size 217
+  AddTestCase (new LenaDlCtrlPhyErrorModelTestCase (3, 1040, 217, 0.045));
+  // 3 interfering eNBs SINR -6.0 BER 0.21 TB size 133
+  AddTestCase (new LenaDlCtrlPhyErrorModelTestCase (4, 1250, 133, 0.206));
+  // 4 interfering eNBs SINR -7.0 BER 0.34 TB size 133
+  AddTestCase (new LenaDlCtrlPhyErrorModelTestCase (5, 1260, 81, 0.343));
 
+  // Tests on DL/UL Data channels (PDSCH, PUSCH)
   // MCS 2 TB size of 256 bits BER 0.33 SINR -5.51
-   AddTestCase (new LenaPhyErrorModelTestCase (4, 1800, 32, 0.35, 29));
+  AddTestCase (new LenaDataPhyErrorModelTestCase (4, 1800, 32, 0.35, 29));
 // MCS 2 TB size of 528 bits BER 0.11 SINR -5.51
-   AddTestCase (new LenaPhyErrorModelTestCase (2, 1800, 66, 0.11, 20));
+  AddTestCase (new LenaDataPhyErrorModelTestCase (2, 1800, 66, 0.11, 20));
 // MCS 2 TB size of 1088 bits BER 0.02 SINR -5.51
-  AddTestCase (new LenaPhyErrorModelTestCase (1, 1800, 136, 0.02, 9));
+  AddTestCase (new LenaDataPhyErrorModelTestCase (1, 1800, 136, 0.02, 9));
   // MCS 12 TB size of 4800 bits  BER 0.3  SINR 4.43
-   AddTestCase (new LenaPhyErrorModelTestCase (1, 600, 600, 0.3, 29));
+  AddTestCase (new LenaDataPhyErrorModelTestCase (1, 600, 600, 0.3, 29));
 // MCS 12 TB size of 1632 bits  BER 0.55  SINR 4.43
-  AddTestCase (new LenaPhyErrorModelTestCase (3, 600, 204, 0.55, 31));
+  AddTestCase (new LenaDataPhyErrorModelTestCase (3, 600, 204, 0.55, 31));
 // MCS 16 TB size of 7272 bits (3648 x 3584) BER 0.14 SINR 8.48
 // BER 0.14 = 1 - ((1-0.075)*(1-0.075))
-   AddTestCase (new LenaPhyErrorModelTestCase (1, 470, 781, 0.14, 22));
+  AddTestCase (new LenaDataPhyErrorModelTestCase (1, 470, 781, 0.14, 22));
 
  
 
@@ -81,14 +93,14 @@
 static LenaTestPhyErrorModelrSuite lenaTestPhyErrorModelrSuite;
 
 std::string 
-LenaPhyErrorModelTestCase::BuildNameString (uint16_t nUser, uint16_t dist)
+LenaDataPhyErrorModelTestCase::BuildNameString (uint16_t nUser, uint16_t dist)
 {
   std::ostringstream oss;
   oss << nUser << " UEs, distance " << dist << " m";
   return oss.str ();
 }
 
-LenaPhyErrorModelTestCase::LenaPhyErrorModelTestCase (uint16_t nUser, uint16_t dist, uint16_t tbSize, double berRef, uint16_t bernQuantile)
+LenaDataPhyErrorModelTestCase::LenaDataPhyErrorModelTestCase (uint16_t nUser, uint16_t dist, uint16_t tbSize, double berRef, uint16_t bernQuantile)
   : TestCase (BuildNameString (nUser, dist)),              
     m_nUser (nUser),
     m_dist (dist),
@@ -98,12 +110,12 @@
 {
 }
 
-LenaPhyErrorModelTestCase::~LenaPhyErrorModelTestCase ()
+LenaDataPhyErrorModelTestCase::~LenaDataPhyErrorModelTestCase ()
 {
 }
 
 void
-LenaPhyErrorModelTestCase::DoRun (void)
+LenaDataPhyErrorModelTestCase::DoRun (void)
 {
   
    double ber = 0.03;
@@ -232,6 +244,7 @@
   /**
    * Check that the assignation is done in a RR fashion
    */
+  NS_LOG_INFO ("\tTest downlink/uplink data shared channels (PDSCH and PUSCH)");
   NS_LOG_INFO ("Test with " << m_nUser << " user(s) at distance " << m_dist << " expected BER " << m_berRef);
   std::vector <uint64_t> dlDataRxed;
   for (int i = 0; i < m_nUser; i++)
@@ -260,3 +273,185 @@
   Simulator::Destroy ();
 }
 
+
+
+
+std::string 
+LenaDlCtrlPhyErrorModelTestCase::BuildNameString (uint16_t nEnb, uint16_t dist)
+{
+  std::ostringstream oss;
+  oss << nEnb << " eNBs, distance " << dist << " m";
+  return oss.str ();
+}
+
+
+LenaDlCtrlPhyErrorModelTestCase::LenaDlCtrlPhyErrorModelTestCase (uint16_t nEnb, uint16_t dist, uint16_t tbSize, double berRef)
+: TestCase (BuildNameString (nEnb, dist)),              
+m_nEnb (nEnb),
+m_dist (dist),
+m_tbSize (tbSize),
+m_berRef (berRef)
+{
+}
+
+LenaDlCtrlPhyErrorModelTestCase::~LenaDlCtrlPhyErrorModelTestCase ()
+{
+}
+
+void
+LenaDlCtrlPhyErrorModelTestCase::DoRun (void)
+{
+  
+  double ber = 0.03;
+  Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (ber));
+  Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
+  Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (true));
+  Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));  
+  //   LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
+  // 
+  //   LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
+  
+  //   LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
+  // 
+  //   LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
+  // 
+  //   LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
+  
+//     LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LenaHelper", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL);
+  
+  
+  //   LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LenaHelper", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL);
+//     LogComponentEnable ("LteMiErrorModel", LOG_LEVEL_ALL);
+  //   LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
+  //   
+  LogComponentDisableAll (LOG_LEVEL_ALL);
+  
+  LogComponentEnable ("LenaTestPhyErrorModel", LOG_LEVEL_ALL);
+  
+  
+  /**
+  * Initialize Simulation Scenario: 1 eNB and m_nUser UEs
+  */
+  
+  Ptr<LteHelper> lena = CreateObject<LteHelper> ();
+  
+  // Create Nodes: eNodeB and UE
+  NodeContainer enbNodes;
+  NodeContainer ueNodes;
+  enbNodes.Create (m_nEnb);
+  ueNodes.Create (1);
+  
+  // Install Mobility Model
+  MobilityHelper mobility;
+  mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+  mobility.Install (enbNodes);
+  mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+  mobility.Install (ueNodes);
+  
+  // remove random shadowing component
+  lena->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
+  lena->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (0.0));
+  lena->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (0.0));
+  lena->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0.0));
+  
+  // Create Devices and install them in the Nodes (eNB and UE)
+  NetDeviceContainer enbDevs;
+  NetDeviceContainer ueDevs;
+  lena->SetSchedulerType ("ns3::RrFfMacScheduler");
+  lena->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
+  
+  enbDevs = lena->InstallEnbDevice (enbNodes);
+  ueDevs = lena->InstallUeDevice (ueNodes);
+  
+  // Attach a UE to one eNB (the others are interfering ones)
+  lena->Attach (ueDevs, enbDevs.Get (0));
+  
+  // Activate an EPS bearer
+  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
+  EpsBearer bearer (q);
+  lena->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  
+  // Set UEs' position and power
+  for (int i = 0; i < m_nEnb; i++)
+    {
+      // place the HeNB over the default rooftop level (20 mt.)
+      Ptr<BuildingsMobilityModel> mm = enbNodes.Get (i)->GetObject<BuildingsMobilityModel> ();
+      mm->SetPosition (Vector (0.0, 0.0, 30.0));
+      Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (i)->GetObject<LteEnbNetDevice> ();
+      Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
+      enbPhy->SetAttribute ("TxPower", DoubleValue (43.0));
+      enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
+    }
+  
+  // Set UEs' position and power
+  Ptr<BuildingsMobilityModel> mm = ueNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
+  mm->SetPosition (Vector (m_dist, 0.0, 1.0));
+  Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
+  Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
+  uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
+  uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
+  
+  
+  lena->EnableRlcTraces ();
+  double simulationTime = 1.000;
+  
+  Simulator::Stop (Seconds (simulationTime));
+  
+  Ptr<RadioBearerStatsCalculator> rlcStats = lena->GetRlcStats ();
+  rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
+  
+  
+  Simulator::Run ();
+  
+  /**
+  * Check that the assignation is done in a RR fashion
+  */
+  NS_LOG_INFO ("\tTest downlink control channels (PCFICH+PDCCH)");
+  NS_LOG_INFO ("Test with " << m_nEnb << " eNB(s) at distance " << m_dist << " expected BER " << m_berRef);
+  std::vector <uint64_t> dlDataRxed;
+  int nUser = 1;
+  for (int i = 0; i < nUser; i++)
+  {
+    // get the imsi
+    uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
+    // get the lcId
+    uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
+    dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
+    double txed = rlcStats->GetDlTxData (imsi, lcId);
+    double ber = 1.0 - ((double)dlDataRxed.at (i)/txed);
+    NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " txed " << txed 
+    << " BER " << ber << " Err " << fabs (m_berRef - ber));
+    NS_UNUSED (ber);
+    NS_TEST_ASSERT_MSG_EQ_TOL (ber, m_berRef, 0.1, " Unexpected BER distribution!");
+  }
+  
+  
+  Simulator::Destroy ();
+}
+
+
+
+
--- a/src/lte/test/lte-test-phy-error-model.h	Thu Jul 05 16:42:48 2012 +0200
+++ b/src/lte/test/lte-test-phy-error-model.h	Fri Jul 06 13:08:22 2012 +0200
@@ -35,11 +35,11 @@
  * implemented obtained by using different SINR values and different numbers of 
  * UEs. The test consists on ...
  */
-class LenaPhyErrorModelTestCase : public TestCase
+class LenaDataPhyErrorModelTestCase : public TestCase
 {
 public:
-  LenaPhyErrorModelTestCase (uint16_t nUser, uint16_t dist, uint16_t tbSize, double refBer, uint16_t bernQuantile);
-  virtual ~LenaPhyErrorModelTestCase ();
+  LenaDataPhyErrorModelTestCase (uint16_t nUser, uint16_t dist, uint16_t tbSize, double refBer, uint16_t bernQuantile);
+  virtual ~LenaDataPhyErrorModelTestCase ();
 
 private:
   virtual void DoRun (void);
@@ -54,6 +54,24 @@
 
 
 
+class LenaDlCtrlPhyErrorModelTestCase : public TestCase
+{
+  public:
+    LenaDlCtrlPhyErrorModelTestCase (uint16_t nEnbr, uint16_t dist, uint16_t tbSize, double refBer);
+    virtual ~LenaDlCtrlPhyErrorModelTestCase ();
+    
+  private:
+    virtual void DoRun (void);
+    static std::string BuildNameString (uint16_t nUser, uint16_t dist);
+    uint16_t m_nEnb;
+    uint16_t m_dist;
+    uint16_t m_tbSize;
+    double m_berRef;
+    
+};
+
+
+
 class LenaTestPhyErrorModelrSuite : public TestSuite
 {
 public: