5G-LENA nr-v3.0-32-g83aee33
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-realistic-beamforming-test.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
3// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4//
5// SPDX-License-Identifier: GPL-2.0-only
6
7#include <ns3/antenna-module.h>
8#include <ns3/core-module.h>
9#include <ns3/mobility-module.h>
10#include <ns3/nr-module.h>
11#include <ns3/spectrum-model.h>
12#include <ns3/three-gpp-channel-model.h>
13#include <ns3/three-gpp-propagation-loss-model.h>
14#include <ns3/three-gpp-spectrum-propagation-loss-model.h>
15
16namespace ns3
17{
18
19NS_LOG_COMPONENT_DEFINE("NrRealisticBeamformingTest");
20
42class NrRealisticBeamformingTestSuite : public TestSuite
43{
44 public:
45 NrRealisticBeamformingTestSuite();
46};
47
48class NrRealisticBeamformingTestCase : public TestCase
49{
50 public:
51 NrRealisticBeamformingTestCase(std::string name, Duration duration);
52 ~NrRealisticBeamformingTestCase() override;
53
54 private:
55 void DoRun() override;
56
57 Duration m_testDuration;
58};
59
63NrRealisticBeamformingTestSuite::NrRealisticBeamformingTestSuite()
64 : TestSuite("nr-realistic-beamforming-test", Type::SYSTEM)
65{
66 NS_LOG_INFO("Creating NrRealisticBeamformingTestSuite");
67
68 auto durationQuick = Duration::QUICK;
69 auto durationExtensive = Duration::EXTENSIVE;
70
71 AddTestCase(
72 new NrRealisticBeamformingTestCase("RealisticBeamforming basic test case", durationQuick),
73 durationQuick);
74 AddTestCase(new NrRealisticBeamformingTestCase("RealisticBeamforming basic test case",
75 durationExtensive),
76 durationExtensive);
77}
78
83NrRealisticBeamformingTestCase::NrRealisticBeamformingTestCase(std::string name, Duration duration)
84 : TestCase(name)
85{
86 m_testDuration = duration;
87}
88
89NrRealisticBeamformingTestCase::~NrRealisticBeamformingTestCase()
90{
91}
92
93void
94NrRealisticBeamformingTestCase::DoRun()
95{
96 RngSeedManager::SetSeed(1);
97
98 std::list<Vector> uePositionsExtensive = {Vector(10, -10, 1.5),
99 Vector(0, 10, 1.5),
100 Vector(0, -10, 1.5)};
101
102 uint16_t totalCounter = 0;
103 uint16_t highSinrCounter = 0;
104 uint16_t lowSinrCounter = 0;
105
106 std::list<uint16_t> rngList = (m_testDuration == Duration::EXTENSIVE)
107 ? std::list<uint16_t>({2, 3})
108 : std::list<uint16_t>({1});
109
110 std::list<Vector> uePositions =
111 (m_testDuration == Duration::EXTENSIVE)
112 ? uePositionsExtensive
113 : std::list<Vector>({Vector(10, 10, 1.5), Vector(-10, 10, 1.5)});
114
115 std::list<uint16_t> antennaConfList = (m_testDuration == Duration::EXTENSIVE)
116 ? std::list<uint16_t>({3, 4})
117 : std::list<uint16_t>({2});
118
119 for (auto rng : rngList)
120 {
121 RngSeedManager::SetRun(rng);
122
123 for (const auto& pos : uePositions)
124 {
125 for (const auto& antennaConf : antennaConfList)
126 {
127 for (auto iso : {false, true})
128 {
129 totalCounter++;
130
131 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
132 // Create Nodes: eNodeB and UE
133 NodeContainer gnbNodes;
134 NodeContainer ueNodes;
135 gnbNodes.Create(1);
136 ueNodes.Create(1);
137 NodeContainer allNodes = NodeContainer(gnbNodes, ueNodes);
138
139 // Install Mobility Model
140 Ptr<ListPositionAllocator> positionAlloc =
141 CreateObject<ListPositionAllocator>();
142 positionAlloc->Add(Vector(0, 0.0, 10)); // gNB
143 positionAlloc->Add(pos); // UE
144
145 MobilityHelper mobility;
146 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
147 mobility.SetPositionAllocator(positionAlloc);
148 mobility.Install(allNodes);
149
150 // Create Devices and install them in the Nodes (eNB and UE)
151 NetDeviceContainer gnbDevs;
152 NetDeviceContainer ueDevs;
153 nrHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(false));
154
155 CcBwpCreator::SimpleOperationBandConf bandConf(29e9,
156 100e6,
157 1,
158 BandwidthPartInfo::UMa_LoS);
159 CcBwpCreator ccBwpCreator;
160 OperationBandInfo band = ccBwpCreator.CreateOperationBandContiguousCc(bandConf);
161 // Initialize channel and pathloss, plus other things inside band.
162 nrHelper->InitializeOperationBand(&band);
163 BandwidthPartInfoPtrVector allBwps = CcBwpCreator::GetAllBwps({band});
164
165 // Antennas for the gNbs
166 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(antennaConf));
167 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(antennaConf));
168
169 // Antennas for the UEs
170 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(antennaConf));
171 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(antennaConf));
172
173 // Antenna element type for both gNB and UE
174 if (iso)
175 {
176 nrHelper->SetGnbAntennaAttribute(
177 "AntennaElement",
178 PointerValue(CreateObject<IsotropicAntennaModel>()));
179 nrHelper->SetUeAntennaAttribute(
180 "AntennaElement",
181 PointerValue(CreateObject<IsotropicAntennaModel>()));
182 }
183 else
184 {
185 nrHelper->SetGnbAntennaAttribute(
186 "AntennaElement",
187 PointerValue(CreateObject<ThreeGppAntennaModel>()));
188 nrHelper->SetUeAntennaAttribute(
189 "AntennaElement",
190 PointerValue(CreateObject<ThreeGppAntennaModel>()));
191 }
192
193 nrHelper->SetGnbBeamManagerTypeId(RealisticBfManager::GetTypeId());
194
195 gnbDevs = nrHelper->InstallGnbDevice(gnbNodes, allBwps);
196 ueDevs = nrHelper->InstallUeDevice(ueNodes, allBwps);
197
198 for (auto it = gnbDevs.Begin(); it != gnbDevs.End(); ++it)
199 {
200 DynamicCast<NrGnbNetDevice>(*it)->UpdateConfig();
201 }
202
203 for (auto it = ueDevs.Begin(); it != ueDevs.End(); ++it)
204 {
205 DynamicCast<NrUeNetDevice>(*it)->UpdateConfig();
206 }
207
208 Ptr<NrUePhy> uePhy = nrHelper->GetUePhy(ueDevs.Get(0), 0);
209
210 Ptr<NrSpectrumPhy> txSpectrumPhy =
211 nrHelper->GetGnbPhy(gnbDevs.Get(0), 0)->GetSpectrumPhy();
212 Ptr<SpectrumChannel> txSpectrumChannel = txSpectrumPhy->GetSpectrumChannel();
213 Ptr<ThreeGppPropagationLossModel> propagationLossModel =
214 DynamicCast<ThreeGppPropagationLossModel>(
215 txSpectrumChannel->GetPropagationLossModel());
216 NS_ASSERT(propagationLossModel != nullptr);
217 propagationLossModel->AssignStreams(1);
218 Ptr<ChannelConditionModel> channelConditionModel =
219 propagationLossModel->GetChannelConditionModel();
220 channelConditionModel->AssignStreams(1);
221 Ptr<ThreeGppSpectrumPropagationLossModel> spectrumLossModel =
222 DynamicCast<ThreeGppSpectrumPropagationLossModel>(
223 txSpectrumChannel->GetPhasedArraySpectrumPropagationLossModel());
224 NS_ASSERT(spectrumLossModel != nullptr);
225 Ptr<ThreeGppChannelModel> channel =
226 DynamicCast<ThreeGppChannelModel>(spectrumLossModel->GetChannelModel());
227 channel->AssignStreams(1);
228
229 double sinrSrsHighLineal = std::pow(10.0, 0.1 * 40);
230 double sinrSrsLowLineal = std::pow(10.0, 0.1 * (-10));
231
232 Ptr<CellScanBeamforming> cellScanBeamforming =
233 CreateObject<CellScanBeamforming>();
234
235 BeamformingVectorPair bfPairIdeal =
236 cellScanBeamforming->GetBeamformingVectors(txSpectrumPhy,
237 uePhy->GetSpectrumPhy());
238
239 Ptr<RealisticBeamformingAlgorithm> realisticBeamforming =
240 CreateObject<RealisticBeamformingAlgorithm>();
241 realisticBeamforming->Install(
242 txSpectrumPhy,
243 uePhy->GetSpectrumPhy(),
244 DynamicCast<NrGnbNetDevice>(gnbDevs.Get(0))->GetScheduler(0));
245
246 // directly update max SINR SRS to a high value, skipping other set functions of
247 // the algorithm
248 realisticBeamforming->m_maxSrsSinrPerSlot = sinrSrsHighLineal;
249
250 BeamformingVectorPair bfPairReal1 =
251 realisticBeamforming->GetBeamformingVectors();
252
253 // directly update max SINR SRS to a new lower value, skipping other set
254 // functions of the algorithm,
255 realisticBeamforming->m_maxSrsSinrPerSlot = sinrSrsLowLineal;
256
257 BeamformingVectorPair bfPairReal2 =
258 realisticBeamforming->GetBeamformingVectors();
259
260 if ((bfPairIdeal.first.second == bfPairReal1.first.second) &&
261 (bfPairIdeal.second.second == bfPairReal1.second.second))
262 {
263 highSinrCounter++;
264 }
265
266 if (!((bfPairIdeal.first.second == bfPairReal2.first.second) &&
267 (bfPairIdeal.second.second == bfPairReal2.second.second)))
268 {
269 lowSinrCounter++;
270 }
271 }
272 }
273 }
274 }
275
276 double tolerance = 0.2;
277 if (m_testDuration == Duration::EXTENSIVE)
278 {
279 tolerance = 0.2;
280 }
281 else
282 {
283 tolerance =
284 0.3; // relax tolerance for QUICK mode since there are only 4 test configurations, e.g.,
285 // if 3 results of 4 are as expected that is already enough, but that gives 0.75
286 // thus it needs larger tolerance than 0.2 which is fine for EXTENSIVE mode
287 }
288
289 NS_TEST_ASSERT_MSG_EQ_TOL(highSinrCounter / (double)totalCounter,
290 1,
291 tolerance,
292 "The pair of beamforming vectors should be equal in most of the "
293 "cases when SINR is high, and they are not");
294 NS_TEST_ASSERT_MSG_EQ_TOL(lowSinrCounter / (double)totalCounter,
295 1,
296 tolerance,
297 "The pair of beamforming vectors should not be equal in most of the "
298 "cases when SINR is low, and they are");
299
300 NS_LOG_INFO("The result is as expected when high SINR in " << highSinrCounter << " out of "
301 << totalCounter << " total cases.");
302 NS_LOG_INFO("The result is as expected when low SINR in " << lowSinrCounter << " out of "
303 << totalCounter << " total cases.");
304
305 Simulator::Destroy();
306}
307
308// Do not forget to allocate an instance of this TestSuite
309static NrRealisticBeamformingTestSuite nrTestSuite;
310
311} // namespace ns3
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo