136 const std::string& scenario,
137 const std::string& radioNetwork,
138 std::string errorModel,
139 const std::string& operationMode,
140 const std::string& direction,
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,
159 std::string powerAllocation,
165 const std::string& scheduler,
166 uint32_t bandwidthMHz,
167 uint32_t freqScenario,
168 double downtiltAngle)
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")
184 if (errorModel.empty())
186 errorModel =
"ns3::LenaErrorModel";
188 else if (errorModel !=
"ns3::NrLteMiErrorModel" && errorModel !=
"ns3::LenaErrorModel")
190 NS_ABORT_MSG(
"The selected error model is not recommended for LTE");
193 else if (radioNetwork ==
"NR")
197 if (errorModel.empty())
199 errorModel =
"ns3::NrEesmCcT2";
201 else if (errorModel ==
"ns3::NrLteMiErrorModel")
203 NS_ABORT_MSG(
"The selected error model is not recommended for NR");
208 NS_ABORT_MSG(
"Unrecognized radio network technology");
219 nrHelper = CreateObject<NrHelper>();
221 Ptr<IdealBeamformingHelper> idealBeamformingHelper;
226 if (radioNetwork ==
"NR" || calibration)
228 idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
229 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
232 Ptr<NrPointToPointEpcHelper> nrEpcHelper = DynamicCast<NrPointToPointEpcHelper>(baseEpcHelper);
233 nrHelper->SetEpcHelper(nrEpcHelper);
235 double txPowerBs = 0.0;
238 if (scenario ==
"UMi")
243 else if (scenario ==
"UMa")
248 else if (scenario ==
"RMa")
255 NS_ABORT_MSG(
"Unsupported scenario " << scenario <<
". Supported values: UMi, UMa, RMa");
262 Config::SetDefault(
"ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(100)));
263 nrHelper->SetChannelConditionModelAttribute(
"UpdatePeriod", TimeValue(MilliSeconds(0)));
266 nrHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(!calibration));
269 nrHelper->SetUePhyAttribute(
"NoiseFigure", DoubleValue(9.0));
270 nrHelper->SetUePhyAttribute(
"EnableUplinkPowerControl", BooleanValue(enableUlPc));
272 NrSpectrumValueHelper::PowerAllocationType powerAllocationEnum;
273 if (powerAllocation ==
"UniformPowerAllocBw")
275 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW;
277 else if (powerAllocation ==
"UniformPowerAllocUsed")
279 powerAllocationEnum = NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED;
283 NS_ABORT_MSG(
"Unsupported power allocation type "
285 <<
". Supported values: "
286 "UniformPowerAllocBw and UniformPowerAllocUsed.");
289 nrHelper->SetUePhyAttribute(
"PowerAllocationType", EnumValue(powerAllocationEnum));
291 nrHelper->SetGnbPhyAttribute(
"PowerAllocationType",
292 EnumValue(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW));
295 nrHelper->SetUlErrorModel(errorModel);
296 nrHelper->SetDlErrorModel(errorModel);
306 nrHelper->SetGnbDlAmcAttribute(
"NumRefScPerRb", UintegerValue(numScPerRb));
307 nrHelper->SetGnbUlAmcAttribute(
"NumRefScPerRb", UintegerValue(1));
309 nrHelper->SetGnbPhyAttribute(
"RbOverhead", DoubleValue(rbOverhead));
310 nrHelper->SetGnbPhyAttribute(
"N2Delay", UintegerValue(n2Delay));
311 nrHelper->SetGnbPhyAttribute(
"N1Delay", UintegerValue(n1Delay));
313 nrHelper->SetUeMacAttribute(
"NumHarqProcess", UintegerValue(harqProcesses));
314 nrHelper->SetGnbMacAttribute(
"NumHarqProcess", UintegerValue(harqProcesses));
367 const double band0Start = 2110e6;
368 double bandwidthBwp = bandwidthMHz * 1e6;
377 if (freqScenario == 0)
381 if (operationMode ==
"FDD")
393 double bandwidthCc = numBwp * bandwidthBwp;
394 uint8_t numCcPerBand = 1;
395 double bandwidthBand = numCcPerBand * bandwidthCc;
396 double bandCenter = band0Start + bandwidthBand / 2.0;
398 NS_LOG_LOGIC(
"NON_OVERLAPPING, " << operationMode <<
": " << bandwidthBand <<
":"
399 << bandwidthCc <<
":" << bandwidthBwp <<
", "
400 << (
int)numCcPerBand <<
", " << (
int)numBwp);
402 NS_LOG_LOGIC(
"bandConf0: " << bandCenter <<
" " << bandwidthBand);
408 bandCenter += bandwidthBand;
410 NS_LOG_LOGIC(
"bandConf1: " << bandCenter <<
" " << bandwidthBand);
416 bandCenter += bandwidthBand;
418 NS_LOG_LOGIC(
"bandConf2: " << bandCenter <<
" " << bandwidthBand);
436 bandCenter = band0Start + bandwidthBwp / 2.0;
438 NS_LOG_LOGIC(
"band0[0][0]: " << bandCenter <<
" " << bandwidthBwp);
439 ConfigureBwpTo(band0.
m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
440 bandCenter += bandwidthBwp;
442 if (operationMode ==
"FDD")
444 NS_LOG_LOGIC(
"band0[0][1]: " << bandCenter <<
" " << bandwidthBwp);
445 ConfigureBwpTo(band0.
m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
446 bandCenter += bandwidthBwp;
449 NS_LOG_LOGIC(
"band1[0][0]: " << bandCenter <<
" " << bandwidthBwp);
450 ConfigureBwpTo(band1.
m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
451 bandCenter += bandwidthBwp;
453 if (operationMode ==
"FDD")
455 NS_LOG_LOGIC(
"band1[0][1]: " << bandCenter <<
" " << bandwidthBwp);
456 ConfigureBwpTo(band1.
m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
457 bandCenter += bandwidthBwp;
460 NS_LOG_LOGIC(
"band2[0][0]: " << bandCenter <<
" " << bandwidthBwp);
461 ConfigureBwpTo(band2.
m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
462 bandCenter += bandwidthBwp;
464 if (operationMode ==
"FDD")
466 NS_LOG_LOGIC(
"band2[0][1]: " << bandCenter <<
" " << bandwidthBwp);
467 ConfigureBwpTo(band2.
m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
470 std::cout <<
"BWP Configuration for NON_OVERLAPPING case, mode " << operationMode <<
"\n"
471 << band0 << band1 << band2;
474 else if (freqScenario == 1)
478 if (operationMode ==
"FDD")
490 double bandwidthCc = numBwp * bandwidthBwp;
491 uint8_t numCcPerBand = 1;
492 double bandwidthBand = numCcPerBand * bandwidthCc;
493 double bandCenter = band0Start + bandwidthBand / 2.0;
495 NS_LOG_LOGIC(
"OVERLAPPING, " << operationMode <<
": " << bandwidthBand <<
":" << bandwidthCc
496 <<
":" << bandwidthBwp <<
", " << (
int)numCcPerBand <<
", "
499 NS_LOG_LOGIC(
"bandConf0: " << bandCenter <<
" " << bandwidthBand);
505 bandCenter += bandwidthBand;
512 bandCenter = band0Start + bandwidthBwp / 2.0;
514 NS_LOG_LOGIC(
"band0[0][0]: " << bandCenter <<
" " << bandwidthBwp);
515 ConfigureBwpTo(band0.
m_cc[0]->m_bwp[0], bandCenter, bandwidthBwp);
516 bandCenter += bandwidthBwp;
518 if (operationMode ==
"FDD")
520 NS_LOG_LOGIC(
"band0[0][1]: " << bandCenter <<
" " << bandwidthBwp);
521 ConfigureBwpTo(band0.
m_cc[0]->m_bwp[1], bandCenter, bandwidthBwp);
524 std::cout <<
"BWP Configuration for OVERLAPPING case, mode " << operationMode <<
"\n"
530 std::cerr <<
"unknown combination of freqScenario = " << freqScenario
531 <<
" and operationMode = " << operationMode << std::endl;
541 nrHelper->InitializeOperationBand(&band0, bandMask);
542 nrHelper->InitializeOperationBand(&band1, bandMask);
543 nrHelper->InitializeOperationBand(&band2, bandMask);
548 if (freqScenario == 0)
582 if (radioNetwork ==
"LTE" && calibration)
584 idealBeamformingHelper->SetAttribute(
588 else if (radioNetwork ==
"NR")
590 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
596 if (scheduler ==
"PF")
598 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(
"ns3::NrMacSchedulerOfdmaPF"));
600 else if (scheduler ==
"RR")
602 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(
"ns3::NrMacSchedulerOfdmaRR"));
606 nrHelper->SetSchedulerAttribute(
"SrsSymbols", UintegerValue(1));
607 nrHelper->SetSchedulerAttribute(
"EnableSrsInUlSlots", BooleanValue(
false));
608 nrHelper->SetSchedulerAttribute(
"EnableSrsInFSlots", BooleanValue(
false));
611 nrHelper->SetSchedulerAttribute(
"DlCtrlSymbols", UintegerValue(1));
614 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
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));
626 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(1));
627 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(1));
631 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(5));
632 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(2));
635 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
636 PointerValue(CreateObject<ThreeGppAntennaModel>()));
637 nrHelper->SetGnbAntennaAttribute(
"DowntiltAngle", DoubleValue(downtiltAngle * M_PI / 180.0));
640 nrHelper->SetUePhyAttribute(
"TxPower", DoubleValue(23.0));
646 if (radioNetwork ==
"LTE")
648 switch (bandwidthMHz)
652 nrHelper->SetGnbMacAttribute(
"NumRbPerRbg", UintegerValue(4));
655 nrHelper->SetGnbMacAttribute(
"NumRbPerRbg", UintegerValue(3));
658 nrHelper->SetGnbMacAttribute(
"NumRbPerRbg", UintegerValue(2));
661 NS_ABORT_MSG(
"Currently, only supported bandwidths are 5, 10, 15, and 20MHz, you chose "
667 uint32_t bwpIdForLowLat = 0;
668 if (operationMode ==
"FDD" && direction ==
"UL")
674 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"NGBR_VIDEO_TCP_DEFAULT",
675 UintegerValue(bwpIdForLowLat));
678 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"NGBR_VIDEO_TCP_DEFAULT",
679 UintegerValue(bwpIdForLowLat));
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);
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);
727 std::vector<double> sectorOrientationRad{
729 sector0AngleRad + 2.0 * M_PI / 3.0,
730 sector0AngleRad - 2.0 * M_PI / 3.0
733 for (uint32_t cellId = 0; cellId < gnbNetDevs.GetN(); ++cellId)
735 Ptr<NetDevice> gnb = gnbNetDevs.Get(cellId);
736 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
739 NS_ABORT_MSG(
"Incorrect number of BWPs per CC");
742 uint32_t sector = cellId % (gnbSector3NetDev.GetN() == 0 ? 1 : 3);
743 double orientation = sectorOrientationRad[sector];
746 ConfigurePhy(nrHelper, gnb, orientation, numerology, txPowerBs, pattern, 0);
750 ConfigurePhy(nrHelper, gnb, orientation, numerology, txPowerBs, pattern, 1);
752 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
757 for (
auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
759 auto uePhyFirst = nrHelper->GetUePhy(*nd, 0);
760 auto uePhySecond{uePhyFirst};
761 if (operationMode ==
"FDD")
763 nrHelper->GetBwpManagerUe(*nd)->SetOutputLink(0, 1);
764 uePhySecond = nrHelper->GetUePhy(*nd, 1);
765 uePhySecond->SetUplinkPowerControl(uePhyFirst->GetUplinkPowerControl());
767 uePhyFirst->TraceConnectWithoutContext(
"DlDataSinr",
768 MakeBoundCallback(&ReportSinrNr, sinrStats));
769 uePhySecond->TraceConnectWithoutContext(
"ReportPowerSpectralDensity",
770 MakeBoundCallback(&ReportPowerNr, ueTxPowerStats));
774 for (
auto nd = gnbNetDevs.Begin(); nd != gnbNetDevs.End(); ++nd)
777 if (operationMode ==
"FDD" && direction ==
"UL")
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(
788 MakeBoundCallback(&ReportGnbRxDataNr, gnbRxPowerStats));
790 DynamicCast<NrGnbNetDevice>(*nd)->UpdateConfig();
793 for (
auto nd = ueNetDevs.Begin(); nd != ueNetDevs.End(); ++nd)
795 DynamicCast<NrUeNetDevice>(*nd)->UpdateConfig();
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)