Bug 2029 - new CQI generation approach fix

This commit is contained in:
Piotr Gawlowicz
2014-12-19 16:18:35 +01:00
parent 433d2b3a70
commit 95eae84b3f
6 changed files with 237 additions and 3 deletions

View File

@@ -139,6 +139,11 @@ public:
*/
virtual void SetSrsConfigurationIndex (uint16_t srcCi) = 0;
/**
* \param pa the P_A value
*/
virtual void SetPa (double pa) = 0;
};
@@ -231,6 +236,7 @@ public:
virtual void SetRnti (uint16_t rnti);
virtual void SetTransmissionMode (uint8_t txMode);
virtual void SetSrsConfigurationIndex (uint16_t srcCi);
virtual void SetPa (double pa);
private:
MemberLteUeCphySapProvider ();
@@ -318,6 +324,12 @@ MemberLteUeCphySapProvider<C>::SetSrsConfigurationIndex (uint16_t srcCi)
m_owner->DoSetSrsConfigurationIndex (srcCi);
}
template <class C>
void
MemberLteUeCphySapProvider<C>::SetPa (double pa)
{
m_owner->DoSetPa (pa);
}
/**

View File

@@ -455,7 +455,26 @@ LteUePhy::GenerateCtrlCqiReport (const SpectrumValue& sinr)
if (m_dataInterferencePowerUpdated)
{
SpectrumValue mixedSinr = m_rsReceivedPower / m_dataInterferencePower;
SpectrumValue mixedSinr = (m_rsReceivedPower * m_paLinear) / m_dataInterferencePower;
/*
* some RBs are not used in PDSCH and their SINR is very high
* for example with bandwidth 25, last RB is not used
* it can make avgSinr value very high, what is incorrect
*/
uint32_t rbgSize = GetRbgSize ();
uint32_t modulo = m_dlBandwidth % rbgSize;
double avgMixedSinr = 0;
uint32_t usedRbgNum = 0;
for(uint32_t i = 0; i < (m_dlBandwidth-1-modulo); i++) {
usedRbgNum++;
avgMixedSinr+=mixedSinr[i];
}
avgMixedSinr = avgMixedSinr/usedRbgNum;
for(uint32_t i = 0; i < modulo; i++) {
mixedSinr[m_dlBandwidth-1-i] = avgMixedSinr;
}
GenerateMixedCqiReport (mixedSinr);
m_dataInterferencePowerUpdated = false;
return;
@@ -1243,6 +1262,7 @@ LteUePhy::DoReset ()
m_rsrpSinrSampleCounter = 0;
m_p10CqiLast = Simulator::Now ();
m_a30CqiLast = Simulator::Now ();
m_paLinear = 1;
m_packetBurstQueue.clear ();
m_controlMessagesQueue.clear ();
@@ -1381,6 +1401,12 @@ LteUePhy::DoSetSrsConfigurationIndex (uint16_t srcCi)
NS_LOG_DEBUG (this << " UE SRS P " << m_srsPeriodicity << " RNTI " << m_rnti << " offset " << m_srsSubframeOffset << " cellId " << m_cellId << " CI " << srcCi);
}
void
LteUePhy::DoSetPa (double pa)
{
NS_LOG_FUNCTION (this << pa);
m_paLinear = pow (10,(pa/10));
}
void
LteUePhy::SetTxMode1Gain (double gain)

View File

@@ -312,6 +312,7 @@ private:
void DoSetRnti (uint16_t rnti);
void DoSetTransmissionMode (uint8_t txMode);
void DoSetSrsConfigurationIndex (uint16_t srcCi);
void DoSetPa (double pa);
// UE PHY SAP methods
virtual void DoSendMacPdu (Ptr<Packet> p);
@@ -364,6 +365,8 @@ private:
uint16_t m_srsConfigured;
Time m_srsStartTime;
double m_paLinear;
bool m_dlConfigured;
bool m_ulConfigured;

View File

@@ -1133,8 +1133,10 @@ LteUeRrc::ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedic
if (pcd.havePdschConfigDedicated)
{
// update PdschConfigDedicated (i.e. P_A value)
m_pdschConfigDedicated = pcd.pdschConfigDedicated;
}
m_pdschConfigDedicated = pcd.pdschConfigDedicated;
double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (m_pdschConfigDedicated);
m_cphySapProvider->SetPa (paDouble);
}
std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
if (stamIt != rrcd.srbToAddModList.end ())

View File

@@ -32,6 +32,9 @@
#include "ns3/mobility-helper.h"
#include "ns3/lte-helper.h"
#include "lte-ffr-simple.h"
#include "ns3/lte-rrc-sap.h"
#include "lte-test-cqi-generation.h"
using namespace ns3;
@@ -54,6 +57,22 @@ LteTestUlSchedulingCallback (LteCqiGenerationTestCase *testcase, std::string pat
testcase->UlScheduling (frameNo, subframeNo, rnti, mcs, sizeTb);
}
void
LteTestDlSchedulingCallback2 (LteCqiGenerationDlPowerControlTestCase *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)
{
testcase->DlScheduling (frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2);
}
void
LteTestUlSchedulingCallback2 (LteCqiGenerationDlPowerControlTestCase *testcase, std::string path,
uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcs, uint16_t sizeTb)
{
testcase->UlScheduling (frameNo, subframeNo, rnti, mcs, sizeTb);
}
/**
* TestSuite
@@ -69,6 +88,20 @@ LteCqiGenerationTestSuite::LteCqiGenerationTestSuite ()
AddTestCase (new LteCqiGenerationTestCase ("UsePdcchForCqiGeneration", false, 4, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationTestCase ("UsePdschForCqiGeneration", true, 28, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB0, LteRrcSap::PdschConfigDedicated::dB0, 4, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB0, LteRrcSap::PdschConfigDedicated::dB_3, 8, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB0, LteRrcSap::PdschConfigDedicated::dB_6, 10, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB1, LteRrcSap::PdschConfigDedicated::dB_6, 12, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB2, LteRrcSap::PdschConfigDedicated::dB_6, 14, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB3, LteRrcSap::PdschConfigDedicated::dB_6, 14, 2), TestCase::QUICK);
AddTestCase (new LteCqiGenerationDlPowerControlTestCase ("CqiGenerationWithDlPowerControl",
LteRrcSap::PdschConfigDedicated::dB3, LteRrcSap::PdschConfigDedicated::dB0, 8, 2), TestCase::QUICK);
}
static LteCqiGenerationTestSuite lteCqiGenerationTestSuite;
@@ -206,3 +239,137 @@ LteCqiGenerationTestCase::DoRun (void)
Simulator::Destroy ();
}
LteCqiGenerationDlPowerControlTestCase::LteCqiGenerationDlPowerControlTestCase (std::string name,
uint8_t cell0Pa, uint8_t cell1Pa, uint16_t dlMcs, uint16_t ulMcs)
: TestCase ("Downlink Power Control: " + name),
m_cell0Pa (cell0Pa),
m_cell1Pa (cell1Pa),
m_dlMcs (dlMcs),
m_ulMcs (ulMcs)
{
NS_LOG_INFO ("Creating LteCqiGenerationTestCase");
}
LteCqiGenerationDlPowerControlTestCase::~LteCqiGenerationDlPowerControlTestCase ()
{
}
void
LteCqiGenerationDlPowerControlTestCase::DlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2)
{
// need to allow for RRC connection establishment + CQI feedback reception
if (Simulator::Now () > MilliSeconds (500))
{
// NS_LOG_UNCOND("DL MSC: " << (uint32_t)mcsTb1 << " expected DL MCS: " << (uint32_t)m_dlMcs);
NS_TEST_ASSERT_MSG_EQ ((uint32_t)mcsTb1, (uint32_t)m_dlMcs, "Wrong DL MCS ");
}
}
void
LteCqiGenerationDlPowerControlTestCase::UlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcs, uint16_t sizeTb)
{
// need to allow for RRC connection establishment + SRS transmission
if (Simulator::Now () > MilliSeconds (500))
{
// NS_LOG_UNCOND("UL MSC: " << (uint32_t)mcs << " expected UL MCS: " << (uint32_t)m_ulMcs);
NS_TEST_ASSERT_MSG_EQ ((uint32_t)mcs, (uint32_t)m_ulMcs, "Wrong UL MCS");
}
}
void
LteCqiGenerationDlPowerControlTestCase::DoRun (void)
{
NS_LOG_DEBUG ("LteCqiGenerationTestCase");
Config::Reset ();
Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (true));
Config::SetDefault ("ns3::LteHelper::UsePdschForCqiGeneration", BooleanValue (true));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (true));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (true));
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetFfrAlgorithmType ("ns3::LteFfrSimple");
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes1;
NodeContainer ueNodes2;
enbNodes.Create (2);
ueNodes1.Create (1);
ueNodes2.Create (1);
NodeContainer allNodes = NodeContainer ( enbNodes, ueNodes1, ueNodes2);
/*
* The topology is the following:
*
* eNB1 UE1 UE2 eNB2
* | | |
* x -------------------------- x -------------------------- x
* 500 m 500 m
*
*/
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNB1
positionAlloc->Add (Vector (1000, 0.0, 0.0)); // eNB2
positionAlloc->Add (Vector (500.0, 0.0, 0.0)); // UE1
positionAlloc->Add (Vector (500, 0.0, 0.0)); // UE2
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.SetPositionAllocator (positionAlloc);
mobility.Install (allNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs1;
NetDeviceContainer ueDevs2;
lteHelper->SetSchedulerType ("ns3::PfFfMacScheduler");
lteHelper->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs1 = lteHelper->InstallUeDevice (ueNodes1);
ueDevs2 = lteHelper->InstallUeDevice (ueNodes2);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs1, enbDevs.Get (0));
lteHelper->Attach (ueDevs2, enbDevs.Get (1));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
PointerValue tmp;
enbDevs.Get (0)->GetAttribute ("LteFfrAlgorithm", tmp);
Ptr<LteFfrSimple> simpleFfrAlgorithmEnb0 = DynamicCast<LteFfrSimple>(tmp.GetObject ());
simpleFfrAlgorithmEnb0->ChangePdschConfigDedicated (true);
LteRrcSap::PdschConfigDedicated pdschConfigDedicatedEnb0;
pdschConfigDedicatedEnb0.pa = m_cell0Pa;
simpleFfrAlgorithmEnb0->SetPdschConfigDedicated (pdschConfigDedicatedEnb0);
enbDevs.Get (1)->GetAttribute ("LteFfrAlgorithm", tmp);
Ptr<LteFfrSimple> simpleFfrAlgorithmEnb1 = DynamicCast<LteFfrSimple>(tmp.GetObject ());
simpleFfrAlgorithmEnb1->ChangePdschConfigDedicated (true);
LteRrcSap::PdschConfigDedicated pdschConfigDedicatedEnb1;
pdschConfigDedicatedEnb1.pa = m_cell1Pa;
simpleFfrAlgorithmEnb1->SetPdschConfigDedicated (pdschConfigDedicatedEnb1);
Config::Connect ("/NodeList/0/DeviceList/0/LteEnbMac/DlScheduling",
MakeBoundCallback (&LteTestDlSchedulingCallback2, this));
Config::Connect ("/NodeList/0/DeviceList/0/LteEnbMac/UlScheduling",
MakeBoundCallback (&LteTestUlSchedulingCallback2, this));
Simulator::Stop (Seconds (1.100));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -54,4 +54,28 @@ private:
};
class LteCqiGenerationDlPowerControlTestCase : public TestCase
{
public:
LteCqiGenerationDlPowerControlTestCase (std::string name, uint8_t cell0Pa, uint8_t cell1Pa,
uint16_t dlMcs, uint16_t ulMcs);
virtual ~LteCqiGenerationDlPowerControlTestCase ();
void DlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2);
void UlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
uint8_t mcs, uint16_t sizeTb);
private:
virtual void DoRun (void);
uint8_t m_cell0Pa;
uint8_t m_cell1Pa;
uint16_t m_dlMcs;
uint16_t m_ulMcs;
};
#endif /* LTE_TEST_CQI_GENERATION_H */