5G-LENA nr-v3.1-69-g2dd513a7
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
cttc-nr-3gpp-calibration-utils-v2.cc
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "cttc-nr-3gpp-calibration-utils-v2.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/log.h"
13#include <ns3/antenna-module.h>
14#include <ns3/config.h>
15#include <ns3/enum.h>
16#include <ns3/nr-spectrum-value-helper.h>
17#include <ns3/object-vector.h>
18#include <ns3/pointer.h>
19
20NS_LOG_COMPONENT_DEFINE("LenaV2Utils");
21
22namespace ns3
23{
24
25void
26LenaV2Utils::ReportSinrNr(SinrOutputStats* stats,
27 uint16_t cellId,
28 uint16_t rnti,
29 double avgSinr,
30 uint16_t bwpId)
31{
32 stats->SaveSinr(cellId, rnti, avgSinr, bwpId);
33}
34
35void
36LenaV2Utils::ReportPowerNr(PowerOutputStats* stats,
37 const SfnSf& sfnSf,
38 Ptr<const SpectrumValue> txPsd,
39 const Time& t,
40 uint16_t rnti,
41 uint64_t imsi,
42 uint16_t bwpId,
43 uint16_t cellId)
44{
45 stats->SavePower(sfnSf, txPsd, t, rnti, imsi, bwpId, cellId);
46}
47
48void
49LenaV2Utils::ReportSlotStatsNr(SlotOutputStats* stats,
50 const SfnSf& sfnSf,
51 uint32_t scheduledUe,
52 uint32_t usedReg,
53 uint32_t usedSym,
54 uint32_t availableRb,
55 uint32_t availableSym,
56 uint16_t bwpId,
57 uint16_t cellId)
58{
59 stats->SaveSlotStats(sfnSf,
60 scheduledUe,
61 usedReg,
62 usedSym,
63 availableRb,
64 availableSym,
65 bwpId,
66 cellId);
67}
68
69void
70LenaV2Utils::ReportRbStatsNr(RbOutputStats* stats,
71 const SfnSf& sfnSf,
72 uint8_t sym,
73 const std::vector<int>& rbUsed,
74 uint16_t bwpId,
75 uint16_t cellId)
76{
77 stats->SaveRbStats(sfnSf, sym, rbUsed, bwpId, cellId);
78}
79
80void
81LenaV2Utils::ReportGnbRxDataNr(PowerOutputStats* gnbRxDataStats,
82 const SfnSf& sfnSf,
83 Ptr<const SpectrumValue> rxPsd,
84 const Time& t,
85 uint16_t bwpId,
86 uint16_t cellId)
87{
88 gnbRxDataStats->SavePower(sfnSf, rxPsd, t, 0, 0, bwpId, cellId);
89}
90
91void
92LenaV2Utils::ConfigureBwpTo(BandwidthPartInfoPtr& bwp, double centerFreq, double bwpBw)
93{
94 bwp->m_centralFrequency = centerFreq;
95 bwp->m_higherFrequency = centerFreq + (bwpBw / 2);
96 bwp->m_lowerFrequency = centerFreq - (bwpBw / 2);
97 bwp->m_channelBandwidth = bwpBw;
98}
99
100// unnamed namespace
101namespace
102{
103
104void
105ConfigurePhy(Ptr<NrHelper>& nrHelper,
106 Ptr<NetDevice> gnb,
107 double orientationRads,
108 uint16_t numerology,
109 double txPowerBs,
110 const std::string& pattern,
111 uint32_t bwpIndex,
112 double gnbFirstSubArray,
113 double gnbSecondSubArray,
114 uint16_t beamConfSector,
115 double beamConfElevation)
116{
117 // Change the antenna orientation
118 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0); // BWP 0
119 Ptr<UniformPlanarArray> antenna0 = ConstCast<UniformPlanarArray>(
120 phy0->GetSpectrumPhy()->GetAntenna()->GetObject<UniformPlanarArray>());
121 antenna0->SetAttribute("BearingAngle", DoubleValue(orientationRads));
122
123 // configure the beam that points toward the center of hexagonal
124 // In case of beamforming, it will be overwritten.
125 phy0->GetSpectrumPhy()->GetBeamManager()->SetPredefinedBeam(beamConfSector, beamConfElevation);
126
127 // Set numerology
128 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Numerology", UintegerValue(numerology)); // BWP
129
130 // Set TX power
131 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("TxPower", DoubleValue(txPowerBs));
132
133 // Set TDD pattern
134 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Pattern", StringValue(pattern));
135}
136
137} // unnamed namespace
138
139void
140LenaV2Utils::SetLenaV2SimulatorParameters(const double sector0AngleRad,
141 const std::string& scenario,
142 const std::string& confType,
143 const std::string& radioNetwork,
144 std::string errorModel,
145 const std::string& operationMode,
146 const std::string& direction,
147 uint16_t numerology,
148 const std::string& pattern,
149 const NodeContainer& gnbSector1Container,
150 const NodeContainer& gnbSector2Container,
151 const NodeContainer& gnbSector3Container,
152 const NodeContainer& ueSector1Container,
153 const NodeContainer& ueSector2Container,
154 const NodeContainer& ueSector3Container,
155 const Ptr<NrPointToPointEpcHelper>& baseEpcHelper,
156 Ptr<NrHelper>& nrHelper,
157 NetDeviceContainer& gnbSector1NetDev,
158 NetDeviceContainer& gnbSector2NetDev,
159 NetDeviceContainer& gnbSector3NetDev,
160 NetDeviceContainer& ueSector1NetDev,
161 NetDeviceContainer& ueSector2NetDev,
162 NetDeviceContainer& ueSector3NetDev,
163 bool enableFading,
164 bool enableUlPc,
165 std::string powerAllocation,
166 SinrOutputStats* sinrStats,
167 PowerOutputStats* ueTxPowerStats,
168 PowerOutputStats* gnbRxPowerStats,
169 SlotOutputStats* slotStats,
170 RbOutputStats* rbStats,
171 const std::string& scheduler,
172 uint32_t bandwidthMHz,
173 double startingFreq,
174 uint32_t freqScenario,
175 double gnbTxPower,
176 double ueTxPower,
177 double downtiltAngle,
178 const uint32_t gnbNumRows,
179 const uint32_t gnbNumColumns,
180 const uint32_t ueNumRows,
181 const uint32_t ueNumColumns,
182 bool gnbEnable3gppElement,
183 bool ueEnable3gppElement,
184 const double gnbHSpacing,
185 const double gnbVSpacing,
186 const double ueHSpacing,
187 const double ueVSpacing,
188 const double gnbNoiseFigure,
189 const double ueNoiseFigure,
190 bool enableRealBF,
191 bool enableShadowing,
192 double o2iThreshold,
193 double o2iLowLossThreshold,
194 bool linkO2iConditionToAntennaHeight,
195 bool crossPolarizedGnb,
196 bool crossPolarizedUe,
197 double polSlantAngleGnb1,
198 double polSlantAngleGnb2,
199 double polSlantAngleUe1,
200 double polSlantAngleUe2,
201 std::string bfMethod,
202 uint16_t beamConfSector,
203 double beamConfElevation,
204 double isd,
205 bool ueBearingAngle)
206{
207 /*
208 * Create the radio network related parameters
209 */
210 uint8_t numScPerRb = 1;
211 double rbOverhead = 0.1;
212 uint32_t harqProcesses = 20;
213 uint32_t n1Delay = 2;
214 uint32_t n2Delay = 2;
215 uint8_t dlCtrlSymbols = 1;
216
217 if (radioNetwork == "LTE")
218 {
219 rbOverhead = 0.1;
220 harqProcesses = 8;
221 n1Delay = 4;
222 n2Delay = 4;
223 // dlCtrlSymbols = 3;
224
225 if (errorModel.empty())
226 {
227 errorModel = "ns3::LenaErrorModel";
228 }
229 else if (errorModel != "ns3::NrLteMiErrorModel" && errorModel != "ns3::LenaErrorModel")
230 {
231 NS_ABORT_MSG("The selected error model is not recommended for LTE");
232 }
233 }
234 else if (radioNetwork == "NR")
235 {
236 rbOverhead = 0.04;
237 harqProcesses = 20;
238 if (errorModel.empty())
239 {
240 errorModel = "ns3::NrEesmIrT1";
241 }
242 else if (errorModel == "ns3::NrLteMiErrorModel")
243 {
244 NS_ABORT_MSG("The selected error model is not recommended for NR");
245 }
246 }
247 else
248 {
249 NS_ABORT_MSG("Unrecognized radio network technology");
250 }
251
252 /*
253 * Setup the NR module. We create the various helpers needed for the
254 * NR simulation:
255 * - IdealBeamformingHelper, which takes care of the beamforming part
256 * - NrHelper, which takes care of creating and connecting the various
257 * part of the NR stack
258 */
259
260 nrHelper = CreateObject<NrHelper>();
261
262 Ptr<BeamformingHelperBase> beamformingHelper;
263
264 // in LTE non-calibration we want to use predefined beams that we set directly
265 // through beam manager. Hence, we do not need any ideal algorithm.
266 // For other cases, we need it (and the beam will be overwritten)
267
268 if (enableFading && bfMethod != "FixedBeam")
269 {
270 if (radioNetwork == "NR" && enableRealBF)
271 {
272 beamformingHelper = CreateObject<RealisticBeamformingHelper>();
273 }
274 else
275 {
276 beamformingHelper = CreateObject<IdealBeamformingHelper>();
277 }
278 nrHelper->SetBeamformingHelper(beamformingHelper);
279 }
280
281 Ptr<NrPointToPointEpcHelper> nrEpcHelper = DynamicCast<NrPointToPointEpcHelper>(baseEpcHelper);
282 nrHelper->SetEpcHelper(nrEpcHelper);
283
284 double txPowerBs = 0.0;
285
287
288 if (scenario == "UMa")
289 {
291 }
292 else if (scenario == "RMa")
293 {
294 scene = BandwidthPartInfo::RMa;
295 }
296 else if (scenario == "UMi-StreetCanyon")
297 {
299 }
300 else
301 {
302 NS_ABORT_MSG("Unsupported scenario " << scenario
303 << ". Supported values: UMa, RMa, UMi_StreetCanyon");
304 }
305
306 txPowerBs = gnbTxPower;
307 std::cout << "Scenario: " << scenario << "gnbTxPower: " << txPowerBs << std::endl;
308
309 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(100)));
310 nrHelper->SetPhasedArraySpectrumPropagationLossModelTypeId(
311 DistanceBasedThreeGppSpectrumPropagationLossModel::GetTypeId());
312 nrHelper->SetPhasedArraySpectrumPropagationLossModelAttribute("MaxDistance",
313 DoubleValue(2 * isd));
314 nrHelper->SetChannelConditionModelAttribute("UpdatePeriod", TimeValue(MilliSeconds(100)));
315 nrHelper->SetChannelConditionModelAttribute("LinkO2iConditionToAntennaHeight",
316 BooleanValue(linkO2iConditionToAntennaHeight));
317 nrHelper->SetChannelConditionModelAttribute("O2iThreshold", DoubleValue(o2iThreshold));
318 nrHelper->SetChannelConditionModelAttribute("O2iLowLossThreshold",
319 DoubleValue(o2iLowLossThreshold));
320
321 std::cout << "o2iThreshold: " << o2iThreshold << std::endl;
322 std::cout << "o2iLowLossThreshold: " << o2iLowLossThreshold << std::endl;
323
324 nrHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(enableShadowing));
325
326 // Noise figure for the gNB
327 nrHelper->SetGnbPhyAttribute("NoiseFigure", DoubleValue(gnbNoiseFigure));
328 // Noise figure for the UE
329 nrHelper->SetUePhyAttribute("NoiseFigure", DoubleValue(ueNoiseFigure));
330 nrHelper->SetUePhyAttribute("EnableUplinkPowerControl", BooleanValue(enableUlPc));
331
332 if (radioNetwork == "LTE" && confType == "calibrationConf" && enableUlPc)
333 {
334 Config::SetDefault("ns3::NrUePowerControl::ClosedLoop", BooleanValue(false));
335 Config::SetDefault("ns3::NrUePowerControl::PoNominalPucch", IntegerValue(-106));
336 Config::SetDefault("ns3::NrUePowerControl::PoNominalPusch", IntegerValue(-106));
337 Config::SetDefault("ns3::NrUePowerControl::Alpha",
338 DoubleValue(1.0)); // well this is the default value also
339 }
340
341 Config::SetDefault("ns3::NrMacSchedulerSrsDefault::StartingPeriodicity", UintegerValue(16));
342 nrHelper->SetSchedulerAttribute("SrsSymbols", UintegerValue(1));
343
344 NrSpectrumValueHelper::PowerAllocationType powerAllocationEnum;
345 if (powerAllocation == "UniformPowerAllocBw")
346 {
347 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW;
348 }
349 else if (powerAllocation == "UniformPowerAllocUsed")
350 {
351 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED;
352 }
353 else
354 {
355 NS_ABORT_MSG("Unsupported power allocation type "
356 << scenario
357 << ". Supported values: "
358 "UniformPowerAllocBw and UniformPowerAllocUsed.");
359 }
360
361 nrHelper->SetUePhyAttribute("PowerAllocationType", EnumValue(powerAllocationEnum));
362 // to match LENA default settings
363 nrHelper->SetGnbPhyAttribute("PowerAllocationType",
364 EnumValue(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW));
365
366 // Error Model: UE and GNB with same spectrum error model.
367 nrHelper->SetUlErrorModel(errorModel);
368 nrHelper->SetDlErrorModel(errorModel);
369
370 // Both DL and UL AMC will have the same model behind.
371 nrHelper->SetGnbDlAmcAttribute("AmcModel", EnumValue(NrAmc::ShannonModel));
372 nrHelper->SetGnbUlAmcAttribute("AmcModel", EnumValue(NrAmc::ShannonModel));
373
374 /*
375 * Adjust the average number of Reference symbols per RB only for LTE case,
376 * which is larger than in NR. We assume a value of 4 (could be 3 too).
377 */
378 nrHelper->SetGnbDlAmcAttribute("NumRefScPerRb", UintegerValue(numScPerRb));
379 nrHelper->SetGnbUlAmcAttribute("NumRefScPerRb", UintegerValue(1)); // FIXME: Might change in LTE
380
381 nrHelper->SetGnbPhyAttribute("RbOverhead", DoubleValue(rbOverhead));
382 nrHelper->SetGnbPhyAttribute("N2Delay", UintegerValue(n2Delay));
383 nrHelper->SetGnbPhyAttribute("N1Delay", UintegerValue(n1Delay));
384
385 nrHelper->SetUeMacAttribute("NumHarqProcess", UintegerValue(harqProcesses));
386 nrHelper->SetGnbMacAttribute("NumHarqProcess", UintegerValue(harqProcesses));
387
388 /*
389 * Create the necessary operation bands.
390 *
391 * In the 0 frequency scenario, each sector operates, in a separate band,
392 * while for scenario 1 all the sectors are in the same band. Please note that
393 * a single BWP in FDD is half the size of the corresponding TDD BWP, and the
394 * parameter bandwidthMHz refers to the size of the FDD BWP.
395 *
396 * Scenario 0: sectors NON_OVERLAPPING in frequency
397 *
398 * FDD scenario 0:
399 *
400 * |--------Band0--------|--------Band1--------|--------Band2--------|
401 * |---------CC0---------|---------CC1---------|---------CC2---------|
402 * |---BWP0---|---BWP1---|---BWP2---|---BWP3---|---BWP4---|---BWP5---|
403 *
404 * Sector i will go in Bandi
405 * DL in the first BWP, UL in the second BWP
406 *
407 * TDD scenario 0:
408 *
409 * |--------Band0--------|--------Band1--------|--------Band2--------|
410 * |---------CC0---------|---------CC2---------|---------CC2---------|
411 * |---------BWP0--------|---------BWP1--------|---------BWP2--------|
412 *
413 * Sector i will go in BWPi
414 *
415 *
416 * Scenario 1: sectors in OVERLAPPING bands
417 *
418 * Note that this configuration has 1/3 the total bandwidth of the
419 * NON_OVERLAPPING configuration.
420 *
421 * FDD scenario 1:
422 *
423 * |--------Band0--------|
424 * |---------CC0---------|
425 * |---BWP0---|---BWP1---|
426 *
427 * Sector i will go in BWPi
428 *
429 * TDD scenario 1:
430 *
431 * |--------Band0--------|
432 * |---------CC0---------|
433 * |---------BWP0--------|
434 *
435 * This is tightly coupled with what happens in lena-v1-utils.cc
436 *
437 */
438 const double band0Start = startingFreq;
439 double bandwidthBwp = bandwidthMHz * 1e6;
440
441 OperationBandInfo band0;
442 OperationBandInfo band1;
443 OperationBandInfo band2;
444 band0.m_bandId = 0;
445 band1.m_bandId = 1;
446 band2.m_bandId = 2;
447
448 uint8_t numBwp = operationMode == "FDD" ? 2 : 1;
449
450 if (freqScenario == 0) // NON_OVERLAPPING
451 {
452 double bandwidthCc = numBwp * bandwidthBwp;
453 uint8_t numCcPerBand = 1;
454 double bandwidthBand = numCcPerBand * bandwidthCc;
455 double bandCenter = band0Start + bandwidthBand / 2.0;
456
457 NS_LOG_LOGIC("NON_OVERLAPPING, " << operationMode << ": " << bandwidthBand << ":"
458 << bandwidthCc << ":" << bandwidthBwp << ", "
459 << (int)numCcPerBand << ", " << (int)numBwp);
460
461 NS_LOG_LOGIC("bandConf0: " << bandCenter << " " << bandwidthBand);
462 CcBwpCreator::SimpleOperationBandConf bandConf0(bandCenter,
463 bandwidthBand,
464 numCcPerBand,
465 scene);
466 bandConf0.m_numBwp = numBwp;
467 bandCenter += bandwidthBand;
468
469 NS_LOG_LOGIC("bandConf1: " << bandCenter << " " << bandwidthBand);
470 CcBwpCreator::SimpleOperationBandConf bandConf1(bandCenter,
471 bandwidthBand,
472 numCcPerBand,
473 scene);
474 bandConf1.m_numBwp = numBwp;
475 bandCenter += bandwidthBand;
476
477 NS_LOG_LOGIC("bandConf2: " << bandCenter << " " << bandwidthBand);
478 CcBwpCreator::SimpleOperationBandConf bandConf2(bandCenter,
479 bandwidthBand,
480 numCcPerBand,
481 scene);
482 bandConf2.m_numBwp = numBwp;
483
484 // Create, then configure
485 CcBwpCreator ccBwpCreator;
486 band0 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf0);
487 band0.m_bandId = 0;
488
489 band1 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf1);
490 band1.m_bandId = 1;
491
492 band2 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf2);
493 band2.m_bandId = 2;
494
495 bandCenter = band0Start + bandwidthBwp / 2.0;
496
497 NS_LOG_LOGIC("band0[0][0]: " << bandCenter << " " << bandwidthBwp);
498 ConfigureBwpTo(band0.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
499 bandCenter += bandwidthBwp;
500
501 if (operationMode == "FDD")
502 {
503 NS_LOG_LOGIC("band0[0][1]: " << bandCenter << " " << bandwidthBwp);
504 ConfigureBwpTo(band0.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
505 bandCenter += bandwidthBwp;
506 }
507
508 NS_LOG_LOGIC("band1[0][0]: " << bandCenter << " " << bandwidthBwp);
509 ConfigureBwpTo(band1.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
510 bandCenter += bandwidthBwp;
511
512 if (operationMode == "FDD")
513 {
514 NS_LOG_LOGIC("band1[0][1]: " << bandCenter << " " << bandwidthBwp);
515 ConfigureBwpTo(band1.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
516 bandCenter += bandwidthBwp;
517 }
518
519 NS_LOG_LOGIC("band2[0][0]: " << bandCenter << " " << bandwidthBwp);
520 ConfigureBwpTo(band2.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
521 bandCenter += bandwidthBwp;
522
523 if (operationMode == "FDD")
524 {
525 NS_LOG_LOGIC("band2[0][1]: " << bandCenter << " " << bandwidthBwp);
526 ConfigureBwpTo(band2.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
527 }
528
529 std::cout << "BWP Configuration for NON_OVERLAPPING case, mode " << operationMode << "\n"
530 << band0 << band1 << band2;
531 }
532
533 else if (freqScenario == 1) // OVERLAPPING
534 {
535 double bandwidthCc = numBwp * bandwidthBwp;
536 uint8_t numCcPerBand = 1;
537 double bandwidthBand = numCcPerBand * bandwidthCc;
538 double bandCenter = band0Start + bandwidthBand / 2.0;
539
540 NS_LOG_LOGIC("OVERLAPPING, " << operationMode << ": " << bandwidthBand << ":" << bandwidthCc
541 << ":" << bandwidthBwp << ", " << (int)numCcPerBand << ", "
542 << (int)numBwp);
543
544 NS_LOG_LOGIC("bandConf0: " << bandCenter << " " << bandwidthBand);
545 CcBwpCreator::SimpleOperationBandConf bandConf0(bandCenter,
546 bandwidthBand,
547 numCcPerBand,
548 scene);
549 bandConf0.m_numBwp = numBwp;
550 bandCenter += bandwidthBand;
551
552 // Create, then configure
553 CcBwpCreator ccBwpCreator;
554 band0 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf0);
555 band0.m_bandId = 0;
556
557 bandCenter = band0Start + bandwidthBwp / 2.0;
558
559 NS_LOG_LOGIC("band0[0][0]: " << bandCenter << " " << bandwidthBwp);
560 ConfigureBwpTo(band0.m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
561 bandCenter += bandwidthBwp;
562
563 if (operationMode == "FDD")
564 {
565 NS_LOG_LOGIC("band0[0][1]: " << bandCenter << " " << bandwidthBwp);
566 ConfigureBwpTo(band0.m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
567 }
568
569 std::cout << "BWP Configuration for OVERLAPPING case, mode " << operationMode << "\n"
570 << band0;
571 }
572
573 else
574 {
575 std::cerr << "unknown combination of freqScenario = " << freqScenario
576 << " and operationMode = " << operationMode << std::endl;
577 exit(1);
578 }
579
581 // Omit fading from calibration mode
582 if (enableFading)
583 {
584 bandMask |= NrHelper::INIT_FADING;
585 }
586 nrHelper->InitializeOperationBand(&band0, bandMask);
587 nrHelper->InitializeOperationBand(&band1, bandMask);
588 nrHelper->InitializeOperationBand(&band2, bandMask);
589
590 BandwidthPartInfoPtrVector sector1Bwps;
591 BandwidthPartInfoPtrVector sector2Bwps;
592 BandwidthPartInfoPtrVector sector3Bwps;
593 if (freqScenario == 0) // NON_OVERLAPPING
594 {
595 sector1Bwps = CcBwpCreator::GetAllBwps({band0});
596 sector2Bwps = CcBwpCreator::GetAllBwps({band1});
597 sector3Bwps = CcBwpCreator::GetAllBwps({band2});
598 }
599 else // OVERLAPPING
600 {
601 sector1Bwps = CcBwpCreator::GetAllBwps({band0});
602 sector2Bwps = CcBwpCreator::GetAllBwps({band0});
603 sector3Bwps = CcBwpCreator::GetAllBwps({band0});
604 }
605
606 RealisticBfManager::TriggerEvent realTriggerEvent{RealisticBfManager::SRS_COUNT};
607
608 // TODO: Optimize this code (repeated code)
609 // if there is no fading, that means that there is no beamforming
610 if (enableFading && bfMethod != "FixedBeam")
611 {
612 if (radioNetwork == "NR")
613 {
614 if (enableRealBF)
615 {
616 beamformingHelper->SetBeamformingMethod(RealisticBeamformingAlgorithm::GetTypeId());
617 nrHelper->SetGnbBeamManagerTypeId(RealisticBfManager::GetTypeId());
618 nrHelper->SetGnbBeamManagerAttribute("TriggerEvent", EnumValue(realTriggerEvent));
619 nrHelper->SetGnbBeamManagerAttribute("UpdateDelay", TimeValue(MicroSeconds(0)));
620 }
621 else
622 {
623 if (bfMethod == "Omni")
624 {
625 beamformingHelper->SetBeamformingMethod(
627 }
628 else if (bfMethod == "CellScan")
629 {
630 beamformingHelper->SetBeamformingMethod(CellScanBeamforming::GetTypeId());
631 beamformingHelper->SetAttribute("BeamformingPeriodicity",
632 TimeValue(MilliSeconds(10)));
633 }
634 else if (bfMethod == "CellScanAzimuth")
635 {
636 beamformingHelper->SetBeamformingMethod(
638 }
639 else
640 {
641 NS_ABORT_MSG("We shouldn't be here. bfMethod is: " << bfMethod);
642 }
643 }
644 }
645 else if (radioNetwork == "LTE") // Omni for LTE
646 {
647 if (bfMethod == "Omni")
648 {
649 beamformingHelper->SetBeamformingMethod(
651 }
652 else if (bfMethod == "CellScan")
653 {
654 beamformingHelper->SetBeamformingMethod(CellScanBeamforming::GetTypeId());
655 beamformingHelper->SetAttribute("BeamformingPeriodicity",
656 TimeValue(MilliSeconds(10)));
657 }
658 else
659 {
660 NS_ABORT_MSG("We shouldn't be here. bfMethod is: " << bfMethod);
661 }
662 }
663 }
664
665 // Scheduler type
666
667 if (radioNetwork == "NR")
668 {
669 if (scheduler == "PF")
670 {
671 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerTdmaPF"));
672 }
673 else if (scheduler == "RR")
674 {
675 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerTdmaRR"));
676 }
677 }
678 else
679 {
680 if (scheduler == "PF")
681 {
682 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaPF"));
683 }
684 else if (scheduler == "RR")
685 {
686 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaRR"));
687 }
688 }
689 nrHelper->SetSchedulerAttribute("EnableHarqReTx", BooleanValue(false));
690
691 // configure SRS symbols
692 nrHelper->SetSchedulerAttribute("SrsSymbols", UintegerValue(1));
693 nrHelper->SetSchedulerAttribute("EnableSrsInUlSlots", BooleanValue(false));
694 nrHelper->SetSchedulerAttribute("EnableSrsInFSlots", BooleanValue(false));
695
696 // configure CTRL symbols
697 nrHelper->SetSchedulerAttribute("DlCtrlSymbols", UintegerValue(dlCtrlSymbols));
698
699 // Core latency
700 nrEpcHelper->SetAttribute("S1uLinkDelay", TimeValue(MilliSeconds(0)));
701
702 // Antennas for all the UEs
703 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(ueNumRows));
704 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(ueNumColumns));
705
706 if (ueEnable3gppElement)
707 {
708 nrHelper->SetUeAntennaAttribute("AntennaElement",
709 PointerValue(CreateObject<ThreeGppAntennaModel>()));
710 }
711 else
712 {
713 nrHelper->SetUeAntennaAttribute("AntennaElement",
714 PointerValue(CreateObject<IsotropicAntennaModel>()));
715 }
716
717 nrHelper->SetUeAntennaAttribute("AntennaHorizontalSpacing", DoubleValue(ueHSpacing));
718 nrHelper->SetUeAntennaAttribute("AntennaVerticalSpacing", DoubleValue(ueVSpacing));
719
720 // Antennas for all the gNbs
721 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(gnbNumRows));
722 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(gnbNumColumns));
723
724 nrHelper->SetGnbAntennaAttribute("AntennaHorizontalSpacing", DoubleValue(gnbHSpacing));
725 nrHelper->SetGnbAntennaAttribute("AntennaVerticalSpacing", DoubleValue(gnbVSpacing));
726
727 nrHelper->SetGnbAntennaAttribute("DowntiltAngle", DoubleValue(downtiltAngle * M_PI / 180.0));
728
729 if (gnbEnable3gppElement)
730 {
731 nrHelper->SetGnbAntennaAttribute("AntennaElement",
732 PointerValue(CreateObject<ThreeGppAntennaModel>()));
733 }
734 else
735 {
736 nrHelper->SetGnbAntennaAttribute("AntennaElement",
737 PointerValue(CreateObject<IsotropicAntennaModel>()));
738 }
739
740 double gnbFirstSubArray = (polSlantAngleGnb1 * M_PI) / 180.0; // converting to radians
741 double gnbSecondSubArray = (polSlantAngleGnb2 * M_PI) / 180.0; // converting to radians
742 double ueFirstSubArray = (polSlantAngleUe1 * M_PI) / 180.0; // converting to radians
743 double ueSecondSubArray = (polSlantAngleUe2 * M_PI) / 180.0; // converting to radians
744
745 // UE transmit power
746 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(ueTxPower));
747
748 // Set LTE RBG size
749 // TODO: What these values would be in TDD? bandwidthMhz refers to FDD.
750 // for example, for TDD, if we have bandwidthMhz to 20, we will have a 40 MHz
751 // BWP.
752 if (radioNetwork == "LTE")
753 {
754 switch (bandwidthMHz)
755 {
756 case 40:
757 case 20:
758 case 15:
759 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(4));
760 break;
761 case 10:
762 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(3));
763 break;
764 case 5:
765 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(2));
766 break;
767 default:
768 NS_ABORT_MSG(
769 "Currently, only supported bandwidths are 5, 10, 15, 20 and 40MHz, you chose "
770 << bandwidthMHz);
771 }
772 }
773 else
774 {
775 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(1));
776 }
777
778 // We assume a common traffic pattern for all UEs
779 uint32_t bwpIdForLowLat = 0;
780 if (operationMode == "FDD" && direction == "UL")
781 {
782 bwpIdForLowLat = 1;
783 }
784
785 // gNb routing between Bearer and bandwidth part
786 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB",
787 UintegerValue(bwpIdForLowLat));
788
789 // Ue routing between Bearer and bandwidth part
790 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdForLowLat));
791
792 // NetDeviceContainer gnbNetDev = nrHelper->InstallGnbDevice (gridScenario.GetBaseStations (),
793 // allBwps);
794 gnbSector1NetDev = nrHelper->InstallGnbDevice(gnbSector1Container, sector1Bwps);
795 NetDeviceContainer gnbNetDevs(gnbSector1NetDev);
796 gnbSector2NetDev = nrHelper->InstallGnbDevice(gnbSector2Container, sector2Bwps);
797 gnbNetDevs.Add(gnbSector2NetDev);
798 gnbSector3NetDev = nrHelper->InstallGnbDevice(gnbSector3Container, sector3Bwps);
799 gnbNetDevs.Add(gnbSector3NetDev);
800 ueSector1NetDev = nrHelper->InstallUeDevice(ueSector1Container, sector1Bwps);
801 NetDeviceContainer ueNetDevs(ueSector1NetDev);
802 ueSector2NetDev = nrHelper->InstallUeDevice(ueSector2Container, sector2Bwps);
803 ueNetDevs.Add(ueSector2NetDev);
804 ueSector3NetDev = nrHelper->InstallUeDevice(ueSector3Container, sector3Bwps);
805 ueNetDevs.Add(ueSector3NetDev);
806
807 int64_t randomStream = 1;
808 randomStream += nrHelper->AssignStreams(gnbSector1NetDev, randomStream);
809 randomStream += nrHelper->AssignStreams(gnbSector2NetDev, randomStream);
810 randomStream += nrHelper->AssignStreams(gnbSector3NetDev, randomStream);
811 randomStream += nrHelper->AssignStreams(ueSector1NetDev, randomStream);
812 randomStream += nrHelper->AssignStreams(ueSector2NetDev, randomStream);
813 randomStream += nrHelper->AssignStreams(ueSector3NetDev, randomStream);
814
815 // Sectors (cells) of a site are pointing at different directions
816 std::vector<double> sectorOrientationRad{
817 sector0AngleRad,
818 sector0AngleRad + 2.0 * M_PI / 3.0, // + 120 deg
819 sector0AngleRad - 2.0 * M_PI / 3.0 // - 120 deg
820 };
821
822 for (uint32_t cellId = 0; cellId < gnbNetDevs.GetN(); ++cellId)
823 {
824 Ptr<NetDevice> gnb = gnbNetDevs.Get(cellId);
825 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
826 if (numBwps > 2)
827 {
828 NS_ABORT_MSG("Incorrect number of BWPs per CC");
829 }
830
831 uint32_t sector = cellId % (gnbSector3NetDev.GetN() == 0 ? 1 : 3);
832 double orientation = sectorOrientationRad[sector];
833
834 // First BWP (in case of FDD) or only BWP (in case of TDD)
835 ConfigurePhy(nrHelper,
836 gnb,
837 orientation,
838 numerology,
839 txPowerBs,
840 pattern,
841 0,
842 gnbFirstSubArray,
843 gnbSecondSubArray,
844 beamConfSector,
845 beamConfElevation);
846
847 if (numBwps == 2) // FDD
848 {
849 ConfigurePhy(nrHelper,
850 gnb,
851 orientation,
852 numerology,
853 txPowerBs,
854 pattern,
855 1,
856 gnbFirstSubArray,
857 gnbSecondSubArray,
858 beamConfSector,
859 beamConfElevation);
860 // Link the two FDD BWP
861 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
862 }
863 }
864
865 Ptr<UniformRandomVariable> m_uniformUeBearingAngle;
866 m_uniformUeBearingAngle = CreateObject<UniformRandomVariable>();
867
868 // Set the UE routing:
869 for (auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
870 {
871 auto uePhyFirst = nrHelper->GetUePhy(*nd, 0);
872 auto uePhySecond{uePhyFirst};
873
874 ObjectVectorValue ueSpectrumPhysFirstBwp;
875 Ptr<NrSpectrumPhy> nrSpectrumPhy = uePhyFirst->GetSpectrumPhy();
876 nrSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>()->SetAttribute(
877 "PolSlantAngle",
878 DoubleValue(ueFirstSubArray));
879
880 if (ueBearingAngle)
881 {
882 // For each UE throw a uniform random variable btw -180 and 180
883 double ueBearingAngleValue = m_uniformUeBearingAngle->GetValue(-180, 180);
884 ueBearingAngleValue = (ueBearingAngleValue * M_PI) / 180.0; // convert to radians
885 nrSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>()->SetAttribute(
886 "BearingAngle",
887 DoubleValue(ueBearingAngleValue));
888 }
889 if (ueSpectrumPhysFirstBwp.GetN() == 2)
890 {
891 nrSpectrumPhy = ueSpectrumPhysFirstBwp.Get(1)->GetObject<NrSpectrumPhy>();
892 nrSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>()->SetAttribute(
893 "PolSlantAngle",
894 DoubleValue(ueSecondSubArray));
895 }
896
897 if (operationMode == "FDD")
898 {
899 nrHelper->GetBwpManagerUe(*nd)->SetOutputLink(0, 1);
900 uePhySecond = nrHelper->GetUePhy(*nd, 1);
901 uePhySecond->SetUplinkPowerControl(uePhyFirst->GetUplinkPowerControl());
902
903 ObjectVectorValue ueSpectrumPhysSecondBwp;
904 nrSpectrumPhy = uePhySecond->GetSpectrumPhy();
905 nrSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>()->SetAttribute(
906 "PolSlantAngle",
907 DoubleValue(ueFirstSubArray));
908 }
909 uePhyFirst->TraceConnectWithoutContext("DlDataSinr",
910 MakeBoundCallback(&ReportSinrNr, sinrStats));
911 uePhySecond->TraceConnectWithoutContext("ReportPowerSpectralDensity",
912 MakeBoundCallback(&ReportPowerNr, ueTxPowerStats));
913 }
914
915 // When all the configuration is done, explicitly call UpdateConfig ()
916 for (auto nd = gnbNetDevs.Begin(); nd != gnbNetDevs.End(); ++nd)
917 {
918 uint32_t bwpId = 0;
919 if (operationMode == "FDD" && direction == "UL")
920 {
921 bwpId = 1;
922 }
923 auto gnbPhy = nrHelper->GetGnbPhy(*nd, bwpId);
924 gnbPhy->TraceConnectWithoutContext("SlotDataStats",
925 MakeBoundCallback(&ReportSlotStatsNr, slotStats));
926 gnbPhy->TraceConnectWithoutContext("RBDataStats",
927 MakeBoundCallback(&ReportRbStatsNr, rbStats));
928 gnbPhy->GetSpectrumPhy()->TraceConnectWithoutContext(
929 "RxDataTrace",
930 MakeBoundCallback(&ReportGnbRxDataNr, gnbRxPowerStats));
931
932 DynamicCast<NrGnbNetDevice>(*nd)->UpdateConfig();
933 }
934
935 for (auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
936 {
937 DynamicCast<NrUeNetDevice>(*nd)->UpdateConfig();
938 }
939}
940
941} // 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
Interface between the physical layer and the channel.
Ptr< Object > GetAntenna() const override
Inherited from SpectrumPhy Note: Implements GetAntenna function from SpectrumPhy.
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.
static TypeId GetTypeId()
GetTypeId.
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.
@ UMi_StreetCanyon
UMi_StreetCanyon.
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.