5#include "ns3/antenna-module.h"
6#include "ns3/applications-module.h"
7#include "ns3/boolean.h"
8#include "ns3/config-store.h"
9#include "ns3/core-module.h"
10#include "ns3/flow-monitor-module.h"
11#include "ns3/internet-module.h"
12#include "ns3/mobility-module.h"
13#include "ns3/network-module.h"
14#include "ns3/nr-module.h"
15#include "ns3/point-to-point-module.h"
16#include "ns3/xr-traffic-mixer-helper.h"
69NS_LOG_COMPONENT_DEFINE(
"CttcNrFhXr");
71std::string m_fhControlMethod;
73std::ofstream m_fhTraceFile;
74std::string m_fhTraceFileName;
75std::ofstream m_aiTraceFile;
76std::string m_aiTraceFileName;
77std::string m_outputDir;
79struct VoiceApplicationSettings
85 std::string transportProtocol;
87 Ptr<NetDevice> ueNetDev;
88 Ptr<NrHelper> nrHelper;
91 ApplicationContainer& serverApps;
92 ApplicationContainer& clientApps;
93 ApplicationContainer& pingApps;
94 std::string direction;
95 Ipv4Address remoteHostAddress;
96 uint16_t remoteHostPort;
99static void PrintUePosition(NodeContainer ueNodes);
101void ReportFhTrace(
const SfnSf& sfn, uint16_t physCellId, uint16_t bwpId, uint64_t reqFh);
102void ReportAiTrace(
const SfnSf& sfn, uint16_t physCellId, uint16_t bwpId, uint32_t airRbs);
104void ConfigurePhy(Ptr<NrHelper> nrHelper,
106 double orientationRads,
107 uint16_t beamConfSector,
108 double beamConfElevation);
110void ConfigureVoiceApp(VoiceApplicationSettings& voiceAppSettings);
111void ConfigureXrApp(NodeContainer& ueContainer,
113 Ipv4InterfaceContainer& ueIpIface,
114 enum NrXrConfig config,
116 std::string transportProtocol,
117 NodeContainer& remoteHostContainer,
118 NetDeviceContainer& ueNetDev,
119 Ptr<NrHelper> nrHelper,
123 std::vector<Ptr<NrEpcTft>>& tfts,
124 ApplicationContainer& serverApps,
125 ApplicationContainer& clientApps,
126 ApplicationContainer& pingApps,
127 std::string direction,
133 Ipv4Address remoteHostAddress,
134 uint16_t remoteHostPort);
137main(
int argc,
char* argv[])
140 bool logging =
false;
142 std::string nrConfigurationScenario =
"DenseA";
143 std::string deployment =
"HEX";
144 uint32_t freqScenario = 0;
147 uint32_t appDurationParam = 10000;
148 Time appStartTimeMs = MilliSeconds(400);
150 uint16_t arUeNum = 0;
151 uint16_t vrUeNum = 0;
152 uint16_t cgUeNum = 0;
153 uint16_t voiceUeNum = 0;
155 double centralFrequency = 4e9;
156 double bandwidth = 10e6;
158 double ueTxPower = 23;
159 uint16_t numerology = 1;
160 std::string pattern =
"DL|DL|DL|DL|UL|DL|DL|DL|DL|UL|";
161 bool enableTDD4_1 =
false;
163 std::string propScenario =
"UMa";
164 std::string propChannelCondition =
"Default";
165 uint16_t numOuterRings = 0;
167 double bsHeight = 25.0;
168 double utHeight = 1.5;
169 double maxUeClosestSiteDistance = 1000;
170 double minBsUtDistance = 10.0;
172 double antennaOffset = 1.0;
173 double uesWithRandomUtHeight = 0;
174 double distance = 200;
176 double gnbNoiseFigure = 5.0;
177 double ueNoiseFigure = 7.0;
179 bool enableMimoFeedback =
false;
181 bool isGnbDualPolarized =
false;
182 uint32_t gnbNumRows = 4;
183 uint32_t gnbNumColumns = 8;
184 size_t gnbHorizPorts = 1;
185 size_t gnbVertPorts = 1;
186 double gnbHSpacing = 0.5;
187 double gnbVSpacing = 0.8;
188 double polSlantAngleGnb = 0.0;
189 double bearingAngleGnb = 0.0;
191 bool isUeDualPolarized =
false;
192 uint32_t ueNumRows = 1;
193 uint32_t ueNumColumns = 1;
194 size_t ueHorizPorts = 1;
195 size_t ueVertPorts = 1;
196 double ueHSpacing = 0.5;
197 double ueVSpacing = 0.5;
198 double polSlantAngleUe = 90.0;
199 double bearingAngleUe = 180.0;
201 double downtiltAngle = 0.0;
202 uint16_t bfConfSector = 1;
203 double bfConfElevation = 30;
204 std::string bfMethod =
"CellScan";
212 bool enableOfdma =
true;
213 std::string schedulerType =
"RR";
216 int channelUpdatePeriod = 20;
217 int channelConditionUpdatePeriod = 100;
219 double o2iThreshold = 0;
220 double o2iLowLossThreshold =
222 bool linkO2iConditionToAntennaHeight =
false;
224 bool enableShadowing =
true;
225 uint8_t fixedMcs = 0;
226 bool useFixedMcs =
false;
227 std::string errorModel =
"ns3::NrEesmIrT2";
230 uint32_t fhCapacity = 10000;
232 std::string fhControlMethod =
"OptimizeMcs";
236 bool enableHarqRetx =
true;
237 bool enableInterServ =
false;
239 bool useRlcUm =
true;
240 bool enableUl =
false;
242 double arDataRate = 5;
244 double vrDataRate = 5;
246 double cgDataRate = 5;
248 bool enablePdcpDiscarding =
false;
249 uint32_t discardTimerMs = 0;
250 uint32_t reorderingTimerMs = 100;
252 bool enableNrHelperTraces =
false;
253 bool enableQosTrafficTraces =
true;
256 std::string simTag =
"";
257 std::string outputDir =
"./";
260 double xMinRem = -2000.0;
261 double xMaxRem = 2000.0;
262 uint16_t xResRem = 100;
263 double yMinRem = -2000.0;
264 double yMaxRem = 2000.0;
265 uint16_t yResRem = 100;
267 uint32_t remSector = 0;
268 bool enableFading =
true;
270 double progressIntervalInSeconds = 600;
273 cmd.AddValue(
"deployment",
274 "The deployment of the cells. Choose among HEX or SIMPLE",
276 cmd.AddValue(
"nrConfigurationScenario",
277 "The NR calibration scenario string. Choose among:"
278 "DenseA (default), RuralA.",
279 nrConfigurationScenario);
280 cmd.AddValue(
"propScenario",
"The urban scenario string (UMa, RMa)", propScenario);
281 cmd.AddValue(
"freqScenario",
282 "0: NON_OVERLAPPING (each sector in different freq - FR3), "
283 "1: OVERLAPPING (same freq for all sectors - FR1)",
285 cmd.AddValue(
"isd",
"The ISD", isd);
286 cmd.AddValue(
"numRings",
"The number of rings", numOuterRings);
287 cmd.AddValue(
"arUeNum",
"The number of AR UEs", arUeNum);
288 cmd.AddValue(
"vrUeNum",
"The number of VR UEs", vrUeNum);
289 cmd.AddValue(
"cgUeNum",
"The number of CG UEs", cgUeNum);
290 cmd.AddValue(
"voiceUeNum",
"The number of VoIP UEs", voiceUeNum);
291 cmd.AddValue(
"numerology",
"The numerology to be used.", numerology);
292 cmd.AddValue(
"enableTDD4_1",
293 "If True enables TDD 4:1 and numerology 1, DataRate 30Mbps for VR"
294 "and Fps 30 for AR.",
296 cmd.AddValue(
"txPower",
"Tx power to be configured to gNB", txPower);
297 cmd.AddValue(
"bsHeight",
"The gNB antenna height", bsHeight);
298 cmd.AddValue(
"distance",
299 "The radius of the disc (in meters) that the UEs will be distributed."
300 "Default value is 200m",
302 cmd.AddValue(
"enableMimoFeedback",
"Enables MIMO feedback", enableMimoFeedback);
303 cmd.AddValue(
"gnbNumRows",
"The number of rows of the phased array of the gNB", gnbNumRows);
304 cmd.AddValue(
"gnbNumColumns",
305 "The number of columns of the phased array of the gNB",
307 cmd.AddValue(
"simTag",
308 "tag to be appended to output filenames to distinguish simulation campaigns",
310 cmd.AddValue(
"outputDir",
"directory where to store simulation results", outputDir);
311 cmd.AddValue(
"frequency",
"The system frequency", centralFrequency);
312 cmd.AddValue(
"bandwidth",
"The system bandwidth", bandwidth);
315 "The fixed MCS that will be used in this example if useFixedMcs is configured to true (1).",
317 cmd.AddValue(
"useFixedMcs",
318 "Whether to use fixed mcs, normally used for testing purposes",
320 cmd.AddValue(
"gnbNoiseFigure",
"gNB Noise Figure", gnbNoiseFigure);
321 cmd.AddValue(
"ueNoiseFigure",
"UE Noise Figure", ueNoiseFigure);
322 cmd.AddValue(
"useUdp",
323 "if true, the applications will run over UDP connection, otherwise a TCP "
324 "connection will be used. ",
326 cmd.AddValue(
"useRlcUm",
"if true, the Rlc UM will be used, otherwise RLC AM ", useRlcUm);
327 cmd.AddValue(
"isLos",
"if true, configure the LOS scenario, otherwise the default.", isLos);
328 cmd.AddValue(
"enableOfdma",
329 "If set to true it enables Ofdma scheduler. Default value is false (Tdma)",
331 cmd.AddValue(
"schedulerType",
332 "RR: Round-Robin (default), PF: Proportional Fair, Qos",
334 cmd.AddValue(
"isMx1",
335 "if true M SDFs will be mapped to 1 DRB, otherwise the mapping will "
336 "be 1x1, i.e., 1 SDF to 1 DRB.",
338 cmd.AddValue(
"logging",
"Enable logging", logging);
339 cmd.AddValue(
"enableNrHelperTraces",
340 "If true, it enables the generation of the NrHelper traces, otherwise"
341 "NrHelper traces will not be generated. Default value is true",
342 enableNrHelperTraces);
343 cmd.AddValue(
"enableQosTrafficTraces",
344 "If true, it enables the generation of the the Delay and Throughput"
345 "traces, otherwise these traces will not be generated. Default value is true",
346 enableQosTrafficTraces);
347 cmd.AddValue(
"enableInterServ",
348 "If set to true VR is assigned 5QI87. Default value is false (5QI80)",
350 cmd.AddValue(
"channelUpdatePeriod",
351 "The channel updated period value in ms. Default value is 20 ms",
352 channelUpdatePeriod);
353 cmd.AddValue(
"channelConditionUpdatePeriod",
354 "The channel condition updated period value in ms. Default value is 100 ms",
355 channelConditionUpdatePeriod);
356 cmd.AddValue(
"enableShadowing",
357 "If set to false shadowing is disabled. Default value is true",
361 "Used to enable/disable fading. By default is enabled. Used for the testing purposes.",
363 cmd.AddValue(
"appDuration",
"Duration of the application in milliseconds.", appDurationParam);
364 cmd.AddValue(
"enableHarqRetx",
365 "If set to false HARQ retransmissions are disabled. Default value is true",
367 cmd.AddValue(
"maxUeClosestSiteDistance",
368 "Max distance between UE and the closest site",
369 maxUeClosestSiteDistance);
370 cmd.AddValue(
"enablePdcpDiscarding",
371 "Whether to enable PDCP TX discarding",
372 enablePdcpDiscarding);
373 cmd.AddValue(
"discardTimerMs",
374 "Discard timer value in milliseconds to use for all the flows",
376 cmd.AddValue(
"reorderingTimerMs",
377 "RLC t-Reordering timer value (See section 7.3 of 3GPP TS 36.322) in milliseconds "
378 "to use for all the flows",
380 cmd.AddValue(
"enableUl",
381 "If true, it enables UL direction traffic for AR and VoIP."
384 cmd.AddValue(
"dlRem",
385 "Generates DL REM without executing simulation. REM needs the"
386 "declaration of VoIP UEs for illustrative purposes",
388 cmd.AddValue(
"xMin",
"The min x coordinate of the rem map", xMinRem);
389 cmd.AddValue(
"xMax",
"The max x coordinate of the rem map", xMaxRem);
390 cmd.AddValue(
"xRes",
"The resolution on the x axis of the rem map", xResRem);
391 cmd.AddValue(
"yMin",
"The min y coordinate of the rem map", yMinRem);
392 cmd.AddValue(
"yMax",
"The max y coordinate of the rem map", yMaxRem);
393 cmd.AddValue(
"yRes",
"The resolution on the y axis of the rem map", yResRem);
394 cmd.AddValue(
"z",
"The z coordinate of the rem map", zRem);
395 cmd.AddValue(
"remSector",
"For which sector to generate the rem", remSector);
396 cmd.AddValue(
"progressInterval",
"Progress reporting interval", progressIntervalInSeconds);
397 cmd.AddValue(
"fhCapacity",
"Fronthaul capacity (Mbps)", fhCapacity);
398 cmd.AddValue(
"ohDyn",
"Overhead for dynamic modulation compression (bits)", ohDyn);
401 "The FH Control Method to be applied. Choose among: Dropping, Postponing, OptimmizeMcs, "
405 cmd.Parse(argc, argv);
407 Time appDuration = MilliSeconds(appDurationParam);
408 NS_ABORT_MSG_IF(deployment ==
"HEX",
409 "HEX deployment needs to be updated for proper operation."
410 "Currently, only SIMPLE deployment can be tested.");
411 NS_ABORT_MSG_IF(appDuration < MilliSeconds(1000),
"The appDuration should be at least 1000ms.");
412 NS_ABORT_MSG_IF(!voiceUeNum && !vrUeNum && !arUeNum && !cgUeNum,
413 "Activate at least one type of traffic");
414 NS_ABORT_MSG_IF(dlRem && !voiceUeNum,
"For REM generation please declare a VoIP UE.");
415 NS_ABORT_MSG_IF(deployment ==
"SIMPLE" && (nrConfigurationScenario ==
"RuralA"),
416 "SIMPLE can be used only with default DenseA configuration");
420 m_fhControlMethod = fhControlMethod;
421 m_fhCapacity = fhCapacity;
422 m_outputDir = outputDir;
424 if (deployment ==
"HEX")
426 if (nrConfigurationScenario ==
"DenseA")
434 else if (nrConfigurationScenario ==
"RuralA")
436 propScenario =
"RMa";
438 centralFrequency = 700e6;
439 pattern =
"DL|DL|DL|DL|UL|DL|DL|DL|DL|UL|";
444 maxUeClosestSiteDistance = 500;
458 else if (deployment ==
"SIMPLE")
460 nrConfigurationScenario =
"InH_OfficeOpen_LoS";
461 propChannelCondition =
"LOS";
462 propScenario =
"InH-OfficeOpen";
463 centralFrequency = 30e9;
464 pattern =
"DL|DL|DL|DL|UL|DL|DL|DL|DL|UL|";
487 bearingAngleGnb = 0.0;
488 bearingAngleUe = 180.0;
490 if (enableMimoFeedback)
492 Config::SetDefault(
"ns3::NrHelper::EnableMimoFeedback", BooleanValue(
true));
494 isGnbDualPolarized =
true;
497 polSlantAngleGnb = 0.0;
499 isUeDualPolarized =
true;
502 polSlantAngleUe = 0.0;
504 if (bandwidth == 400e6)
510 downtiltAngle = 90.0;
520 NS_ABORT_MSG(
"Please choose between HEX and SIMPLE deployment");
523 NS_ABORT_MSG_IF(discardTimerMs && !enablePdcpDiscarding,
524 "General discard timer enabled but PDCP discarding not enabled!");
526 ShowProgress spinner(Seconds(progressIntervalInSeconds));
528 Time simTimeMs = appStartTimeMs + appDuration + MilliSeconds(10);
529 std::cout <<
"Start example" << std::endl;
531 if (deployment ==
"HEX")
533 std::string frChosen = freqScenario == 0 ?
"FR3" :
"FR1";
535 std::cout <<
"Deployment chosen: " << deployment
536 <<
" - Configuration: " << nrConfigurationScenario << std::endl;
538 std::string qosScenarioState = enableInterServ == 1 ?
"Enabled" :
"Disabled";
539 std::cout <<
"Interactive Service for VR is: " << qosScenarioState << std::endl;
541 std::string mappingArch = isMx1 == 1 ?
"Mx1" :
"1x1";
542 std::cout <<
"Mapping architecture is set to: " << mappingArch << std::endl;
544 std::string enableMimo = enableMimoFeedback == 1 ?
"Enabled" :
"Disabled";
545 std::cout <<
"Mimo is set to: " << enableMimo << std::endl;
550 (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_LEVEL_INFO);
553 LogComponentEnable(
"NrFhControl", logLevel1);
561 Config::SetDefault(
"ns3::NrRlcUm::EnablePdcpDiscarding", BooleanValue(enablePdcpDiscarding));
562 Config::SetDefault(
"ns3::NrRlcUm::DiscardTimerMs", UintegerValue(discardTimerMs));
563 Config::SetDefault(
"ns3::NrRlcUm::ReorderingTimer", TimeValue(MilliSeconds(reorderingTimerMs)));
565 Config::SetDefault(
"ns3::ThreeGppChannelModel::UpdatePeriod",
566 TimeValue(MilliSeconds(channelUpdatePeriod)));
567 Config::SetDefault(
"ns3::NrGnbRrc::EpsBearerToRlcMapping",
568 EnumValue(useUdp ? NrGnbRrc::RLC_UM_ALWAYS :
NrGnbRrc::RLC_AM_ALWAYS));
569 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
575 uint32_t gnbSites = 0;
576 NodeContainer gnbNodes;
577 NodeContainer ueNodes;
578 MobilityHelper mobility;
579 double sector0AngleRad = 30;
580 uint32_t sectors = 3;
584 if (deployment ==
"HEX")
586 scenarioParams.
m_isd = isd;
595 std::cout <<
" hexagonal grid: ";
597 gridScenario.SetSimTag(simTag);
598 gridScenario.SetResultsDir(outputDir);
601 uint32_t ueNum = (voiceUeNum + arUeNum + vrUeNum + cgUeNum) * gnbSites * sectors;
604 std::cout << sector0AngleRad << std::endl;
607 gridScenario.SetMaxUeDistanceToClosestSite(maxUeClosestSiteDistance);
609 uesWithRandomUtHeight);
613 scenario = &gridScenario;
619 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
622 ueNodes.Create(voiceUeNum + arUeNum + vrUeNum + cgUeNum);
624 Ptr<ListPositionAllocator> bsPositionAlloc = CreateObject<ListPositionAllocator>();
625 bsPositionAlloc->Add(Vector(0.0, 0.0, bsHeight));
626 mobility.SetPositionAllocator(bsPositionAlloc);
627 mobility.Install(gnbNodes);
629 Ptr<ListPositionAllocator> uePositionAlloc = CreateObject<ListPositionAllocator>();
630 uePositionAlloc->Add(Vector(0.0, distance, utHeight));
631 mobility.SetPositionAllocator(uePositionAlloc);
632 mobility.Install(ueNodes.Get(
636 Ptr<RandomDiscPositionAllocator> ueDiscPositionAlloc =
637 CreateObject<RandomDiscPositionAllocator>();
638 ueDiscPositionAlloc->SetX(0.0);
639 ueDiscPositionAlloc->SetY(0.0);
640 ueDiscPositionAlloc->SetZ(utHeight);
641 Ptr<UniformRandomVariable> randomDiscPos = CreateObject<UniformRandomVariable>();
642 randomDiscPos->SetAttribute(
"Min", DoubleValue(0));
643 randomDiscPos->SetAttribute(
"Max", DoubleValue(20));
644 ueDiscPositionAlloc->SetRho(randomDiscPos);
645 mobility.SetPositionAllocator(ueDiscPositionAlloc);
647 for (uint32_t i = 1; i < ueNodes.GetN(); i++)
649 mobility.Install(ueNodes.Get(i));
654 std::cout <<
"\n Topology configuration: " << gnbSites <<
" sites, " << sectors
655 <<
" sectors/site, " << gnbNodes.GetN() <<
" cells, " << ueNodes.GetN() <<
" UEs\n";
671 NodeContainer gnbSector1Container;
672 NodeContainer gnbSector2Container;
673 NodeContainer gnbSector3Container;
674 std::vector<NodeContainer*> gnbNodesBySector{&gnbSector1Container,
675 &gnbSector2Container,
676 &gnbSector3Container};
678 for (uint32_t cellId = 0; cellId < gnbNodes.GetN(); ++cellId)
680 Ptr<Node> gnb = gnbNodes.Get(cellId);
681 auto sectorIndex = deployment ==
"HEX" ? scenario->GetSectorIndex(cellId) : 0;
682 gnbNodesBySector[sectorIndex]->Add(gnb);
684 std::cout <<
" gNb containers: " << gnbSector1Container.GetN() <<
", "
685 << gnbSector2Container.GetN() <<
", " << gnbSector3Container.GetN() << std::endl;
696 NodeContainer ueSector1Container;
697 NodeContainer ueSector2Container;
698 NodeContainer ueSector3Container;
699 std::vector<NodeContainer*> ueNodesBySector{&ueSector1Container,
701 &ueSector3Container};
703 NodeContainer ueArSector1Container;
704 NodeContainer ueVrSector1Container;
705 NodeContainer ueCgSector1Container;
706 NodeContainer ueVoiceSector1Container;
707 NodeContainer ueArSector2Container;
708 NodeContainer ueVrSector2Container;
709 NodeContainer ueCgSector2Container;
710 NodeContainer ueVoiceSector2Container;
711 NodeContainer ueArSector3Container;
712 NodeContainer ueVrSector3Container;
713 NodeContainer ueCgSector3Container;
714 NodeContainer ueVoiceSector3Container;
716 std::vector<NodeContainer*> ueVoiceBySector{&ueVoiceSector1Container,
717 &ueVoiceSector2Container,
718 &ueVoiceSector3Container};
719 std::vector<NodeContainer*> ueArBySector{&ueArSector1Container,
720 &ueArSector2Container,
721 &ueArSector3Container};
722 std::vector<NodeContainer*> ueVrBySector{&ueVrSector1Container,
723 &ueVrSector2Container,
724 &ueVrSector3Container};
725 std::vector<NodeContainer*> ueCgBySector{&ueCgSector1Container,
726 &ueCgSector2Container,
727 &ueCgSector3Container};
729 uint32_t voiceUeCnt = voiceUeNum * gnbNodes.GetN();
730 uint32_t arUeCnt = arUeNum * gnbNodes.GetN();
731 uint32_t vrUeCnt = vrUeNum * gnbNodes.GetN();
732 uint32_t cgUeCnt = cgUeNum * gnbNodes.GetN();
734 for (uint32_t ueId = 0; ueId < ueNodes.GetN(); ++ueId)
736 Ptr<Node> ue = ueNodes.Get(ueId);
737 auto cellId = deployment ==
"HEX" ? scenario->GetCellIndex(ueId) : 0;
738 auto sectorIndex = deployment ==
"HEX" ? scenario->GetSectorIndex(cellId) : 0;
739 ueNodesBySector[sectorIndex]->Add(ue);
743 ueVoiceBySector[sectorIndex]->Add(ue);
746 else if (arUeCnt > 0)
748 ueArBySector[sectorIndex]->Add(ue);
751 else if (vrUeCnt > 0)
753 ueVrBySector[sectorIndex]->Add(ue);
756 else if (cgUeCnt > 0)
758 ueCgBySector[sectorIndex]->Add(ue);
762 std::cout <<
" UE containers: " << ueSector1Container.GetN() <<
", "
763 << ueSector2Container.GetN() <<
", " << ueSector3Container.GetN() << std::endl;
765 std::cout <<
" UE Traffic containers: "
767 <<
"Sector 1: " << ueVoiceSector1Container.GetN() <<
", "
768 << ueArSector1Container.GetN() <<
", " << ueVrSector1Container.GetN() <<
", "
769 << ueCgSector1Container.GetN() <<
", "
770 <<
"Sector 2: " << ueVoiceSector2Container.GetN() <<
", "
771 << ueArSector2Container.GetN() <<
", " << ueVrSector2Container.GetN() <<
", "
772 << ueCgSector2Container.GetN() <<
", "
773 <<
"Sector 3: " << ueVoiceSector3Container.GetN() <<
", "
774 << ueArSector3Container.GetN() <<
", " << ueVrSector3Container.GetN() <<
", "
775 << ueCgSector3Container.GetN() <<
", " << std::endl;
778 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
780 Ptr<NrPointToPointEpcHelper> epcHelper = CreateObject<NrPointToPointEpcHelper>();
781 nrHelper->SetEpcHelper(epcHelper);
783 Ptr<IdealBeamformingHelper> idealBeamformingHelper;
784 idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
786 uint8_t numScPerRb = 1;
787 double rbOverhead = 0.04;
788 uint32_t harqProcesses = 16;
790 uint32_t n1Delay = 2;
791 uint32_t n2Delay = 2;
792 uint8_t dlCtrlSymbols = 1;
795 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
798 propChannelCondition =
"LOS";
802 propScenario ==
"UMa" || propScenario ==
"RMa" || propScenario ==
"InH-OfficeOpen",
803 "Unsupported scenario " << scenario <<
". Supported values: UMa, RMa, InH-OfficeOpen");
805 channelHelper->ConfigureFactories(propScenario, propChannelCondition);
806 channelHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(enableShadowing));
809 channelHelper->SetChannelConditionModelAttribute(
811 TimeValue(MilliSeconds(channelConditionUpdatePeriod)));
816 ObjectFactory distanceBasedChannelFactory;
817 if (deployment ==
"HEX")
819 distanceBasedChannelFactory.SetTypeId(
820 DistanceBasedThreeGppSpectrumPropagationLossModel::GetTypeId());
821 distanceBasedChannelFactory.Set(
"MaxDistance", DoubleValue(2 * isd));
822 channelHelper->SetChannelConditionModelAttribute(
823 "LinkO2iConditionToAntennaHeight",
824 BooleanValue(linkO2iConditionToAntennaHeight));
825 channelHelper->SetChannelConditionModelAttribute(
"O2iThreshold", DoubleValue(o2iThreshold));
826 channelHelper->SetChannelConditionModelAttribute(
"O2iLowLossThreshold",
827 DoubleValue(o2iLowLossThreshold));
829 std::cout <<
"o2iThreshold: " << o2iThreshold << std::endl;
833 nrHelper->EnableFhControl();
834 nrHelper->SetFhControlAttribute(
"FhControlMethod", StringValue(fhControlMethod));
835 nrHelper->SetFhControlAttribute(
"FhCapacity", UintegerValue(fhCapacity));
836 nrHelper->SetFhControlAttribute(
"OverheadDyn", UintegerValue(ohDyn));
839 std::stringstream scheduler;
842 subType = !enableOfdma ?
"Tdma" :
"Ofdma";
843 scheduler <<
"ns3::NrMacScheduler" << subType << schedulerType;
844 std::cout <<
"Scheduler: " << scheduler.str() << std::endl;
845 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(scheduler.str()));
849 nrHelper->SetGnbPhyAttribute(
"Pattern", StringValue(pattern));
853 nrHelper->SetUlErrorModel(errorModel);
854 nrHelper->SetDlErrorModel(errorModel);
860 if (deployment ==
"HEX")
862 Config::SetDefault(
"ns3::NrMacSchedulerSrsDefault::StartingPeriodicity", UintegerValue(16));
864 nrHelper->SetSchedulerAttribute(
"SrsSymbols", UintegerValue(1));
865 nrHelper->SetSchedulerAttribute(
"EnableSrsInUlSlots", BooleanValue(
false));
866 nrHelper->SetSchedulerAttribute(
"EnableSrsInFSlots", BooleanValue(
false));
872 nrHelper->SetGnbDlAmcAttribute(
"NumRefScPerRb", UintegerValue(numScPerRb));
873 nrHelper->SetGnbUlAmcAttribute(
"NumRefScPerRb",
876 nrHelper->SetGnbPhyAttribute(
"RbOverhead", DoubleValue(rbOverhead));
877 nrHelper->SetGnbPhyAttribute(
"N2Delay", UintegerValue(n2Delay));
878 nrHelper->SetGnbPhyAttribute(
"N1Delay", UintegerValue(n1Delay));
880 nrHelper->SetUeMacAttribute(
"NumHarqProcess", UintegerValue(harqProcesses));
881 nrHelper->SetGnbMacAttribute(
"NumHarqProcess", UintegerValue(harqProcesses));
884 nrHelper->SetSchedulerAttribute(
"DlCtrlSymbols", UintegerValue(dlCtrlSymbols));
887 nrHelper->SetSchedulerAttribute(
"EnableHarqReTx", BooleanValue(enableHarqRetx));
888 nrHelper->SetGnbPhyAttribute(
"TxPower", DoubleValue(txPower));
889 nrHelper->SetGnbPhyAttribute(
"Numerology", UintegerValue(numerology));
890 nrHelper->SetUePhyAttribute(
"TxPower", DoubleValue(ueTxPower));
892 nrHelper->SetSchedulerAttribute(
"FixedMcsDl", BooleanValue(useFixedMcs));
893 nrHelper->SetSchedulerAttribute(
"FixedMcsUl", BooleanValue(useFixedMcs));
896 nrHelper->SetSchedulerAttribute(
"StartingMcsDl", UintegerValue(fixedMcs));
897 nrHelper->SetSchedulerAttribute(
"StartingMcsUl", UintegerValue(fixedMcs));
901 nrHelper->SetGnbPhyAttribute(
"NoiseFigure", DoubleValue(gnbNoiseFigure));
903 nrHelper->SetUePhyAttribute(
"NoiseFigure", DoubleValue(ueNoiseFigure));
905 const double band0Start = centralFrequency;
907 double bandwidthCc = numBwp * bandwidth;
908 uint8_t numCcPerBand = 1;
909 double bandwidthBand = numCcPerBand * bandwidthCc;
910 double bandCenter = band0Start + bandwidthBand / 2.0;
925 if (deployment ==
"SIMPLE")
931 channelHelper->AssignChannelsToBands({band0}, bandMask);
933 else if (deployment ==
"HEX" && freqScenario == 0)
935 NS_LOG_LOGIC(
"NON_OVERLAPPING, "
936 <<
": " << bandwidthBand <<
":" << bandwidthCc <<
", " << (
int)numCcPerBand
937 <<
", " << (
int)numBwp);
939 NS_LOG_LOGIC(
"bandConf0: " << bandCenter <<
" " << bandwidthBand);
941 bandConf0.m_numBwp = numBwp;
942 bandCenter += bandwidthBand;
944 NS_LOG_LOGIC(
"bandConf1: " << bandCenter <<
" " << bandwidthBand);
946 bandConf1.m_numBwp = numBwp;
947 bandCenter += bandwidthBand;
949 NS_LOG_LOGIC(
"bandConf2: " << bandCenter <<
" " << bandwidthBand);
951 bandConf2.m_numBwp = numBwp;
964 bandCenter = band0Start + bandwidth / 2.0;
966 NS_LOG_LOGIC(
"band0[0][0]: " << bandCenter <<
" " << bandwidth);
967 ConfigureBwpTo(band0.
m_cc[0]->m_bwp[0], bandCenter, bandwidth);
968 bandCenter += bandwidth;
970 NS_LOG_LOGIC(
"band1[0][0]: " << bandCenter <<
" " << bandwidth);
971 ConfigureBwpTo(band1.
m_cc[0]->m_bwp[0], bandCenter, bandwidth);
972 bandCenter += bandwidth;
974 NS_LOG_LOGIC(
"band2[0][0]: " << bandCenter <<
" " << bandwidth);
975 ConfigureBwpTo(band2.
m_cc[0]->m_bwp[0], bandCenter, bandwidth);
976 bandCenter += bandwidth;
978 std::cout <<
"BWP Configuration for NON_OVERLAPPING case "
980 << band0 << band1 << band2;
983 for (
size_t i = 0; i < band0.
GetBwps().size(); i++)
985 auto distanceBased3gpp =
986 distanceBasedChannelFactory
987 .Create<DistanceBasedThreeGppSpectrumPropagationLossModel>();
988 distanceBased3gpp->SetChannelModelAttribute(
990 DoubleValue(band0.
GetBwpAt(0, i)->m_centralFrequency));
991 distanceBased3gpp->SetChannelModelAttribute(
"Scenario", StringValue(propScenario));
995 PointerValue channelConditionModel0;
996 specChannelBand0->GetPropagationLossModel()->GetAttribute(
"ChannelConditionModel",
997 channelConditionModel0);
998 distanceBased3gpp->SetChannelModelAttribute(
999 "ChannelConditionModel",
1000 PointerValue(channelConditionModel0.Get<ChannelConditionModel>()));
1001 specChannelBand0->AddPhasedArraySpectrumPropagationLossModel(distanceBased3gpp);
1003 band0.
GetBwpAt(0, i)->SetChannel(specChannelBand0);
1005 for (
size_t i = 0; i < band1.
GetBwps().size(); i++)
1007 auto distanceBased3gpp =
1008 distanceBasedChannelFactory
1009 .Create<DistanceBasedThreeGppSpectrumPropagationLossModel>();
1010 distanceBased3gpp->SetChannelModelAttribute(
1012 DoubleValue(band1.
GetBwpAt(0, i)->m_centralFrequency));
1013 distanceBased3gpp->SetChannelModelAttribute(
"Scenario", StringValue(propScenario));
1017 PointerValue channelConditionModel1;
1018 specChannelBand1->GetPropagationLossModel()->GetAttribute(
"ChannelConditionModel",
1019 channelConditionModel1);
1020 distanceBased3gpp->SetChannelModelAttribute(
1021 "ChannelConditionModel",
1022 PointerValue(channelConditionModel1.Get<ChannelConditionModel>()));
1023 specChannelBand1->AddPhasedArraySpectrumPropagationLossModel(distanceBased3gpp);
1025 band1.
GetBwpAt(0, i)->SetChannel(specChannelBand1);
1027 for (
size_t i = 0; i < band2.GetBwps().size(); i++)
1029 auto distanceBased3gpp =
1030 distanceBasedChannelFactory
1031 .Create<DistanceBasedThreeGppSpectrumPropagationLossModel>();
1032 distanceBased3gpp->SetAttribute(
"MaxDistance", DoubleValue(2 * isd));
1033 distanceBased3gpp->SetChannelModelAttribute(
"Scenario", StringValue(propScenario));
1034 distanceBased3gpp->SetChannelModelAttribute(
1036 DoubleValue(band2.GetBwpAt(0, i)->m_centralFrequency));
1040 PointerValue channelConditionModel2;
1041 specChannelBand2->GetPropagationLossModel()->GetAttribute(
"ChannelConditionModel",
1042 channelConditionModel2);
1043 distanceBased3gpp->SetChannelModelAttribute(
1044 "ChannelConditionModel",
1045 PointerValue(channelConditionModel2.Get<ChannelConditionModel>()));
1046 specChannelBand2->AddPhasedArraySpectrumPropagationLossModel(distanceBased3gpp);
1048 band2.GetBwpAt(0, i)->SetChannel(specChannelBand2);
1051 else if (deployment ==
"HEX" && freqScenario == 1)
1053 NS_LOG_LOGIC(
"OVERLAPPING, " << bandwidthBand <<
":" << bandwidthCc <<
":" << bandwidth
1054 <<
", " << (
int)numCcPerBand <<
", " << (
int)numBwp);
1056 NS_LOG_LOGIC(
"bandConf0: " << bandCenter <<
" " << bandwidthBand);
1058 bandConf0.m_numBwp = numBwp;
1059 bandCenter += bandwidthBand;
1066 bandCenter = band0Start + bandwidth / 2.0;
1068 NS_LOG_LOGIC(
"band0[0][0]: " << bandCenter <<
" " << bandwidth);
1069 ConfigureBwpTo(band0.
m_cc[0]->m_bwp[0], bandCenter, bandwidth);
1070 bandCenter += bandwidth;
1072 for (
size_t i = 0; i < band0.
GetBwps().size(); i++)
1074 auto distanceBased3gpp =
1075 distanceBasedChannelFactory
1076 .Create<DistanceBasedThreeGppSpectrumPropagationLossModel>();
1077 distanceBased3gpp->SetChannelModelAttribute(
1079 DoubleValue(band0.
GetBwpAt(0, i)->m_centralFrequency));
1080 distanceBased3gpp->SetChannelModelAttribute(
"Scenario", StringValue(propScenario));
1084 PointerValue channelConditionModel0;
1085 specChannelBand0->GetPropagationLossModel()->GetAttribute(
"ChannelConditionModel",
1086 channelConditionModel0);
1087 distanceBased3gpp->SetChannelModelAttribute(
1088 "ChannelConditionModel",
1089 PointerValue(channelConditionModel0.Get<ChannelConditionModel>()));
1090 specChannelBand0->AddPhasedArraySpectrumPropagationLossModel(distanceBased3gpp);
1092 band0.
GetBwpAt(0, i)->SetChannel(specChannelBand0);
1100 if (deployment ==
"SIMPLE")
1104 else if (deployment ==
"HEX" && freqScenario == 0)
1118 if (deployment ==
"HEX")
1120 if (bfMethod ==
"Omni")
1122 idealBeamformingHelper->SetBeamformingMethod(
1125 else if (bfMethod ==
"CellScan")
1128 idealBeamformingHelper->SetAttribute(
"BeamformingPeriodicity",
1129 TimeValue(MilliSeconds(10)));
1132 else if (deployment ==
"SIMPLE")
1134 idealBeamformingHelper->SetAttribute(
1135 "BeamformingMethod",
1140 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
1143 bearingAngleGnb = bearingAngleGnb * (M_PI / 180);
1144 bearingAngleUe = bearingAngleUe * (M_PI / 180);
1146 epcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
1148 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(gnbNumRows));
1149 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(gnbNumColumns));
1150 nrHelper->SetGnbAntennaAttribute(
"AntennaHorizontalSpacing", DoubleValue(gnbHSpacing));
1151 nrHelper->SetGnbAntennaAttribute(
"AntennaVerticalSpacing", DoubleValue(gnbVSpacing));
1152 nrHelper->SetGnbAntennaAttribute(
"DowntiltAngle", DoubleValue(downtiltAngle * M_PI / 180.0));
1153 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
1154 PointerValue(CreateObject<IsotropicAntennaModel>()));
1155 nrHelper->SetGnbAntennaAttribute(
"BearingAngle", DoubleValue(bearingAngleGnb));
1157 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(ueNumRows));
1158 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(ueNumColumns));
1159 nrHelper->SetUeAntennaAttribute(
"AntennaHorizontalSpacing", DoubleValue(ueHSpacing));
1160 nrHelper->SetUeAntennaAttribute(
"AntennaVerticalSpacing", DoubleValue(ueVSpacing));
1161 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
1162 PointerValue(CreateObject<IsotropicAntennaModel>()));
1163 nrHelper->SetUeAntennaAttribute(
"BearingAngle", DoubleValue(bearingAngleUe));
1165 if (enableMimoFeedback)
1167 polSlantAngleGnb = bearingAngleGnb * (M_PI / 180);
1169 nrHelper->SetGnbAntennaAttribute(
"IsDualPolarized", BooleanValue(isGnbDualPolarized));
1170 nrHelper->SetGnbAntennaAttribute(
"NumHorizontalPorts", UintegerValue(gnbHorizPorts));
1171 nrHelper->SetGnbAntennaAttribute(
"NumVerticalPorts", UintegerValue(gnbVertPorts));
1172 nrHelper->SetGnbAntennaAttribute(
"PolSlantAngle", DoubleValue(polSlantAngleGnb));
1174 polSlantAngleUe = polSlantAngleUe * (M_PI / 180);
1176 nrHelper->SetUeAntennaAttribute(
"IsDualPolarized", BooleanValue(isUeDualPolarized));
1177 nrHelper->SetUeAntennaAttribute(
"NumHorizontalPorts", UintegerValue(ueHorizPorts));
1178 nrHelper->SetUeAntennaAttribute(
"NumVerticalPorts", UintegerValue(ueVertPorts));
1179 nrHelper->SetUeAntennaAttribute(
"PolSlantAngle", DoubleValue(polSlantAngleUe));
1181 nrHelper->SetupMimoPmi(mimoPmiParams);
1184 uint32_t bwpIdForLowLat = 0;
1185 uint32_t bwpIdForVoice = 0;
1186 uint32_t bwpIdForVR = 0;
1189 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB",
1190 UintegerValue(bwpIdForLowLat));
1191 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
1194 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdForLowLat));
1195 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
1197 if (enableInterServ)
1199 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"DGBR_INTER_SERV_87",
1200 UintegerValue(bwpIdForVR));
1201 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"DGBR_INTER_SERV_87",
1202 UintegerValue(bwpIdForVR));
1206 nrHelper->Initialize();
1208 NetDeviceContainer gnbSector1NetDev;
1209 NetDeviceContainer gnbSector2NetDev;
1210 NetDeviceContainer gnbSector3NetDev;
1212 NetDeviceContainer ueVoiceSector1NetDev;
1213 NetDeviceContainer ueArSector1NetDev;
1214 NetDeviceContainer ueVrSector1NetDev;
1215 NetDeviceContainer ueCgSector1NetDev;
1216 NetDeviceContainer ueVoiceSector2NetDev;
1217 NetDeviceContainer ueArSector2NetDev;
1218 NetDeviceContainer ueVrSector2NetDev;
1219 NetDeviceContainer ueCgSector2NetDev;
1220 NetDeviceContainer ueVoiceSector3NetDev;
1221 NetDeviceContainer ueArSector3NetDev;
1222 NetDeviceContainer ueVrSector3NetDev;
1223 NetDeviceContainer ueCgSector3NetDev;
1226 std::vector<NetDeviceContainer*> gnbNdBySector{&gnbSector1NetDev,
1229 std::vector<NetDeviceContainer*> ueNdBySector{&ueVoiceSector1NetDev,
1230 &ueVoiceSector2NetDev,
1231 &ueVoiceSector3NetDev};
1233 gnbSector1NetDev = nrHelper->InstallGnbDevice(gnbSector1Container, sector1Bwps);
1234 NetDeviceContainer gnbNetDevs(gnbSector1NetDev);
1236 ueVoiceSector1NetDev = nrHelper->InstallUeDevice(ueVoiceSector1Container, sector1Bwps);
1237 ueArSector1NetDev = nrHelper->InstallUeDevice(ueArSector1Container, sector1Bwps);
1238 ueVrSector1NetDev = nrHelper->InstallUeDevice(ueVrSector1Container, sector1Bwps);
1239 ueCgSector1NetDev = nrHelper->InstallUeDevice(ueCgSector1Container, sector1Bwps);
1241 NetDeviceContainer ueNetDevs(ueVoiceSector1NetDev);
1242 ueNetDevs.Add(ueArSector1NetDev);
1243 ueNetDevs.Add(ueVrSector1NetDev);
1244 ueNetDevs.Add(ueCgSector1NetDev);
1246 if (deployment ==
"HEX")
1248 gnbSector2NetDev = nrHelper->InstallGnbDevice(gnbSector2Container, sector2Bwps);
1249 gnbNetDevs.Add(gnbSector2NetDev);
1250 gnbSector3NetDev = nrHelper->InstallGnbDevice(gnbSector3Container, sector3Bwps);
1251 gnbNetDevs.Add(gnbSector3NetDev);
1253 ueVoiceSector2NetDev = nrHelper->InstallUeDevice(ueVoiceSector2Container, sector2Bwps);
1254 ueArSector2NetDev = nrHelper->InstallUeDevice(ueArSector2Container, sector2Bwps);
1255 ueVrSector2NetDev = nrHelper->InstallUeDevice(ueVrSector2Container, sector2Bwps);
1256 ueCgSector2NetDev = nrHelper->InstallUeDevice(ueCgSector2Container, sector2Bwps);
1257 ueNetDevs.Add(ueVoiceSector2NetDev);
1258 ueNetDevs.Add(ueArSector2NetDev);
1259 ueNetDevs.Add(ueVrSector2NetDev);
1260 ueNetDevs.Add(ueCgSector2NetDev);
1262 ueVoiceSector3NetDev = nrHelper->InstallUeDevice(ueVoiceSector3Container, sector3Bwps);
1263 ueArSector3NetDev = nrHelper->InstallUeDevice(ueArSector3Container, sector3Bwps);
1264 ueVrSector3NetDev = nrHelper->InstallUeDevice(ueVrSector3Container, sector3Bwps);
1265 ueCgSector3NetDev = nrHelper->InstallUeDevice(ueCgSector3Container, sector3Bwps);
1266 ueNetDevs.Add(ueVoiceSector3NetDev);
1267 ueNetDevs.Add(ueArSector3NetDev);
1268 ueNetDevs.Add(ueVrSector3NetDev);
1269 ueNetDevs.Add(ueCgSector3NetDev);
1272 int64_t randomStream = 1;
1273 randomStream += nrHelper->AssignStreams(gnbNetDevs, randomStream);
1274 randomStream += nrHelper->AssignStreams(ueNetDevs, randomStream);
1277 std::vector<double> sectorOrientationRad{
1279 sector0AngleRad + 2.0 * M_PI / 3.0,
1280 sector0AngleRad - 2.0 * M_PI / 3.0
1284 if (deployment ==
"HEX")
1286 for (uint32_t cellId = 0; cellId < gnbNetDevs.GetN(); ++cellId)
1288 Ptr<NetDevice> gnb = gnbNetDevs.Get(cellId);
1289 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
1292 NS_ABORT_MSG(
"Incorrect number of BWPs per CC");
1295 uint32_t sector = cellId % (gnbSector3NetDev.GetN() == 0 ? 1 : 3);
1296 double orientation = sectorOrientationRad[sector];
1299 ConfigurePhy(nrHelper, gnb, orientation, bfConfSector, bfConfElevation);
1303 nrHelper->ConfigureFhControl(gnbSector1NetDev);
1304 if (deployment ==
"HEX")
1306 nrHelper->ConfigureFhControl(gnbSector2NetDev);
1307 nrHelper->ConfigureFhControl(gnbSector3NetDev);
1310 PrintUePosition(ueNodes);
1314 Ptr<Node> pgw = epcHelper->GetPgwNode();
1315 NodeContainer remoteHostContainer;
1316 remoteHostContainer.Create(1);
1317 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
1318 InternetStackHelper internet;
1319 internet.Install(remoteHostContainer);
1322 PointToPointHelper p2ph;
1323 p2ph.SetDeviceAttribute(
"DataRate", DataRateValue(DataRate(
"100Gb/s")));
1324 p2ph.SetDeviceAttribute(
"Mtu", UintegerValue(1000));
1325 p2ph.SetChannelAttribute(
"Delay", TimeValue(Seconds(0.000)));
1326 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
1327 Ipv4AddressHelper ipv4h;
1328 ipv4h.SetBase(
"1.0.0.0",
"255.0.0.0");
1329 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
1331 Ipv4StaticRoutingHelper ipv4RoutingHelper;
1332 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
1333 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
1334 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address(
"7.0.0.0"), Ipv4Mask(
"255.0.0.0"), 1);
1335 internet.Install(ueNodes);
1337 Ipv4InterfaceContainer ueVoiceSector1IpIface;
1338 Ipv4InterfaceContainer ueArSector1IpIface;
1339 Ipv4InterfaceContainer ueVrSector1IpIface;
1340 Ipv4InterfaceContainer ueCgSector1IpIface;
1342 Ipv4InterfaceContainer ueVoiceSector2IpIface;
1343 Ipv4InterfaceContainer ueArSector2IpIface;
1344 Ipv4InterfaceContainer ueVrSector2IpIface;
1345 Ipv4InterfaceContainer ueCgSector2IpIface;
1347 Ipv4InterfaceContainer ueVoiceSector3IpIface;
1348 Ipv4InterfaceContainer ueArSector3IpIface;
1349 Ipv4InterfaceContainer ueVrSector3IpIface;
1350 Ipv4InterfaceContainer ueCgSector3IpIface;
1352 ueVoiceSector1IpIface =
1353 epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVoiceSector1NetDev));
1354 ueArSector1IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueArSector1NetDev));
1355 ueVrSector1IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVrSector1NetDev));
1356 ueCgSector1IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueCgSector1NetDev));
1358 if (deployment ==
"HEX")
1360 ueVoiceSector2IpIface =
1361 epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVoiceSector2NetDev));
1362 ueArSector2IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueArSector2NetDev));
1363 ueVrSector2IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVrSector2NetDev));
1364 ueCgSector2IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueCgSector2NetDev));
1366 ueVoiceSector3IpIface =
1367 epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVoiceSector3NetDev));
1368 ueArSector3IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueArSector3NetDev));
1369 ueVrSector3IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVrSector3NetDev));
1370 ueCgSector3IpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueCgSector3NetDev));
1374 nrHelper->AttachToClosestGnb(ueVoiceSector1NetDev, gnbSector1NetDev);
1375 nrHelper->AttachToClosestGnb(ueArSector1NetDev, gnbSector1NetDev);
1376 nrHelper->AttachToClosestGnb(ueVrSector1NetDev, gnbSector1NetDev);
1377 nrHelper->AttachToClosestGnb(ueCgSector1NetDev, gnbSector1NetDev);
1379 if (deployment ==
"HEX")
1381 nrHelper->AttachToClosestGnb(ueVoiceSector2NetDev, gnbSector2NetDev);
1382 nrHelper->AttachToClosestGnb(ueArSector2NetDev, gnbSector2NetDev);
1383 nrHelper->AttachToClosestGnb(ueVrSector2NetDev, gnbSector2NetDev);
1384 nrHelper->AttachToClosestGnb(ueCgSector2NetDev, gnbSector2NetDev);
1386 nrHelper->AttachToClosestGnb(ueVoiceSector3NetDev, gnbSector3NetDev);
1387 nrHelper->AttachToClosestGnb(ueArSector3NetDev, gnbSector3NetDev);
1388 nrHelper->AttachToClosestGnb(ueVrSector3NetDev, gnbSector3NetDev);
1389 nrHelper->AttachToClosestGnb(ueCgSector3NetDev, gnbSector3NetDev);
1393 ApplicationContainer serverApps;
1396 std::string transportProtocol;
1397 transportProtocol = useUdp ?
"ns3::UdpSocketFactory" :
"ns3::TcpSocketFactory";
1400 uint16_t dlPortArStart = 1121;
1401 uint16_t dlPortArStop = 1124;
1402 uint16_t dlPortVrStart = 1131;
1403 uint16_t dlPortCgStart = 1141;
1405 uint16_t dlPortVoiceStart = 1254;
1408 uint16_t ulPortArStart = 2121;
1409 uint16_t ulPortArStop = 2124;
1410 uint16_t ulPortVoiceStart = 2254;
1415 Ptr<NrEpcTft> arTft = Create<NrEpcTft>();
1417 std::vector<Ptr<NrEpcTft>> arTfts;
1428 for (uint32_t i = 0; i < 3; i++)
1430 Ptr<NrEpcTft> tempTft = Create<NrEpcTft>();
1433 tempTft->Add(dlpfAr);
1434 arTfts.push_back(tempTft);
1443 Ptr<NrEpcTft> vrTft = Create<NrEpcTft>();
1452 Ptr<NrEpcTft> cgTft = Create<NrEpcTft>();
1461 Ptr<NrEpcTft> voiceTft = Create<NrEpcTft>();
1465 voiceTft->Add(dlpfVoice);
1471 Ptr<NrEpcTft> arUlTft = Create<NrEpcTft>();
1473 std::vector<Ptr<NrEpcTft>> arUlTfts;
1480 arUlTft->Add(ulpfAr);
1485 for (uint32_t i = 0; i < 3; i++)
1487 Ptr<NrEpcTft> tempTft = Create<NrEpcTft>();
1491 tempTft->Add(ulpfAr);
1492 arUlTfts.push_back(tempTft);
1499 Ptr<NrEpcTft> voiceUlTft = Create<NrEpcTft>();
1504 voiceUlTft->Add(ulpfVoice);
1507 ApplicationContainer clientApps;
1508 ApplicationContainer pingApps;
1510 auto sectorContainers =
1511 std::vector<std::tuple<NodeContainer, NetDeviceContainer, Ipv4InterfaceContainer>>{
1512 {ueVoiceSector1Container, ueVoiceSector1NetDev, ueVoiceSector1IpIface},
1513 {ueVoiceSector2Container, ueVoiceSector2NetDev, ueVoiceSector2IpIface},
1514 {ueVoiceSector3Container, ueVoiceSector3NetDev, ueVoiceSector3IpIface}};
1516 VoiceApplicationSettings voiceAppSettings = {
1517 .uePort = dlPortVoiceStart,
1518 .transportProtocol = transportProtocol,
1519 .nrHelper = nrHelper,
1520 .bearer = voiceBearer,
1522 .serverApps = serverApps,
1523 .clientApps = clientApps,
1524 .pingApps = pingApps,
1528 for (
auto [nodeContainer, netDevContainer, ipIfaceContainer] : sectorContainers)
1530 for (uint32_t i = 0; i < nodeContainer.GetN(); ++i)
1532 voiceAppSettings.ue = nodeContainer.Get(i);
1533 voiceAppSettings.ueNetDev = netDevContainer.Get(i);
1534 voiceAppSettings.ueIp = ipIfaceContainer.GetAddress(i, 0);
1535 voiceAppSettings.remoteHost = remoteHostContainer.Get(0);
1536 ConfigureVoiceApp(voiceAppSettings);
1540 uint16_t remoteHostPort = 3254;
1543 voiceAppSettings.bearer = voiceUlBearer;
1544 voiceAppSettings.tft = voiceUlTft;
1545 voiceAppSettings.direction =
"UL";
1546 for (
auto [nodeContainer, netDevContainer, ipIfaceContainer] : sectorContainers)
1548 for (uint32_t i = 0; i < nodeContainer.GetN(); ++i)
1550 voiceAppSettings.uePort = remoteHostPort++;
1551 ConfigureVoiceApp(voiceAppSettings);
1564 for (uint32_t i = 0; i < ueArSector1Container.GetN(); ++i)
1566 ConfigureXrApp(ueArSector1Container,
1572 remoteHostContainer,
1588 internetIpIfaces.GetAddress(1),
1600 for (uint32_t i = 0; i < ueArSector2Container.GetN(); ++i)
1602 ConfigureXrApp(ueArSector2Container,
1608 remoteHostContainer,
1624 internetIpIfaces.GetAddress(1),
1627 for (uint32_t i = 0; i < ueArSector3Container.GetN(); ++i)
1629 ConfigureXrApp(ueArSector3Container,
1635 remoteHostContainer,
1651 internetIpIfaces.GetAddress(1),
1657 remoteHostPort = 4121;
1658 for (uint32_t i = 0; i < ueArSector1Container.GetN(); ++i)
1660 ConfigureXrApp(ueArSector1Container,
1666 remoteHostContainer,
1682 internetIpIfaces.GetAddress(1),
1684 remoteHostPort += 3;
1686 for (uint32_t i = 0; i < ueArSector2Container.GetN(); ++i)
1688 ConfigureXrApp(ueArSector2Container,
1694 remoteHostContainer,
1710 internetIpIfaces.GetAddress(1),
1712 remoteHostPort += 3;
1714 for (uint32_t i = 0; i < ueArSector3Container.GetN(); ++i)
1716 ConfigureXrApp(ueArSector3Container,
1722 remoteHostContainer,
1738 internetIpIfaces.GetAddress(1),
1740 remoteHostPort += 3;
1744 for (uint32_t i = 0; i < ueVrSector1Container.GetN(); ++i)
1746 ConfigureXrApp(ueVrSector1Container,
1752 remoteHostContainer,
1768 internetIpIfaces.GetAddress(1),
1771 for (uint32_t i = 0; i < ueVrSector2Container.GetN(); ++i)
1773 ConfigureXrApp(ueVrSector2Container,
1779 remoteHostContainer,
1795 internetIpIfaces.GetAddress(1),
1798 for (uint32_t i = 0; i < ueVrSector3Container.GetN(); ++i)
1800 ConfigureXrApp(ueVrSector3Container,
1806 remoteHostContainer,
1822 internetIpIfaces.GetAddress(1),
1826 for (uint32_t i = 0; i < ueCgSector1Container.GetN(); ++i)
1828 ConfigureXrApp(ueCgSector1Container,
1834 remoteHostContainer,
1850 internetIpIfaces.GetAddress(1),
1853 for (uint32_t i = 0; i < ueCgSector2Container.GetN(); ++i)
1855 ConfigureXrApp(ueCgSector2Container,
1861 remoteHostContainer,
1877 internetIpIfaces.GetAddress(1),
1880 for (uint32_t i = 0; i < ueCgSector3Container.GetN(); ++i)
1882 ConfigureXrApp(ueCgSector3Container,
1888 remoteHostContainer,
1904 internetIpIfaces.GetAddress(1),
1908 pingApps.Start(MilliSeconds(100));
1909 pingApps.Stop(appStartTimeMs);
1912 serverApps.Start(appStartTimeMs);
1913 clientApps.Start(appStartTimeMs);
1914 serverApps.Stop(simTimeMs);
1915 clientApps.Stop(appStartTimeMs + appDuration);
1918 if (enableNrHelperTraces)
1920 nrHelper->EnableTraces();
1923 for (NetDeviceContainer::Iterator i = gnbSector1NetDev.Begin(); i != gnbSector1NetDev.End();
1926 Ptr<NrGnbNetDevice> gnbNetDev = DynamicCast<NrGnbNetDevice>(*i);
1927 gnbNetDev->GetNrFhControl()->TraceConnectWithoutContext(
"RequiredFhDlThroughput",
1928 MakeCallback(&ReportFhTrace));
1929 gnbNetDev->GetNrFhControl()->TraceConnectWithoutContext(
"UsedAirRbs",
1930 MakeCallback(&ReportAiTrace));
1933 if (deployment ==
"HEX")
1935 for (NetDeviceContainer::Iterator i = gnbSector2NetDev.Begin(); i != gnbSector2NetDev.End();
1938 Ptr<NrGnbNetDevice> gnbNetDev = DynamicCast<NrGnbNetDevice>(*i);
1939 gnbNetDev->GetNrFhControl()->TraceConnectWithoutContext(
"RequiredFhDlThroughput",
1940 MakeCallback(&ReportFhTrace));
1941 gnbNetDev->GetNrFhControl()->TraceConnectWithoutContext(
"UsedAirRbs",
1942 MakeCallback(&ReportAiTrace));
1945 for (NetDeviceContainer::Iterator i = gnbSector3NetDev.Begin(); i != gnbSector3NetDev.End();
1948 Ptr<NrGnbNetDevice> gnbNetDev = DynamicCast<NrGnbNetDevice>(*i);
1949 gnbNetDev->GetNrFhControl()->TraceConnectWithoutContext(
"RequiredFhDlThroughput",
1950 MakeCallback(&ReportFhTrace));
1951 gnbNetDev->GetNrFhControl()->TraceConnectWithoutContext(
"UsedAirRbs",
1952 MakeCallback(&ReportAiTrace));
1957 Ptr<NrRadioEnvironmentMapHelper> remHelper;
1961 std::cout <<
" rem helper\n";
1962 uint16_t remPhyIndex = 0;
1964 NetDeviceContainer remNd;
1965 Ptr<NetDevice> remDevice;
1967 std::vector<NetDeviceContainer*> remNdBySector{gnbNdBySector};
1968 std::vector<NetDeviceContainer*> remDevBySector{ueNdBySector};
1970 uint32_t sectorIndex = 0;
1972 for (uint32_t sector = sectors; sector > 0; --sector)
1974 if (remSector == sector || remSector == 0)
1976 sectorIndex = sector - 1;
1977 remNd.Add(*remNdBySector[sectorIndex]);
1978 remDevice = remDevBySector[sectorIndex]->Get(0);
1983 remHelper = CreateObject<NrRadioEnvironmentMapHelper>();
1984 remHelper->SetMinX(xMinRem);
1985 remHelper->SetMaxX(xMaxRem);
1986 remHelper->SetResX(xResRem);
1987 remHelper->SetMinY(yMinRem);
1988 remHelper->SetMaxY(yMaxRem);
1989 remHelper->SetResY(yResRem);
1990 remHelper->SetZ(zRem);
1993 for (uint32_t sector = sectors; sector > 0; --sector)
1995 if ((remSector == sector) || (remSector == 0))
1997 sectorIndex = sector - 1;
1998 for (uint32_t siteId = 0; siteId < gnbSites; ++siteId)
2000 gnbNdBySector[sectorIndex]
2003 ->GetPhy(remPhyIndex)
2004 ->ChangeBeamformingVector(
2005 DynamicCast<NrUeNetDevice>(ueNdBySector[sectorIndex]->Get(siteId)));
2010 remHelper->CreateRem(remNd, remDevice, remPhyIndex);
2013 FlowMonitorHelper flowmonHelper;
2014 NodeContainer endpointNodes;
2015 endpointNodes.Add(remoteHost);
2016 endpointNodes.Add(ueNodes);
2018 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
2019 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.0001));
2020 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
2021 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
2023 Simulator::Stop(simTimeMs);
2025 std::cout <<
"Run simulation" << std::endl;
2030 monitor->CheckForLostPackets();
2031 Ptr<Ipv4FlowClassifier> classifier =
2032 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
2033 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
2035 double averageFlowThroughput = 0.0;
2036 double averageFlowDelay = 0.0;
2038 std::ofstream delayFile;
2039 std::ofstream throughputFile;
2041 std::ostringstream delayFileName;
2042 std::ostringstream throughputFileName;
2045 delayFileName <<
"XR_Delay"
2046 <<
"_ar_" << std::to_string(arUeNum).c_str() <<
"_vr_"
2047 << std::to_string(vrUeNum).c_str() <<
"_cg_"
2048 << std::to_string(cgUeNum).c_str() <<
"_voice_"
2049 << std::to_string(voiceUeNum).c_str() <<
"_" << schedulerType.c_str()
2050 <<
"_Mx1_" << isMx1 <<
".txt";
2052 throughputFileName <<
"XR_Throughput"
2053 <<
"_ar_" << std::to_string(arUeNum).c_str() <<
"_vr_"
2054 << std::to_string(vrUeNum).c_str() <<
"_cg_"
2055 << std::to_string(cgUeNum).c_str() <<
"_voice_"
2056 << std::to_string(voiceUeNum).c_str() <<
"_" << schedulerType.c_str()
2057 <<
"_Mx1_" << isMx1 <<
".txt";
2061 delayFileName << outputDir <<
"Delay_" << simTag << std::string(
".txt").c_str();
2062 throughputFileName << outputDir <<
"Throughput_" << simTag << std::string(
".txt").c_str();
2065 if (enableQosTrafficTraces)
2067 delayFile.open(delayFileName.str());
2068 delayFile.setf(std::ios_base::fixed);
2070 if (!delayFile.is_open())
2072 NS_ABORT_MSG(
"Can't open file " << delayFileName.str());
2074 delayFile <<
"source_address"
2085 throughputFile.open(throughputFileName.str());
2086 throughputFile.setf(std::ios_base::fixed);
2088 if (!throughputFile.is_open())
2090 NS_ABORT_MSG(
"Can't open file " << throughputFileName.str());
2093 throughputFile <<
"source_port"
2103 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
2107 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
2109 if (enableQosTrafficTraces)
2111 for (uint32_t j = 0; j < i->second.delayHistogram.GetNBins(); j++)
2113 Histogram h = i->second.delayHistogram;
2114 if (h.GetBinCount(j))
2116 for (uint32_t k = 0; k < h.GetBinCount(j); k++)
2118 delayFile << t.sourceAddress <<
"\t" << t.sourcePort <<
"\t"
2119 << t.destinationAddress <<
"\t" << t.destinationPort <<
"\t"
2120 << h.GetBinStart(j) <<
"\n";
2126 std::stringstream protoStream;
2127 protoStream << (uint16_t)t.protocol;
2128 if (t.protocol == 6)
2130 protoStream.str(
"TCP");
2132 if (t.protocol == 17)
2134 protoStream.str(
"UDP");
2137 const Time& txDuration = appDuration;
2138 std::cout <<
"Flow " << i->first <<
" (" << t.sourceAddress <<
":" << t.sourcePort <<
" -> "
2139 << t.destinationAddress <<
":" << t.destinationPort <<
") proto "
2140 << protoStream.str() <<
"\n";
2141 std::cout <<
" Tx Packets: " << i->second.txPackets <<
"\n";
2142 std::cout <<
" Tx Bytes: " << i->second.txBytes <<
"\n";
2143 std::cout <<
" TxOffered: "
2144 << ((i->second.txBytes * 8.0) / txDuration.GetSeconds()) * 1e-6 <<
" Mbps\n";
2145 std::cout <<
" Rx Bytes: " << i->second.rxBytes <<
"\n";
2147 if (i->second.rxPackets > 0)
2150 Time rxDuration = Seconds(0);
2151 if (t.protocol == 6)
2153 rxDuration = appDuration;
2155 else if (t.protocol == 17)
2158 rxDuration = appDuration + MilliSeconds(10);
2166 averageFlowThroughput += ((i->second.rxBytes * 8.0) / rxDuration.GetSeconds()) * 1e-6;
2167 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
2169 double throughput = ((i->second.rxBytes * 8.0) / rxDuration.GetSeconds()) * 1e-6;
2170 double delay = 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
2171 double jitter = 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets;
2173 std::cout <<
" Throughput: " << throughput <<
" Mbps\n";
2174 std::cout <<
" Mean delay: " << delay <<
" ms\n";
2175 std::cout <<
" Mean jitter: " << jitter <<
" ms\n";
2177 if (enableQosTrafficTraces)
2179 throughputFile << t.sourcePort <<
"\t" << t.destinationPort <<
"\t" << throughput
2180 <<
"\t" << delay << std::endl;
2185 std::cout <<
" Throughput: 0 Mbps\n";
2186 std::cout <<
" Mean delay: 0 ms\n";
2187 std::cout <<
" Mean upt: 0 Mbps \n";
2188 std::cout <<
" Mean jitter: 0 ms\n";
2190 if (enableQosTrafficTraces)
2192 throughputFile << t.sourcePort <<
"\t" << t.destinationPort <<
"\t" << 0 <<
"\t"
2196 std::cout <<
" Rx Packets: " << i->second.rxPackets <<
"\n";
2200 throughputFile.close();
2202 std::cout <<
"\n\n Mean flow throughput: " << averageFlowThroughput / stats.size()
2204 std::cout <<
" Mean flow delay: " << averageFlowDelay / stats.size() <<
" ms\n";
2206 Simulator::Destroy();
2211PrintUePosition(NodeContainer ueNodes)
2213 std::ofstream outUePositionsFile;
2214 std::string filenameUePositions =
"uePositions.txt";
2216 outUePositionsFile.open(filenameUePositions.c_str());
2217 outUePositionsFile.setf(std::ios_base::fixed);
2219 if (!outUePositionsFile.is_open())
2221 NS_ABORT_MSG(
"Can't open file " << filenameUePositions);
2224 for (uint32_t ueId = 0; ueId < ueNodes.GetN(); ++ueId)
2226 Vector uepos = ueNodes.Get(ueId)->GetObject<MobilityModel>()->GetPosition();
2227 outUePositionsFile <<
"ueId: " << ueId <<
", at " << uepos << std::endl;
2230 outUePositionsFile.close();
2236 bwp->m_centralFrequency = centerFreq;
2237 bwp->m_higherFrequency = centerFreq + (bwpBw / 2);
2238 bwp->m_lowerFrequency = centerFreq - (bwpBw / 2);
2239 bwp->m_channelBandwidth = bwpBw;
2243ConfigurePhy(Ptr<NrHelper> nrHelper,
2245 double orientationRads,
2246 uint16_t beamConfSector,
2247 double beamConfElevation)
2250 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
2251 Ptr<UniformPlanarArray> antenna0 = ConstCast<UniformPlanarArray>(
2252 phy0->GetSpectrumPhy()->GetAntenna()->GetObject<UniformPlanarArray>());
2253 antenna0->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
2257 phy0->GetSpectrumPhy()->GetBeamManager()->SetPredefinedBeam(beamConfSector, beamConfElevation);
2261ConfigureXrApp(NodeContainer& ueContainer,
2263 Ipv4InterfaceContainer& ueIpIface,
2264 enum NrXrConfig config,
2266 std::string transportProtocol,
2267 NodeContainer& remoteHostContainer,
2268 NetDeviceContainer& ueNetDev,
2269 Ptr<NrHelper> nrHelper,
2273 std::vector<Ptr<NrEpcTft>>& tfts,
2274 ApplicationContainer& serverApps,
2275 ApplicationContainer& clientApps,
2276 ApplicationContainer& pingApps,
2277 std::string direction,
2283 Ipv4Address remoteHostAddress,
2284 uint16_t remoteHostPort)
2287 Ipv4Address ipAddress = ueIpIface.GetAddress(i, 0);
2288 trafficMixerHelper.ConfigureXr(config);
2289 auto it = XrPreconfig.find(config);
2291 Ipv4Address address = direction ==
"UL" ? remoteHostAddress : ipAddress;
2292 uint16_t port = direction ==
"UL" ? remoteHostPort : uePort;
2294 std::vector<Address> addresses;
2295 std::vector<InetSocketAddress> localAddresses;
2297 for (
size_t j = 0; j < it->second.size(); j++)
2299 addresses.push_back(InetSocketAddress(address, port + j));
2301 localAddresses.emplace_back(Ipv4Address::GetAny(), port + j);
2304 ApplicationContainer currentUeClientApps;
2308 PingHelper ping(address);
2310 if (direction ==
"UL")
2312 pingApps.Add(ping.Install(ueContainer.Get(i)));
2313 currentUeClientApps.Add(
2314 trafficMixerHelper.Install(transportProtocol, addresses, ueContainer.Get(i)));
2318 pingApps.Add(ping.Install(remoteHostContainer));
2319 currentUeClientApps.Add(
2320 trafficMixerHelper.Install(transportProtocol, addresses, remoteHostContainer.Get(0)));
2323 Ptr<NetDevice> ueDevice = ueNetDev.Get(i);
2326 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tft);
2331 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tft);
2335 NS_ASSERT(tfts.size() >= currentUeClientApps.GetN());
2336 for (uint32_t j = 0; j < currentUeClientApps.GetN(); j++)
2338 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tfts[j]);
2342 for (uint32_t j = 0; j < currentUeClientApps.GetN(); j++)
2344 PacketSinkHelper dlPacketSinkHelper(transportProtocol, localAddresses.at(j));
2345 Ptr<Application> packetSink;
2346 if (direction ==
"UL")
2348 packetSink = dlPacketSinkHelper.Install(remoteHostContainer.Get(0)).Get(0);
2352 packetSink = dlPacketSinkHelper.Install(ueContainer.Get(i)).Get(0);
2355 serverApps.Add(packetSink);
2357 Ptr<TrafficGenerator3gppGenericVideo> app =
2358 DynamicCast<TrafficGenerator3gppGenericVideo>(currentUeClientApps.Get(j));
2359 if (app && config == NrXrConfig::AR_M3)
2361 app->SetAttribute(
"DataRate", DoubleValue(arDataRate));
2362 app->SetAttribute(
"Fps", UintegerValue(arFps));
2364 else if (app && config == NrXrConfig::VR_DL1)
2366 app->SetAttribute(
"DataRate", DoubleValue(vrDataRate));
2367 app->SetAttribute(
"Fps", UintegerValue(vrFps));
2369 else if (app && config == NrXrConfig::CG_DL1)
2371 app->SetAttribute(
"DataRate", DoubleValue(cgDataRate));
2374 clientApps.Add(currentUeClientApps);
2378ConfigureVoiceApp(VoiceApplicationSettings& voiceAppSettings)
2380 Ipv4Address ipAddress = voiceAppSettings.ueIp;
2381 Ipv4Address address =
2382 voiceAppSettings.direction ==
"UL" ? voiceAppSettings.remoteHostAddress : ipAddress;
2383 uint16_t port = voiceAppSettings.direction ==
"UL" ? voiceAppSettings.remoteHostPort
2384 : voiceAppSettings.uePort;
2387 InetSocketAddress(address, port),
2392 PingHelper ping(ipAddress);
2394 if (voiceAppSettings.direction ==
"UL")
2396 voiceAppSettings.clientApps.Add(trafficGeneratorHelper.Install(voiceAppSettings.ue).Get(0));
2397 voiceAppSettings.pingApps.Add(ping.Install(voiceAppSettings.ue));
2401 voiceAppSettings.clientApps.Add(
2402 trafficGeneratorHelper.Install(voiceAppSettings.remoteHost));
2403 voiceAppSettings.pingApps.Add(ping.Install(voiceAppSettings.remoteHost));
2406 Ptr<NetDevice> ueDevice = voiceAppSettings.ueNetDev;
2408 voiceAppSettings.nrHelper->ActivateDedicatedEpsBearer(ueDevice,
2409 voiceAppSettings.bearer,
2410 voiceAppSettings.tft);
2412 InetSocketAddress localAddress(Ipv4Address::GetAny(), port);
2413 PacketSinkHelper dlPacketSinkHelper(voiceAppSettings.transportProtocol, localAddress);
2414 Ptr<Application> packetSink;
2415 if (voiceAppSettings.direction ==
"UL")
2417 packetSink = dlPacketSinkHelper.Install(voiceAppSettings.remoteHost).Get(0);
2421 packetSink = dlPacketSinkHelper.Install(voiceAppSettings.ue).Get(0);
2424 voiceAppSettings.serverApps.Add(packetSink);
2428ReportFhTrace(
const SfnSf& sfn, uint16_t physCellId, uint16_t bwpId, uint64_t reqFh)
2430 if (!m_fhTraceFile.is_open())
2432 std::stringstream fileName;
2433 fileName << m_outputDir <<
"fh-trace_" << m_fhControlMethod.c_str() <<
"_"
2434 << std::to_string(m_fhCapacity) <<
".txt";
2435 m_fhTraceFileName = fileName.str();
2436 m_fhTraceFile.open(m_fhTraceFileName.c_str());
2438 if (!m_fhTraceFile.is_open())
2440 NS_FATAL_ERROR(
"Could not open FH tracefile");
2443 m_fhTraceFile <<
"CellId"
2450 m_fhTraceFile << physCellId <<
"\t" << bwpId <<
"\t" << reqFh << std::endl;
2454ReportAiTrace(
const SfnSf& sfn, uint16_t physCellId, uint16_t bwpId, uint32_t airRbs)
2456 if (!m_aiTraceFile.is_open())
2458 std::stringstream fileName;
2459 fileName << m_outputDir <<
"air-trace_" << m_fhControlMethod.c_str() <<
"_"
2460 << std::to_string(m_fhCapacity) <<
".txt";
2461 m_aiTraceFileName = fileName.str();
2462 m_aiTraceFile.open(m_aiTraceFileName.c_str());
2464 if (!m_aiTraceFile.is_open())
2466 NS_FATAL_ERROR(
"Could not open Air tracefile");
2469 m_aiTraceFile << physCellId <<
"\t" << bwpId <<
"\t" << airRbs << std::endl;
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.
The HexagonalGridScenarioHelper class.
void SetNumRings(uint8_t numRings)
Sets the number of outer rings of sites around the central site.
void CreateScenarioWithMobility(const Vector &speed, double percentage)
This function can be used to create a scenario with UEs with mobility and define a percentage of UEs,...
Represents a scenario with base stations and user terminals.
const NodeContainer & GetUserTerminals() const
Get the list of user nodes.
std::size_t GetNumSites() const
Gets the number of sites with cell base stations.
void SetUtNumber(std::size_t n)
Set the number of UT/UE.
const NodeContainer & GetBaseStations() const
Get the list of gnb/base station nodes.
double GetAntennaOrientationRadians(std::size_t cellId) const
Returns the orientation in radians of the antenna array for the given cellId.
@ ErrorModel
Error Model version (can use different error models, see NrErrorModel)
@ INIT_PROPAGATION
Initialize the propagation loss model.
@ INIT_FADING
Initialize the fading model.
This class contains the specification of EPS Bearers.
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
@ GBR_CONV_VOICE
GBR Conversational Voice.
@ DGBR_INTER_SERV_87
Delay-Critical GBR Interactive Service - Motion tracking data (TS 23.501)
The NrGnbNetDevice class.
Basic simulation scenario parameters.
double m_isd
Inter-site distance (ISD) in meters.
double m_bsHeight
Height of gNB nodes.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.
double m_minBsUtDistance
Minimum distance between BS and UT in meters.
void SetScenarioParameters(const std::string &scenario)
Sets parameters to the specified scenario.
double m_utHeight
Height of UE nodes.
double m_antennaOffset
Cell antenna offset in meters w.r.t. site location.
A helper to make it easier to instantiate an ns3::TrafficGenerator types of applications on a set of ...
static TypeId GetTypeId()
Get the type ID.
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.
Direction direction
Whether the filter needs to be applied to uplink / downlink only, or in both cases.
uint16_t localPortStart
start of the port number range of the UE
uint16_t localPortEnd
end of the port number range of the UE
parameters for the search of optimal rank and precoding matrix indicator (RI, PMI)
uint8_t subbandSize
Number of PRBs per subband for downsampling.
std::string fullSearchCb
Codebook when using full-search algorithm.
std::string pmSearchMethod
Precoding matrix search algorithm.
Operation band information structure.
BandwidthPartInfoPtr & GetBwpAt(uint32_t ccId, uint32_t bwpId) const
Get the BWP at the cc/bwp specified.
std::vector< ComponentCarrierInfoPtr > m_cc
Operation band component carriers.
BandwidthPartInfoPtrVector GetBwps() const
Get the list of all the BWPs to pass to NrHelper.
uint8_t m_bandId
Operation band id.