5G-LENA nr-v3.1-69-g2dd513a7
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 */
218
219 nrHelper = CreateObject<NrHelper>();
220
221 Ptr<IdealBeamformingHelper> idealBeamformingHelper;
222
223 // in LTE non-calibration we want to use predefined beams that we set directly
224 // through beam manager. Hence, we do not need any ideal algorithm.
225 // For other cases, we need it (and the beam will be overwritten)
226 if (radioNetwork == "NR" || calibration)
227 {
228 idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
229 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
230 }
231
232 Ptr<NrPointToPointEpcHelper> nrEpcHelper = DynamicCast<NrPointToPointEpcHelper>(baseEpcHelper);
233 nrHelper->SetEpcHelper(nrEpcHelper);
234
235 double txPowerBs = 0.0;
236
238 if (scenario == "UMi")
239 {
240 txPowerBs = 30;
242 }
243 else if (scenario == "UMa")
244 {
245 txPowerBs = 43;
247 }
248 else if (scenario == "RMa")
249 {
250 txPowerBs = 43;
252 }
253 else
254 {
255 NS_ABORT_MSG("Unsupported scenario " << scenario << ". Supported values: UMi, UMa, RMa");
256 }
257
258 /*
259 * Attributes of ThreeGppChannelModel still cannot be set in our way.
260 * TODO: Coordinate with Tommaso
261 */
262 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(100)));
263 nrHelper->SetChannelConditionModelAttribute("UpdatePeriod", TimeValue(MilliSeconds(0)));
264
265 // Disable shadowing in calibration, and enable it in non-calibration mode
266 nrHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(!calibration));
267
268 // Noise figure for the UE
269 nrHelper->SetUePhyAttribute("NoiseFigure", DoubleValue(9.0));
270 nrHelper->SetUePhyAttribute("EnableUplinkPowerControl", BooleanValue(enableUlPc));
271
272 NrSpectrumValueHelper::PowerAllocationType powerAllocationEnum;
273 if (powerAllocation == "UniformPowerAllocBw")
274 {
275 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW;
276 }
277 else if (powerAllocation == "UniformPowerAllocUsed")
278 {
279 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED;
280 }
281 else
282 {
283 NS_ABORT_MSG("Unsupported power allocation type "
284 << scenario
285 << ". Supported values: "
286 "UniformPowerAllocBw and UniformPowerAllocUsed.");
287 }
288
289 nrHelper->SetUePhyAttribute("PowerAllocationType", EnumValue(powerAllocationEnum));
290 // to match LENA default settings
291 nrHelper->SetGnbPhyAttribute("PowerAllocationType",
292 EnumValue(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW));
293
294 // Error Model: UE and GNB with same spectrum error model.
295 nrHelper->SetUlErrorModel(errorModel);
296 nrHelper->SetDlErrorModel(errorModel);
297
298 // Both DL and UL AMC will have the same model behind.
299 nrHelper->SetGnbDlAmcAttribute("AmcModel", EnumValue(NrAmc::ShannonModel));
300 nrHelper->SetGnbUlAmcAttribute("AmcModel", EnumValue(NrAmc::ShannonModel));
301
302 /*
303 * Adjust the average number of Reference symbols per RB only for LTE case,
304 * which is larger than in NR. We assume a value of 4 (could be 3 too).
305 */
306 nrHelper->SetGnbDlAmcAttribute("NumRefScPerRb", UintegerValue(numScPerRb));
307 nrHelper->SetGnbUlAmcAttribute("NumRefScPerRb", UintegerValue(1)); // FIXME: Might change in LTE
308
309 nrHelper->SetGnbPhyAttribute("RbOverhead", DoubleValue(rbOverhead));
310 nrHelper->SetGnbPhyAttribute("N2Delay", UintegerValue(n2Delay));
311 nrHelper->SetGnbPhyAttribute("N1Delay", UintegerValue(n1Delay));
312
313 nrHelper->SetUeMacAttribute("NumHarqProcess", UintegerValue(harqProcesses));
314 nrHelper->SetGnbMacAttribute("NumHarqProcess", UintegerValue(harqProcesses));
315
316 /*
317 * Create the necessary operation bands.
318 *
319 * In the 0 frequency scenario, each sector operates, in a separate band,
320 * while for scenario 1 all the sectors are in the same band. Please note that
321 * a single BWP in FDD is half the size of the corresponding TDD BWP, and the
322 * parameter bandwidthMHz refers to the size of the FDD BWP.
323 *
324 * Scenario 0: sectors NON_OVERLAPPING in frequency
325 *
326 * FDD scenario 0:
327 *
328 * |--------Band0--------|--------Band1--------|--------Band2--------|
329 * |---------CC0---------|---------CC1---------|---------CC2---------|
330 * |---BWP0---|---BWP1---|---BWP2---|---BWP3---|---BWP4---|---BWP5---|
331 *
332 * Sector i will go in Bandi
333 * DL in the first BWP, UL in the second BWP
334 *
335 * TDD scenario 0:
336 *
337 * |--------Band0--------|--------Band1--------|--------Band2--------|
338 * |---------CC0---------|---------CC2---------|---------CC2---------|
339 * |---------BWP0--------|---------BWP1--------|---------BWP2--------|
340 *
341 * Sector i will go in BWPi
342 *
343 *
344 * Scenario 1: sectors in OVERLAPPING bands
345 *
346 * Note that this configuration has 1/3 the total bandwidth of the
347 * NON_OVERLAPPING configuration.
348 *
349 * FDD scenario 1:
350 *
351 * |--------Band0--------|
352 * |---------CC0---------|
353 * |---BWP0---|---BWP1---|
354 *
355 * Sector i will go in BWPi
356 *
357 * TDD scenario 1:
358 *
359 * |--------Band0--------|
360 * |---------CC0---------|
361 * |---------BWP0--------|
362 *
363 * This is tightly coupled with what happens in lena-v1-utils.cc
364 *
365 */
366 // \todo: set band 0 start frequency from the command line
367 const double band0Start = 2110e6;
368 double bandwidthBwp = bandwidthMHz * 1e6;
369
370 OperationBandInfo band0;
371 OperationBandInfo band1;
372 OperationBandInfo band2;
373 band0.m_bandId = 0;
374 band1.m_bandId = 1;
375 band2.m_bandId = 2;
376
377 if (freqScenario == 0) // NON_OVERLAPPING
378 {
379 uint8_t numBwp;
380
381 if (operationMode == "FDD")
382 {
383 // FDD uses two BWPs per CC, one CC per band
384 numBwp = 2;
385 }
386 else // if (operationMode = "TDD")
387 {
388 // Use double with BWP, to match total bandwidth for FDD in UL and DL
389 bandwidthBwp *= 2;
390 numBwp = 1;
391 }
392
393 double bandwidthCc = numBwp * bandwidthBwp;
394 uint8_t numCcPerBand = 1;
395 double bandwidthBand = numCcPerBand * bandwidthCc;
396 double bandCenter = band0Start + bandwidthBand / 2.0;
397
398 NS_LOG_LOGIC("NON_OVERLAPPING, " << operationMode << ": " << bandwidthBand << ":"
399 << bandwidthCc << ":" << bandwidthBwp << ", "
400 << (int)numCcPerBand << ", " << (int)numBwp);
401
402 NS_LOG_LOGIC("bandConf0: " << bandCenter << " " << bandwidthBand);
403 CcBwpCreator::SimpleOperationBandConf bandConf0(bandCenter,
404 bandwidthBand,
405 numCcPerBand,
406 scene);
407 bandConf0.m_numBwp = numBwp;
408 bandCenter += bandwidthBand;
409
410 NS_LOG_LOGIC("bandConf1: " << bandCenter << " " << bandwidthBand);
411 CcBwpCreator::SimpleOperationBandConf bandConf1(bandCenter,
412 bandwidthBand,
413 numCcPerBand,
414 scene);
415 bandConf1.m_numBwp = numBwp;
416 bandCenter += bandwidthBand;
417
418 NS_LOG_LOGIC("bandConf2: " << bandCenter << " " << bandwidthBand);
419 CcBwpCreator::SimpleOperationBandConf bandConf2(bandCenter,
420 bandwidthBand,
421 numCcPerBand,
422 scene);
423 bandConf2.m_numBwp = numBwp;
424
425 // Create, then configure
426 CcBwpCreator ccBwpCreator;
427 band0 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf0);
428 band0.m_bandId = 0;
429
430 band1 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf1);
431 band1.m_bandId = 1;
432
433 band2 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf2);
434 band2.m_bandId = 2;
435
436 bandCenter = band0Start + bandwidthBwp / 2.0;
437
438 NS_LOG_LOGIC("band0[0][0]: " << bandCenter << " " << bandwidthBwp);
439 ConfigureBwpTo(band0.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
440 bandCenter += bandwidthBwp;
441
442 if (operationMode == "FDD")
443 {
444 NS_LOG_LOGIC("band0[0][1]: " << bandCenter << " " << bandwidthBwp);
445 ConfigureBwpTo(band0.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
446 bandCenter += bandwidthBwp;
447 }
448
449 NS_LOG_LOGIC("band1[0][0]: " << bandCenter << " " << bandwidthBwp);
450 ConfigureBwpTo(band1.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
451 bandCenter += bandwidthBwp;
452
453 if (operationMode == "FDD")
454 {
455 NS_LOG_LOGIC("band1[0][1]: " << bandCenter << " " << bandwidthBwp);
456 ConfigureBwpTo(band1.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
457 bandCenter += bandwidthBwp;
458 }
459
460 NS_LOG_LOGIC("band2[0][0]: " << bandCenter << " " << bandwidthBwp);
461 ConfigureBwpTo(band2.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
462 bandCenter += bandwidthBwp;
463
464 if (operationMode == "FDD")
465 {
466 NS_LOG_LOGIC("band2[0][1]: " << bandCenter << " " << bandwidthBwp);
467 ConfigureBwpTo(band2.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
468 }
469
470 std::cout << "BWP Configuration for NON_OVERLAPPING case, mode " << operationMode << "\n"
471 << band0 << band1 << band2;
472 }
473
474 else if (freqScenario == 1) // OVERLAPPING
475 {
476 uint8_t numBwp;
477
478 if (operationMode == "FDD")
479 {
480 // FDD uses two BWPs per CC, one CC per band
481 numBwp = 2;
482 }
483 else // if (operationMode = "TDD")
484 {
485 // Use double with BWP, to match total bandwidth for FDD in UL and DL
486 bandwidthBwp *= 2;
487 numBwp = 1;
488 }
489
490 double bandwidthCc = numBwp * bandwidthBwp;
491 uint8_t numCcPerBand = 1;
492 double bandwidthBand = numCcPerBand * bandwidthCc;
493 double bandCenter = band0Start + bandwidthBand / 2.0;
494
495 NS_LOG_LOGIC("OVERLAPPING, " << operationMode << ": " << bandwidthBand << ":" << bandwidthCc
496 << ":" << bandwidthBwp << ", " << (int)numCcPerBand << ", "
497 << (int)numBwp);
498
499 NS_LOG_LOGIC("bandConf0: " << bandCenter << " " << bandwidthBand);
500 CcBwpCreator::SimpleOperationBandConf bandConf0(bandCenter,
501 bandwidthBand,
502 numCcPerBand,
503 scene);
504 bandConf0.m_numBwp = numBwp;
505 bandCenter += bandwidthBand;
506
507 // Create, then configure
508 CcBwpCreator ccBwpCreator;
509 band0 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf0);
510 band0.m_bandId = 0;
511
512 bandCenter = band0Start + bandwidthBwp / 2.0;
513
514 NS_LOG_LOGIC("band0[0][0]: " << bandCenter << " " << bandwidthBwp);
515 ConfigureBwpTo(band0.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
516 bandCenter += bandwidthBwp;
517
518 if (operationMode == "FDD")
519 {
520 NS_LOG_LOGIC("band0[0][1]: " << bandCenter << " " << bandwidthBwp);
521 ConfigureBwpTo(band0.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
522 }
523
524 std::cout << "BWP Configuration for OVERLAPPING case, mode " << operationMode << "\n"
525 << band0;
526 }
527
528 else
529 {
530 std::cerr << "unknown combination of freqScenario = " << freqScenario
531 << " and operationMode = " << operationMode << std::endl;
532 exit(1);
533 }
534
536 // Omit fading from calibration mode
537 if (!calibration)
538 {
539 bandMask |= NrHelper::INIT_FADING;
540 }
541 nrHelper->InitializeOperationBand(&band0, bandMask);
542 nrHelper->InitializeOperationBand(&band1, bandMask);
543 nrHelper->InitializeOperationBand(&band2, bandMask);
544
545 BandwidthPartInfoPtrVector sector1Bwps;
546 BandwidthPartInfoPtrVector sector2Bwps;
547 BandwidthPartInfoPtrVector sector3Bwps;
548 if (freqScenario == 0) // NON_OVERLAPPING
549 {
550 sector1Bwps = CcBwpCreator::GetAllBwps({band0});
551 sector2Bwps = CcBwpCreator::GetAllBwps({band1});
552 sector3Bwps = CcBwpCreator::GetAllBwps({band2});
553 }
554 else // OVERLAPPING
555 {
556 sector1Bwps = CcBwpCreator::GetAllBwps({band0});
557 sector2Bwps = CcBwpCreator::GetAllBwps({band0});
558 sector3Bwps = CcBwpCreator::GetAllBwps({band0});
559 }
560
561 /*
562 * Now, we can setup the attributes. We can have three kind of attributes:
563 * (i) parameters that are valid for all the bandwidth parts and applies to
564 * all nodes, (ii) parameters that are valid for all the bandwidth parts
565 * and applies to some node only, and (iii) parameters that are different for
566 * every bandwidth parts. The approach is:
567 *
568 * - for (i): Configure the attribute through the helper, and then install;
569 * - for (ii): Configure the attribute through the helper, and then install
570 * for the first set of nodes. Then, change the attribute through the helper,
571 * and install again;
572 * - for (iii): Install, and then configure the attributes by retrieving
573 * the pointer needed, and calling "SetAttribute" on top of such pointer.
574 *
575 */
576
577 /*
578 * Case (i): Attributes valid for all the nodes
579 */
580 // Beamforming method
581
582 if (radioNetwork == "LTE" && calibration)
583 {
584 idealBeamformingHelper->SetAttribute(
585 "BeamformingMethod",
587 }
588 else if (radioNetwork == "NR")
589 {
590 idealBeamformingHelper->SetAttribute("BeamformingMethod",
591 TypeIdValue(DirectPathBeamforming::GetTypeId()));
592 }
593
594 // Scheduler type
595
596 if (scheduler == "PF")
597 {
598 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaPF"));
599 }
600 else if (scheduler == "RR")
601 {
602 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaRR"));
603 }
604
605 // configure SRS symbols
606 nrHelper->SetSchedulerAttribute("SrsSymbols", UintegerValue(1));
607 nrHelper->SetSchedulerAttribute("EnableSrsInUlSlots", BooleanValue(false));
608 nrHelper->SetSchedulerAttribute("EnableSrsInFSlots", BooleanValue(false));
609
610 // configure CTRL symbols
611 nrHelper->SetSchedulerAttribute("DlCtrlSymbols", UintegerValue(1));
612
613 // Core latency
614 nrEpcHelper->SetAttribute("S1uLinkDelay", TimeValue(MilliSeconds(0)));
615
616 // Antennas for all the UEs
617 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(1));
618 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(1));
619 Ptr<IsotropicAntennaModel> ueIsotropicAntenna = CreateObject<IsotropicAntennaModel>();
620 ueIsotropicAntenna->SetAttribute("Gain", DoubleValue(0.0));
621 nrHelper->SetUeAntennaAttribute("AntennaElement", PointerValue(ueIsotropicAntenna));
622
623 // Antennas for all the gNbs
624 if (calibration)
625 {
626 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(1));
627 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(1));
628 }
629 else
630 {
631 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(5));
632 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(2));
633 }
634
635 nrHelper->SetGnbAntennaAttribute("AntennaElement",
636 PointerValue(CreateObject<ThreeGppAntennaModel>()));
637 nrHelper->SetGnbAntennaAttribute("DowntiltAngle", DoubleValue(downtiltAngle * M_PI / 180.0));
638
639 // UE transmit power
640 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(23.0));
641
642 // Set LTE RBG size
643 // TODO: What these values would be in TDD? bandwidthMhz refers to FDD.
644 // for example, for TDD, if we have bandwidthMhz to 20, we will have a 40 MHz
645 // BWP.
646 if (radioNetwork == "LTE")
647 {
648 switch (bandwidthMHz)
649 {
650 case 20:
651 case 15:
652 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(4));
653 break;
654 case 10:
655 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(3));
656 break;
657 case 5:
658 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(2));
659 break;
660 default:
661 NS_ABORT_MSG("Currently, only supported bandwidths are 5, 10, 15, and 20MHz, you chose "
662 << bandwidthMHz);
663 }
664 }
665
666 // We assume a common traffic pattern for all UEs
667 uint32_t bwpIdForLowLat = 0;
668 if (operationMode == "FDD" && direction == "UL")
669 {
670 bwpIdForLowLat = 1;
671 }
672
673 // gNb routing between Bearer and bandwidth part
674 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
675 UintegerValue(bwpIdForLowLat));
676
677 // Ue routing between Bearer and bandwidth part
678 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
679 UintegerValue(bwpIdForLowLat));
680
681 /*
682 * We miss many other parameters. By default, not configuring them is equivalent
683 * to use the default values. Please, have a look at the documentation to see
684 * what are the default values for all the attributes you are not seeing here.
685 */
686
687 /*
688 * Case (ii): Attributes valid for a subset of the nodes
689 */
690
691 // NOT PRESENT IN THIS SIMPLE EXAMPLE
692
693 /*
694 * We have configured the attributes we needed. Now, install and get the pointers
695 * to the NetDevices, which contains all the NR stack:
696 */
697
698 // NetDeviceContainer gnbNetDev = nrHelper->InstallGnbDevice (gridScenario.GetBaseStations (),
699 // allBwps);
700 gnbSector1NetDev = nrHelper->InstallGnbDevice(gnbSector1Container, sector1Bwps);
701 NetDeviceContainer gnbNetDevs(gnbSector1NetDev);
702 gnbSector2NetDev = nrHelper->InstallGnbDevice(gnbSector2Container, sector2Bwps);
703 gnbNetDevs.Add(gnbSector2NetDev);
704 gnbSector3NetDev = nrHelper->InstallGnbDevice(gnbSector3Container, sector3Bwps);
705 gnbNetDevs.Add(gnbSector3NetDev);
706 ueSector1NetDev = nrHelper->InstallUeDevice(ueSector1Container, sector1Bwps);
707 NetDeviceContainer ueNetDevs(ueSector1NetDev);
708 ueSector2NetDev = nrHelper->InstallUeDevice(ueSector2Container, sector2Bwps);
709 ueNetDevs.Add(ueSector2NetDev);
710 ueSector3NetDev = nrHelper->InstallUeDevice(ueSector3Container, sector3Bwps);
711 ueNetDevs.Add(ueSector3NetDev);
712
713 int64_t randomStream = 1;
714 randomStream += nrHelper->AssignStreams(gnbSector1NetDev, randomStream);
715 randomStream += nrHelper->AssignStreams(gnbSector2NetDev, randomStream);
716 randomStream += nrHelper->AssignStreams(gnbSector3NetDev, randomStream);
717 randomStream += nrHelper->AssignStreams(ueSector1NetDev, randomStream);
718 randomStream += nrHelper->AssignStreams(ueSector2NetDev, randomStream);
719 randomStream += nrHelper->AssignStreams(ueSector3NetDev, randomStream);
720
721 /*
722 * Case (iii): Go node for node and change the attributes we have to setup
723 * per-node.
724 */
725
726 // Sectors (cells) of a site are pointing at different directions
727 std::vector<double> sectorOrientationRad{
728 sector0AngleRad,
729 sector0AngleRad + 2.0 * M_PI / 3.0, // + 120 deg
730 sector0AngleRad - 2.0 * M_PI / 3.0 // - 120 deg
731 };
732
733 for (uint32_t cellId = 0; cellId < gnbNetDevs.GetN(); ++cellId)
734 {
735 Ptr<NetDevice> gnb = gnbNetDevs.Get(cellId);
736 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
737 if (numBwps > 2)
738 {
739 NS_ABORT_MSG("Incorrect number of BWPs per CC");
740 }
741
742 uint32_t sector = cellId % (gnbSector3NetDev.GetN() == 0 ? 1 : 3);
743 double orientation = sectorOrientationRad[sector];
744
745 // First BWP (in case of FDD) or only BWP (in case of TDD)
746 ConfigurePhy(nrHelper, gnb, orientation, numerology, txPowerBs, pattern, 0);
747
748 if (numBwps == 2) // FDD
749 {
750 ConfigurePhy(nrHelper, gnb, orientation, numerology, txPowerBs, pattern, 1);
751 // Link the two FDD BWP
752 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
753 }
754 }
755
756 // Set the UE routing:
757 for (auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
758 {
759 auto uePhyFirst = nrHelper->GetUePhy(*nd, 0);
760 auto uePhySecond{uePhyFirst};
761 if (operationMode == "FDD")
762 {
763 nrHelper->GetBwpManagerUe(*nd)->SetOutputLink(0, 1);
764 uePhySecond = nrHelper->GetUePhy(*nd, 1);
765 uePhySecond->SetUplinkPowerControl(uePhyFirst->GetUplinkPowerControl());
766 }
767 uePhyFirst->TraceConnectWithoutContext("DlDataSinr",
768 MakeBoundCallback(&ReportSinrNr, sinrStats));
769 uePhySecond->TraceConnectWithoutContext("ReportPowerSpectralDensity",
770 MakeBoundCallback(&ReportPowerNr, ueTxPowerStats));
771 }
772
773 // When all the configuration is done, explicitly call UpdateConfig ()
774 for (auto nd = gnbNetDevs.Begin(); nd != gnbNetDevs.End(); ++nd)
775 {
776 uint32_t bwpId = 0;
777 if (operationMode == "FDD" && direction == "UL")
778 {
779 bwpId = 1;
780 }
781 auto gnbPhy = nrHelper->GetGnbPhy(*nd, bwpId);
782 gnbPhy->TraceConnectWithoutContext("SlotDataStats",
783 MakeBoundCallback(&ReportSlotStatsNr, slotStats));
784 gnbPhy->TraceConnectWithoutContext("RBDataStats",
785 MakeBoundCallback(&ReportRbStatsNr, rbStats));
786 gnbPhy->GetSpectrumPhy()->TraceConnectWithoutContext(
787 "RxDataTrace",
788 MakeBoundCallback(&ReportGnbRxDataNr, gnbRxPowerStats));
789
790 DynamicCast<NrGnbNetDevice>(*nd)->UpdateConfig();
791 }
792
793 for (auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
794 {
795 DynamicCast<NrUeNetDevice>(*nd)->UpdateConfig();
796 }
797}
798
799} // 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:86
@ INIT_PROPAGATION
Initialize the propagation loss model.
Definition nr-helper.h:371
@ INIT_FADING
Initialize the fading model.
Definition nr-helper.h:372
@ INIT_CHANNEL
Initialize the channel model.
Definition nr-helper.h:373
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
Scenario
Different types for the propagation loss model of this bandwidth part.
@ UMa_LoS
UMa where all the nodes will be in Line-of-Sight.
@ RMa_LoS
RMa where all the nodes will be in Line-of-Sight.
@ UMi_StreetCanyon_LoS
UMi_StreetCanyon where all the nodes will be in Line-of-Sight.
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.