5G-LENA nr-v3.3-120-gdac69c56
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-antenna-3gpp-model-conf.cc
1// Copyright (c) 2018 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "ns3/antenna-module.h"
6#include "ns3/applications-module.h"
7#include "ns3/config-store-module.h"
8#include "ns3/config-store.h"
9#include "ns3/core-module.h"
10#include "ns3/internet-module.h"
11#include "ns3/mobility-module.h"
12#include "ns3/network-module.h"
13#include "ns3/nr-module.h"
14#include "ns3/point-to-point-module.h"
15#include "ns3/test.h"
16
17using namespace ns3;
18
33class TestAntenna3gppModelConf : public TestCase
34{
35 public:
36 enum DirectionGnbUeXYAngle
37 {
38 DirectionGnbUe_45,
39 DirectionGnbUe_135,
40 DirectionGnbUe_225,
41 DirectionGnbUe_315,
42 DirectionGnbUe_0,
43 DirectionGnbUe_90,
44 DirectionGnbUe_180,
45 DirectionGnbUe_270,
46 };
47
48 TestAntenna3gppModelConf(const std::string& name,
49 DirectionGnbUeXYAngle conf,
50 bool gNbOmniAntennaElem,
51 bool ueOmniAntennaElem,
52 uint8_t ueNoOfAntennas,
53 std::string losCondition);
54 ~TestAntenna3gppModelConf() override;
55 void UeReception(RxPacketTraceParams params);
56
57 private:
58 void DoRun() override;
59 std::string m_name;
60 DirectionGnbUeXYAngle m_conf;
61 bool m_ueOmniAntennaElem;
62 bool m_gNbOmniAntennaElem;
63
64 uint8_t m_ueNoOfAntennas;
65 std::string m_losCondition;
66 Ptr<MinMaxAvgTotalCalculator<double>> m_sinrCell1;
67 Ptr<MinMaxAvgTotalCalculator<double>> m_sinrCell2;
68 Ptr<MinMaxAvgTotalCalculator<double>> m_mcsCell1;
69 Ptr<MinMaxAvgTotalCalculator<double>> m_mcsCell2;
70 Ptr<MinMaxAvgTotalCalculator<double>> m_rbNumCell1;
71 Ptr<MinMaxAvgTotalCalculator<double>> m_rbNumCell2;
72};
73
74void
75UETraceReception(TestAntenna3gppModelConf* test, RxPacketTraceParams params)
76{
77 test->UeReception(params);
78}
79
80void
81TestAntenna3gppModelConf::UeReception(RxPacketTraceParams params)
82{
83 if (params.m_cellId == 1)
84 {
85 m_sinrCell1->Update(params.m_sinr);
86 m_mcsCell1->Update(params.m_mcs);
87 m_rbNumCell1->Update(params.m_rbAssignedNum);
88 }
89 else if (params.m_cellId == 2)
90 {
91 m_sinrCell2->Update(params.m_sinr);
92 m_mcsCell2->Update(params.m_mcs);
93 m_rbNumCell2->Update(params.m_rbAssignedNum);
94 }
95 else
96 {
97 NS_ABORT_MSG("Cell does not exist ... ");
98 }
99}
100
101TestAntenna3gppModelConf::TestAntenna3gppModelConf(const std::string& name,
102 DirectionGnbUeXYAngle conf,
103 bool gNbOmniAntennaElem,
104 bool ueOmniAntennaElem,
105 uint8_t ueNoOfAntennas,
106 std::string losCondition)
107 : TestCase(name)
108{
109 m_name = name;
110 m_conf = conf;
111 m_gNbOmniAntennaElem = gNbOmniAntennaElem;
112 m_ueOmniAntennaElem = ueOmniAntennaElem;
113 m_ueNoOfAntennas = ueNoOfAntennas;
114 m_losCondition = losCondition;
115 m_sinrCell1 = Create<MinMaxAvgTotalCalculator<double>>();
116 m_sinrCell2 = Create<MinMaxAvgTotalCalculator<double>>();
117 m_mcsCell1 = Create<MinMaxAvgTotalCalculator<double>>();
118 m_mcsCell2 = Create<MinMaxAvgTotalCalculator<double>>();
119 m_rbNumCell1 = Create<MinMaxAvgTotalCalculator<double>>();
120 m_rbNumCell2 = Create<MinMaxAvgTotalCalculator<double>>();
121}
122
123// This destructor does nothing but we include it as a reminder that
124// the test case should clean up after itself
125TestAntenna3gppModelConf::~TestAntenna3gppModelConf()
126{
127}
128
129void
130TestAntenna3gppModelConf::DoRun()
131{
132 std::cout << "\n\n\n" << m_name << std::endl;
133 // set simulation time and mobility
134 Time simTime = MilliSeconds(800);
135 Time udpAppStartTimeDl = MilliSeconds(400);
136 Time udpAppStopTimeDl = MilliSeconds(800);
137 uint32_t packetSize = 1000;
138 DataRate udpRate = DataRate("2Mbps");
139
140 Config::SetDefault("ns3::LteRlcUm::MaxTxBufferSize", UintegerValue(999999999));
141 Config::SetDefault("ns3::NrEpsBearer::Release", UintegerValue(15));
142
143 // create base stations and mobile terminals
144 NodeContainer gNbNodes;
145 NodeContainer ueNodes;
146 MobilityHelper mobility;
147
148 double gNbHeight = 1.5;
149 double ueHeight = 1.5;
150 gNbNodes.Create(1);
151 ueNodes.Create(1);
152
153 Ptr<ListPositionAllocator> gNbPositionAlloc = CreateObject<ListPositionAllocator>();
154 Ptr<ListPositionAllocator> uePositionAlloc = CreateObject<ListPositionAllocator>();
155
156 gNbPositionAlloc->Add(Vector(0, 0, gNbHeight));
157
158 if (m_conf == DirectionGnbUe_45)
159 {
160 uePositionAlloc->Add(Vector(20, 20, ueHeight));
161 }
162 else if (m_conf == DirectionGnbUe_135)
163 {
164 uePositionAlloc->Add(Vector(-20, 20, ueHeight));
165 }
166 else if (m_conf == DirectionGnbUe_225)
167 {
168 uePositionAlloc->Add(Vector(-20, -20, ueHeight));
169 }
170 else if (m_conf == DirectionGnbUe_315)
171 {
172 uePositionAlloc->Add(Vector(20, -20, ueHeight));
173 }
174 else if (m_conf == DirectionGnbUe_0)
175 {
176 uePositionAlloc->Add(Vector(20, 0, ueHeight));
177 }
178 else if (m_conf == DirectionGnbUe_90)
179 {
180 uePositionAlloc->Add(Vector(0, 20, ueHeight));
181 }
182 else if (m_conf == DirectionGnbUe_180)
183 {
184 uePositionAlloc->Add(Vector(-20, 0, ueHeight));
185 }
186 else if (m_conf == DirectionGnbUe_270)
187 {
188 uePositionAlloc->Add(Vector(0, -20, ueHeight));
189 }
190
191 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
192 mobility.SetPositionAllocator(gNbPositionAlloc);
193 mobility.Install(gNbNodes);
194
195 mobility.SetPositionAllocator(uePositionAlloc);
196 mobility.Install(ueNodes);
197
198 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
199 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
200 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
201 // Put the pointers inside nrHelper
202 idealBeamformingHelper->SetAttribute("BeamformingMethod",
203 TypeIdValue(CellScanBeamforming::GetTypeId()));
204 double beamSearchAngleStep = 30.0;
205 idealBeamformingHelper->SetBeamformingAlgorithmAttribute("BeamSearchAngleStep",
206 DoubleValue(beamSearchAngleStep));
207 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
208
209 // set the number of antenna elements of UE
210 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(sqrt(m_ueNoOfAntennas)));
211 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(sqrt(m_ueNoOfAntennas)));
212 if (m_ueOmniAntennaElem)
213 {
214 nrHelper->SetUeAntennaAttribute("AntennaElement",
215 PointerValue(CreateObject<IsotropicAntennaModel>()));
216 }
217 else
218 {
219 nrHelper->SetUeAntennaAttribute("AntennaElement",
220 PointerValue(CreateObject<ThreeGppAntennaModel>()));
221 }
222 // set the number of antenna elements of gNbs
223 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(4));
224 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(8));
225 if (m_gNbOmniAntennaElem)
226 {
227 nrHelper->SetGnbAntennaAttribute("AntennaElement",
228 PointerValue(CreateObject<IsotropicAntennaModel>()));
229 }
230 else
231 {
232 nrHelper->SetGnbAntennaAttribute("AntennaElement",
233 PointerValue(CreateObject<ThreeGppAntennaModel>()));
234 }
235
236 // UE transmit power
237 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(20.0));
238
239 // gNB transmit power
240 nrHelper->SetGnbPhyAttribute("TxPower", DoubleValue(44.0));
241
242 nrHelper->SetGnbPhyAttribute("Numerology", UintegerValue(3.0));
243
244 nrHelper->SetEpcHelper(nrEpcHelper);
245
246 /*
247 * Spectrum division. We create two operational bands, each of them containing
248 * one component carrier, and each CC containing a single bandwidth part
249 * centered at the frequency specified by the input parameters.
250 * Each spectrum part length is, as well, specified by the input parameters.
251 * Both operational bands will use the StreetCanyon channel modeling.
252 */
254 CcBwpCreator ccBwpCreator;
255 double centralFrequency = 28e9;
256 double bandwidth = 20e6;
257 const uint8_t numCcPerBand = 1;
258 CcBwpCreator::SimpleOperationBandConf bandConf(centralFrequency, bandwidth, numCcPerBand);
259
260 // By using the configuration created, it is time to make the operation bands
261 OperationBandInfo band = ccBwpCreator.CreateOperationBandContiguousCc(bandConf);
262 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
263 // Set the spectrum channel using
264 channelHelper->ConfigureFactories("UMi", m_losCondition);
265 // Shadowing
266 channelHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(false));
267 channelHelper->AssignChannelsToBands({band});
268 allBwps = CcBwpCreator::GetAllBwps({band});
269
270 uint32_t bwpIdForLowLat = 0;
271 // gNb routing between Bearer and bandwidh part
272 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB",
273 UintegerValue(bwpIdForLowLat));
274 // UE routing between Bearer and bandwidh part
275 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdForLowLat));
276
277 // install nr net devices
278 NetDeviceContainer gNbDevs = nrHelper->InstallGnbDevice(gNbNodes, allBwps);
279 NetDeviceContainer ueNetDevs = nrHelper->InstallUeDevice(ueNodes, allBwps);
280
281 // create the internet and install the IP stack on the UEs
282 // get SGW/PGW and create a single RemoteHost
283 Ptr<Node> pgw = nrEpcHelper->GetPgwNode();
284 NodeContainer remoteHostContainer;
285 remoteHostContainer.Create(1);
286 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
287 InternetStackHelper internet;
288 internet.Install(remoteHostContainer);
289 // connect a remoteHost to pgw. Setup routing too
290 PointToPointHelper p2ph;
291 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
292 p2ph.SetDeviceAttribute("Mtu", UintegerValue(2500));
293 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.000)));
294 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
295 Ipv4AddressHelper ipv4h;
296 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
297 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
298 // in this container, interface 0 is the pgw, 1 is the remoteHost
299 // Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
300
301 Ipv4StaticRoutingHelper ipv4RoutingHelper;
302 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
303 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
304 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
305 internet.Install(ueNodes);
306 Ipv4InterfaceContainer ueIpIface;
307 ueIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDevs));
308
309 // Set the default gateway for the UEs
310 for (uint32_t j = 0; j < ueNodes.GetN(); ++j)
311 {
312 Ptr<Ipv4StaticRouting> ueStaticRouting =
313 ipv4RoutingHelper.GetStaticRouting(ueNodes.Get(j)->GetObject<Ipv4>());
314 ueStaticRouting->SetDefaultRoute(nrEpcHelper->GetUeDefaultGatewayAddress(), 1);
315 }
316
317 // attach UEs to the closest gNB
318 nrHelper->AttachToClosestGnb(ueNetDevs, gNbDevs);
319
320 // assign IP address to UEs, and install UDP downlink applications
321 uint16_t dlPort = 1234;
322 ApplicationContainer clientAppsDl;
323 ApplicationContainer serverAppsDl;
324
325 Time udpInterval =
326 Time::FromDouble((packetSize * 8) / static_cast<double>(udpRate.GetBitRate()), Time::S);
327
328 UdpServerHelper dlPacketSinkHelper(dlPort);
329 serverAppsDl.Add(dlPacketSinkHelper.Install(ueNodes));
330
331 UdpClientHelper dlClient(ueIpIface.GetAddress(0), dlPort);
332 dlClient.SetAttribute("PacketSize", UintegerValue(packetSize));
333 dlClient.SetAttribute("Interval", TimeValue(udpInterval));
334 dlClient.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
335 clientAppsDl.Add(dlClient.Install(remoteHost));
336
337 Ptr<NrEpcTft> tft = Create<NrEpcTft>();
339 dlpf.localPortStart = dlPort;
340 dlpf.localPortEnd = dlPort;
341 tft->Add(dlpf);
342
344 nrHelper->ActivateDedicatedEpsBearer(ueNetDevs.Get(0), bearer, tft);
345
346 // start UDP server and client apps
347 serverAppsDl.Start(udpAppStartTimeDl);
348 clientAppsDl.Start(udpAppStartTimeDl);
349
350 serverAppsDl.Stop(udpAppStopTimeDl);
351 clientAppsDl.Stop(udpAppStopTimeDl);
352
353 Ptr<NrSpectrumPhy> ue1SpectrumPhy = nrHelper->GetUePhy(ueNetDevs.Get(0), 0)->GetSpectrumPhy();
354 ue1SpectrumPhy->TraceConnectWithoutContext("RxPacketTraceUe",
355 MakeBoundCallback(&UETraceReception, this));
356
357 // nrHelper->EnableTraces();
358 Simulator::Stop(simTime);
359 Simulator::Run();
360
361 std::cout << serverAppsDl.GetN() << std::endl;
362 Ptr<UdpServer> serverApp1 = serverAppsDl.Get(0)->GetObject<UdpServer>();
363 // double throughput1 = (serverApp1->GetReceived () * packetSize *
364 // 8)/(udpAppStopTimeDl-udpAppStartTimeDl).GetSeconds ();
365 double throughput1 = (serverApp1->GetReceived() * (packetSize + 28) * 8) /
366 (udpAppStopTimeDl - udpAppStartTimeDl).GetSeconds();
367
368 std::cout << "\n UE: " << throughput1 / 1e6 << " Mbps"
369 << "\t Avg.SINR:" << 10 * log10(m_sinrCell1->getMean())
370 << "\t Avg.MCS:" << m_mcsCell1->getMean()
371 << "\t Avg. RB Num:" << m_rbNumCell1->getMean();
372
373 Simulator::Destroy();
374}
375
376// The TestSuite class names the TestNrSystemTestOfdmaTestSuite, identifies what type of TestSuite,
377// and enables the TestCases to be run. Typically, only the constructor for
378// this class must be defined
379//
380class Antenna3gppModelConfTestSuite : public TestSuite
381{
382 public:
383 Antenna3gppModelConfTestSuite();
384};
385
386Antenna3gppModelConfTestSuite::Antenna3gppModelConfTestSuite()
387 : TestSuite("nr-antenna-3gpp-model-conf", Type::SYSTEM)
388{
389 std::list<TestAntenna3gppModelConf::DirectionGnbUeXYAngle> conf = {
390 TestAntenna3gppModelConf::DirectionGnbUe_45,
391 TestAntenna3gppModelConf::DirectionGnbUe_135,
392 TestAntenna3gppModelConf::DirectionGnbUe_225,
393 TestAntenna3gppModelConf::DirectionGnbUe_315,
394 TestAntenna3gppModelConf::DirectionGnbUe_0,
395 TestAntenna3gppModelConf::DirectionGnbUe_90,
396 TestAntenna3gppModelConf::DirectionGnbUe_180,
397 TestAntenna3gppModelConf::DirectionGnbUe_270};
398
399 std::list<uint8_t> ueNoOfAntennas = {16};
400
401 std::list<std::string> losConditions = {"LOS"};
402
403 // std::list<TypeId> gNbantennaArrayModelTypes = {AntennaArrayModel::GetTypeId(),
404 // AntennaArray3gppModel::GetTypeId ()};
405 std::list<bool> gNbOmniAntennaElement = {false, true};
406
407 // std::list<TypeId> ueAntennaArrayModelTypes = {AntennaArrayModel::GetTypeId(),
408 // AntennaArray3gppModel::GetTypeId ()};
409 std::list<bool> ueOmniAntennaElement = {false, true};
410
411 for (const auto& losCondition : losConditions)
412 {
413 for (const auto& c : conf)
414 {
415 for (const auto& oaaGnb : gNbOmniAntennaElement)
416 {
417 for (const auto& oaaUe : ueOmniAntennaElement)
418 {
419 for (const auto& n : ueNoOfAntennas)
420 {
421 std::stringstream ss;
422 ss << " Test: ";
423
424 if (c == TestAntenna3gppModelConf::DirectionGnbUe_45)
425 {
426 ss << "DirectionGnbUe_45";
427 }
428 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_135)
429 {
430 ss << "DirectionGnbUe_135";
431 }
432 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_225)
433 {
434 ss << "DirectionGnbUe_225";
435 }
436 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_315)
437 {
438 ss << "DirectionGnbUe_315";
439 }
440 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_0)
441 {
442 ss << "DirectionGnbUe_0";
443 }
444 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_90)
445 {
446 ss << "DirectionGnbUe_90";
447 }
448 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_180)
449 {
450 ss << "DirectionGnbUe_180";
451 }
452 else if (c == TestAntenna3gppModelConf::DirectionGnbUe_270)
453 {
454 ss << "DirectionGnbUe_270";
455 }
456
457 ss << " , channelCondition: " << losCondition;
458
459 ss << " , UE number of antennas:" << (unsigned)n;
460
461 if (oaaGnb)
462 {
463 ss << " , gNB antenna element type: omni";
464 }
465 else
466 {
467 ss << " , gNB antenna element type: 3gpp";
468 }
469
470 if (oaaUe)
471 {
472 ss << " , UE antenna element type: omni";
473 }
474 else
475 {
476 ss << " , UE antenna element type: 3gpp";
477 }
478
479 AddTestCase(new TestAntenna3gppModelConf(ss.str(),
480 c,
481 oaaGnb,
482 oaaUe,
483 n,
484 losCondition),
485 Duration::QUICK);
486 }
487 }
488 }
489 }
490 }
491}
492
493// Do not forget to allocate an instance of this TestSuite
494static Antenna3gppModelConfTestSuite testSuite;
Manages the correct creation of operation bands, component carriers and bandwidth parts.
OperationBandInfo CreateOperationBandContiguousCc(const SimpleOperationBandConf &conf)
Create an operation band with the CC specified.
static BandwidthPartInfoPtrVector GetAllBwps(const std::vector< std::reference_wrapper< OperationBandInfo > > &operationBands)
Get all the BWP pointers from the specified vector of operation bands.
static TypeId GetTypeId()
Get the type id.
This class contains the specification of EPS Bearers.
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
uint16_t localPortStart
start of the port number range of the UE
Definition nr-epc-tft.h:118
uint16_t localPortEnd
end of the port number range of the UE
Definition nr-epc-tft.h:119
Operation band information structure.
The RxPacketTraceParams struct.