diff --git a/doc/manual/figures/lte-enb-architecture.dia b/doc/manual/figures/lte-enb-architecture.dia new file mode 100644 index 000000000..a7b7c5273 Binary files /dev/null and b/doc/manual/figures/lte-enb-architecture.dia differ diff --git a/doc/manual/source/lte-design.rst b/doc/manual/source/lte-design.rst new file mode 100644 index 000000000..1a03b13df --- /dev/null +++ b/doc/manual/source/lte-design.rst @@ -0,0 +1,107 @@ +.. include:: replace.txt + + +++++++++++++++++++++++++++ + LTE Design Documentation +++++++++++++++++++++++++++ + +----------------------------------------------------------------------------- + +* the new eutra stack diagram with all SAPs, differentiated between eNB and UE +* the explanation of the new example program + + +----------------------------------------------------------------------------- + +Radio Resource Management and Packet Scheduling +############################################### + +For how the ns-3 LTE module handles Radio Resource Management and Packet Scheduling at the eNB, please see the :ref:`ff-mac-sched-api`. + + +Physical layer +############## + +A :cpp:class:`ns3::LtePhy` class models the LTE PHY layer. + +Basic functionalities of the PHY layer are: (i) transmit packets coming from the device to the channel; (ii) receive packets from the channel; (ii) evaluate the quality of the channel from the Signal To Noise ratio of the received signal; and (iii) forward received packets to the device. + +Both the PHY and channel have been developed extending :cpp:class:`ns3::SpectrumPhy` and +:cpp:class:`ns3::SpectrumChannel` classes, respectively, which are provided by the Spectrum Framework [1]_. + +The module implements an FDD channel access. In FDD channel access, downlink and uplink +transmissions work together in the time but using a different set of frequencies. +Since DL and UL are indipendent between them, the PHY is composed by couple of +:cpp:class:`ns3::LteSpectrumPhy` object, one for the downlink and one for the uplink. +The :cpp:class:`ns3::LtePhy` stores and manages both downlink and uplink +:cpp:class:`ns3::LteSpectrumPhy` elements. + +In order to customize all physical functionalities for both UE and eNB devices, dedicated +classes have been inherited from ones described before. In particular, +:cpp:class:`ns3::LteUePhy` and :cpp:class:`ns3::LteEnbPhy` classes, inherited from +the :cpp:class:`ns3::LtePhy` class, implement the PHY layer for the UE and the +eNB, respectively. + +The figure below shows how UE and eNB can exchange packets through the considered PHY layer. + +.. _lte-transmission: + +.. figure:: figures/lte-transmission.png + + DL and UL transmision on the LTE network + +For the downlink, when the eNB whants to send packets, it calls the ``StartTx`` function to +send them into the downlink channel. Then, the downlink channel delivers the burst +of packets to all the :cpp:class:`ns3::UeLteSpectrumPhy` attached to it, handling the +``StartRx`` function. +When the UE receives packets, it executes the following tasks: + +* compute the SINR for all the sub channel used in the downlink + +* create and send CQI feedbacks + +* forward all the received packets to the MAC layer through the PHY SAP. + +The uplink works similary. + +Propagation Loss Models +####################### + +A proper propagation loss model has been developed for the LTE E-UTRAN interface (see [2]_ and [3]_). +It is used by the PHY layer to compute the loss due to the propagation. + +The LTE propagation loss model is composed by 4 different models (shadowing, multipath, +penetration loss and path loss) [2]_: + +* Pathloss: :math:`PL = 128.1 + (37.6 * log10 (R))`, where R is the distance between the + UE and the eNB in Km. + +* Multipath: Jakes model + +* PenetrationLoss: 10 dB + +* Shadowing: log-normal distribution (mean=0dB, standard deviation=8dB) + +Every time that the ``LteSpectrumPHY::StartRx ()`` function is called, the +``SpectrumInterferenceModel`` is used to computed the SINR, as proposed in [3]_. Then, +the network device uses the AMC module to map the SINR to a proper CQI and to send it +to the eNB using the ideal control channel. + + +References +---------- + +.. [1] N. Baldo and M. Miozzo, Spectrum-aware Channel and PHY layer modeling for ns3, Proceedings + of ICST NSTools 2009, Pisa, Italy. The framework is designed to simulate only data + transmissions. For the transmission of control messages (such as CQI feedback, PDCCH, + etc..) will be used an ideal control channel). + +.. [2] 3GPP TS 25.814 ( http://www.3gpp.org/ftp/specs/html-INFO/25814.htm ) + +.. [3] Giuseppe Piro, Luigi Alfredo Grieco, Gennaro Boggia, and Pietro Camarda", A Two-level + Scheduling Algorithm for QoS Support in the Downlink of LTE Cellular Networks", Proc. of + European Wireless, EW2010, Lucca, Italy, Apr., 2010 ( draft version is available on + http://telematics.poliba.it/index.php?option=com_jombib&task=showbib&id=330 ) + +.. [4] 3GPP R1-081483 (available on + http://www.3gpp.org/ftp/tsg_ran/WG1_RL1/TSGR1_52b/Docs/R1-081483.zip ) diff --git a/doc/manual/source/lte-testing.rst b/doc/manual/source/lte-testing.rst new file mode 100644 index 000000000..68cd25e5c --- /dev/null +++ b/doc/manual/source/lte-testing.rst @@ -0,0 +1,52 @@ +.. include:: replace.txt + + ++++++++++++++++++++++++++++ + LTE Testing Documentation ++++++++++++++++++++++++++++ + + +Overview +******** + +The tests for the ns-3 LTE module are integrated with the ns-3 test framework. +To run them, you need to have configured the build of the simulator in this way:: + + ./waf configure --enable-tests --enable-modules=lte --enable-examples + ./test.py + +The above will run not only the test suites belonging to the LTE module, but also those belonging to all the other ns-3 modules on which the LTE module depends. See the ns-3 manual for generic information on the testing framework. + +You can get a more detailed report in HTML format in this way:: + + ./test.py -w results.html + +After the above command has run, you can view the detailed result for each test by opebning the file ``results.html`` with a web browser. + + + + +Description of the tests +************************ + +Unit Tests +~~~~~~~~~~ + +SINR calculation in the Downlink +-------------------------------- + +SINR calculation in the uplink +------------------------------ + + +System Tests +~~~~~~~~~~~~ + +Adaptive Modulation and Coding +------------------------------ + +Round Robin scheduler performance +--------------------------------- + +Proportional Fair scheduler performance +--------------------------------------- diff --git a/doc/manual/source/lte-user.rst b/doc/manual/source/lte-user.rst new file mode 100644 index 000000000..08c5daa69 --- /dev/null +++ b/doc/manual/source/lte-user.rst @@ -0,0 +1,71 @@ +.. include:: replace.txt + + ++++++++++++++++++++++++++ + LTE User Documentation ++++++++++++++++++++++++++ + +EUTRA stack diagram +******************* + + +Usage +***** + +Users interact with the LTE model through the LENA helper API and through the publicly visible methods of the model. The helper API is defined in ``src/lte/helper/lena-helper.h``. + +The ``src/lte/examples/`` directory contains some basic examples that shows how to set up the LTE model in order to simulate an EUTRA downlink transmission. + +Example simulation program +-------------------------- + +``src/lte/examples/lena-first-sim.cc`` shows how to build a simple but complete simulation with one LTE eNB and one LTE UE. The detail explanation of the code follows: + +#. Declare the helper. This helper keeps together all the LTE components:: + + LenaHelper lena; + + +#. Enable the logs in the LTE components:: + + lena.EnableLogComponents (); + + +#. Create eNB and UE. They are created in its own node container:: + + NodeContainer enbNodes; + NodeContainer ueNodes; + enbNodes.Create (1); + ueNodes.Create (1); + + +#. Install mobility models to eNB and UE. This has to be done before devices are created and installed:: + + MobilityHelper mobility; + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (enbNodes); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (ueNodes); + + +#. Create devices and install them to the eNB and UE:: + + NetDeviceContainer enbDevs; + NetDeviceContainer ueDevs; + enbDevs = lena.InstallEnbDevice (enbNodes); + ueDevs = lena.InstallUeDevice (ueNodes); + + +#. Attach a UE to a eNB. It will also create a RRC connection between them and configure the UE:: + + lena.Attach (ueDevs, enbDevs.Get (0)); + + +#. Activate an EPS Bearer including the setup of the Radio Bearer between an eNB and its attached UE:: + + enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; + EpsBearer bearer (q); + lena.ActivateEpsBearer (ueDevs, bearer); + + +``src/lte/examples/lena-first-sim.cc`` shows how to build a simple but complete simulation with one LTE eNB and one LTE UE. The detail explanation of the code follows: diff --git a/doc/manual/source/lte.rst b/doc/manual/source/lte.rst index 8530b93bc..75c3a11a7 100644 --- a/doc/manual/source/lte.rst +++ b/doc/manual/source/lte.rst @@ -1,175 +1,18 @@ -.. include:: replace.txt +######################## LTE Module ----------- +######################## + This chapter describes the ns-3 LTE module located in ``src/lte``. -EUTRA stack diagram -******************* -Usage -***** +.. toctree:: -Users interact with the LTE model through the LENA helper API and through the publicly visible methods of the model. The helper API is defined in ``src/lte/helper/lena-helper.h``. - -The ``src/lte/examples/`` directory contains some basic examples that shows how to set up the LTE model in order to simulate an EUTRA downlink transmission. - -Example simulation program -========================== - -``src/lte/examples/lena-first-sim.cc`` shows how to build a simple but complete simulation with one LTE eNB and one LTE UE. The detail explanation of the code follows: - -#. Declare the helper. This helper keeps together all the LTE components:: - - LenaHelper lena; - - -#. Enable the logs in the LTE components:: - - lena.EnableLogComponents (); - - -#. Create eNB and UE. They are created in its own node container:: - - NodeContainer enbNodes; - NodeContainer ueNodes; - enbNodes.Create (1); - ueNodes.Create (1); - - -#. Install mobility models to eNB and UE. This has to be done before devices are created and installed:: - - MobilityHelper mobility; - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (enbNodes); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (ueNodes); - - -#. Create devices and install them to the eNB and UE:: - - NetDeviceContainer enbDevs; - NetDeviceContainer ueDevs; - enbDevs = lena.InstallEnbDevice (enbNodes); - ueDevs = lena.InstallUeDevice (ueNodes); - - -#. Attach a UE to a eNB. It will also create a RRC connection between them and configure the UE:: - - lena.Attach (ueDevs, enbDevs.Get (0)); - - -#. Activate an EPS Bearer including the setup of the Radio Bearer between an eNB and its attached UE:: - - enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; - EpsBearer bearer (q); - lena.ActivateEpsBearer (ueDevs, bearer); - - -``src/lte/examples/lena-first-sim.cc`` shows how to build a simple but complete simulation with one LTE eNB and one LTE UE. The detail explanation of the code follows: - ------------------------------------------------------------------------------ - -* the new eutra stack diagram with all SAPs, differentiated between eNB and UE -* the explanation of the new example program - - ------------------------------------------------------------------------------ - -Radio Resource Management and Packet Scheduling -############################################### - -For how the ns-3 LTE module handles Radio Resource Management and Packet Scheduling at the eNB, please see the :ref:`ff-mac-sched-api`. - - -Physical layer -############## - -A :cpp:class:`ns3::LtePhy` class models the LTE PHY layer. - -Basic functionalities of the PHY layer are: (i) transmit packets coming from the device to the channel; (ii) receive packets from the channel; (ii) evaluate the quality of the channel from the Signal To Noise ratio of the received signal; and (iii) forward received packets to the device. - -Both the PHY and channel have been developed extending :cpp:class:`ns3::SpectrumPhy` and -:cpp:class:`ns3::SpectrumChannel` classes, respectively, which are provided by the Spectrum Framework [1]_. - -The module implements an FDD channel access. In FDD channel access, downlink and uplink -transmissions work together in the time but using a different set of frequencies. -Since DL and UL are indipendent between them, the PHY is composed by couple of -:cpp:class:`ns3::LteSpectrumPhy` object, one for the downlink and one for the uplink. -The :cpp:class:`ns3::LtePhy` stores and manages both downlink and uplink -:cpp:class:`ns3::LteSpectrumPhy` elements. - -In order to customize all physical functionalities for both UE and eNB devices, dedicated -classes have been inherited from ones described before. In particular, -:cpp:class:`ns3::LteUePhy` and :cpp:class:`ns3::LteEnbPhy` classes, inherited from -the :cpp:class:`ns3::LtePhy` class, implement the PHY layer for the UE and the -eNB, respectively. - -The figure below shows how UE and eNB can exchange packets through the considered PHY layer. - -.. _lte-transmission: - -.. figure:: figures/lte-transmission.png - - DL and UL transmision on the LTE network - -For the downlink, when the eNB whants to send packets, it calls the ``StartTx`` function to -send them into the downlink channel. Then, the downlink channel delivers the burst -of packets to all the :cpp:class:`ns3::UeLteSpectrumPhy` attached to it, handling the -``StartRx`` function. -When the UE receives packets, it executes the following tasks: - -* compute the SINR for all the sub channel used in the downlink - -* create and send CQI feedbacks - -* forward all the received packets to the MAC layer through the PHY SAP. - -The uplink works similary. - -Propagation Loss Models -####################### - -A proper propagation loss model has been developed for the LTE E-UTRAN interface (see [2]_ and [3]_). -It is used by the PHY layer to compute the loss due to the propagation. - -The LTE propagation loss model is composed by 4 different models (shadowing, multipath, -penetration loss and path loss) [2]_: - -* Pathloss: :math:`PL = 128.1 + (37.6 * log10 (R))`, where R is the distance between the - UE and the eNB in Km. - -* Multipath: Jakes model - -* PenetrationLoss: 10 dB - -* Shadowing: log-normal distribution (mean=0dB, standard deviation=8dB) - -Every time that the ``LteSpectrumPHY::StartRx ()`` function is called, the -``SpectrumInterferenceModel`` is used to computed the SINR, as proposed in [3]_. Then, -the network device uses the AMC module to map the SINR to a proper CQI and to send it -to the eNB using the ideal control channel. - - -References -========== - -.. [1] N. Baldo and M. Miozzo, Spectrum-aware Channel and PHY layer modeling for ns3, Proceedings - of ICST NSTools 2009, Pisa, Italy. The framework is designed to simulate only data - transmissions. For the transmission of control messages (such as CQI feedback, PDCCH, - etc..) will be used an ideal control channel). - -.. [2] 3GPP TS 25.814 ( http://www.3gpp.org/ftp/specs/html-INFO/25814.htm ) - -.. [3] Giuseppe Piro, Luigi Alfredo Grieco, Gennaro Boggia, and Pietro Camarda", A Two-level - Scheduling Algorithm for QoS Support in the Downlink of LTE Cellular Networks", Proc. of - European Wireless, EW2010, Lucca, Italy, Apr., 2010 ( draft version is available on - http://telematics.poliba.it/index.php?option=com_jombib&task=showbib&id=330 ) - -.. [4] 3GPP R1-081483 (available on - http://www.3gpp.org/ftp/tsg_ran/WG1_RL1/TSGR1_52b/Docs/R1-081483.zip ) + lte-design + lte-user + lte-testing diff --git a/src/lte/examples/lena-rlc-calculator.cc b/src/lte/examples/lena-rlc-calculator.cc index 2c3303fb9..73fdc7e68 100644 --- a/src/lte/examples/lena-rlc-calculator.cc +++ b/src/lte/examples/lena-rlc-calculator.cc @@ -73,7 +73,7 @@ int main (int argc, char *argv[]) EpsBearer bearer (q); lena->ActivateEpsBearer (ueDevs, bearer); - Simulator::Stop (Seconds (4)); + Simulator::Stop (Seconds (35)); lena->EnableMacTraces (); lena->EnableRlcTraces (); diff --git a/src/lte/helper/lena-helper.cc b/src/lte/helper/lena-helper.cc index 5ae17f8f6..2f4ea2ff9 100644 --- a/src/lte/helper/lena-helper.cc +++ b/src/lte/helper/lena-helper.cc @@ -92,7 +92,7 @@ TypeId LenaHelper::GetTypeId (void) .AddConstructor () .AddAttribute ("Scheduler", "The type of scheduler to be used for eNBs", - StringValue ("ns3::RrFfMacScheduler"), + StringValue ("ns3::PfFfMacScheduler"), MakeStringAccessor (&LenaHelper::SetSchedulerType), MakeStringChecker ()) .AddAttribute ("PropagationModel", diff --git a/src/lte/model/lte-amc.cc b/src/lte/model/lte-amc.cc index 44826db3a..a918f2260 100644 --- a/src/lte/model/lte-amc.cc +++ b/src/lte/model/lte-amc.cc @@ -31,42 +31,27 @@ NS_LOG_COMPONENT_DEFINE ("LteAmc"); namespace ns3 { + -int CqiIndex[15] = { - 1, 2, 3, 4, 5, 6, // QAM - 7, 8, 9, // 4-QAM - 10, 11, 12, 13, 14, 15 // 16QAM -}; - - -double SpectralEfficiencyForCqiIndex[15] = { +// from 3GPP R1-081483 "Conveying MCS and TB size via PDCCH" +// file TBS_support.xls +// tab "MCS table" (rounded to 2 decimal digits) +// the index in the vector (0-15) identifies the CQI value +double SpectralEfficiencyForCqi[16] = { + 0.0, // out of range 0.15, 0.23, 0.38, 0.6, 0.88, 1.18, 1.48, 1.91, 2.41, 2.73, 3.32, 3.9, 4.52, 5.12, 5.55 }; -int McsIndex[32] = { - 0, // RESERVED - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // QAM - 12, 13, 14, 15, 16, 17, 18, // 4-QAM - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 16-QAM - 30, // QAM, RESERVED - 31 // RESERVED -}; -// legacy table -// int ModulationSchemeForMcsIndex[32] = { -// 0, // Not defined -// 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -// 4, 4, 4, 4, 4, 4, 4, -// 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -// 2, -// 0 // Not defined -// }; - -// Table 7.1.7.1-1 of 36.213 v8.6.0 -int ModulationSchemeForMcsIndex[32] = { - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +// Table 7.1.7.1-1 of 3GPP TS 36.213 v8.8.0 +// the index in the vector (range 0-31; valid values 0-28) identifies the MCS index +// note that this is similar to the one in R1-081483 but: +// 1) a few values are different +// 2) in R1-081483, a valid MCS index is in the range 1-30 (not 0-28) +int ModulationSchemeForMcs[32] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, // reserved @@ -74,40 +59,27 @@ int ModulationSchemeForMcsIndex[32] = { 6, // reserved }; -// legacy table -// double SpectralEfficiencyForMcsIndex[32] = { -// 0, -// 0.15, 0.19, 0.23, 0.31, 0.38, 0.49, 0.6, 0.74, 0.88, 1.03, 1.18, -// 1.33, 1.48, 1.7, 1.91, 2.16, 2.41, 2.57, -// 2.73, 3.03, 3.32, 3.61, 3.9, 4.21, 4.52, 4.82, 5.12, 5.33, 5.55, -// 2.4, -// 0 -// }; - -double SpectralEfficiencyForMcsIndex[32] = { +// from 3GPP R1-081483 "Conveying MCS and TB size via PDCCH" +// file TBS_support.xls +// tab "MCS table" (rounded to 2 decimal digits) +// the index in the table corresponds to the MCS index according to the convention in TS 36.213 +// (i.e., the MCS index reported in R1-081483 minus one) +double SpectralEfficiencyForMcs[32] = { 0.15, 0.19, 0.23, 0.31, 0.38, 0.49, 0.6, 0.74, 0.88, 1.03, 1.18, 1.33, 1.48, 1.7, 1.91, 2.16, 2.41, 2.57, 2.73, 3.03, 3.32, 3.61, 3.9, 4.21, 4.52, 4.82, 5.12, 5.33, 5.55, 0, 0, 0 }; - -int TransportBlockSize[32] = { - 0, - 18, 23, 28, 37, 45, 59, 72, 89, 105, 123, 141, - 159, 177, 203, 230, 259, 289, 288, - 308, 328, 363, 399, 433, 468, 506, 543, 578, 614, 640, - 667, - 0 -}; - +// Table 7.1.7.1-1 of 3GPP TS 36.213 v8.8.0 int McsToItbs[29] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; + // 3GPP TS 36.213 v8.8.0 Table 7.1.7.2.1-1: Transport block size table (dimension 27×110) int TransportBlockSizeTable [110][27] = { /* NPRB 001*/ { 16, 24, 32, 40, 56, 72, 328, 104, 120, 136, 144, 176, 208, 224, 256, 280, 328, 336, 376, 408, 440, 488, 520, 552, 584, 616, 712}, @@ -229,10 +201,11 @@ int LteAmc::GetCqiFromSpectralEfficiency (double s) { NS_LOG_FUNCTION (s); - int cqi = 1; // == CqiIndex[0] - while (SpectralEfficiencyForCqiIndex[cqi] < s && cqi <= 14) + NS_ASSERT_MSG (s >= 0.0, "negative spectral efficiency = "<< s); + int cqi = 0; + while ((cqi < 15) && (SpectralEfficiencyForCqi[cqi + 1] < s)) { - cqi++; + ++cqi; } NS_LOG_FUNCTION (s << cqi); return cqi; @@ -243,30 +216,29 @@ int LteAmc::GetMcsFromCqi (int cqi) { NS_LOG_FUNCTION (cqi); - double spectralEfficiency = SpectralEfficiencyForCqiIndex[cqi - 1]; - int mcs = 1; - while (SpectralEfficiencyForMcsIndex[mcs] < spectralEfficiency && mcs < 28) + double spectralEfficiency = SpectralEfficiencyForCqi[cqi]; + int mcs = 0; + while ((mcs < 28) && (SpectralEfficiencyForMcs[mcs + 1] <= spectralEfficiency)) { - mcs++; + ++mcs; } NS_LOG_FUNCTION (cqi << mcs); return mcs; } -int -LteAmc::GetTbSizeFromMcs (int mcs) -{ - NS_LOG_FUNCTION (mcs); - NS_LOG_FUNCTION (mcs << TransportBlockSize[mcs]); - return TransportBlockSize[mcs]; -} +// int +// LteAmc::GetTbSizeFromMcs (int mcs) +// { +// NS_LOG_FUNCTION (mcs); +// NS_LOG_FUNCTION (mcs << TransportBlockSize[mcs]); +// return TransportBlockSize[mcs]; +// } int LteAmc::GetTbSizeFromMcs (int mcs, int nprb) { NS_LOG_FUNCTION (mcs); - NS_LOG_FUNCTION (mcs << TransportBlockSize[mcs]); NS_ASSERT_MSG (mcs < 29, "MCS=" << mcs); NS_ASSERT_MSG (nprb < 111, "NPRB=" << nprb); @@ -279,9 +251,8 @@ LteAmc::GetTbSizeFromMcs (int mcs, int nprb) double LteAmc::GetSpectralEfficiencyFromCqi (int cqi) { - NS_LOG_FUNCTION (cqi); - NS_LOG_FUNCTION (cqi << SpectralEfficiencyForCqiIndex[cqi - 1]); - return SpectralEfficiencyForCqiIndex[cqi - 1]; + NS_LOG_FUNCTION (cqi << SpectralEfficiencyForCqi[cqi]); + return SpectralEfficiencyForCqi[cqi]; } @@ -298,7 +269,7 @@ LteAmc::CreateCqiFeedbacks (const SpectrumValue& sinr) double sinr_ = (*it); if (sinr_ == 0.0) { - cqi.push_back (-1); // SINR == 0 means no signal in this RB + cqi.push_back (-1); // SINR == 0 (linear units) means no signal in this RB } else { @@ -307,13 +278,11 @@ LteAmc::CreateCqiFeedbacks (const SpectrumValue& sinr) * SINR * spectralEfficiency = log2 (1 + -------------------- ) * -ln(5*BER)/1.5 - * NB: SINR must be expressed in natural unit: - * (SINR)dB => 10 ^ (SINR/10) + * NB: SINR must be expressed in linear units */ - double s = log2 ( 1 + ( - pow (10, sinr_ / 10 ) / - ( (-log (5.0 * 0.00005 )) / 1.5) )); + double s = log2 ( 1 + ( sinr_ / + ( (-log (5.0 * 0.00005 )) / 1.5) )); int cqi_ = GetCqiFromSpectralEfficiency (s); diff --git a/src/lte/model/lte-amc.h b/src/lte/model/lte-amc.h index 3c01fdcdb..48e6f2162 100644 --- a/src/lte/model/lte-amc.h +++ b/src/lte/model/lte-amc.h @@ -41,10 +41,6 @@ class LteAmc { public: - /** - * \brief Initialize CQI, MCS, SpectralEfficiency e TBs values - */ - static void Initialize (); /** * \brief Get the Modulation anc Coding Scheme for @@ -54,12 +50,12 @@ public: */ static int GetMcsFromCqi (int cqi); - /** - * \brief Get the Transport Block Size for a selected MCS - * \param mcs the mcs index - * \return the TBs value - */ - static int GetTbSizeFromMcs (int mcs); + // /** + // * \brief Get the Transport Block Size for a selected MCS + // * \param mcs the mcs index + // * \return the TBs value + // */ + // static int GetTbSizeFromMcs (int mcs); /** * \brief Get the Transport Block Size for a selected MCS and number of PRB (table 7.1.7.2.1-1 of 36.213) diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index 45d4b184a..7c19f2f5e 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -327,12 +327,20 @@ LteUePhy::CreateDlCqiFeedbackMessage (const SpectrumValue& sinr) cqiSum += cqi.at (i); activeSubChannels++; } - //NS_LOG_DEBUG (this << " subch " << i << " cqi " << cqi.at (i)); + NS_LOG_DEBUG (this << " subch " << i << " cqi " << cqi.at (i)); } dlcqi.m_rnti = m_rnti; dlcqi.m_ri = 1; // not yet used dlcqi.m_cqiType = CqiListElement_s::P10; // Peridic CQI using PUCCH wideband - dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / activeSubChannels); + if (activeSubChannels>0) + { + dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / activeSubChannels); + } + else + { + // approximate with the worst case -> CQI = 1 + dlcqi.m_wbCqi.push_back (1); + } //NS_LOG_DEBUG (this << " Generate P10 CQI feedback " << (uint16_t) cqiSum / activeSubChannels); dlcqi.m_wbPmi = 0; // not yet used // dl.cqi.m_sbMeasResult others CQI report modes: not yet implemented diff --git a/src/lte/model/pf-ff-mac-scheduler.cc b/src/lte/model/pf-ff-mac-scheduler.cc index 9b370ba3c..d5508ad68 100644 --- a/src/lte/model/pf-ff-mac-scheduler.cc +++ b/src/lte/model/pf-ff-mac-scheduler.cc @@ -210,7 +210,7 @@ PfSchedulerMemberSchedSapProvider::SchedUlCqiInfoReq (const struct SchedUlCqiInf PfFfMacScheduler::PfFfMacScheduler () : m_cschedSapUser (0), m_schedSapUser (0), - m_timeWindow (10.0), + m_timeWindow (99.0), m_schedTtiDelay (2) // WILD ACK: based on a m_macChTtiDelay = 1 { m_cschedSapProvider = new PfSchedulerMemberCschedSapProvider (this); @@ -485,7 +485,14 @@ PfFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched NS_LOG_DEBUG (this << " UE assigned " << (*itMax).first); } } // end for RBGs - + + // reset TTI stats of users + std::map ::iterator itStats; + for (itStats = m_flowStats.begin (); itStats != m_flowStats.end (); itStats++) + { + (*itStats).second.lastTtiBytesTrasmitted = 0; + } + // generate the transmission opportunities by grouping the RBGs of the same RNTI and // creating the correspondent DCIs FfMacSchedSapUser::SchedDlConfigIndParameters ret; @@ -572,12 +579,7 @@ PfFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched { (*it).second.lastTtiBytesTrasmitted = tbSize; NS_LOG_DEBUG (this << " UE bytes txed " << (*it).second.lastTtiBytesTrasmitted); - (*it).second.totalBytesTransmitted += (*it).second.lastTtiBytesTrasmitted; - // update average throughput (see eq. 12.3 of Sec 12.3.1.2 of LTE – The UMTS Long Term Evolution, Ed Wiley) - (*it).second.lastAveragedThroughput = ((1.0 - (1.0 / m_timeWindow)) * (*it).second.lastAveragedThroughput) + ((1.0 / m_timeWindow) * (double)((*it).second.lastTtiBytesTrasmitted / 0.001)); - (*it).second.lastTtiBytesTrasmitted = 0; - NS_LOG_DEBUG (this << " UE tot bytes " << (*it).second.totalBytesTransmitted); - NS_LOG_DEBUG (this << " UE avg thr " << (*it).second.lastAveragedThroughput); + } else @@ -588,6 +590,18 @@ PfFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched itMap++; } // end while allocation ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed + + + // update UEs stats + for (itStats = m_flowStats.begin (); itStats != m_flowStats.end (); itStats++) + { + (*itStats).second.totalBytesTransmitted += (*itStats).second.lastTtiBytesTrasmitted; + // update average throughput (see eq. 12.3 of Sec 12.3.1.2 of LTE – The UMTS Long Term Evolution, Ed Wiley) + (*itStats).second.lastAveragedThroughput = ((1.0 - (1.0 / m_timeWindow)) * (*itStats).second.lastAveragedThroughput) + ((1.0 / m_timeWindow) * (double)((*itStats).second.lastTtiBytesTrasmitted / 0.001)); + NS_LOG_DEBUG (this << " UE tot bytes " << (*itStats).second.totalBytesTransmitted); + NS_LOG_DEBUG (this << " UE avg thr " << (*itStats).second.lastAveragedThroughput); + (*itStats).second.lastTtiBytesTrasmitted = 0; + } m_schedSapUser->SchedDlConfigInd (ret); diff --git a/src/lte/test/lte-test-earfcn.cc b/src/lte/test/lte-test-earfcn.cc index 857d29abe..a7dd899a8 100644 --- a/src/lte/test/lte-test-earfcn.cc +++ b/src/lte/test/lte-test-earfcn.cc @@ -79,9 +79,9 @@ LteEarfcnDlTestCase::LteEarfcnDlTestCase (const char* str, uint16_t earfcn, doub void LteEarfcnDlTestCase::DoRun (void) { - LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); - LogComponentEnable ("LteSpectrumValueHelper", logLevel); - LogComponentEnable ("LteTestEarfcn", logLevel); +// LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); +// LogComponentEnable ("LteSpectrumValueHelper", logLevel); +// LogComponentEnable ("LteTestEarfcn", logLevel); double f = LteSpectrumValueHelper::GetDownlinkCarrierFrequency (m_earfcn); NS_TEST_ASSERT_MSG_EQ_TOL (f, m_f, 0.0000001, "wrong frequency"); diff --git a/src/lte/test/lte-test-link-adaptation.cc b/src/lte/test/lte-test-link-adaptation.cc index 12de7ca46..65faee970 100644 --- a/src/lte/test/lte-test-link-adaptation.cc +++ b/src/lte/test/lte-test-link-adaptation.cc @@ -33,32 +33,16 @@ NS_LOG_COMPONENT_DEFINE ("LteLinkAdaptationTest"); using namespace ns3; -uint32_t LteLinkAdaptationTestCase::m_runId = 0; - - /** * Test 1.3 Link Adaptation */ void -LteTestDlSchedulingCallback (std::string path, - uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, - uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2) +LteTestDlSchedulingCallback (LteLinkAdaptationTestCase *testcase, std::string path, + uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, + uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2) { - static bool firstTime = true; - - if ( firstTime ) - { - NS_LOG_UNCOND ("frame\tsbframe\trnti\tmcsTb1\tsizeTb1\tmcsTb2\tsizeTb2"); - firstTime = false; - } - - if ( subframeNo == 10 ) - { - NS_LOG_UNCOND (" " << frameNo << "\t" << subframeNo << "\t" << rnti << "\t" - << (uint16_t)mcsTb1 << "\t" << sizeTb1 << "\t" - << (uint16_t)mcsTb2 << "\t" << sizeTb2); - } + testcase->DlScheduling(frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2); } /** @@ -69,34 +53,116 @@ LteLinkAdaptationTestSuite::LteLinkAdaptationTestSuite () : TestSuite ("lte-link-adaptation", SYSTEM) { // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); - -// LogComponentEnable ("LteTestUePhy", logLevel); // LogComponentEnable ("LteLinkAdaptationTest", logLevel); NS_LOG_INFO ("Creating LteLinkAdaptionTestSuite"); +// Tests: distance --> loss +#if 0 int distanceMin = 1; - int distanceMax = 100000; - int distanceStep = 10000; + int distanceMax = 2000; + int distanceStep = 1000; bool logStep = false; - for ( int distance = distanceMin ; distance <= distanceMax ; logStep ? ( distance *= distanceStep) : ( distance += distanceStep ) ) + for ( int distance = distanceMin ; + distance <= distanceMax ; + logStep ? ( distance *= distanceStep) : ( distance += distanceStep ) ) { /** - * Propagation Loss + * Propagation Loss (in W/Hz) * * ( 4 * PI * distance * frequency ) 2 * Loss = ( ------------------------------- ) - * ( c ) + * ( c ) * * where: c is speed of light in vacuum = 3e8 (m/s) * distance in (m) * frequency in (Hz) */ - double myLoss = ( ( 4 * M_PI * distance * 1.92e9 ) / 3e8 ); - myLoss = myLoss * myLoss; + double lossLinear = ( ( 4.0 * M_PI * distance * 2.160e9 ) / 3e8 ); + lossLinear = lossLinear * lossLinear; + double lossDb = 10 * log10(lossLinear); - AddTestCase (new LteLinkAdaptationTestCase (myLoss)); + AddTestCase (new LteLinkAdaptationTestCase (lossDb, distance)); + } +#endif + + struct SnrEfficiencyMcs + { + double snr; + double efficiency; + int mcsIndex; + }; + + /** + * Test vectors: SNR, Spectral Efficiency, MCS index + * From XXX + */ + SnrEfficiencyMcs snrEfficiencyMcs[] = { + // {-5.00000, 0.08024, -1}, + // {-4.00000, 0.10030, -1}, + // {-3.00000, 0.12518, -1}, + {-2.00000, 0.15589, 0}, + {-1.00000, 0.19365, 0}, + {0.00000, 0.23983, 2}, + {1.00000, 0.29593, 2}, + {2.00000, 0.36360, 2}, + {3.00000, 0.44451, 4}, + {4.00000, 0.54031, 4}, + {5.00000, 0.65251, 6}, + {6.00000, 0.78240, 6}, + {7.00000, 0.93086, 8}, + {8.00000, 1.09835, 8}, + {9.00000, 1.28485, 10}, + {10.00000, 1.48981, 12}, + {11.00000, 1.71229, 12}, + {12.00000, 1.95096, 14}, + {13.00000, 2.20429, 14}, + {14.00000, 2.47062, 16}, + {15.00000, 2.74826, 18}, + {16.00000, 3.03560, 18}, + {17.00000, 3.33115, 20}, + {18.00000, 3.63355, 20}, + {19.00000, 3.94163, 22}, + {20.00000, 4.25439, 22}, + {21.00000, 4.57095, 24}, + {22.00000, 4.89060, 24}, + {23.00000, 5.21276, 26}, + {24.00000, 5.53693, 26}, + {25.00000, 5.86271, 28}, + {26.00000, 6.18980, 28}, + {27.00000, 6.51792, 28}, + {28.00000, 6.84687, 28}, + {29.00000, 7.17649, 28}, + {30.00000, 7.50663, 28}, + }; + int numOfTests = sizeof (snrEfficiencyMcs) / sizeof (SnrEfficiencyMcs); + + + for ( int i = 0 ; i < numOfTests; i++ ) + { + /** + * SNR (in dB) + * + * SNR = P_tx - loss - noise - receiverNoiseFigure + * + * loss = P_tx - SNR - noise - receiverNoiseFigure + * + * where: P_tx is transmission power + * loss in (dB) + * noise + */ + double noiseDb = -107.5; + double receiverNoiseFigureDb = 5.0; + double lossDb = 30.0 - snrEfficiencyMcs[i].snr - noiseDb - receiverNoiseFigureDb; + double lossLinear = pow (10, lossDb / 10); + double distance = ( ( 3e8 * sqrt ( lossLinear ) ) / ( 4.0 * M_PI * 2.160e9 ) ); + + std::ostringstream name; + name << "link adaptation" + << " snr= " << snrEfficiencyMcs[i].snr + << " mcs= " << snrEfficiencyMcs[i].mcsIndex; + AddTestCase (new LteLinkAdaptationTestCase (name.str (), snrEfficiencyMcs[i].snr, lossDb, distance, snrEfficiencyMcs[i].mcsIndex)); } } @@ -108,15 +174,18 @@ static LteLinkAdaptationTestSuite lteLinkAdaptationTestSuite; * TestCase */ -LteLinkAdaptationTestCase::LteLinkAdaptationTestCase (double loss) - : TestCase ("Link Adaptation"), - m_loss (loss) +LteLinkAdaptationTestCase::LteLinkAdaptationTestCase (std::string name, double snr, double loss, double distance, uint16_t mcsIndex) + : TestCase (name), + m_snr (snr), + m_loss (loss), + m_distance (distance), + m_mcsIndex (mcsIndex) { std::ostringstream sstream1, sstream2; - sstream1 << loss; - sstream2 << ++m_runId; + sstream1 << " snr=" << snr + << " mcs=" << mcsIndex; - NS_LOG_INFO ("Creating LteLinkAdaptationTestCase (" << sstream2.str () + "): LOSS = " + sstream1.str ()); + NS_LOG_UNCOND ("Creating LteLinkAdaptationTestCase: " + sstream1.str ()); } LteLinkAdaptationTestCase::~LteLinkAdaptationTestCase () @@ -126,9 +195,9 @@ LteLinkAdaptationTestCase::~LteLinkAdaptationTestCase () void LteLinkAdaptationTestCase::DoRun (void) { -#if 1 -// LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); - + LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); + LogComponentEnable ("LteAmc", logLevel); + LogComponentEnable ("LteLinkAdaptationTest", logLevel); // LogComponentEnable ("LteEnbRrc", logLevel); // LogComponentEnable ("LteUeRrc", logLevel); // LogComponentEnable ("LteEnbMac", logLevel); @@ -164,7 +233,6 @@ LteLinkAdaptationTestCase::DoRun (void) // LogComponentEnable ("ConstantPositionMobilityModel", logLevel); // LogComponentEnable ("MultiModelSpectrumChannel", logLevel); // LogComponentEnable ("SingleModelSpectrumChannel", logLevel); -#endif /** * Simulation Topology @@ -175,31 +243,9 @@ LteLinkAdaptationTestCase::DoRun (void) lena->EnableMacTraces (); lena->EnableRlcTraces (); lena->SetAttribute ("PropagationModel", StringValue ("ns3::ConstantSpectrumPropagationLossModel")); - NS_LOG_INFO ("LOSS = " << m_loss); + NS_LOG_INFO ("SNR = " << m_snr << " LOSS = " << m_loss); lena->SetPropagationModelAttribute ("Loss", DoubleValue (m_loss)); - /** - * Distance (m) PropagationLoss (XXX) - * 0 0.0 - * 100 6.46814e+07 - * 200 2.58726e+08 - * 300 5.82133e+08 - * 400 1.0349e+09 - * 500 1.61704e+09 - * 600 2.32853e+09 - * 700 3.16939e+09 - * 800 4.13961e+09 - * 900 5.2392e+09 - * 1000 6.46814e+09 - */ - -// for ( int i = 0 ; i <= 10 ; i++ ) -// { -// double myLoss = ( ( 4 * M_PI * ( i * 100.0 ) * 1.92e9 ) / 3e8 ); -// myLoss = myLoss * myLoss; -// NS_LOG_INFO ("i = " << i << "\tLoss = " << myLoss); -// } - // Create Nodes: eNodeB and UE NodeContainer enbNodes; NodeContainer ueNodes; @@ -235,16 +281,45 @@ LteLinkAdaptationTestCase::DoRun (void) Config::Connect ("/NodeList/0/DeviceList/0/LteEnbMac/DlScheduling", - MakeCallback(&LteTestDlSchedulingCallback)); + MakeBoundCallback(&LteTestDlSchedulingCallback, this)); - -// Simulator::Stop (Seconds (0.005)); - Simulator::Stop (Seconds (0.01)); + Simulator::Stop (Seconds (0.005)); + //Simulator::Stop (Seconds (0.01)); +// Simulator::Stop (Seconds (0.1)); +/* Simulator::Stop (Seconds (2.0));*/ +// Simulator::Stop (Seconds (10.0)); Simulator::Run (); Simulator::Destroy (); - - - NS_LOG_INFO ("Link Adaptation Test"); - - NS_TEST_ASSERT_MSG_EQ_TOL (1.0, 1.0, 0.0000001, "Wrong Test !"); +} + + +void +LteLinkAdaptationTestCase::DlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, + uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2) +{ + static bool firstTime = true; + + if ( firstTime ) + { + firstTime = false; +// NS_LOG_UNCOND (" Frame\tSbframe\tRnti\tmcsTb1\tsizeTb1\tmcsTb2\tsizeTb2"); + NS_LOG_UNCOND ("SNR\tRef_MCS\tCalc_MCS"); + } + + /** + * Note: + * For first 4 subframeNo in the first frameNo, the MCS cannot be properly evaluated, + * because CQI feedback is still not available at the eNB. + */ + if ( (frameNo > 1) || (subframeNo > 4) ) +// if ( (frameNo == 1) && (subframeNo == 10) ) + { +// NS_LOG_UNCOND (" " << frameNo << "\t" << subframeNo << "\t" << rnti << "\t" +// << (uint16_t)mcsTb1 << "\t" << sizeTb1 << "\t" +// << (uint16_t)mcsTb2 << "\t" << sizeTb2); + + NS_LOG_UNCOND (m_snr << "\t" << m_mcsIndex << "\t" << (uint16_t)mcsTb1); + + NS_TEST_ASSERT_MSG_EQ ((uint16_t)mcsTb1, m_mcsIndex, "Wrong MCS index"); + } } diff --git a/src/lte/test/lte-test-link-adaptation.h b/src/lte/test/lte-test-link-adaptation.h index 835eed734..3d012b68f 100644 --- a/src/lte/test/lte-test-link-adaptation.h +++ b/src/lte/test/lte-test-link-adaptation.h @@ -27,8 +27,6 @@ using namespace ns3; - - /** * Test 1.3 Link adaptation */ @@ -42,23 +40,21 @@ public: class LteLinkAdaptationTestCase : public TestCase { public: -// LteLinkAdaptationTestCase (Ptr sv, Ptr sinr, std::string name); - LteLinkAdaptationTestCase (double loss); + LteLinkAdaptationTestCase (std::string name, double snr, double loss, double distance, uint16_t mcsIndex); LteLinkAdaptationTestCase (); virtual ~LteLinkAdaptationTestCase (); + void DlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, + uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2); + private: virtual void DoRun (void); - Ptr macStats; - + double m_snr; double m_loss; -// Ptr m_sv; -// Ptr m_sm; -// Ptr m_sinr; - - static uint32_t m_runId; + double m_distance; + uint16_t m_mcsIndex; }; -#endif /* LTE_TEST_LINK_ADAPTATION_H */ \ No newline at end of file +#endif /* LTE_TEST_LINK_ADAPTATION_H */ diff --git a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc index 9dc4f922c..08e7b77ee 100644 --- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc @@ -51,13 +51,70 @@ LenaTestPfFfMacSchedulerSuite::LenaTestPfFfMacSchedulerSuite () SetVerbose (true); NS_LOG_INFO ("creating LenaPfFfMacSchedulerTestCase"); - //AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,1,2196000)); - + + // DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec + // 3 users -> 2196000 among 3 users -> 732000 bytes/sec + // 6 users -> 2196000 among 6 users -> 366000 bytes/sec + // 12 users -> 2196000 among 12 users -> 183000 bytes/sec + // 15 users -> 2196000 among 15 users -> 146400 bytes/sec AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,0,2196000)); - AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,0,749000)); - AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,0,373000)); - AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,0,185000)); - AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,0,148000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,0,732000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,0,366000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,0,183000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,0,146400)); + + // DISTANCE 6000 -> MCS 24 -> Itbs 22 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 22 -> 1572 -> 1572000 bytes/sec + // 3 users -> 1572000 among 3 users -> 524000 bytes/sec + // 6 users -> 1572000 among 6 users -> 262000 bytes/sec + // 12 users -> 1572000 among 12 users -> 131000 bytes/sec + // 15 users -> 1572000 among 15 users -> 104800 bytes/sec + AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,6000,1572000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,6000,524000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,6000,262000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,6000,131000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,6000,104800)); + + // DISTANCE 9000 -> MCS 10 -> Itbs 9 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 9 -> 469 -> 469000 bytes/sec + // 3 users -> 469000 among 3 users -> 156333 bytes/sec + // 6 users -> 469000 among 6 users -> 78166 bytes/sec + // 12 users -> 469000 among 12 users -> 39083 bytes/sec + // 15 users -> 469000 among 15 users -> 31266 bytes/sec + AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,9000,469000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,9000,156333)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,9000,78166)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,9000,39083)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,9000,31266)); + + // DISTANCE 15000 -> MCS 4 -> Itbs 4 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 4 -> 217 -> 217000 bytes/sec + // 3 users -> 217000 among 3 users -> 72333 bytes/sec + // 6 users -> 217000 among 6 users -> 36166 bytes/sec + // 12 users -> 217000 among 12 users -> 18083 bytes/sec + // 15 users -> 217000 among 15 users -> 14466 bytes/sec + AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,15000,217000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,15000,72333)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,15000,36166)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,15000,18083)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,15000,14466)); + + // DISTANCE 20000 -> MCS 2 -> Itbs 2 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 2 -> 133 -> 133000 bytes/sec + // 3 users -> 217000 among 3 users -> 44333 bytes/sec + // 6 users -> 217000 among 6 users -> 22166 bytes/sec + // 12 users -> 217000 among 12 users -> 11083 bytes/sec + // 15 users -> 217000 among 15 users -> 8866 bytes/sec + AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,20000,133000)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,20000,44333)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,20000,22166)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,20000,11083)); + AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,20000,8866)); + + + + } static LenaTestPfFfMacSchedulerSuite lenaTestPfFfMacSchedulerSuite; @@ -82,7 +139,7 @@ LenaPfFfMacSchedulerTestCase::DoRun (void) // LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL); // LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL); -// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL); + // LogComponentEnable ("LteRlc", LOG_LEVEL_ALL); // // LogComponentEnable ("LtePhy", LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL); @@ -103,10 +160,10 @@ LenaPfFfMacSchedulerTestCase::DoRun (void) // LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL); - //LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL); + // LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL); LogComponentEnable ("LenaTestPfFfMacCheduler", LOG_LEVEL_ALL); - //LogComponentEnable ("LteAmc", LOG_LEVEL_ALL); -// LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL); + // LogComponentEnable ("LteAmc", LOG_LEVEL_ALL); + // LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL); /** * Initialize Simulation Scenario: 1 eNB and m_nUser UEs @@ -152,7 +209,7 @@ LenaPfFfMacSchedulerTestCase::DoRun (void) lena->EnableDlRlcTraces(); - double simulationTime = 0.40; + double simulationTime = 2.0; double tolerance = 0.1; Simulator::Stop (Seconds (simulationTime)); @@ -174,7 +231,6 @@ LenaPfFfMacSchedulerTestCase::DoRun (void) uint8_t lcId = ueDevs.Get (i)-> GetObject ()->GetRrc ()->GetLcIdVector ().at(0); dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId)); NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRef); - //NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRef, m_thrRef * tolerance, " Unfair Throughput!"); } for (int i = 0; i < m_nUser; i++) diff --git a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc index 860894929..1fba064e7 100644 --- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc @@ -51,6 +51,7 @@ LenaTestRrFfMacSchedulerSuite::LenaTestRrFfMacSchedulerSuite () { SetVerbose (true); NS_LOG_INFO ("creating LenaRrFfMacSchedulerTestCase"); + // DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213) // 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec // 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec @@ -58,15 +59,68 @@ LenaTestRrFfMacSchedulerSuite::LenaTestRrFfMacSchedulerSuite () // 9 user -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec // 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec // 15 users -> 2 PRB at Itbs 26 * 0.8 -> 148 -> 148000 bytes/sec + AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,0,2196000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (3,0,0,749000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (6,0,0,373000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (9,0,0,185000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (12,0,0,185000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (15,0,0,148000)); - AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,1,2196000)); + // DISTANCE 6000 -> MCS 24 -> Itbs 22 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 22 -> 1572 -> 1572000 bytes/sec + // 3 users -> 8 PRB at Itbs 22 -> 533 -> 533000 bytes/sec + // 6 users -> 4 PRB at Itbs 22 -> 269 -> 269000 bytes/sec + // 9 user -> 2 PRB at Itbs 22 -> 133 -> 133000 bytes/sec + // 12 users -> 2 PRB at Itbs 22 -> 133 -> 133000 bytes/sec + // 15 users -> 2 PRB at Itbs 22 * 0.8 -> 106.4 -> 106400 bytes/sec + AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,6000,1572000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (3,0,6000,533000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (6,0,6000,269000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (9,0,6000,133000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (12,0,6000,133000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (15,0,6000,106400)); -// AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,0,2196000)); -// AddTestCase (new LenaRrFfMacSchedulerTestCase (3,0,0,749000)); -// AddTestCase (new LenaRrFfMacSchedulerTestCase (6,0,0,373000)); -// AddTestCase (new LenaRrFfMacSchedulerTestCase (9,0,0,185000)); -// AddTestCase (new LenaRrFfMacSchedulerTestCase (12,0,0,185000)); -// AddTestCase (new LenaRrFfMacSchedulerTestCase (15,0,0,148000)); + // DISTANCE 9000 -> MCS 10 -> Itbs 9 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 9 -> 469 -> 469000 bytes/sec + // 3 users -> 8 PRB at Itbs 9 -> 157 -> 157000 bytes/sec + // 6 users -> 4 PRB at Itbs 9 -> 77 -> 77000 bytes/sec + // 9 user -> 2 PRB at Itbs 9 -> 37 -> 37000 bytes/sec + // 12 users -> 2 PRB at Itbs 9 -> 37 -> 37000 bytes/sec + // 15 users -> 2 PRB at Itbs 9 * 0.8 -> 29.6 -> 29600 bytes/sec + AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,9000,469000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (3,0,9000,157000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (6,0,9000,77000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (9,0,9000,37000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (12,0,9000,37000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (15,0,9000,29600)); + + // DISTANCE 15000 -> MCS 4 -> Itbs 4 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 4 -> 217 -> 217000 bytes/sec + // 3 users -> 8 PRB at Itbs 4 -> 69 -> 69000 bytes/sec + // 6 users -> 4 PRB at Itbs 4 -> 32 -> 32000 bytes/sec + // 9 user -> 2 PRB at Itbs 4 -> 15 -> 15000 bytes/sec + // 12 users -> 2 PRB at Itbs 4 -> 15 -> 15000 bytes/sec + // 15 users -> 2 PRB at Itbs 4 * 0.8 -> 12 -> 12000 bytes/sec + AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,15000,217000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (3,0,15000,69000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (6,0,15000,32000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (9,0,15000,15000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (12,0,15000,15000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (15,0,15000,12000)); + + // DISTANCE 20000 -> MCS 2 -> Itbs 2 (from table 7.1.7.2.1-1 of 36.213) + // 1 user -> 24 PRB at Itbs 2 -> 133 -> 133000 bytes/sec + // 3 users -> 8 PRB at Itbs 2 -> 41 -> 41000 bytes/sec + // 6 users -> 4 PRB at Itbs 2 -> 22 -> 22000 bytes/sec + // 9 user -> 2 PRB at Itbs 2 -> 9 -> 9000 bytes/sec + // 12 users -> 2 PRB at Itbs 2 -> 9 -> 9000 bytes/sec + // 15 users -> 2 PRB at Itbs 2 * 0.8 -> 7.2 -> 7200 bytes/sec + AddTestCase (new LenaRrFfMacSchedulerTestCase (1,0,20000,133000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (3,0,20000,41000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (6,0,20000,22000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (9,0,20000,9000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (12,0,20000,9000)); + AddTestCase (new LenaRrFfMacSchedulerTestCase (15,0,20000,7200)); } @@ -92,7 +146,7 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) // LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL); // LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL); - LogComponentEnable ("LteRlc", LOG_LEVEL_ALL); +// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL); // // LogComponentEnable ("LtePhy", LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL); @@ -113,9 +167,9 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) // LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL); // LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL); - LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL); +// LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL); LogComponentEnable ("LenaTestRrFfMacCheduler", LOG_LEVEL_ALL); - //LogComponentEnable ("LteAmc", LOG_LEVEL_ALL); +// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL); // LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL); @@ -127,23 +181,6 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) Ptr lena = CreateObject (); - // Define the propagation model - /** - * Propagation Loss - * - * ( 4 * PI * distance * frequency ) 2 - * Loss = ( ------------------------------- ) - * ( c ) - * - * where: c is speed of light in vacuum = 3e8 (m/s) - * distance in (m) - * frequency in (Hz) - */ - double myLoss = ( ( 4 * M_PI * m_dist * 1.92e9 ) / 3e8 ); - myLoss = myLoss * myLoss; - lena->SetAttribute ("PropagationModel", StringValue ("ns3::ConstantSpectrumPropagationLossModel")); - lena->SetPropagationModelAttribute ("Loss", DoubleValue (myLoss)); - // Create Nodes: eNodeB and UE NodeContainer enbNodes; NodeContainer ueNodes; @@ -183,8 +220,7 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) double simulationTime = 0.4; double tolerance = 0.1; Simulator::Stop (Seconds (simulationTime)); - -// Config::SetDefault ("ns3::RlcStatsCalculator::EpochDuration", TimeValue(Seconds(simulationTime))); + Ptr rlcStats = lena->GetRlcStats (); rlcStats->SetAttribute("EpochDuration", TimeValue(Seconds(simulationTime))); @@ -194,7 +230,7 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) /** * Check that the assignation is done in a RR fashion */ - NS_LOG_INFO("Test with " << m_nUser << " user(s) at distance " << m_dist << " loss " << myLoss); + NS_LOG_INFO("Test with " << m_nUser << " user(s) at distance " << m_dist); std::vector dlDataRxed; for (int i = 0; i < m_nUser; i++) { diff --git a/src/lte/test/lte-test-spectrum-value-helper.cc b/src/lte/test/lte-test-spectrum-value-helper.cc index 6fbcbbfd3..cda356424 100644 --- a/src/lte/test/lte-test-spectrum-value-helper.cc +++ b/src/lte/test/lte-test-spectrum-value-helper.cc @@ -150,10 +150,10 @@ static LteSpectrumValueHelperTestSuite g_lteSpectrumValueHelperTestSuite; LteSpectrumValueHelperTestSuite::LteSpectrumValueHelperTestSuite () : TestSuite ("lte-spectrum-value-helper", UNIT) { - //LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); - //LogComponentEnable ("LteSpectrumModelTestCase", logLevel); - //LogComponentEnable ("LteSpectrumValueHelperTestSuite", logLevel); - //LogComponentEnable ("LteSpectrumValueHelper", logLevel); +// LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL); +// LogComponentEnable ("LteSpectrumModelTestCase", logLevel); +// LogComponentEnable ("LteSpectrumValueHelperTestSuite", logLevel); +// LogComponentEnable ("LteSpectrumValueHelper", logLevel); NS_LOG_INFO ("Creating LteSpectrumValueHelperTestSuite"); diff --git a/src/lte/test/reference/lte_amc.m b/src/lte/test/reference/lte_amc.m new file mode 100644 index 000000000..bdad74631 --- /dev/null +++ b/src/lte/test/reference/lte_amc.m @@ -0,0 +1,94 @@ + +clear all; +close all; + +snr_db = (-5:30)'; +snr = (10.^(snr_db./10)); + + +## this model is from: +## G. Piro, N. Baldo. M. Miozzo, "An LTE module for the ns-3 network simulator", +## WNS3 2011 (in conjunction with SimuTOOLS 2011) +## which cites this one: +## "A Proportional-Fair Power Allocation Scheme for Fair and Efficient Multiuser OFDM Systems" + + +ber = 0.00005; +gamma = -log (5*ber)./1.5 +spectral_efficiency_piro2011 = log2(1 + snr./gamma); + + + +# ## this eventually would be an alternative model from: +# ## Preben Mogensen et al., "LTE Capacity compared to the Shannon Bound" +# ## IEEE VTC Spring 2007 +# +# snr_eff = 1.25; +# bw_eff_times_eta = 0.75; +# spectral_efficiency_mogensen2007= bw_eff_times_eta .* log2(1 + snr./snr_eff); +# +# plot (snr_db, spectral_efficiency_piro2011, ";piro 2011;", +# snr_db, spectral_efficiency_mogensen2007, ";morgensen2007;"); + + +[snr_db spectral_efficiency_piro2011] + +## +## now that we got the spectral efficiency for each value of SNR in dB +## you should do the following: +## we look up (manually) into the XLS sheet annexed to 3GPP R1-081483 "Conveying MCS +## and TB size via PDCCH". Look at the tab "MCS Table", quantize the +## spectral efficiency based on the CQI (rounding to the lowest value), and get the corresponding MCS +## scheme (i.e., the MCS index that appears on the same line looking at +## the MCS table on the right). Note that the quantization of the CQI is +## coarser than the spectral efficiency reported in the CQI table. +## Finally, note that there are some discrepancies between the MCS index +## in R1-081483 and that indicated by the standard: TS 36.213 Table +## 7.1.7.1-1 says that the MCS index goes from 0 to 31, and 0 appears to +## be a valid MCS scheme (TB size is not 0) but in R1-081483 the first useful MCS index is 1. +## Hence to get the value as intended by the standard we need to +## subtract 1 from the index reported in R1-081483. + +## the resulting values after the manual lookup are reported here: + +## SNR (dB) sp. eff MCS index + +## -5.00000 0.08024 -1 +## -4.00000 0.10030 -1 +## -3.00000 0.12518 -1 +## -2.00000 0.15589 0 +## -1.00000 0.19365 0 +## 0.00000 0.23983 2 +## 1.00000 0.29593 2 +## 2.00000 0.36360 2 +## 3.00000 0.44451 4 +## 4.00000 0.54031 4 +## 5.00000 0.65251 6 +## 6.00000 0.78240 6 +## 7.00000 0.93086 8 +## 8.00000 1.09835 8 +## 9.00000 1.28485 10 +## 10.00000 1.48981 12 +## 11.00000 1.71229 12 +## 12.00000 1.95096 14 +## 13.00000 2.20429 14 +## 14.00000 2.47062 16 +## 15.00000 2.74826 18 +## 16.00000 3.03560 18 +## 17.00000 3.33115 20 +## 18.00000 3.63355 20 +## 19.00000 3.94163 22 +## 20.00000 4.25439 22 +## 21.00000 4.57095 24 +## 22.00000 4.89060 24 +## 23.00000 5.21276 26 +## 24.00000 5.53693 26 +## 25.00000 5.86271 28 +## 26.00000 6.18980 28 +## 27.00000 6.51792 28 +## 28.00000 6.84687 28 +## 29.00000 7.17649 28 +## 30.00000 7.50663 28 + + + diff --git a/src/lte/test/reference/lte_link_budget.m b/src/lte/test/reference/lte_link_budget.m index 86d164141..77fffa848 100644 --- a/src/lte/test/reference/lte_link_budget.m +++ b/src/lte/test/reference/lte_link_budget.m @@ -5,10 +5,11 @@ f = 2160e6; # carrier freq Hz, EARFCN = 500 (downlink) n = -107.5 # noise power dBm, corresponds to 5 MHz BW p = 30; # tx power dBm +nf = 5; # receiver noise figure in dB d = logspace (0,5,100); g = 10.*log10 (gain_freespace(d,f)); # propagation gain in dB -snr = p + g - n; #dB +snr = p + g - n - nf ; #dB semilogx (d, snr); diff --git a/src/spectrum/model/constant-spectrum-propagation-loss.cc b/src/spectrum/model/constant-spectrum-propagation-loss.cc index 74ad71e8b..3167051ec 100644 --- a/src/spectrum/model/constant-spectrum-propagation-loss.cc +++ b/src/spectrum/model/constant-spectrum-propagation-loss.cc @@ -18,6 +18,8 @@ * Author: Manuel Requena */ +#include + #include "ns3/log.h" #include "ns3/constant-spectrum-propagation-loss.h" @@ -50,13 +52,31 @@ ConstantSpectrumPropagationLossModel::GetTypeId (void) .AddAttribute ("Loss", "Path loss (dB) between transmitter and receiver", DoubleValue (1.0), - MakeDoubleAccessor (&ConstantSpectrumPropagationLossModel::m_loss), + MakeDoubleAccessor (&ConstantSpectrumPropagationLossModel::SetLossDb, + &ConstantSpectrumPropagationLossModel::GetLossDb), MakeDoubleChecker ()) ; return tid; } +void +ConstantSpectrumPropagationLossModel::SetLossDb (double lossDb) +{ + NS_LOG_FUNCTION (this); + m_lossDb = lossDb; + m_lossLinear = pow (10, m_lossDb / 10); +} + + +double +ConstantSpectrumPropagationLossModel::GetLossDb () const +{ + NS_LOG_FUNCTION (this); + return m_lossDb; +} + + Ptr ConstantSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (Ptr txPsd, Ptr a, @@ -73,7 +93,7 @@ ConstantSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (PtrConstBandsEnd ()); // NS_LOG_INFO ("Ptx = " << *vit); - *vit /= m_loss; // Prx = Ptx / loss + *vit /= m_lossLinear; // Prx = Ptx / loss // NS_LOG_INFO ("Prx = " << *vit); ++vit; ++fit; diff --git a/src/spectrum/model/constant-spectrum-propagation-loss.h b/src/spectrum/model/constant-spectrum-propagation-loss.h index 4063b0b7e..4e0e97660 100644 --- a/src/spectrum/model/constant-spectrum-propagation-loss.h +++ b/src/spectrum/model/constant-spectrum-propagation-loss.h @@ -38,8 +38,13 @@ public: Ptr a, Ptr b) const; + void SetLossDb (double lossDb); + double GetLossDb () const; + +protected: + double m_lossDb; + double m_lossLinear; private: - double m_loss; };