5G-LENA nr-v3.3-120-gdac69c56
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
lena-v2-utils.cc
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "lena-v2-utils.h"
6
7#include "flow-monitor-output-stats.h"
8#include "power-output-stats.h"
9#include "rb-output-stats.h"
10#include "slot-output-stats.h"
11
12#include "ns3/antenna-module.h"
13#include "ns3/config.h"
14#include "ns3/enum.h"
15#include "ns3/log.h"
16#include "ns3/nr-spectrum-value-helper.h"
17#include "ns3/pointer.h"
18
19NS_LOG_COMPONENT_DEFINE("LenaV2Utils");
20
21namespace ns3
22{
23
24void
25LenaV2Utils::ReportSinrNr(SinrOutputStats* stats,
26 uint16_t cellId,
27 uint16_t rnti,
28 double avgSinr,
29 uint16_t bwpId)
30{
31 stats->SaveSinr(cellId, rnti, avgSinr, bwpId);
32}
33
34void
35LenaV2Utils::ReportPowerNr(PowerOutputStats* stats,
36 const SfnSf& sfnSf,
37 Ptr<const SpectrumValue> txPsd,
38 const Time& t,
39 uint16_t rnti,
40 uint64_t imsi,
41 uint16_t bwpId,
42 uint16_t cellId)
43{
44 stats->SavePower(sfnSf, txPsd, t, rnti, imsi, bwpId, cellId);
45}
46
47void
48LenaV2Utils::ReportSlotStatsNr(SlotOutputStats* stats,
49 const SfnSf& sfnSf,
50 uint32_t scheduledUe,
51 uint32_t usedReg,
52 uint32_t usedSym,
53 uint32_t availableRb,
54 uint32_t availableSym,
55 uint16_t bwpId,
56 uint16_t cellId)
57{
58 stats->SaveSlotStats(sfnSf,
59 scheduledUe,
60 usedReg,
61 usedSym,
62 availableRb,
63 availableSym,
64 bwpId,
65 cellId);
66}
67
68void
69LenaV2Utils::ReportRbStatsNr(RbOutputStats* stats,
70 const SfnSf& sfnSf,
71 uint8_t sym,
72 const std::vector<int>& rbUsed,
73 uint16_t bwpId,
74 uint16_t cellId)
75{
76 stats->SaveRbStats(sfnSf, sym, rbUsed, bwpId, cellId);
77}
78
79void
80LenaV2Utils::ReportGnbRxDataNr(PowerOutputStats* gnbRxDataStats,
81 const SfnSf& sfnSf,
82 Ptr<const SpectrumValue> rxPsd,
83 const Time& t,
84 uint16_t bwpId,
85 uint16_t cellId)
86{
87 gnbRxDataStats->SavePower(sfnSf, rxPsd, t, 0, 0, bwpId, cellId);
88}
89
90void
91LenaV2Utils::ConfigureBwpTo(BandwidthPartInfoPtr& bwp, double centerFreq, double bwpBw)
92{
93 bwp->m_centralFrequency = centerFreq;
94 bwp->m_higherFrequency = centerFreq + (bwpBw / 2);
95 bwp->m_lowerFrequency = centerFreq - (bwpBw / 2);
96 bwp->m_channelBandwidth = bwpBw;
97}
98
99// unnamed namespace
100namespace
101{
102
103void
104ConfigurePhy(Ptr<NrHelper>& nrHelper,
105 Ptr<NetDevice> gnb,
106 double orientationRads,
107 uint16_t numerology,
108 double txPowerBs,
109 const std::string& pattern,
110 uint32_t bwpIndex)
111{
112 // Change the antenna orientation
113 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0); // BWP 0
114 Ptr<UniformPlanarArray> antenna0 =
115 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
116 antenna0->SetAttribute("BearingAngle", DoubleValue(orientationRads));
117
118 // configure the beam that points toward the center of hexagonal
119 // In case of beamforming, it will be overwritten.
120 phy0->GetSpectrumPhy()->GetBeamManager()->SetPredefinedBeam(3, 30);
121
122 // Set numerology
123 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Numerology", UintegerValue(numerology)); // BWP
124
125 // Set TX power
126 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("TxPower", DoubleValue(txPowerBs));
127
128 // Set TDD pattern
129 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Pattern", StringValue(pattern));
130}
131
132} // unnamed namespace
133
134void
135LenaV2Utils::SetLenaV2SimulatorParameters(const double sector0AngleRad,
136 const std::string& scenario,
137 const std::string& radioNetwork,
138 std::string errorModel,
139 const std::string& operationMode,
140 const std::string& direction,
141 uint16_t numerology,
142 const std::string& pattern,
143 const NodeContainer& gnbSector1Container,
144 const NodeContainer& gnbSector2Container,
145 const NodeContainer& gnbSector3Container,
146 const NodeContainer& ueSector1Container,
147 const NodeContainer& ueSector2Container,
148 const NodeContainer& ueSector3Container,
149 const Ptr<NrPointToPointEpcHelper>& baseEpcHelper,
150 Ptr<NrHelper>& nrHelper,
151 NetDeviceContainer& gnbSector1NetDev,
152 NetDeviceContainer& gnbSector2NetDev,
153 NetDeviceContainer& gnbSector3NetDev,
154 NetDeviceContainer& ueSector1NetDev,
155 NetDeviceContainer& ueSector2NetDev,
156 NetDeviceContainer& ueSector3NetDev,
157 bool calibration,
158 bool enableUlPc,
159 std::string powerAllocation,
160 SinrOutputStats* sinrStats,
161 PowerOutputStats* ueTxPowerStats,
162 PowerOutputStats* gnbRxPowerStats,
163 SlotOutputStats* slotStats,
164 RbOutputStats* rbStats,
165 const std::string& scheduler,
166 uint32_t bandwidthMHz,
167 uint32_t freqScenario,
168 double downtiltAngle)
169{
170 /*
171 * Create the radio network related parameters
172 */
173 uint8_t numScPerRb = 1;
174 double rbOverhead = 0.1;
175 uint32_t harqProcesses = 20;
176 uint32_t n1Delay = 2;
177 uint32_t n2Delay = 2;
178 if (radioNetwork == "LTE")
179 {
180 rbOverhead = 0.1;
181 harqProcesses = 8;
182 n1Delay = 4;
183 n2Delay = 4;
184 if (errorModel.empty())
185 {
186 errorModel = "ns3::LenaErrorModel";
187 }
188 else if (errorModel != "ns3::NrLteMiErrorModel" && errorModel != "ns3::LenaErrorModel")
189 {
190 NS_ABORT_MSG("The selected error model is not recommended for LTE");
191 }
192 }
193 else if (radioNetwork == "NR")
194 {
195 rbOverhead = 0.04;
196 harqProcesses = 20;
197 if (errorModel.empty())
198 {
199 errorModel = "ns3::NrEesmCcT2";
200 }
201 else if (errorModel == "ns3::NrLteMiErrorModel")
202 {
203 NS_ABORT_MSG("The selected error model is not recommended for NR");
204 }
205 }
206 else
207 {
208 NS_ABORT_MSG("Unrecognized radio network technology");
209 }
210
211 /*
212 * Setup the NR module. We create the various helpers needed for the
213 * NR simulation:
214 * - IdealBeamformingHelper, which takes care of the beamforming part
215 * - NrHelper, which takes care of creating and connecting the various
216 * part of the NR stack
217 * - NrChannelHelper, which takes care of the spectrum channel
218 */
219
220 nrHelper = CreateObject<NrHelper>();
221
222 Ptr<IdealBeamformingHelper> idealBeamformingHelper;
223
224 // in LTE non-calibration we want to use predefined beams that we set directly
225 // through beam manager. Hence, we do not need any ideal algorithm.
226 // For other cases, we need it (and the beam will be overwritten)
227 if (radioNetwork == "NR" || calibration)
228 {
229 idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
230 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
231 }
232
233 Ptr<NrPointToPointEpcHelper> nrEpcHelper = DynamicCast<NrPointToPointEpcHelper>(baseEpcHelper);
234 nrHelper->SetEpcHelper(nrEpcHelper);
235
236 double txPowerBs = 0.0;
237
238 if (scenario == "UMi")
239 {
240 txPowerBs = 30;
241 }
242 else if (scenario == "UMa" || scenario == "RMa")
243 {
244 txPowerBs = 43;
245 }
246 else
247 {
248 NS_ABORT_MSG("Unsupported scenario " << scenario << ". Supported values: UMi, UMa, RMa");
249 }
250 // Noise figure for the UE
251 nrHelper->SetUePhyAttribute("NoiseFigure", DoubleValue(9.0));
252 nrHelper->SetUePhyAttribute("EnableUplinkPowerControl", BooleanValue(enableUlPc));
253
254 NrSpectrumValueHelper::PowerAllocationType powerAllocationEnum;
255 if (powerAllocation == "UniformPowerAllocBw")
256 {
257 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW;
258 }
259 else if (powerAllocation == "UniformPowerAllocUsed")
260 {
261 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED;
262 }
263 else
264 {
265 NS_ABORT_MSG("Unsupported power allocation type "
266 << scenario
267 << ". Supported values: "
268 "UniformPowerAllocBw and UniformPowerAllocUsed.");
269 }
270
271 nrHelper->SetUePhyAttribute("PowerAllocationType", EnumValue(powerAllocationEnum));
272 // to match LENA default settings
273 nrHelper->SetGnbPhyAttribute("PowerAllocationType",
274 EnumValue(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW));
275
276 // Error Model: UE and GNB with same spectrum error model.
277 nrHelper->SetUlErrorModel(errorModel);
278 nrHelper->SetDlErrorModel(errorModel);
279
280 // Both DL and UL AMC will have the same model behind.
281 nrHelper->SetGnbDlAmcAttribute("AmcModel", EnumValue(NrAmc::ShannonModel));
282 nrHelper->SetGnbUlAmcAttribute("AmcModel", EnumValue(NrAmc::ShannonModel));
283
284 /*
285 * Adjust the average number of Reference symbols per RB only for LTE case,
286 * which is larger than in NR. We assume a value of 4 (could be 3 too).
287 */
288 nrHelper->SetGnbDlAmcAttribute("NumRefScPerRb", UintegerValue(numScPerRb));
289 nrHelper->SetGnbUlAmcAttribute("NumRefScPerRb", UintegerValue(1)); // FIXME: Might change in LTE
290
291 nrHelper->SetGnbPhyAttribute("RbOverhead", DoubleValue(rbOverhead));
292 nrHelper->SetGnbPhyAttribute("N2Delay", UintegerValue(n2Delay));
293 nrHelper->SetGnbPhyAttribute("N1Delay", UintegerValue(n1Delay));
294
295 nrHelper->SetUeMacAttribute("NumHarqProcess", UintegerValue(harqProcesses));
296 nrHelper->SetGnbMacAttribute("NumHarqProcess", UintegerValue(harqProcesses));
297
298 /*
299 * Create the necessary operation bands.
300 *
301 * In the 0 frequency scenario, each sector operates, in a separate band,
302 * while for scenario 1 all the sectors are in the same band. Please note that
303 * a single BWP in FDD is half the size of the corresponding TDD BWP, and the
304 * parameter bandwidthMHz refers to the size of the FDD BWP.
305 *
306 * Scenario 0: sectors NON_OVERLAPPING in frequency
307 *
308 * FDD scenario 0:
309 *
310 * |--------Band0--------|--------Band1--------|--------Band2--------|
311 * |---------CC0---------|---------CC1---------|---------CC2---------|
312 * |---BWP0---|---BWP1---|---BWP2---|---BWP3---|---BWP4---|---BWP5---|
313 *
314 * Sector i will go in Bandi
315 * DL in the first BWP, UL in the second BWP
316 *
317 * TDD scenario 0:
318 *
319 * |--------Band0--------|--------Band1--------|--------Band2--------|
320 * |---------CC0---------|---------CC2---------|---------CC2---------|
321 * |---------BWP0--------|---------BWP1--------|---------BWP2--------|
322 *
323 * Sector i will go in BWPi
324 *
325 *
326 * Scenario 1: sectors in OVERLAPPING bands
327 *
328 * Note that this configuration has 1/3 the total bandwidth of the
329 * NON_OVERLAPPING configuration.
330 *
331 * FDD scenario 1:
332 *
333 * |--------Band0--------|
334 * |---------CC0---------|
335 * |---BWP0---|---BWP1---|
336 *
337 * Sector i will go in BWPi
338 *
339 * TDD scenario 1:
340 *
341 * |--------Band0--------|
342 * |---------CC0---------|
343 * |---------BWP0--------|
344 *
345 * This is tightly coupled with what happens in lena-v1-utils.cc
346 *
347 */
348 // \todo: set band 0 start frequency from the command line
349 const double band0Start = 2110e6;
350 double bandwidthBwp = bandwidthMHz * 1e6;
351
352 OperationBandInfo band0;
353 OperationBandInfo band1;
354 OperationBandInfo band2;
355 band0.m_bandId = 0;
356 band1.m_bandId = 1;
357 band2.m_bandId = 2;
358
359 if (operationMode == "FDD")
360 {
361 Config::SetDefault("ns3::NrUeNetDevice::PrimaryUlIndex", UintegerValue(1));
362 }
363 if (freqScenario == 0) // NON_OVERLAPPING
364 {
365 uint8_t numBwp;
366
367 if (operationMode == "FDD")
368 {
369 // FDD uses two BWPs per CC, one CC per band
370 numBwp = 2;
371 }
372 else // if (operationMode = "TDD")
373 {
374 // Use double with BWP, to match total bandwidth for FDD in UL and DL
375 bandwidthBwp *= 2;
376 numBwp = 1;
377 }
378
379 double bandwidthCc = numBwp * bandwidthBwp;
380 uint8_t numCcPerBand = 1;
381 double bandwidthBand = numCcPerBand * bandwidthCc;
382 double bandCenter = band0Start + bandwidthBand / 2.0;
383
384 NS_LOG_LOGIC("NON_OVERLAPPING, " << operationMode << ": " << bandwidthBand << ":"
385 << bandwidthCc << ":" << bandwidthBwp << ", "
386 << (int)numCcPerBand << ", " << (int)numBwp);
387
388 NS_LOG_LOGIC("bandConf0: " << bandCenter << " " << bandwidthBand);
389 CcBwpCreator::SimpleOperationBandConf bandConf0(bandCenter, bandwidthBand, numCcPerBand);
390 bandConf0.m_numBwp = numBwp;
391 bandCenter += bandwidthBand;
392
393 NS_LOG_LOGIC("bandConf1: " << bandCenter << " " << bandwidthBand);
394 CcBwpCreator::SimpleOperationBandConf bandConf1(bandCenter, bandwidthBand, numCcPerBand);
395 bandConf1.m_numBwp = numBwp;
396 bandCenter += bandwidthBand;
397
398 NS_LOG_LOGIC("bandConf2: " << bandCenter << " " << bandwidthBand);
399 CcBwpCreator::SimpleOperationBandConf bandConf2(bandCenter, bandwidthBand, numCcPerBand);
400 bandConf2.m_numBwp = numBwp;
401
402 // Create, then configure
403 CcBwpCreator ccBwpCreator;
404 band0 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf0);
405 band0.m_bandId = 0;
406 band1 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf1);
407 band1.m_bandId = 1;
408 band2 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf2);
409 band2.m_bandId = 2;
410 bandCenter = band0Start + bandwidthBwp / 2.0;
411
412 NS_LOG_LOGIC("band0[0][0]: " << bandCenter << " " << bandwidthBwp);
413 ConfigureBwpTo(band0.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
414 bandCenter += bandwidthBwp;
415
416 if (operationMode == "FDD")
417 {
418 NS_LOG_LOGIC("band0[0][1]: " << bandCenter << " " << bandwidthBwp);
419 ConfigureBwpTo(band0.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
420 bandCenter += bandwidthBwp;
421 }
422
423 NS_LOG_LOGIC("band1[0][0]: " << bandCenter << " " << bandwidthBwp);
424 ConfigureBwpTo(band1.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
425 bandCenter += bandwidthBwp;
426
427 if (operationMode == "FDD")
428 {
429 NS_LOG_LOGIC("band1[0][1]: " << bandCenter << " " << bandwidthBwp);
430 ConfigureBwpTo(band1.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
431 bandCenter += bandwidthBwp;
432 }
433
434 NS_LOG_LOGIC("band2[0][0]: " << bandCenter << " " << bandwidthBwp);
435 ConfigureBwpTo(band2.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
436 bandCenter += bandwidthBwp;
437
438 if (operationMode == "FDD")
439 {
440 NS_LOG_LOGIC("band2[0][1]: " << bandCenter << " " << bandwidthBwp);
441 ConfigureBwpTo(band2.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
442 }
443
444 std::cout << "BWP Configuration for NON_OVERLAPPING case, mode " << operationMode << "\n"
445 << band0 << band1 << band2;
446 }
447
448 else if (freqScenario == 1) // OVERLAPPING
449 {
450 uint8_t numBwp;
451
452 if (operationMode == "FDD")
453 {
454 // FDD uses two BWPs per CC, one CC per band
455 numBwp = 2;
456 }
457 else // if (operationMode = "TDD")
458 {
459 // Use double with BWP, to match total bandwidth for FDD in UL and DL
460 bandwidthBwp *= 2;
461 numBwp = 1;
462 }
463
464 double bandwidthCc = numBwp * bandwidthBwp;
465 uint8_t numCcPerBand = 1;
466 double bandwidthBand = numCcPerBand * bandwidthCc;
467 double bandCenter = band0Start + bandwidthBand / 2.0;
468
469 NS_LOG_LOGIC("OVERLAPPING, " << operationMode << ": " << bandwidthBand << ":" << bandwidthCc
470 << ":" << bandwidthBwp << ", " << (int)numCcPerBand << ", "
471 << (int)numBwp);
472
473 NS_LOG_LOGIC("bandConf0: " << bandCenter << " " << bandwidthBand);
474 CcBwpCreator::SimpleOperationBandConf bandConf0(bandCenter, bandwidthBand, numCcPerBand);
475 bandConf0.m_numBwp = numBwp;
476 bandCenter += bandwidthBand;
477
478 // Create, then configure
479 CcBwpCreator ccBwpCreator;
480 band0 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf0);
481 band0.m_bandId = 0;
482
483 bandCenter = band0Start + bandwidthBwp / 2.0;
484
485 NS_LOG_LOGIC("band0[0][0]: " << bandCenter << " " << bandwidthBwp);
486 ConfigureBwpTo(band0.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
487 bandCenter += bandwidthBwp;
488
489 if (operationMode == "FDD")
490 {
491 NS_LOG_LOGIC("band0[0][1]: " << bandCenter << " " << bandwidthBwp);
492 ConfigureBwpTo(band0.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
493 }
494
495 std::cout << "BWP Configuration for OVERLAPPING case, mode " << operationMode << "\n"
496 << band0;
497 }
498
499 else
500 {
501 std::cerr << "unknown combination of freqScenario = " << freqScenario
502 << " and operationMode = " << operationMode << std::endl;
503 exit(1);
504 }
505 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
506 channelHelper->ConfigureFactories(scenario, "LOS", "ThreeGpp");
507 // Set attributes for all the channels
508 channelHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(!calibration));
509 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(100)));
510
511 // Omit fading from calibration mode
512 if (!calibration)
513 {
514 channelHelper->AssignChannelsToBands({band0, band1, band2},
516 }
517 else
518 {
519 channelHelper->AssignChannelsToBands({band0, band1, band2});
520 }
521
522 BandwidthPartInfoPtrVector sector1Bwps;
523 BandwidthPartInfoPtrVector sector2Bwps;
524 BandwidthPartInfoPtrVector sector3Bwps;
525 if (freqScenario == 0) // NON_OVERLAPPING
526 {
527 sector1Bwps = CcBwpCreator::GetAllBwps({band0});
528 sector2Bwps = CcBwpCreator::GetAllBwps({band1});
529 sector3Bwps = CcBwpCreator::GetAllBwps({band2});
530 }
531 else // OVERLAPPING
532 {
533 sector1Bwps = CcBwpCreator::GetAllBwps({band0});
534 sector2Bwps = CcBwpCreator::GetAllBwps({band0});
535 sector3Bwps = CcBwpCreator::GetAllBwps({band0});
536 }
537
538 /*
539 * Now, we can setup the attributes. We can have three kind of attributes:
540 * (i) parameters that are valid for all the bandwidth parts and applies to
541 * all nodes, (ii) parameters that are valid for all the bandwidth parts
542 * and applies to some node only, and (iii) parameters that are different for
543 * every bandwidth parts. The approach is:
544 *
545 * - for (i): Configure the attribute through the helper, and then install;
546 * - for (ii): Configure the attribute through the helper, and then install
547 * for the first set of nodes. Then, change the attribute through the helper,
548 * and install again;
549 * - for (iii): Install, and then configure the attributes by retrieving
550 * the pointer needed, and calling "SetAttribute" on top of such pointer.
551 *
552 */
553
554 /*
555 * Case (i): Attributes valid for all the nodes
556 */
557 // Beamforming method
558
559 if (radioNetwork == "LTE" && calibration)
560 {
561 idealBeamformingHelper->SetAttribute(
562 "BeamformingMethod",
564 }
565 else if (radioNetwork == "NR")
566 {
567 idealBeamformingHelper->SetAttribute("BeamformingMethod",
568 TypeIdValue(DirectPathBeamforming::GetTypeId()));
569 }
570
571 // Scheduler type
572
573 if (scheduler == "PF")
574 {
575 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaPF"));
576 }
577 else if (scheduler == "RR")
578 {
579 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaRR"));
580 }
581
582 // configure SRS symbols
583 nrHelper->SetSchedulerAttribute("SrsSymbols", UintegerValue(1));
584 nrHelper->SetSchedulerAttribute("EnableSrsInUlSlots", BooleanValue(false));
585 nrHelper->SetSchedulerAttribute("EnableSrsInFSlots", BooleanValue(false));
586
587 // configure CTRL symbols
588 nrHelper->SetSchedulerAttribute("DlCtrlSymbols", UintegerValue(1));
589
590 // Core latency
591 nrEpcHelper->SetAttribute("S1uLinkDelay", TimeValue(MilliSeconds(0)));
592
593 // Antennas for all the UEs
594 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(1));
595 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(1));
596 Ptr<IsotropicAntennaModel> ueIsotropicAntenna = CreateObject<IsotropicAntennaModel>();
597 ueIsotropicAntenna->SetAttribute("Gain", DoubleValue(0.0));
598 nrHelper->SetUeAntennaAttribute("AntennaElement", PointerValue(ueIsotropicAntenna));
599
600 // Antennas for all the gNbs
601 if (calibration)
602 {
603 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(1));
604 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(1));
605 }
606 else
607 {
608 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(5));
609 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(2));
610 }
611
612 nrHelper->SetGnbAntennaAttribute("AntennaElement",
613 PointerValue(CreateObject<ThreeGppAntennaModel>()));
614 nrHelper->SetGnbAntennaAttribute("DowntiltAngle", DoubleValue(downtiltAngle * M_PI / 180.0));
615
616 // UE transmit power
617 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(23.0));
618
619 // Set LTE RBG size
620 // TODO: What these values would be in TDD? bandwidthMhz refers to FDD.
621 // for example, for TDD, if we have bandwidthMhz to 20, we will have a 40 MHz
622 // BWP.
623 if (radioNetwork == "LTE")
624 {
625 switch (bandwidthMHz)
626 {
627 case 20:
628 case 15:
629 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(4));
630 break;
631 case 10:
632 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(3));
633 break;
634 case 5:
635 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(2));
636 break;
637 default:
638 NS_ABORT_MSG("Currently, only supported bandwidths are 5, 10, 15, and 20MHz, you chose "
639 << bandwidthMHz);
640 }
641 }
642
643 // We assume a common traffic pattern for all UEs
644 uint32_t bwpIdForLowLat = 0;
645 if (operationMode == "FDD" && direction == "UL")
646 {
647 bwpIdForLowLat = 1;
648 }
649
650 // gNb routing between Bearer and bandwidth part
651 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
652 UintegerValue(bwpIdForLowLat));
653
654 // Ue routing between Bearer and bandwidth part
655 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
656 UintegerValue(bwpIdForLowLat));
657
658 /*
659 * We miss many other parameters. By default, not configuring them is equivalent
660 * to use the default values. Please, have a look at the documentation to see
661 * what are the default values for all the attributes you are not seeing here.
662 */
663
664 /*
665 * Case (ii): Attributes valid for a subset of the nodes
666 */
667
668 // NOT PRESENT IN THIS SIMPLE EXAMPLE
669
670 /*
671 * We have configured the attributes we needed. Now, install and get the pointers
672 * to the NetDevices, which contains all the NR stack:
673 */
674
675 // NetDeviceContainer gnbNetDev = nrHelper->InstallGnbDevice (gridScenario.GetBaseStations (),
676 // allBwps);
677 gnbSector1NetDev = nrHelper->InstallGnbDevice(gnbSector1Container, sector1Bwps);
678 NetDeviceContainer gnbNetDevs(gnbSector1NetDev);
679 gnbSector2NetDev = nrHelper->InstallGnbDevice(gnbSector2Container, sector2Bwps);
680 gnbNetDevs.Add(gnbSector2NetDev);
681 gnbSector3NetDev = nrHelper->InstallGnbDevice(gnbSector3Container, sector3Bwps);
682 gnbNetDevs.Add(gnbSector3NetDev);
683 ueSector1NetDev = nrHelper->InstallUeDevice(ueSector1Container, sector1Bwps);
684 NetDeviceContainer ueNetDevs(ueSector1NetDev);
685 ueSector2NetDev = nrHelper->InstallUeDevice(ueSector2Container, sector2Bwps);
686 ueNetDevs.Add(ueSector2NetDev);
687 ueSector3NetDev = nrHelper->InstallUeDevice(ueSector3Container, sector3Bwps);
688 ueNetDevs.Add(ueSector3NetDev);
689
690 int64_t randomStream = 1;
691 randomStream += nrHelper->AssignStreams(gnbSector1NetDev, randomStream);
692 randomStream += nrHelper->AssignStreams(gnbSector2NetDev, randomStream);
693 randomStream += nrHelper->AssignStreams(gnbSector3NetDev, randomStream);
694 randomStream += nrHelper->AssignStreams(ueSector1NetDev, randomStream);
695 randomStream += nrHelper->AssignStreams(ueSector2NetDev, randomStream);
696 randomStream += nrHelper->AssignStreams(ueSector3NetDev, randomStream);
697
698 /*
699 * Case (iii): Go node for node and change the attributes we have to setup
700 * per-node.
701 */
702
703 // Sectors (cells) of a site are pointing at different directions
704 std::vector<double> sectorOrientationRad{
705 sector0AngleRad,
706 sector0AngleRad + 2.0 * M_PI / 3.0, // + 120 deg
707 sector0AngleRad - 2.0 * M_PI / 3.0 // - 120 deg
708 };
709
710 for (uint32_t cellId = 0; cellId < gnbNetDevs.GetN(); ++cellId)
711 {
712 Ptr<NetDevice> gnb = gnbNetDevs.Get(cellId);
713 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
714 if (numBwps > 2)
715 {
716 NS_ABORT_MSG("Incorrect number of BWPs per CC");
717 }
718
719 uint32_t sector = cellId % (gnbSector3NetDev.GetN() == 0 ? 1 : 3);
720 double orientation = sectorOrientationRad[sector];
721
722 // First BWP (in case of FDD) or only BWP (in case of TDD)
723 ConfigurePhy(nrHelper, gnb, orientation, numerology, txPowerBs, pattern, 0);
724
725 if (numBwps == 2) // FDD
726 {
727 ConfigurePhy(nrHelper, gnb, orientation, numerology, txPowerBs, pattern, 1);
728 // Link the two FDD BWP
729 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
730 }
731 }
732
733 // Set the UE routing:
734 for (auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
735 {
736 auto uePhyFirst = nrHelper->GetUePhy(*nd, 0);
737 auto uePhySecond{uePhyFirst};
738 if (operationMode == "FDD")
739 {
740 nrHelper->GetBwpManagerUe(*nd)->SetOutputLink(0, 1);
741 uePhySecond = nrHelper->GetUePhy(*nd, 1);
742 uePhySecond->SetUplinkPowerControl(uePhyFirst->GetUplinkPowerControl());
743 }
744 uePhyFirst->TraceConnectWithoutContext("DlDataSinr",
745 MakeBoundCallback(&ReportSinrNr, sinrStats));
746 uePhySecond->TraceConnectWithoutContext("ReportPowerSpectralDensity",
747 MakeBoundCallback(&ReportPowerNr, ueTxPowerStats));
748 }
749
750 for (auto nd = gnbNetDevs.Begin(); nd != gnbNetDevs.End(); ++nd)
751 {
752 uint32_t bwpId = 0;
753 if (operationMode == "FDD" && direction == "UL")
754 {
755 bwpId = 1;
756 }
757 auto gnbPhy = nrHelper->GetGnbPhy(*nd, bwpId);
758 gnbPhy->TraceConnectWithoutContext("SlotDataStats",
759 MakeBoundCallback(&ReportSlotStatsNr, slotStats));
760 gnbPhy->TraceConnectWithoutContext("RBDataStats",
761 MakeBoundCallback(&ReportRbStatsNr, rbStats));
762 gnbPhy->GetSpectrumPhy()->TraceConnectWithoutContext(
763 "RxDataTrace",
764 MakeBoundCallback(&ReportGnbRxDataNr, gnbRxPowerStats));
765 }
766}
767
768} // namespace ns3
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.
static void SetLenaV2SimulatorParameters(const double sector0AngleRad, const std::string &scenario, const std::string &confType, const std::string &radioNetwork, std::string errorModel, const std::string &operationMode, const std::string &direction, uint16_t numerology, const std::string &pattern, const NodeContainer &gnbSector1Container, const NodeContainer &gnbSector2Container, const NodeContainer &gnbSector3Container, const NodeContainer &ueSector1Container, const NodeContainer &ueSector2Container, const NodeContainer &ueSector3Container, const Ptr< NrPointToPointEpcHelper > &baseEpcHelper, Ptr< NrHelper > &nrHelper, NetDeviceContainer &gnbSector1NetDev, NetDeviceContainer &gnbSector2NetDev, NetDeviceContainer &gnbSector3NetDev, NetDeviceContainer &ueSector1NetDev, NetDeviceContainer &ueSector2NetDev, NetDeviceContainer &ueSector3NetDev, bool enableFading, bool enableUlPc, std::string powerAllocation, SinrOutputStats *sinrStats, PowerOutputStats *ueTxPowerStats, PowerOutputStats *gnbRxPowerStats, SlotOutputStats *slotStats, RbOutputStats *rbStats, const std::string &scheduler, uint32_t bandwidthMHz, double startingFreq, uint32_t freqScenario, double gnbTxPower, double ueTxPower, double downtiltAngle, const uint32_t gnbNumRows, const uint32_t gnbNumColumns, const uint32_t ueNumRows, const uint32_t ueNumColumns, bool gnbEnable3gppElement, bool ueEnable3gppElement, const double gnbHSpacing, const double gnbVSpacing, const double ueHSpacing, const double ueVSpacing, const double gnbNoiseFigure, const double ueNoiseFigure, bool enableRealBF, bool enableShadowing, double o2iThreshold, double o2iLowLossThreshold, bool linkO2iConditionToAntennaHeight, bool crossPolarizedGnb, bool crossPolarizedUe, double polSlantAngleGnb1, double polSlantAngleGnb2, double polSlantAngleUe1, double polSlantAngleUe2, std::string bfMethod, uint16_t beamConfSector, double beamConfElevation, double isd, bool ueBearingAngle)
@ ShannonModel
Shannon based model (very conservative)
Definition nr-amc.h:80
@ INIT_PROPAGATION
Initialize the propagation loss model.
Class to collect and store the transmission power values obtained from a simulation.
Class to collect and store the Resource Block statistics from a simulation.
Class to collect and store the SINR values obtained from a simulation.
Class to collect and store the SINR values obtained from a simulation.
std::unique_ptr< BandwidthPartInfo > BandwidthPartInfoPtr
unique_ptr of BandwidthPartInfo
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
uint8_t m_numBwp
Number of BWP per CC.
Operation band information structure.
std::vector< ComponentCarrierInfoPtr > m_cc
Operation band component carriers.
uint8_t m_bandId
Operation band id.