38#include "ns3/antenna-module.h"
39#include "ns3/applications-module.h"
40#include "ns3/config-store-module.h"
41#include "ns3/config-store.h"
42#include "ns3/core-module.h"
43#include "ns3/flow-monitor-module.h"
44#include "ns3/internet-apps-module.h"
45#include "ns3/internet-module.h"
46#include "ns3/lte-module.h"
47#include "ns3/mobility-module.h"
48#include "ns3/nr-module.h"
49#include "ns3/point-to-point-module.h"
50#include "ns3/rng-seed-manager.h"
51#include "ns3/three-gpp-ftp-m1-helper.h"
71NS_LOG_COMPONENT_DEFINE(
"FhCompression");
73class RadioNetworkParametersHelper
80 void SetNetworkToLte(
const std::string scenario,
81 const std::string operationMode,
90 void SetNetworkToNr(
const std::string scenario,
91 const std::string operationMode,
99 double GetTxPower()
const;
105 double GetBandwidth()
const;
111 double GetCentralFrequency()
const;
117 uint16_t GetNumerology()
const;
123 std::vector<int16_t> GetMcsVectorFromInput();
126 double m_txPower{-1.0};
127 double m_bandwidth{0.0};
128 double m_centralFrequency{-1.0};
129 uint16_t m_numerology{0};
133GetMcsVectorFromInput(
const std::string& pattern)
135 static std::unordered_map<std::string, int16_t> lookupTable = {
136 {
"1", 1}, {
"2", 2}, {
"3", 3}, {
"4", 4}, {
"5", 5}, {
"6", 6}, {
"7", 7},
137 {
"8", 8}, {
"9", 9}, {
"10", 10}, {
"11", 11}, {
"12", 12}, {
"13", 13}, {
"14", 14},
138 {
"15", 15}, {
"16", 16}, {
"17", 17}, {
"18", 18}, {
"19", 19}, {
"20", 20}, {
"21", 21},
139 {
"22", 22}, {
"23", 23}, {
"24", 24}, {
"25", 25}, {
"26", 26}, {
"27", 27}, {
"28", 28},
142 std::vector<int16_t> vector;
143 std::stringstream ss(pattern);
145 std::vector<std::string> extracted;
147 while (std::getline(ss, token,
'|'))
149 extracted.push_back(token);
152 for (
const auto& v : extracted)
154 if (lookupTable.find(v) == lookupTable.end())
156 NS_FATAL_ERROR(
"Not valid MCS input");
158 vector.push_back(lookupTable[v]);
165RadioNetworkParametersHelper::SetNetworkToLte(
const std::string scenario,
166 const std::string operationMode,
169 NS_ABORT_MSG_IF(scenario !=
"UMa" && scenario !=
"UMi",
"Unsupported scenario");
172 m_centralFrequency = 2e9;
173 m_bandwidth = 20e6 * numCcs;
174 if (operationMode ==
"FDD")
176 m_bandwidth += m_bandwidth;
178 if (scenario ==
"UMa")
189RadioNetworkParametersHelper::SetNetworkToNr(
const std::string scenario,
190 const std::string operationMode,
194 NS_ABORT_MSG_IF(scenario !=
"UMa" && scenario !=
"UMi",
"Unsupported scenario");
196 m_numerology = numerology;
197 m_centralFrequency = 2e9;
198 m_bandwidth = 100e6 * numCcs;
199 if (operationMode ==
"FDD")
201 m_bandwidth += m_bandwidth;
203 if (scenario ==
"UMa")
214RadioNetworkParametersHelper::GetTxPower()
const
220RadioNetworkParametersHelper::GetBandwidth()
const
226RadioNetworkParametersHelper::GetCentralFrequency()
const
228 return m_centralFrequency;
232RadioNetworkParametersHelper::GetNumerology()
const
239 std::string scenario,
240 std::string radioNetwork,
241 std::string errorModel,
242 std::string operationMode,
243 std::string direction,
245 std::string pattern1,
246 std::string pattern2,
248 NodeContainer gnbSector1Container,
249 NodeContainer gnbSector2Container,
250 NodeContainer gnbSector3Container,
251 NodeContainer ueSector1Container,
252 NodeContainer ueSector2Container,
253 NodeContainer ueSector3Container,
254 Ptr<NrPointToPointEpcHelper>& baseNrEpcHelper,
255 Ptr<NrHelper>& nrHelper,
256 NetDeviceContainer& gnbSector1NetDev,
257 NetDeviceContainer& gnbSector2NetDev,
258 NetDeviceContainer& gnbSector3NetDev,
259 NetDeviceContainer& ueSector1NetDev,
260 NetDeviceContainer& ueSector2NetDev,
261 NetDeviceContainer& ueSector3NetDev,
264 std::vector<int16_t>& maxMcsVector,
271 RadioNetworkParametersHelper ranHelper;
272 if (radioNetwork ==
"LTE")
274 ranHelper.SetNetworkToLte(scenario, operationMode, 1);
275 if (errorModel.empty())
277 errorModel =
"ns3::LenaErrorModel";
279 else if (errorModel !=
"ns3::NrLteMiErrorModel" && errorModel !=
"ns3::LenaErrorModel")
281 NS_ABORT_MSG(
"The selected error model is not recommended for LTE");
284 else if (radioNetwork ==
"NR")
286 ranHelper.SetNetworkToNr(scenario, operationMode, numerology, 1);
287 if (errorModel.empty())
289 errorModel =
"ns3::NrEesmIrT2";
291 else if (errorModel ==
"ns3::NrLteMiErrorModel")
293 NS_ABORT_MSG(
"The selected error model is not recommended for NR");
298 NS_ABORT_MSG(
"Unrecognized radio network technology");
310 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
311 nrHelper = CreateObject<NrHelper>();
314 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
316 Ptr<NrPointToPointEpcHelper> nrEpcHelper =
317 DynamicCast<NrPointToPointEpcHelper>(baseNrEpcHelper);
318 nrHelper->SetEpcHelper(nrEpcHelper);
333 double centralFrequencyBand = ranHelper.GetCentralFrequency();
334 double bandwidthBand = ranHelper.GetBandwidth();
335 const uint8_t numCcPerBand = 1;
337 NS_ABORT_MSG_UNLESS(scenario ==
"UMa" || scenario ==
"UMi",
"Unsupported scenario");
340 nrHelper->SetUlErrorModel(errorModel);
341 nrHelper->SetDlErrorModel(errorModel);
344 nrHelper->SetGnbDlAmcAttribute(
347 nrHelper->SetGnbUlAmcAttribute(
368 double centralFrequencyBand1 = centralFrequencyBand - bandwidthBand;
369 double centralFrequencyBand2 = centralFrequencyBand;
370 double centralFrequencyBand3 = centralFrequencyBand + bandwidthBand;
371 double bandwidthBand1 = bandwidthBand;
372 double bandwidthBand2 = bandwidthBand;
373 double bandwidthBand3 = bandwidthBand;
375 uint8_t numBwpPerCc = 1;
376 if (operationMode ==
"FDD")
379 Config::SetDefault(
"ns3::NrUeNetDevice::PrimaryUlIndex", UintegerValue(1));
399 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
400 channelHelper->ConfigureFactories(scenario);
402 Config::SetDefault(
"ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(0)));
403 channelHelper->SetChannelConditionModelAttribute(
"UpdatePeriod", TimeValue(MilliSeconds(0)));
404 channelHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(
false));
409 channelHelper->AssignChannelsToBands({band1, band2, band3});
421 double totalTxPower = ranHelper.GetTxPower();
422 double x = pow(10, totalTxPower / 10);
442 Packet::EnableChecking();
443 Packet::EnablePrinting();
449 if (radioNetwork ==
"LTE")
451 idealBeamformingHelper->SetAttribute(
457 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
464 if (radioNetwork ==
"LTE")
466 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(
"ns3::NrMacSchedulerOfdmaPF"));
467 nrHelper->SetSchedulerAttribute(
"DlCtrlSymbols", UintegerValue(1));
475 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
478 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(1));
479 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(1));
480 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
481 PointerValue(CreateObject<IsotropicAntennaModel>()));
484 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(8));
485 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(8));
486 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
487 PointerValue(CreateObject<ThreeGppAntennaModel>()));
490 nrHelper->SetUePhyAttribute(
"TxPower", DoubleValue(20.0));
493 if (radioNetwork ==
"LTE")
495 nrHelper->SetGnbMacAttribute(
"NumRbPerRbg", UintegerValue(4));
499 uint32_t bwpIdForLowLat = 0;
500 if (operationMode ==
"FDD" && direction ==
"UL")
506 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"NGBR_VIDEO_TCP_DEFAULT",
507 UintegerValue(bwpIdForLowLat));
510 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"NGBR_VIDEO_TCP_DEFAULT",
511 UintegerValue(bwpIdForLowLat));
532 gnbSector1NetDev = nrHelper->InstallGnbDevice(gnbSector1Container, bwps1);
533 gnbSector2NetDev = nrHelper->InstallGnbDevice(gnbSector2Container, bwps2);
534 gnbSector3NetDev = nrHelper->InstallGnbDevice(gnbSector3Container, bwps3);
535 ueSector1NetDev = nrHelper->InstallUeDevice(ueSector1Container, bwps1);
536 ueSector2NetDev = nrHelper->InstallUeDevice(ueSector2Container, bwps2);
537 ueSector3NetDev = nrHelper->InstallUeDevice(ueSector3Container, bwps3);
539 int64_t randomStream = 1;
540 randomStream += nrHelper->AssignStreams(gnbSector1NetDev, randomStream);
541 randomStream += nrHelper->AssignStreams(gnbSector2NetDev, randomStream);
542 randomStream += nrHelper->AssignStreams(gnbSector3NetDev, randomStream);
543 randomStream += nrHelper->AssignStreams(ueSector1NetDev, randomStream);
544 randomStream += nrHelper->AssignStreams(ueSector2NetDev, randomStream);
545 randomStream += nrHelper->AssignStreams(ueSector3NetDev, randomStream);
551 std::vector<int16_t> maxMcsPerCell(gridScenario.
GetNumCells());
554 for (uint32_t i = 0; i < gridScenario.
GetNumCells(); ++i)
556 maxMcsPerCell[i] = maxMcsDl1;
557 std::cout <<
"Cell: " << i <<
" mcs (same mcs): " << maxMcsPerCell[i] << std::endl;
563 if (uniformPattern &&
566 for (uint32_t i = 0; i < gridScenario.
GetNumCells(); ++i)
568 maxMcsPerCell[i] = maxMcsDl1;
569 std::cout <<
"Cell: " << i <<
" mcs (diff mcs): " << maxMcsPerCell[i] << std::endl;
572 else if (uniformLambda &&
575 for (uint32_t i = 0; i < gridScenario.
GetNumCells(); ++i)
579 maxMcsPerCell[i] = maxMcsDl1;
583 maxMcsPerCell[i] = maxMcsDl2;
585 std::cout <<
"Cell: " << i <<
" mcs (diff tdd): " << maxMcsPerCell[i] << std::endl;
588 else if (uniformPattern && !uniformLambda)
590 for (uint32_t i = 0; i < gridScenario.
GetNumCells(); ++i)
592 maxMcsPerCell[i] = maxMcsVector[i];
593 std::cout <<
"Cell: " << i <<
" mcs (diff lambda): " << maxMcsPerCell[i]
601 uint32_t globalCellId = 0;
602 for (uint32_t numCell = 0; numCell < gnbSector1NetDev.GetN(); ++numCell)
604 Ptr<NetDevice> gnb = gnbSector1NetDev.Get(numCell);
605 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
609 Ptr<NrGnbPhy> phy = nrHelper->GetGnbPhy(gnb, 0);
610 Ptr<UniformPlanarArray> antenna =
611 DynamicCast<UniformPlanarArray>(phy->GetSpectrumPhy()->GetAntenna());
612 antenna->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
615 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Numerology",
616 UintegerValue(ranHelper.GetNumerology()));
619 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
622 if (uniformPattern || (globalCellId % 2 == 1))
624 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Pattern", StringValue(pattern1));
628 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Pattern", StringValue(pattern2));
632 nrHelper->GetScheduler(gnb, 0)->SetAttribute(
"MaxDlMcs",
633 IntegerValue(maxMcsPerCell[globalCellId]));
639 else if (numBwps == 2)
642 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
643 Ptr<UniformPlanarArray> antenna0 =
644 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
645 antenna0->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
646 Ptr<NrGnbPhy> phy1 = nrHelper->GetGnbPhy(gnb, 1);
647 Ptr<UniformPlanarArray> antenna1 =
648 DynamicCast<UniformPlanarArray>(phy1->GetSpectrumPhy()->GetAntenna());
649 antenna1->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
652 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Numerology",
653 UintegerValue(ranHelper.GetNumerology()));
654 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
"Numerology",
655 UintegerValue(ranHelper.GetNumerology()));
658 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
659 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
"TxPower", DoubleValue(-30.0));
661 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
663 StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
664 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
666 StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
669 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
674 NS_ABORT_MSG(
"Incorrect number of BWPs per CC");
680 for (uint32_t numCell = 0; numCell < gnbSector2NetDev.GetN(); ++numCell)
682 Ptr<NetDevice> gnb = gnbSector2NetDev.Get(numCell);
683 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
687 Ptr<NrGnbPhy> phy = nrHelper->GetGnbPhy(gnb, 0);
688 Ptr<UniformPlanarArray> antenna =
689 DynamicCast<UniformPlanarArray>(phy->GetSpectrumPhy()->GetAntenna());
690 antenna->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
693 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Numerology",
694 UintegerValue(ranHelper.GetNumerology()));
697 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
700 if (uniformPattern || (globalCellId % 2 == 1))
702 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Pattern", StringValue(pattern1));
706 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Pattern", StringValue(pattern2));
710 nrHelper->GetScheduler(gnb, 0)->SetAttribute(
"MaxDlMcs",
711 IntegerValue(maxMcsPerCell[globalCellId]));
717 else if (numBwps == 2)
720 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
721 Ptr<UniformPlanarArray> antenna0 =
722 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
723 antenna0->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
724 Ptr<NrGnbPhy> phy1 = nrHelper->GetGnbPhy(gnb, 1);
725 Ptr<UniformPlanarArray> antenna1 =
726 DynamicCast<UniformPlanarArray>(phy1->GetSpectrumPhy()->GetAntenna());
727 antenna1->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
730 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Numerology",
731 UintegerValue(ranHelper.GetNumerology()));
732 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
"Numerology",
733 UintegerValue(ranHelper.GetNumerology()));
736 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
737 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
"TxPower", DoubleValue(-30.0));
740 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
742 StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
743 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
745 StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
748 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
753 NS_ABORT_MSG(
"Incorrect number of BWPs per CC");
759 for (uint32_t numCell = 0; numCell < gnbSector3NetDev.GetN(); ++numCell)
761 Ptr<NetDevice> gnb = gnbSector3NetDev.Get(numCell);
762 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
766 Ptr<NrGnbPhy> phy = nrHelper->GetGnbPhy(gnb, 0);
767 Ptr<UniformPlanarArray> antenna =
768 DynamicCast<UniformPlanarArray>(phy->GetSpectrumPhy()->GetAntenna());
769 antenna->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
772 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Numerology",
773 UintegerValue(ranHelper.GetNumerology()));
776 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
779 if (uniformPattern || (globalCellId % 2 == 1))
781 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Pattern", StringValue(pattern1));
785 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Pattern", StringValue(pattern2));
789 nrHelper->GetScheduler(gnb, 0)->SetAttribute(
"MaxDlMcs",
790 IntegerValue(maxMcsPerCell[globalCellId]));
796 else if (numBwps == 2)
799 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
800 Ptr<UniformPlanarArray> antenna0 =
801 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
802 antenna0->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
803 Ptr<NrGnbPhy> phy1 = nrHelper->GetGnbPhy(gnb, 1);
804 Ptr<UniformPlanarArray> antenna1 =
805 DynamicCast<UniformPlanarArray>(phy1->GetSpectrumPhy()->GetAntenna());
806 antenna1->SetAttribute(
"BearingAngle", DoubleValue(orientationRads));
809 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"Numerology",
810 UintegerValue(ranHelper.GetNumerology()));
811 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
"Numerology",
812 UintegerValue(ranHelper.GetNumerology()));
815 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
816 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
"TxPower", DoubleValue(-30.0));
819 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
821 StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
822 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
824 StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
827 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
832 NS_ABORT_MSG(
"Incorrect number of BWPs per CC");
839 if (operationMode ==
"FDD")
841 for (uint32_t i = 0; i < ueSector1NetDev.GetN(); i++)
843 nrHelper->GetBwpManagerUe(ueSector1NetDev.Get(i))->SetOutputLink(0, 1);
846 for (uint32_t i = 0; i < ueSector2NetDev.GetN(); i++)
848 nrHelper->GetBwpManagerUe(ueSector2NetDev.Get(i))->SetOutputLink(0, 1);
851 for (uint32_t i = 0; i < ueSector3NetDev.GetN(); i++)
853 nrHelper->GetBwpManagerUe(ueSector3NetDev.Get(i))->SetOutputLink(0, 1);
860CreateLowLatTft(uint16_t start, uint16_t end, std::string dir)
863 lowLatTft = Create<T>();
864 typename T::PacketFilter dlpfLowLat;
867 dlpfLowLat.localPortStart = start;
868 dlpfLowLat.localPortEnd = end;
869 dlpfLowLat.direction = T::DOWNLINK;
873 dlpfLowLat.remotePortStart = start;
874 dlpfLowLat.remotePortEnd = end;
875 dlpfLowLat.direction = T::UPLINK;
877 lowLatTft->Add(dlpfLowLat);
881template Ptr<ns3::EpcTft> CreateLowLatTft<ns3::EpcTft>(uint16_t, uint16_t, std::string);
882template Ptr<ns3::NrEpcTft> CreateLowLatTft<ns3::NrEpcTft>(uint16_t, uint16_t, std::string);
885main(
int argc,
char* argv[])
892 uint16_t numOuterRings = 0;
893 uint16_t ueNumPergNb = 2;
894 bool logging =
false;
896 std::string simulator =
"";
897 std::string scenario =
"UMi";
898 std::string radioNetwork =
"NR";
899 std::string operationMode =
"TDD";
902 uint32_t udpPacketSize = 600;
903 uint32_t lambda = 2000;
909 bool ftpM1Enabled =
true;
910 double ftpLambda = 5;
911 uint32_t ftpFileSize = 512000;
912 uint16_t ftpPortSector1 = 2001;
913 uint16_t ftpPortSector2 = 2002;
914 uint16_t ftpPortSector3 = 2003;
915 uint32_t ftpClientAppStartTimeMs = 400;
916 uint32_t ftpServerAppStartTimeMs = 400;
919 uint32_t simTimeMs = 1400;
920 uint32_t udpAppStartTimeMs = 400;
921 std::string direction =
"DL";
925 uint16_t numerologyBwp = 2;
929 std::string pattern1 =
930 "F|F|F|F|F|F|F|F|F|F|";
931 std::string pattern2 =
"F|F|F|F|F|UL|UL|UL|UL|UL|";
932 bool uniformPattern =
true;
933 bool uniformMcs =
true;
934 bool uniformLambda =
true;
937 std::string simTag =
"default";
938 std::string outputDir =
"./";
941 std::string errorModel =
"ns3::NrEesmIrT2";
944 int16_t maxMcs1 = 28;
945 int16_t maxMcs2 = 28;
947 std::string maxMcsVectorInput =
"1|2|4";
954 CommandLine cmd(__FILE__);
956 cmd.AddValue(
"scenario",
"The urban scenario string (UMa or UMi)", scenario);
957 cmd.AddValue(
"numRings",
"The number of rings around the central site", numOuterRings);
958 cmd.AddValue(
"ueNumPergNb",
959 "The number of UE per cell or gNB in multiple-ue topology",
961 cmd.AddValue(
"logging",
"Enable logging", logging);
962 cmd.AddValue(
"traces",
"Enable output traces", traces);
963 cmd.AddValue(
"packetSize",
"packet size in bytes to be used by UE traffic", udpPacketSize);
964 cmd.AddValue(
"lambda",
"Number of UDP packets generated in one second per UE", lambda);
965 cmd.AddValue(
"uniformLambda",
966 "1: Use same lambda (packets/s) for all UEs and cells (equal to 'lambda' input), "
967 "0: use different packet arrival rates (lambdas) among cells",
969 cmd.AddValue(
"simTimeMs",
"Simulation time", simTimeMs);
970 cmd.AddValue(
"numerologyBwp",
"The numerology to be used (NR only)", numerologyBwp);
971 cmd.AddValue(
"pattern1",
"The TDD pattern to use", pattern1);
972 cmd.AddValue(
"pattern2",
"The TDD pattern to use", pattern2);
973 cmd.AddValue(
"uniformPattern",
974 "1: Use same TDD pattern (pattern1) for all cells, 0: use different TDD patterns "
975 "(pattern1 and pattern2) for cells",
977 cmd.AddValue(
"direction",
"The flow direction (DL or UL)", direction);
984 cmd.AddValue(
"technology",
"The radio access network technology", radioNetwork);
985 cmd.AddValue(
"operationMode",
"The network operation mode can be TDD or FDD", operationMode);
986 cmd.AddValue(
"simTag",
987 "tag to be appended to output filenames to distinguish simulation campaigns",
989 cmd.AddValue(
"outputDir",
"directory where to store simulation results", outputDir);
990 cmd.AddValue(
"ftpM1Enabled",
991 "An indicator whether to enable FTP Model 1 traffic model. To enable configure 1, "
996 cmd.Parse(argc, argv);
1003 NS_ABORT_IF(numerologyBwp > 4);
1004 NS_ABORT_MSG_IF(direction !=
"DL" && direction !=
"UL",
"Flow direction can only be DL or UL");
1005 NS_ABORT_MSG_IF(operationMode !=
"TDD" && operationMode !=
"FDD",
1006 "Operation mode can only be TDD or FDD");
1007 NS_ABORT_MSG_IF(radioNetwork !=
"LTE" && radioNetwork !=
"NR",
1008 "Unrecognized radio network technology");
1021 LogComponentEnable(
"UdpClient", LOG_LEVEL_INFO);
1022 LogComponentEnable(
"UdpServer", LOG_LEVEL_INFO);
1023 LogComponentEnable(
"NrPdcp", LOG_LEVEL_INFO);
1031 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
1043 std::cout <<
"numcells: " << gNbNum << std::endl;
1044 uint32_t ueNum = ueNumPergNb * gNbNum;
1045 std::cout <<
"numUEs: " << ueNum << std::endl;
1049 const uint16_t ffr =
1055 NodeContainer gnbSector1Container;
1056 NodeContainer gnbSector2Container;
1057 NodeContainer gnbSector3Container;
1064 gnbSector1Container.Add(gnb);
1067 gnbSector2Container.Add(gnb);
1070 gnbSector3Container.Add(gnb);
1073 NS_ABORT_MSG(
"ffr param cannot be larger than 3");
1081 NodeContainer ueSector1Container;
1082 NodeContainer ueSector2Container;
1083 NodeContainer ueSector3Container;
1091 ueSector1Container.Add(ue);
1094 ueSector2Container.Add(ue);
1097 ueSector3Container.Add(ue);
1100 NS_ABORT_MSG(
"ffr param cannot be larger than 3");
1109 Ptr<NrPointToPointEpcHelper> nrEpcHelper;
1111 NetDeviceContainer gnbSector1NetDev;
1112 NetDeviceContainer gnbSector2NetDev;
1113 NetDeviceContainer gnbSector3NetDev;
1114 NetDeviceContainer ueSector1NetDev;
1115 NetDeviceContainer ueSector2NetDev;
1116 NetDeviceContainer ueSector3NetDev;
1118 Ptr<LteHelper> lteHelper;
1119 Ptr<NrHelper> nrHelper;
1121 std::vector<int16_t> maxMcsVector = GetMcsVectorFromInput(maxMcsVectorInput);
1123 nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
1134 gnbSector1Container,
1135 gnbSector2Container,
1136 gnbSector3Container,
1157 auto [remoteHost, remoteHostIpv4Address] =
1158 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 2500, Seconds(0.000));
1159 auto remoteHostContainer = NodeContainer(remoteHost);
1161 InternetStackHelper internet;
1165 Ipv4InterfaceContainer ueSector1IpIface =
1166 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueSector1NetDev));
1167 Ipv4InterfaceContainer ueSector2IpIface =
1168 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueSector2NetDev));
1169 Ipv4InterfaceContainer ueSector3IpIface =
1170 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueSector3NetDev));
1173 for (uint32_t u = 0; u < ueNum; ++u)
1175 uint32_t sector = u % ffr;
1176 uint32_t i = u / ffr;
1179 Ptr<NetDevice> gnbNetDev = gnbSector1NetDev.Get(i % gridScenario.
GetNumSites());
1180 Ptr<NetDevice> ueNetDev = ueSector1NetDev.Get(i);
1181 if (lteHelper !=
nullptr)
1183 lteHelper->Attach(ueNetDev, gnbNetDev);
1185 else if (nrHelper !=
nullptr)
1187 nrHelper->AttachToGnb(ueNetDev, gnbNetDev);
1191 NS_ABORT_MSG(
"Programming error");
1195 Vector gnbpos = gnbNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1196 Vector uepos = ueNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1197 double distance = CalculateDistance(gnbpos, uepos);
1198 std::cout <<
"Distance = " << distance <<
" meters" << std::endl;
1201 else if (sector == 1)
1203 Ptr<NetDevice> gnbNetDev = gnbSector2NetDev.Get(i % gridScenario.
GetNumSites());
1204 Ptr<NetDevice> ueNetDev = ueSector2NetDev.Get(i);
1205 if (lteHelper !=
nullptr)
1207 lteHelper->Attach(ueNetDev, gnbNetDev);
1209 else if (nrHelper !=
nullptr)
1211 nrHelper->AttachToGnb(ueNetDev, gnbNetDev);
1215 NS_ABORT_MSG(
"Programming error");
1219 Vector gnbpos = gnbNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1220 Vector uepos = ueNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1221 double distance = CalculateDistance(gnbpos, uepos);
1222 std::cout <<
"Distance = " << distance <<
" meters" << std::endl;
1225 else if (sector == 2)
1227 Ptr<NetDevice> gnbNetDev = gnbSector3NetDev.Get(i % gridScenario.
GetNumSites());
1228 Ptr<NetDevice> ueNetDev = ueSector3NetDev.Get(i);
1229 if (lteHelper !=
nullptr)
1231 lteHelper->Attach(ueNetDev, gnbNetDev);
1233 else if (nrHelper !=
nullptr)
1235 nrHelper->AttachToGnb(ueNetDev, gnbNetDev);
1239 NS_ABORT_MSG(
"Programming error");
1243 Vector gnbpos = gnbNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1244 Vector uepos = ueNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1245 double distance = CalculateDistance(gnbpos, uepos);
1246 std::cout <<
"Distance = " << distance <<
" meters" << std::endl;
1251 NS_ABORT_MSG(
"Number of sector cannot be larger than 3");
1259 uint16_t dlPortLowLat = 1234;
1261 ApplicationContainer serverApps;
1264 UdpServerHelper dlPacketSinkLowLat(dlPortLowLat);
1267 if (direction ==
"DL")
1269 serverApps.Add(dlPacketSinkLowLat.Install(
1270 {ueSector1Container, ueSector2Container, ueSector3Container}));
1274 serverApps.Add(dlPacketSinkLowLat.Install(remoteHost));
1283 UdpClientHelper dlClientLowLat;
1284 dlClientLowLat.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
1285 dlClientLowLat.SetAttribute(
"PacketSize", UintegerValue(udpPacketSize));
1289 EpsBearer lowLatBearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
1293 Ptr<EpcTft> lowLatTft = CreateLowLatTft<EpcTft>(dlPortLowLat, dlPortLowLat, direction);
1294 Ptr<NrEpcTft> nrLowLatTft = CreateLowLatTft<NrEpcTft>(dlPortLowLat, dlPortLowLat, direction);
1296 std::vector<uint32_t> lambdaPerCell(gridScenario.
GetNumCells());
1299 for (uint32_t bs = 0; bs < gridScenario.
GetNumCells(); ++bs)
1301 lambdaPerCell[bs] = lambda;
1302 std::cout <<
"Cell: " << bs <<
" lambda (same lambda): " << lambdaPerCell[bs]
1308 for (uint32_t bs = 0; bs < gridScenario.
GetNumCells(); ++bs)
1310 lambdaPerCell[bs] = 1000 + bs * 2000;
1311 std::cout <<
"Cell: " << bs <<
" lambda (diff lambda): " << lambdaPerCell[bs]
1319 ApplicationContainer clientApps;
1320 ApplicationContainer ftpClientAppsSector1;
1321 ApplicationContainer ftpServerAppsSector1;
1322 ApplicationContainer ftpClientAppsSector2;
1323 ApplicationContainer ftpServerAppsSector2;
1324 ApplicationContainer ftpClientAppsSector3;
1325 ApplicationContainer ftpServerAppsSector3;
1326 Ptr<ThreeGppFtpM1Helper> ftpHelperSector1;
1327 Ptr<ThreeGppFtpM1Helper> ftpHelperSector2;
1328 Ptr<ThreeGppFtpM1Helper> ftpHelperSector3;
1333 ftpHelperSector1 = CreateObject<ThreeGppFtpM1Helper>(&ftpServerAppsSector1,
1334 &ftpClientAppsSector1,
1335 &ueSector1Container,
1336 &remoteHostContainer,
1338 ftpHelperSector1->Configure(ftpPortSector1,
1339 MilliSeconds(ftpServerAppStartTimeMs),
1340 MilliSeconds(ftpClientAppStartTimeMs),
1341 MilliSeconds(simTimeMs),
1344 ftpHelperSector1->Start();
1347 ftpHelperSector2 = CreateObject<ThreeGppFtpM1Helper>(&ftpServerAppsSector2,
1348 &ftpClientAppsSector2,
1349 &ueSector2Container,
1350 &remoteHostContainer,
1352 ftpHelperSector2->Configure(ftpPortSector2,
1353 MilliSeconds(ftpServerAppStartTimeMs),
1354 MilliSeconds(ftpClientAppStartTimeMs),
1355 MilliSeconds(simTimeMs),
1358 ftpHelperSector2->Start();
1361 ftpHelperSector3 = CreateObject<ThreeGppFtpM1Helper>(&ftpServerAppsSector3,
1362 &ftpClientAppsSector3,
1363 &ueSector3Container,
1364 &remoteHostContainer,
1366 ftpHelperSector3->Configure(ftpPortSector3,
1367 MilliSeconds(ftpServerAppStartTimeMs),
1368 MilliSeconds(ftpClientAppStartTimeMs),
1369 MilliSeconds(simTimeMs),
1372 ftpHelperSector3->Start();
1374 clientApps.Add(ftpClientAppsSector1);
1375 clientApps.Add(ftpClientAppsSector2);
1376 clientApps.Add(ftpClientAppsSector3);
1378 serverApps.Add(ftpServerAppsSector1);
1379 serverApps.Add(ftpServerAppsSector2);
1380 serverApps.Add(ftpServerAppsSector3);
1384 for (uint32_t i = 0; i < ueSector1Container.GetN(); ++i)
1386 dlClientLowLat.SetAttribute(
1388 TimeValue(Seconds(1.0 / lambdaPerCell[(i % gridScenario.
GetNumSites()) *
1390 std::cout <<
"ue (sector1): " << i <<
" index: "
1393 << lambdaPerCell[(i % gridScenario.
GetNumSites()) *
1396 Ptr<Node> ue = ueSector1Container.Get(i);
1397 Ptr<NetDevice> ueDevice = ueSector1NetDev.Get(i);
1398 Address ueAddress = ueSector1IpIface.GetAddress(i);
1402 if (direction ==
"DL")
1404 dlClientLowLat.SetAttribute(
1406 AddressValue(addressUtils::ConvertToSocketAddress(ueAddress, dlPortLowLat)));
1407 clientApps.Add(dlClientLowLat.Install(remoteHost));
1411 dlClientLowLat.SetAttribute(
1414 addressUtils::ConvertToSocketAddress(remoteHostIpv4Address, dlPortLowLat)));
1415 clientApps.Add(dlClientLowLat.Install(ue));
1418 if (lteHelper !=
nullptr)
1420 lteHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
1422 else if (nrHelper !=
nullptr)
1424 nrHelper->ActivateDedicatedEpsBearer(ueDevice, nrLowLatBearer, nrLowLatTft);
1428 NS_ABORT_MSG(
"Programming error");
1432 for (uint32_t i = 0; i < ueSector2Container.GetN(); ++i)
1434 dlClientLowLat.SetAttribute(
1436 TimeValue(Seconds(1.0 / lambdaPerCell[(i % gridScenario.
GetNumSites()) *
1439 std::cout <<
"ue (sector2): " << i <<
" index: "
1442 << lambdaPerCell[(i % gridScenario.
GetNumSites()) *
1446 Ptr<Node> ue = ueSector2Container.Get(i);
1447 Ptr<NetDevice> ueDevice = ueSector2NetDev.Get(i);
1448 Address ueAddress = ueSector2IpIface.GetAddress(i);
1452 if (direction ==
"DL")
1454 dlClientLowLat.SetAttribute(
1456 AddressValue(addressUtils::ConvertToSocketAddress(ueAddress, dlPortLowLat)));
1457 clientApps.Add(dlClientLowLat.Install(remoteHost));
1461 dlClientLowLat.SetAttribute(
1464 addressUtils::ConvertToSocketAddress(remoteHostIpv4Address, dlPortLowLat)));
1465 clientApps.Add(dlClientLowLat.Install(ue));
1468 if (lteHelper !=
nullptr)
1470 lteHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
1472 else if (nrHelper !=
nullptr)
1474 nrHelper->ActivateDedicatedEpsBearer(ueDevice, nrLowLatBearer, nrLowLatTft);
1478 NS_ABORT_MSG(
"Programming error");
1482 for (uint32_t i = 0; i < ueSector3Container.GetN(); ++i)
1484 dlClientLowLat.SetAttribute(
1486 TimeValue(Seconds(1.0 / lambdaPerCell[(i % gridScenario.
GetNumSites()) *
1489 std::cout <<
"ue (sector3): " << i <<
" index: "
1492 << lambdaPerCell[(i % gridScenario.
GetNumSites()) *
1496 Ptr<Node> ue = ueSector3Container.Get(i);
1497 Ptr<NetDevice> ueDevice = ueSector3NetDev.Get(i);
1498 Address ueAddress = ueSector3IpIface.GetAddress(i);
1502 if (direction ==
"DL")
1504 dlClientLowLat.SetAttribute(
1506 AddressValue(addressUtils::ConvertToSocketAddress(ueAddress, dlPortLowLat)));
1507 clientApps.Add(dlClientLowLat.Install(remoteHost));
1511 dlClientLowLat.SetAttribute(
1514 addressUtils::ConvertToSocketAddress(remoteHostIpv4Address, dlPortLowLat)));
1515 clientApps.Add(dlClientLowLat.Install(ue));
1518 if (lteHelper !=
nullptr)
1520 lteHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
1522 else if (nrHelper !=
nullptr)
1524 nrHelper->ActivateDedicatedEpsBearer(ueDevice, nrLowLatBearer, nrLowLatTft);
1528 NS_ABORT_MSG(
"Programming error");
1534 serverApps.Start(MilliSeconds(udpAppStartTimeMs));
1535 clientApps.Start(MilliSeconds(udpAppStartTimeMs));
1536 serverApps.Stop(MilliSeconds(simTimeMs));
1537 clientApps.Stop(MilliSeconds(simTimeMs));
1542 if (lteHelper !=
nullptr)
1544 lteHelper->EnableTraces();
1546 else if (nrHelper !=
nullptr)
1548 nrHelper->EnableTraces();
1552 FlowMonitorHelper flowmonHelper;
1553 NodeContainer endpointNodes;
1554 endpointNodes.Add(remoteHost);
1557 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
1558 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.001));
1559 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
1560 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
1562 Simulator::Stop(MilliSeconds(simTimeMs));
1573 monitor->CheckForLostPackets();
1574 Ptr<Ipv4FlowClassifier> classifier =
1575 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
1576 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
1578 double averageFlowThroughput = 0.0;
1579 double averageFlowDelay = 0.0;
1581 std::ofstream outFile;
1582 std::string filename = outputDir +
"/" + simTag;
1583 std::vector<double> delayValues(stats.size());
1586 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
1587 if (!outFile.is_open())
1589 std::cerr <<
"Can't open file " << filename << std::endl;
1593 outFile.setf(std::ios_base::fixed);
1595 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
1599 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
1600 std::stringstream protoStream;
1601 protoStream << (uint16_t)t.protocol;
1602 if (t.protocol == 6)
1604 protoStream.str(
"TCP");
1606 if (t.protocol == 17)
1608 protoStream.str(
"UDP");
1616 if (i->second.rxPackets > 0)
1621 double rxDuration = (simTimeMs - udpAppStartTimeMs) / 1000.0;
1623 averageFlowThroughput += i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000;
1624 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
1625 delayValues[cont] = 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
1642 std::stable_sort(delayValues.begin(), delayValues.end());
1648 double FiftyTileFlowDelay = delayValues[stats.size() / 2];
1650 outFile <<
"\n\n Mean flow throughput: " << averageFlowThroughput / stats.size() <<
"\n";
1651 outFile <<
" Mean flow delay: " << averageFlowDelay / stats.size() <<
"\n";
1652 outFile <<
" Median flow delay: " << FiftyTileFlowDelay <<
"\n";
1656 std::ifstream f(filename.c_str());
1660 std::cout << f.rdbuf();
1663 Simulator::Destroy();
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.
int64_t AssignStreams(int64_t stream)
void CreateScenario() override
Create the scenario, with the configured parameter.
void SetNumRings(uint8_t numRings)
Sets the number of outer rings of sites around the central site.
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.
std::size_t GetNumCells() const
Gets the total number of cells deployed.
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)
This class contains the specification of EPS Bearers.
@ NGBR_VIDEO_TCP_DEFAULT
Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
uint32_t GetNumSectorsPerSite() const
Gets the number of sectors per site.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.
void SetScenarioParameters(const std::string &scenario)
Sets parameters to the specified scenario.
void Set5gLenaSimulatorParameters(HexagonalGridScenarioHelper gridScenario, std::string scenario, std::string radioNetwork, std::string errorModel, std::string operationMode, std::string direction, uint16_t numerology, std::string pattern1, std::string pattern2, bool uniformPattern, NodeContainer gnbSector1Container, NodeContainer gnbSector2Container, NodeContainer gnbSector3Container, NodeContainer ueSector1Container, NodeContainer ueSector2Container, NodeContainer ueSector3Container, Ptr< NrPointToPointEpcHelper > &baseNrEpcHelper, Ptr< NrHelper > &nrHelper, NetDeviceContainer &gnbSector1NetDev, NetDeviceContainer &gnbSector2NetDev, NetDeviceContainer &gnbSector3NetDev, NetDeviceContainer &ueSector1NetDev, NetDeviceContainer &ueSector2NetDev, NetDeviceContainer &ueSector3NetDev, int16_t maxMcsDl1, int16_t maxMcsDl2, std::vector< int16_t > &maxMcsVector, bool uniformMcs, bool uniformLambda)
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
uint8_t m_numBwp
Number of BWP per CC.
Operation band information structure.