From f7cec7ad567f775a0441b55984000c7ee7a1ca6b Mon Sep 17 00:00:00 2001 From: mmiozzo Date: Wed, 9 Nov 2011 11:20:14 +0100 Subject: [PATCH 1/5] Refine LenaHelper::EnableLogComponents with new propagation classes --- src/lte/helper/lena-helper.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lte/helper/lena-helper.cc b/src/lte/helper/lena-helper.cc index 8d9167e80..6b43a91bb 100644 --- a/src/lte/helper/lena-helper.cc +++ b/src/lte/helper/lena-helper.cc @@ -467,12 +467,16 @@ LenaHelper::EnableLogComponents (void) 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); + std::string propModelStr = m_dlPropagationModelFactory.GetTypeId ().GetName ().erase (0,5).c_str (); + + const char* propModel = m_dlPropagationModelFactory.GetTypeId ().GetName ().erase (0,5).c_str (); + LogComponentEnable (propModel, LOG_LEVEL_ALL); + if (m_fadingModelType.compare ( "ns3::TraceFadingLossModel") == 0) + { + const char* fadingModel = m_fadingModelType.erase (0,5).c_str (); + LogComponentEnable (fadingModel, LOG_LEVEL_ALL); + } + LogComponentEnable ("SingleModelSpectrumChannel", LOG_LEVEL_ALL); LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL); LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL); From 50b6ee887f4677dca3f360c8335daa897ca4441c Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Wed, 9 Nov 2011 16:31:20 +0100 Subject: [PATCH 2/5] =?UTF-8?q?fixed=20variable=20=E2=80=98freq=E2=80=99?= =?UTF-8?q?=20set=20but=20not=20used=20in=20buildings-shadowing-test.cc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/buildings/test/buildings-shadowing-test.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/buildings/test/buildings-shadowing-test.cc b/src/buildings/test/buildings-shadowing-test.cc index 448c18ddc..90adf7124 100644 --- a/src/buildings/test/buildings-shadowing-test.cc +++ b/src/buildings/test/buildings-shadowing-test.cc @@ -64,7 +64,6 @@ BuildingsShadowingTestSuite::BuildingsShadowingTestSuite () double distance = 2000; double hm = 1; double hb = 30; - double freq = 869e6; // E_UTRA BAND #5 see table 5.5-1 of 36.101 Ptr mm1 = CreateObject (); mm1->SetPosition (Vector (0.0, 0.0, hb)); @@ -76,7 +75,6 @@ BuildingsShadowingTestSuite::BuildingsShadowingTestSuite () // Test #2 Indoor model distance = 30; - freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101 double henbHeight = 10.0; Ptr mm5 = CreateObject (); mm5->SetPosition (Vector (0.0, 0.0, henbHeight)); @@ -93,7 +91,6 @@ BuildingsShadowingTestSuite::BuildingsShadowingTestSuite () // Test #3 Indoor -> Outdoor distance = 100; - freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101 Ptr mm9 = CreateObject (); mm9->SetPosition (Vector (0.0, 0.0, henbHeight)); mm9->SetIndoor (building1); From cad137bf43a932b0219e3eb988bda56afcaf8bf4 Mon Sep 17 00:00:00 2001 From: Marco Miozzo Date: Wed, 9 Nov 2011 16:46:52 +0100 Subject: [PATCH 3/5] Address LENA-173: CQI refresh procedure introduced in Pf and Rr schedulers --- src/lte/examples/lena-cqi-threshold.cc | 138 +++++++++++++++++++++++++ src/lte/examples/wscript | 5 +- src/lte/model/pf-ff-mac-scheduler.cc | 118 +++++++++++++++++++-- src/lte/model/pf-ff-mac-scheduler.h | 17 +++ src/lte/model/rr-ff-mac-scheduler.cc | 116 ++++++++++++++++++--- src/lte/model/rr-ff-mac-scheduler.h | 14 +++ 6 files changed, 387 insertions(+), 21 deletions(-) create mode 100644 src/lte/examples/lena-cqi-threshold.cc diff --git a/src/lte/examples/lena-cqi-threshold.cc b/src/lte/examples/lena-cqi-threshold.cc new file mode 100644 index 000000000..856a8bc4f --- /dev/null +++ b/src/lte/examples/lena-cqi-threshold.cc @@ -0,0 +1,138 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Manuel Requena + */ + + +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/mobility-module.h" +#include "ns3/lte-module.h" +#include "ns3/config-store.h" +//#include "ns3/gtk-config-store.h" +using namespace ns3; + +// position functions insipred by /examples/wireless/wifi-ap.cc + +static void +SetPosition (Ptr node, Vector position) +{ + Ptr mobility = node->GetObject (); + mobility->SetPosition (position); +} + +static Vector +GetPosition (Ptr node) +{ + Ptr mobility = node->GetObject (); + return mobility->GetPosition (); +} + +static void +ChangePosition (Ptr node) +{ + Vector pos = GetPosition (node); + + if (pos.x <= 10.0) + { + pos.x = 100000.0; // force CQI to 0 + } + else + { + pos.x = 5.0; + } + SetPosition (node, pos); + +} + +int main (int argc, char *argv[]) +{ + CommandLine cmd; + cmd.Parse (argc, argv); + + // to save a template default attribute file run it like this: + // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim + // + // to load a previously created default attribute file + // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Load --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim + + ConfigStore inputConfig; + inputConfig.ConfigureDefaults (); + + // parse again so you can override default values from the command line + cmd.Parse (argc, argv); + + Ptr lena = CreateObject (); + lena->SetAttribute ("PropagationModel", StringValue ("ns3::FriisSpectrumPropagationLossModel")); + //lena->EnableLogComponents (); + + // LogComponentEnable ("LtePhy", LOG_LEVEL_ALL); + LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL); + // LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL); + LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL); + LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL); + LogComponentEnable ("LenaHelper", LOG_LEVEL_ALL); + LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL); + + // Create Nodes: eNodeB and UE + NodeContainer enbNodes; + NodeContainer ueNodes; + enbNodes.Create (1); + ueNodes.Create (1); + + // Install Mobility Model + MobilityHelper mobility; + mobility.SetMobilityModel ("ns3::BuildingsMobilityModel"); + mobility.Install (enbNodes); + mobility.SetMobilityModel ("ns3::BuildingsMobilityModel"); + mobility.Install (ueNodes); + + // Create Devices and install them in the Nodes (eNB and UE) + NetDeviceContainer enbDevs; + NetDeviceContainer ueDevs; +// lena->SetSchedulerType ("ns3::RrFfMacScheduler"); + lena->SetSchedulerType ("ns3::PfFfMacScheduler"); + lena->SetSchedulerAttribute ("CqiTimerThreshold", UintegerValue (3)); + enbDevs = lena->InstallEnbDevice (enbNodes); + ueDevs = lena->InstallUeDevice (ueNodes); + + lena->EnableRlcTraces(); + lena->EnableMacTraces(); + + // Attach a UE to a eNB + lena->Attach (ueDevs, enbDevs.Get (0)); + + Simulator::Schedule (Seconds (0.010), &ChangePosition, ueNodes.Get (0)); + Simulator::Schedule (Seconds (0.020), &ChangePosition, ueNodes.Get (0)); + + // Activate an EPS bearer + enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; + EpsBearer bearer (q); + lena->ActivateEpsBearer (ueDevs, bearer); + + + Simulator::Stop (Seconds (0.030)); + + Simulator::Run (); + + //GtkConfigStore config; + //config.ConfigureAttributes (); + + Simulator::Destroy (); + return 0; +} diff --git a/src/lte/examples/wscript b/src/lte/examples/wscript index 2fcdbd06b..9d7a28a19 100644 --- a/src/lte/examples/wscript +++ b/src/lte/examples/wscript @@ -12,7 +12,10 @@ def build(bld): obj.source = 'lena-rlc-calculator.cc' obj = bld.create_ns3_program('lena-fading', ['lte']) - obj.source = 'lena-fading.cc' + obj.source = 'lena-fading.cc' + obj = bld.create_ns3_program('lena-cqi-threshold', + ['lte']) + obj.source = 'lena-cqi-threshold.cc' obj = bld.create_ns3_program('lena-runtime-profiler', ['lte']) obj.source = 'lena-runtime-profiler.cc' diff --git a/src/lte/model/pf-ff-mac-scheduler.cc b/src/lte/model/pf-ff-mac-scheduler.cc index 6f2b5ca91..2b1d064d3 100644 --- a/src/lte/model/pf-ff-mac-scheduler.cc +++ b/src/lte/model/pf-ff-mac-scheduler.cc @@ -237,7 +237,13 @@ PfFfMacScheduler::GetTypeId (void) { static TypeId tid = TypeId ("ns3::PfFfMacScheduler") .SetParent () - .AddConstructor (); + .AddConstructor () + .AddAttribute ("CqiTimerThreshold", + "The number of TTIs a CQI is valid (default 1000 - 1 sec.)", + UintegerValue (1000), + MakeUintegerAccessor (&PfFfMacScheduler::m_cqiTimersThreshold), + MakeUintegerChecker ()) + ; return tid; } @@ -426,6 +432,9 @@ PfFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched // evaluate the relative channel quality indicator for each UE per each RBG // (since we are using allocation type 0 the small unit of allocation is RBG) // Resource allocation type 0 (see sec 7.1.6.1 of 36.213) + + RefreshDlCqiMaps (); + int rbgSize = GetRbgSize (m_cschedCellConfig.m_dlBandwidth); int rbgNum = m_cschedCellConfig.m_dlBandwidth / rbgSize; //std::vector rbgAllocationMap; @@ -443,12 +452,13 @@ PfFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched uint8_t cqi = 0; if (itCqi == m_a30CqiRxed.end ()) { - NS_LOG_DEBUG (this << " No DL-CQI for this UE " << (*it).first); +// NS_LOG_DEBUG (this << " No DL-CQI for this UE " << (*it).first); cqi = 1; // start with lowest value } else { cqi = (*itCqi).second.m_higherLayerSelected.at (i).m_sbCqi.at (0); +// NS_LOG_INFO (this << " CQI " << (uint32_t)cqi); } if (cqi > 0) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213) { @@ -527,7 +537,7 @@ PfFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched { if ((*itCqi).second.m_higherLayerSelected.size () > (*itMap).second.at (k)) { - // NS_LOG_DEBUG (this << " RBG " << (*itMap).second.at (k) << " CQI " << (uint16_t)((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)) ); +// NS_LOG_DEBUG (this << " RBG " << (*itMap).second.at (k) << " CQI " << (uint16_t)((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)) ); if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)) < worstCqi) { worstCqi = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)); @@ -649,11 +659,17 @@ PfFfMacScheduler::DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::Sched { // create the new entry m_p10CqiRxed.insert ( std::pair (rnti, params.m_cqiList.at (i).m_wbCqi.at (0)) ); // only codeword 0 at this stage (SISO) + // generate correspondent timer + m_p10CqiTimers.insert ( std::pair (rnti, m_cqiTimersThreshold)); } else { - // update the CQI value + // update the CQI value and refresh correspondent timer (*it).second = params.m_cqiList.at (i).m_wbCqi.at (0); + // update correspondent timer + std::map ::iterator itTimers; + itTimers = m_p10CqiTimers.find (rnti); + (*itTimers).second = m_cqiTimersThreshold; } } else if ( params.m_cqiList.at (i).m_cqiType == CqiListElement_s::A30 ) @@ -666,11 +682,15 @@ PfFfMacScheduler::DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::Sched { // create the new entry m_a30CqiRxed.insert ( std::pair (rnti, params.m_cqiList.at (i).m_sbMeasResult) ); + m_a30CqiTimers.insert ( std::pair (rnti, m_cqiTimersThreshold)); } else { - // update the CQI value + // update the CQI value and refresh correspondent timer (*it).second = params.m_cqiList.at (i).m_sbMeasResult; + std::map ::iterator itTimers; + itTimers = m_a30CqiTimers.find (rnti); + (*itTimers).second = m_cqiTimersThreshold; } } else @@ -719,6 +739,7 @@ PfFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::Sched { // NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf)); + RefreshUlCqiMaps (); std::map ::iterator it; int nflows = 0; @@ -974,7 +995,7 @@ PfFfMacScheduler::DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::Sched for (uint32_t i = 0; i < (*itMap).second.size (); i++) { // convert from fixed point notation Sxxxxxxxxxxx.xxx to double - NS_LOG_INFO (this << " i " << i << " size " << params.m_ulCqi.m_sinr.size () << " mapSIze " << (*itMap).second.size ()); +// NS_LOG_INFO (this << " i " << i << " size " << params.m_ulCqi.m_sinr.size () << " mapSIze " << (*itMap).second.size ()); double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (i)); //NS_LOG_DEBUG (this << " UE " << (*itMap).second.at (i) << " SINRfp " << params.m_ulCqi.m_sinr.at (i) << " sinrdb " << sinr); itCqi = m_ueCqi.find ((*itMap).second.at (i)); @@ -996,11 +1017,18 @@ PfFfMacScheduler::DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::Sched } m_ueCqi.insert (std::pair > ((*itMap).second.at (i), newCqi)); + // generate correspondent timer + m_ueCqiTimers.insert (std::pair ((*itMap).second.at (i), m_cqiTimersThreshold)); } else { // update the value (*itCqi).second.at (i) = sinr; + // update correspondent timer + std::map ::iterator itTimers; + itTimers = m_ueCqiTimers.find ((*itMap).second.at (i)); + (*itTimers).second = m_cqiTimersThreshold; + } } @@ -1010,4 +1038,82 @@ PfFfMacScheduler::DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::Sched return; } +void +PfFfMacScheduler::RefreshDlCqiMaps(void) +{ + // refresh DL CQI P01 Map + std::map ::iterator itP10 = m_p10CqiTimers.begin (); + while (itP10!=m_p10CqiTimers.end ()) + { +// NS_LOG_INFO (this << " P10-CQI for user " << (*itP10).first << " is " << (uint32_t)(*itP10).second << " thr " << (uint32_t)m_cqiTimersThreshold); + if ((*itP10).second == 0) + { + // delete correspondent entries + std::map ::iterator itMap = m_p10CqiRxed.find ((*itP10).first); + NS_ASSERT_MSG (itMap != m_p10CqiRxed.end (), " Does not find CQI report for user " << (*itP10).first); + NS_LOG_INFO (this << " P10-CQI exired for user " << (*itP10).first); + m_p10CqiRxed.erase (itMap); + m_p10CqiTimers.erase (itP10); + } + else + { + (*itP10).second--; + } + itP10++; + } + + // refresh DL CQI A30 Map + std::map ::iterator itA30 = m_a30CqiTimers.begin (); + while (itA30!=m_a30CqiTimers.end ()) + { +// NS_LOG_INFO (this << " A30-CQI for user " << (*itA30).first << " is " << (uint32_t)(*itA30).second << " thr " << (uint32_t)m_cqiTimersThreshold); + if ((*itA30).second == 0) + { + // delete correspondent entries + std::map ::iterator itMap = m_a30CqiRxed.find ((*itA30).first); + NS_ASSERT_MSG (itMap != m_a30CqiRxed.end (), " Does not find CQI report for user " << (*itA30).first); + NS_LOG_INFO (this << " A30-CQI exired for user " << (*itA30).first); + m_a30CqiRxed.erase (itMap); + m_a30CqiTimers.erase (itA30); + } + else + { + (*itA30).second--; + } + itA30++; + } + + return; +} + + +void +PfFfMacScheduler::RefreshUlCqiMaps(void) +{ + // refresh UL CQI Map + std::map ::iterator itUl = m_ueCqiTimers.begin (); + while (itUl!=m_ueCqiTimers.end ()) + { +// NS_LOG_INFO (this << " UL-CQI for user " << (*itUl).first << " is " << (uint32_t)(*itUl).second << " thr " << (uint32_t)m_cqiTimersThreshold); + if ((*itUl).second == 0) + { + // delete correspondent entries + std::map >::iterator itMap = m_ueCqi.find ((*itUl).first); + NS_ASSERT_MSG (itMap != m_ueCqi.end (), " Does not find CQI report for user " << (*itUl).first); + NS_LOG_INFO (this << " UL-CQI exired for user " << (*itUl).first); + (*itMap).second.clear (); + m_ueCqi.erase (itMap); + m_ueCqiTimers.erase (itUl); + } + else + { + (*itUl).second--; + } + itUl++; + } + + return; +} + + } diff --git a/src/lte/model/pf-ff-mac-scheduler.h b/src/lte/model/pf-ff-mac-scheduler.h index 3f2048860..34fc9ad14 100644 --- a/src/lte/model/pf-ff-mac-scheduler.h +++ b/src/lte/model/pf-ff-mac-scheduler.h @@ -134,6 +134,9 @@ private: int LcActivePerFlow (uint16_t rnti); double EstimateUlSinr (uint16_t rnti, uint16_t rb); + + void RefreshDlCqiMaps(void); + void RefreshUlCqiMaps(void); /* * Vectors of UE's LC info @@ -156,11 +159,19 @@ private: * Map of UE's DL CQI P01 received */ std::map m_p10CqiRxed; + /* + * Map of UE's timers on DL CQI P01 received + */ + std::map m_p10CqiTimers; /* * Map of UE's DL CQI A30 received */ std::map m_a30CqiRxed; + /* + * Map of UE's timers on DL CQI A30 received + */ + std::map m_a30CqiTimers; /* * Map of previous allocated UE per RBG @@ -172,6 +183,10 @@ private: * Map of UEs' UL-CQI per RBG */ std::map > m_ueCqi; + /* + * Map of UEs' timers on UL-CQI per RBG + */ + std::map m_ueCqiTimers; /* * Map of UE's buffer status reports received @@ -193,6 +208,8 @@ private: uint8_t m_schedTtiDelay; // delay between scheduling and reception (based on m_macChTtiDelay) uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL + + uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid }; diff --git a/src/lte/model/rr-ff-mac-scheduler.cc b/src/lte/model/rr-ff-mac-scheduler.cc index fb12f2e33..4f044e33c 100644 --- a/src/lte/model/rr-ff-mac-scheduler.cc +++ b/src/lte/model/rr-ff-mac-scheduler.cc @@ -235,7 +235,13 @@ RrFfMacScheduler::GetTypeId (void) { static TypeId tid = TypeId ("ns3::RrFfMacScheduler") .SetParent () - .AddConstructor (); + .AddConstructor () + .AddAttribute ("CqiTimerThreshold", + "The number of TTIs a CQI is valid (default 1000 - 1 sec.)", + UintegerValue (1000), + MakeUintegerAccessor (&RrFfMacScheduler::m_cqiTimersThreshold), + MakeUintegerChecker ()) + ; return tid; } @@ -333,6 +339,7 @@ RrFfMacScheduler::DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::Sch { m_p10CqiRxed.insert ( std::pair (params.m_rnti, 1)); // only codeword 0 at this stage (SISO) // initialized to 1 (i.e., the lowest value for transmitting a signal) + m_p10CqiTimers.insert ( std::pair (params.m_rnti, m_cqiTimersThreshold)); } return; @@ -374,6 +381,8 @@ RrFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched { NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf)); // API generated by RLC for triggering the scheduling of a DL subframe + + RefreshDlCqiMaps (); // Get the actual active flows (queue!=0) std::vector::iterator it; @@ -388,22 +397,29 @@ RrFfMacScheduler::DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::Sched || ((*it).m_rlcStatusPduSize > 0) ) { std::map ::iterator itCqi = m_p10CqiRxed.find ((*it).m_rnti); + uint8_t cqi = 0; if (itCqi != m_p10CqiRxed.end ()) { - if ((*itCqi).second != 0) + cqi = (*itCqi).second; + } + else + { + cqi = 1; // lowest value fro trying a transmission + } + if (cqi != 0) + { + // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213) + nflows++; + itLcRnti = lcActivesPerRnti.find ((*it).m_rnti); + if (itLcRnti != lcActivesPerRnti.end ()) { - // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213) - nflows++; - itLcRnti = lcActivesPerRnti.find ((*it).m_rnti); - if (itLcRnti != lcActivesPerRnti.end ()) - { - (*itLcRnti).second++; - } - else - { - lcActivesPerRnti.insert (std::pair ((*it).m_rnti, 1)); - } + (*itLcRnti).second++; } + else + { + lcActivesPerRnti.insert (std::pair ((*it).m_rnti, 1)); + } + } } } @@ -563,11 +579,17 @@ RrFfMacScheduler::DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::Sched { // create the new entry m_p10CqiRxed.insert ( std::pair (rnti, params.m_cqiList.at (i).m_wbCqi.at (0)) ); // only codeword 0 at this stage (SISO) + // generate correspondent timer + m_p10CqiTimers.insert ( std::pair (rnti, m_cqiTimersThreshold)); } else { // update the CQI value (*it).second = params.m_cqiList.at (i).m_wbCqi.at (0); + // update correspondent timer + std::map ::iterator itTimers; + itTimers = m_p10CqiTimers.find (rnti); + (*itTimers).second = m_cqiTimersThreshold; } } else if ( params.m_cqiList.at (i).m_cqiType == CqiListElement_s::A30 ) @@ -587,9 +609,11 @@ RrFfMacScheduler::DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::Sched void RrFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params) { - NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf)); +// NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf)); + RefreshUlCqiMaps (); + std::map ::iterator it; int nflows = 0; @@ -828,11 +852,17 @@ RrFfMacScheduler::DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::Sched } m_ueCqi.insert (std::pair > ((*itMap).second.at (i), newCqi)); + // generate correspondent timer + m_ueCqiTimers.insert (std::pair ((*itMap).second.at (i), m_cqiTimersThreshold)); } else { // update the value (*itCqi).second.at (i) = sinr; + // update correspondent timer + std::map ::iterator itTimers; + itTimers = m_ueCqiTimers.find ((*itMap).second.at (i)); + (*itTimers).second = m_cqiTimersThreshold; } } @@ -842,4 +872,62 @@ RrFfMacScheduler::DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::Sched return; } + +void +RrFfMacScheduler::RefreshDlCqiMaps(void) +{ + NS_LOG_FUNCTION (this << m_p10CqiTimers.size ()); + // refresh DL CQI P01 Map + std::map ::iterator itP10 = m_p10CqiTimers.begin (); + while (itP10!=m_p10CqiTimers.end ()) + { + NS_LOG_INFO (this << " P10-CQI for user " << (*itP10).first << " is " << (uint32_t)(*itP10).second << " thr " << (uint32_t)m_cqiTimersThreshold); + if ((*itP10).second == 0) + { + // delete correspondent entries + std::map ::iterator itMap = m_p10CqiRxed.find ((*itP10).first); + NS_ASSERT_MSG (itMap != m_p10CqiRxed.end (), " Does not find CQI report for user " << (*itP10).first); + NS_LOG_INFO (this << " P10-CQI exired for user " << (*itP10).first); + m_p10CqiRxed.erase (itMap); + m_p10CqiTimers.erase (itP10); + } + else + { + (*itP10).second--; + } + itP10++; + } + + return; +} + + +void +RrFfMacScheduler::RefreshUlCqiMaps(void) +{ + // refresh UL CQI Map + std::map ::iterator itUl = m_ueCqiTimers.begin (); + while (itUl!=m_ueCqiTimers.end ()) + { + NS_LOG_INFO (this << " UL-CQI for user " << (*itUl).first << " is " << (uint32_t)(*itUl).second << " thr " << (uint32_t)m_cqiTimersThreshold); + if ((*itUl).second == 0) + { + // delete correspondent entries + std::map >::iterator itMap = m_ueCqi.find ((*itUl).first); + NS_ASSERT_MSG (itMap != m_ueCqi.end (), " Does not find CQI report for user " << (*itUl).first); + NS_LOG_INFO (this << " UL-CQI exired for user " << (*itUl).first); + (*itMap).second.clear (); + m_ueCqi.erase (itMap); + m_ueCqiTimers.erase (itUl); + } + else + { + (*itUl).second--; + } + itUl++; + } + + return; +} + } diff --git a/src/lte/model/rr-ff-mac-scheduler.h b/src/lte/model/rr-ff-mac-scheduler.h index e77bbab23..1d2807143 100644 --- a/src/lte/model/rr-ff-mac-scheduler.h +++ b/src/lte/model/rr-ff-mac-scheduler.h @@ -118,6 +118,9 @@ private: int GetRbgSize (int dlbandwidth); + + void RefreshDlCqiMaps(void); + void RefreshUlCqiMaps(void); /* * Vectors of UE's RLC info @@ -128,6 +131,10 @@ private: * Map of UE's DL CQI P01 received */ std::map m_p10CqiRxed; + /* + * Map of UE's timers on DL CQI P01 received + */ + std::map m_p10CqiTimers; /* * Map of previous allocated UE per RBG @@ -139,6 +146,10 @@ private: * Map of UEs' UL-CQI per RBG */ std::map > m_ueCqi; + /* + * Map of UEs' timers on UL-CQI per RBG + */ + std::map m_ueCqiTimers; @@ -161,6 +172,9 @@ private: uint16_t m_nextRntiDl; // RNTI of the next user to be served next scheduling in DL uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL + + uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid + }; From 09707f9a67e6449dce6bde490c529251eca58c80 Mon Sep 17 00:00:00 2001 From: Marco Miozzo Date: Wed, 9 Nov 2011 17:24:39 +0100 Subject: [PATCH 4/5] Fixed fading designed documentation wrongly merged --- src/lte/doc/source/lte-design.rst | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/lte/doc/source/lte-design.rst b/src/lte/doc/source/lte-design.rst index 9b63ce074..d1c09c0ae 100644 --- a/src/lte/doc/source/lte-design.rst +++ b/src/lte/doc/source/lte-design.rst @@ -421,3 +421,58 @@ For communications involving at least one indoor node, the corresponding wall pe Please refer to the documentation of the Buildings module for details on the actual models used in each case. + +Trace Fading Model +++++++++++++++++++ + +The fading model is based on the one developed during the GSoC 2010 [Piro2011]_. The main characteristic of this model is the fact that the fading evaluation during simulation run-time is based on per-calculated traces. This is done for limiting the computational complexity of the simulator. On the other hand, it needs huge structures for storing the traces; therefore, a trade-off between the number of possible parameters and the memory occupancy has to be found. The most important ones are: + + * users' speed: relative speed between users (affects the Doppler frequency, which in turns affects the time-variance property of the fading) + * number of taps (and relative power): number of multiple paths considered, which affects the frequency property of the fading. + * time granularity of the trace: sampling time of the trace. + * frequency granularity of the trace: number of values in frequency to be evaluated. + * length of trace: ideally large as the simulation time, might be reduced by windowing mechanism. + * number of users: number of independent traces to be used (ideally one trace per user). + +Respect to the mathematical channel propagation model, we suggest the one provided by the ``rayleighchan`` function of Matlab since it provides a well accepted channel modelization both in time and frequency domain, more information following the link: + +http://www.mathworks.es/help/toolbox/comm/ug/a1069449399.html#bq5zk36 + +The simulator provides a matlab script (``/lte/model/JakesTraces/fading-trace-generator.m``) for generating traces based on the format used by the simulator. +In detail, the channel object created with the rayleighchan function is used for filtering a discrete-time impulse signal in order to obtain the channel impulse response. The filtering is repeated for different TTI, thus yielding subsequent time-correlated channel responses (one per TTI). The channel response is then processed with the ``pwelch`` function for obtaining its power spectral density values, which are then saved in a file with the proper format compatible with the simulator model. + +Since the number of variable it is pretty high, generate traces considering all of them might produce a high number of traces of huge size. On this matter, we considered the following assumptions of the parameters based on the 3GPP fading propagation conditions (see Annex B.2 of [TS36.104]_): + + * users' speed: consider the most common typical value + + * 0 and 3 kmph for pedestrian scenarios + * 30 and 60 kmph for vehicular scenarios + * 0, 3, 30 and 60 for urban scenarios + + * number of taps: use the three models presented in Annex B.2 of TS 36.104. + * time granularity: 1 ms (as the simulator granularity in time). + * frequency granularity: per RB basis (which implies 100 RBs, as the simulator granularity in frequency). + * length of the trace: the simulator includes the windowing mechanism implemented during the GSoC 2011, which consists of picking up a window of the trace each window length in a random fashion. + * number of users: users share the same fading trace, but the windows are independent among users which randomly pick up their starting point. + +According to the parameters we considered, the following formula express in detail the dimension: + +.. math:: + T_{SIZE} = Sample_{size} \times RB_{NUM} \times \frac{T_{total}}{T_{sample}} \times Speed_{NUM} \times Scenarios_{NUM} \mbox{ [bytes]} + +where :math:`Sample_{size}` is the size in bytes of the sample (e.g., 8 in case of double precision, 4 in case of float precision), :math:`RB_{NUM}` is the number of RB or set of RBs to be considered, :math:`T_{total}` is the total length of the trace, :math:`T_{sample}` is the sampling period (1 ms for having a new sample each subframe), :math:`Speed_{NUM}` is the number of users relative speeds considered and :math:`Scenarios_{NUM}` is the number of scenarios (i.e., different taps configurations). +According to the formula we have that a typical single channel realization (i.e., independent RB traces at a given speed and given set of number of taps with one sample per ms/TTI)) implies the usage of 8,000,000 bytes (7.6294 MB) considering the precision of double (:math:`1\times10^{-308}` to :math:`1\times10^{308}`). + +A typical set of traces for a simulation will result therefore in: + + * :math:`RB_{NUM}`: 100 + * :math:`T_{total}`: 10 secs + * :math:`T_{sample}`: 0.001 secs (1 ms as a subframe) + * :math:`Speed_{NUM}`: 1 speed per scenarios (e.g. 3 kmph for pedestrian) + * :math:`Scenarios_{NUM}`: 1 (pedestrian) + +which results in 8,000,000 bytes (~8 MB) of traces with double precision. + + + + From ee9c06421702d5746e8c57475504a4f32903a9e4 Mon Sep 17 00:00:00 2001 From: Marco Miozzo Date: Thu, 10 Nov 2011 10:35:02 +0100 Subject: [PATCH 5/5] Fixed merge conflicts in fading desgin documentation --- src/lte/doc/source/lte-design.rst | 37 ++++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/lte/doc/source/lte-design.rst b/src/lte/doc/source/lte-design.rst index d1c09c0ae..3bc334682 100644 --- a/src/lte/doc/source/lte-design.rst +++ b/src/lte/doc/source/lte-design.rst @@ -434,45 +434,36 @@ The fading model is based on the one developed during the GSoC 2010 [Piro2011]_. * length of trace: ideally large as the simulation time, might be reduced by windowing mechanism. * number of users: number of independent traces to be used (ideally one trace per user). -Respect to the mathematical channel propagation model, we suggest the one provided by the ``rayleighchan`` function of Matlab since it provides a well accepted channel modelization both in time and frequency domain, more information following the link: - -http://www.mathworks.es/help/toolbox/comm/ug/a1069449399.html#bq5zk36 +With respect to the mathematical channel propagation model, we suggest the one provided by the ``rayleighchan`` function of Matlab, since it provides a well accepted channel modelization both in time and frequency domain. For more information, the reader is referred to [mathworks]_. The simulator provides a matlab script (``/lte/model/JakesTraces/fading-trace-generator.m``) for generating traces based on the format used by the simulator. In detail, the channel object created with the rayleighchan function is used for filtering a discrete-time impulse signal in order to obtain the channel impulse response. The filtering is repeated for different TTI, thus yielding subsequent time-correlated channel responses (one per TTI). The channel response is then processed with the ``pwelch`` function for obtaining its power spectral density values, which are then saved in a file with the proper format compatible with the simulator model. Since the number of variable it is pretty high, generate traces considering all of them might produce a high number of traces of huge size. On this matter, we considered the following assumptions of the parameters based on the 3GPP fading propagation conditions (see Annex B.2 of [TS36.104]_): - * users' speed: consider the most common typical value + * users' speed: typically only a few discrete values are considered, i.e.: * 0 and 3 kmph for pedestrian scenarios * 30 and 60 kmph for vehicular scenarios * 0, 3, 30 and 60 for urban scenarios - * number of taps: use the three models presented in Annex B.2 of TS 36.104. - * time granularity: 1 ms (as the simulator granularity in time). - * frequency granularity: per RB basis (which implies 100 RBs, as the simulator granularity in frequency). - * length of the trace: the simulator includes the windowing mechanism implemented during the GSoC 2011, which consists of picking up a window of the trace each window length in a random fashion. - * number of users: users share the same fading trace, but the windows are independent among users which randomly pick up their starting point. + * channel taps: only a limited number of sets of channel taps are normally considered, for example three models are mentioned in Annex B.2 of [TS36.104]_. + * time granularity: we need one fading value per TTI, i.e., every 1 ms (as this is the granularity in time of the ns-3 LTE PHY model). + * frequency granularity: we need one fading value per RB (which is the frequency granularity of the spectrum model used by the ns-3 LTE model). + * length of the trace: the simulator includes the windowing mechanism implemented during the GSoC 2011, which consists of picking up a window of the trace each window length in a random fashion. + * per-user fading process: users share the same fading trace, but for each user a different starting point in the trace is randomly picked up. This choice was made to avoid the need to provide one fading trace per user. -According to the parameters we considered, the following formula express in detail the dimension: +According to the parameters we considered, the following formula express in detail the total size :math:`S_{traces}` of the fading traces: .. math:: - T_{SIZE} = Sample_{size} \times RB_{NUM} \times \frac{T_{total}}{T_{sample}} \times Speed_{NUM} \times Scenarios_{NUM} \mbox{ [bytes]} + S_{traces} = S_{sample} \times N_{RB} \times \frac{T_{trace}}{T_{sample}} \times N_{scenarios} \mbox{ [bytes]} -where :math:`Sample_{size}` is the size in bytes of the sample (e.g., 8 in case of double precision, 4 in case of float precision), :math:`RB_{NUM}` is the number of RB or set of RBs to be considered, :math:`T_{total}` is the total length of the trace, :math:`T_{sample}` is the sampling period (1 ms for having a new sample each subframe), :math:`Speed_{NUM}` is the number of users relative speeds considered and :math:`Scenarios_{NUM}` is the number of scenarios (i.e., different taps configurations). -According to the formula we have that a typical single channel realization (i.e., independent RB traces at a given speed and given set of number of taps with one sample per ms/TTI)) implies the usage of 8,000,000 bytes (7.6294 MB) considering the precision of double (:math:`1\times10^{-308}` to :math:`1\times10^{308}`). - -A typical set of traces for a simulation will result therefore in: - - * :math:`RB_{NUM}`: 100 - * :math:`T_{total}`: 10 secs - * :math:`T_{sample}`: 0.001 secs (1 ms as a subframe) - * :math:`Speed_{NUM}`: 1 speed per scenarios (e.g. 3 kmph for pedestrian) - * :math:`Scenarios_{NUM}`: 1 (pedestrian) - -which results in 8,000,000 bytes (~8 MB) of traces with double precision. +where :math:`S_{sample}` is the size in bytes of the sample (e.g., 8 in case of double precision, 4 in case of float precision), :math:`N_{RB}` is the number of RB or set of RBs to be considered, :math:`T_{trace}` is the total length of the trace, :math:`T_{sample}` is the time resolution of the trace (1 ms), and :math:`N_{scenarios}` is the number of fading scenarios that are desired (i.e., combinations of different sets of channel taps and user speed values). We provide traces for 3 different scenarios one for each taps configuration defined in Annex B.2 of [TS36.104]_: + * Pedestrian: with nodes' speed of 3 kmph. + * Vehicular: with nodes' speed of 60 kmph. + * Urban: with nodes' speed of 3 kmph. +hence :math:`N_{scenarios} = 3`. All traces have :math:`T_{trace} = 10` s and :math:`RB_{NUM} = 100`. This results in a total 24 MB bytes of traces.