49#include "ns3/antenna-module.h"
50#include "ns3/applications-module.h"
51#include "ns3/buildings-module.h"
52#include "ns3/config-store-module.h"
53#include "ns3/core-module.h"
54#include "ns3/flow-monitor-module.h"
55#include "ns3/internet-apps-module.h"
56#include "ns3/internet-module.h"
57#include "ns3/mobility-module.h"
58#include "ns3/nr-module.h"
59#include "ns3/point-to-point-module.h"
71NS_LOG_COMPONENT_DEFINE(
"CttcNrDemo");
74main(
int argc,
char* argv[])
83 uint16_t ueNumPergNb = 2;
85 bool doubleOperationalBand =
true;
88 uint32_t udpPacketSizeULL = 100;
89 uint32_t udpPacketSizeBe = 1252;
90 uint32_t lambdaULL = 10000;
91 uint32_t lambdaBe = 10000;
95 Time simTime = MilliSeconds(1000);
96 Time udpAppStartTime = MilliSeconds(400);
103 uint16_t numerologyBwp1 = 4;
104 double centralFrequencyBand1 = 28e9;
105 double bandwidthBand1 = 50e6;
106 uint16_t numerologyBwp2 = 2;
107 double centralFrequencyBand2 = 28.2e9;
108 double bandwidthBand2 = 50e6;
109 double totalTxPower = 35;
112 std::string simTag =
"default";
113 std::string outputDir =
"./";
120 CommandLine cmd(__FILE__);
122 cmd.AddValue(
"gNbNum",
"The number of gNbs in multiple-ue topology", gNbNum);
123 cmd.AddValue(
"ueNumPergNb",
"The number of UE per gNb in multiple-ue topology", ueNumPergNb);
124 cmd.AddValue(
"logging",
"Enable logging", logging);
125 cmd.AddValue(
"doubleOperationalBand",
126 "If true, simulate two operational bands with one CC for each band,"
127 "and each CC will have 1 BWP that spans the entire CC.",
128 doubleOperationalBand);
129 cmd.AddValue(
"packetSizeUll",
130 "packet size in bytes to be used by ultra low latency traffic",
132 cmd.AddValue(
"packetSizeBe",
133 "packet size in bytes to be used by best effort traffic",
135 cmd.AddValue(
"lambdaUll",
136 "Number of UDP packets in one second for ultra low latency traffic",
138 cmd.AddValue(
"lambdaBe",
139 "Number of UDP packets in one second for best effort traffic",
141 cmd.AddValue(
"simTime",
"Simulation time", simTime);
142 cmd.AddValue(
"numerologyBwp1",
"The numerology to be used in bandwidth part 1", numerologyBwp1);
143 cmd.AddValue(
"centralFrequencyBand1",
144 "The system frequency to be used in band 1",
145 centralFrequencyBand1);
146 cmd.AddValue(
"bandwidthBand1",
"The system bandwidth to be used in band 1", bandwidthBand1);
147 cmd.AddValue(
"numerologyBwp2",
"The numerology to be used in bandwidth part 2", numerologyBwp2);
148 cmd.AddValue(
"centralFrequencyBand2",
149 "The system frequency to be used in band 2",
150 centralFrequencyBand2);
151 cmd.AddValue(
"bandwidthBand2",
"The system bandwidth to be used in band 2", bandwidthBand2);
152 cmd.AddValue(
"totalTxPower",
153 "total tx power that will be proportionally assigned to"
154 " bands, CCs and bandwidth parts depending on each BWP bandwidth ",
156 cmd.AddValue(
"simTag",
157 "tag to be appended to output filenames to distinguish simulation campaigns",
159 cmd.AddValue(
"outputDir",
"directory where to store simulation results", outputDir);
162 cmd.Parse(argc, argv);
168 NS_ABORT_IF(centralFrequencyBand1 < 0.5e9 && centralFrequencyBand1 > 100e9);
169 NS_ABORT_IF(centralFrequencyBand2 < 0.5e9 && centralFrequencyBand2 > 100e9);
183 LogComponentEnable(
"UdpClient", LOG_LEVEL_INFO);
184 LogComponentEnable(
"UdpServer", LOG_LEVEL_INFO);
185 LogComponentEnable(
"NrPdcp", LOG_LEVEL_INFO);
194 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
201 int64_t randomStream = 1;
214 gridScenario.SetScenarioHeight(3);
215 gridScenario.SetScenarioLength(3);
224 NodeContainer ueLowLatContainer;
225 NodeContainer ueVoiceContainer;
232 ueLowLatContainer.Add(ue);
236 ueVoiceContainer.Add(ue);
243 NS_LOG_INFO(
"Creating " << gridScenario.
GetUserTerminals().GetN() <<
" user terminals and "
255 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
256 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
257 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
260 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
261 nrHelper->SetEpcHelper(nrEpcHelper);
272 const uint8_t numCcPerBand = 1;
299 double x = pow(10, totalTxPower / 10);
300 double totalBandwidth = bandwidthBand1;
306 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
307 channelHelper->ConfigureFactories(
"UMi",
"Default",
"ThreeGpp");
312 channelHelper->SetChannelConditionModelAttribute(
"UpdatePeriod", TimeValue(MilliSeconds(0)));
313 channelHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(
false));
318 if (doubleOperationalBand)
320 channelHelper->AssignChannelsToBands({band1, band2});
321 totalBandwidth += bandwidthBand2;
326 channelHelper->AssignChannelsToBands({band1});
348 Packet::EnableChecking();
349 Packet::EnablePrinting();
355 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
359 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
362 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(2));
363 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(4));
364 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
365 PointerValue(CreateObject<IsotropicAntennaModel>()));
368 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(4));
369 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(8));
370 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
371 PointerValue(CreateObject<IsotropicAntennaModel>()));
373 uint32_t bwpIdForLowLat = 0;
374 uint32_t bwpIdForVoice = 0;
375 if (doubleOperationalBand)
382 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB",
383 UintegerValue(bwpIdForLowLat));
384 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
387 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdForLowLat));
388 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
407 NetDeviceContainer gnbNetDev =
409 NetDeviceContainer ueLowLatNetDev = nrHelper->InstallUeDevice(ueLowLatContainer, allBwps);
410 NetDeviceContainer ueVoiceNetDev = nrHelper->InstallUeDevice(ueVoiceContainer, allBwps);
412 randomStream += nrHelper->AssignStreams(gnbNetDev, randomStream);
413 randomStream += nrHelper->AssignStreams(ueLowLatNetDev, randomStream);
414 randomStream += nrHelper->AssignStreams(ueVoiceNetDev, randomStream);
422 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)
423 ->SetAttribute(
"Numerology", UintegerValue(numerologyBwp1));
424 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)
425 ->SetAttribute(
"TxPower", DoubleValue(10 * log10((bandwidthBand1 / totalBandwidth) * x)));
427 if (doubleOperationalBand)
431 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 1)
432 ->SetAttribute(
"Numerology", UintegerValue(numerologyBwp2));
433 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 1)
434 ->SetTxPower(10 * log10((bandwidthBand2 / totalBandwidth) * x));
440 auto [remoteHost, remoteHostIpv4Address] =
441 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 2500, Seconds(0.000));
443 InternetStackHelper internet;
447 Ipv4InterfaceContainer ueLowLatIpIface =
448 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLowLatNetDev));
449 Ipv4InterfaceContainer ueVoiceIpIface =
450 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVoiceNetDev));
453 nrHelper->AttachToClosestGnb(ueLowLatNetDev, gnbNetDev);
454 nrHelper->AttachToClosestGnb(ueVoiceNetDev, gnbNetDev);
460 uint16_t dlPortLowLat = 1234;
461 uint16_t dlPortVoice = 1235;
463 ApplicationContainer serverApps;
466 UdpServerHelper dlPacketSinkLowLat(dlPortLowLat);
467 UdpServerHelper dlPacketSinkVoice(dlPortVoice);
470 serverApps.Add(dlPacketSinkLowLat.Install(ueLowLatContainer));
471 serverApps.Add(dlPacketSinkVoice.Install(ueVoiceContainer));
479 UdpClientHelper dlClientLowLat;
480 dlClientLowLat.SetAttribute(
"RemotePort", UintegerValue(dlPortLowLat));
481 dlClientLowLat.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
482 dlClientLowLat.SetAttribute(
"PacketSize", UintegerValue(udpPacketSizeULL));
483 dlClientLowLat.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambdaULL)));
489 Ptr<NrEpcTft> lowLatTft = Create<NrEpcTft>();
493 lowLatTft->Add(dlpfLowLat);
496 UdpClientHelper dlClientVoice;
497 dlClientVoice.SetAttribute(
"RemotePort", UintegerValue(dlPortVoice));
498 dlClientVoice.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
499 dlClientVoice.SetAttribute(
"PacketSize", UintegerValue(udpPacketSizeBe));
500 dlClientVoice.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambdaBe)));
506 Ptr<NrEpcTft> voiceTft = Create<NrEpcTft>();
510 voiceTft->Add(dlpfVoice);
515 ApplicationContainer clientApps;
517 for (uint32_t i = 0; i < ueLowLatContainer.GetN(); ++i)
519 Ptr<Node> ue = ueLowLatContainer.Get(i);
520 Ptr<NetDevice> ueDevice = ueLowLatNetDev.Get(i);
521 Address ueAddress = ueLowLatIpIface.GetAddress(i);
525 dlClientLowLat.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
526 clientApps.Add(dlClientLowLat.Install(remoteHost));
529 nrHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
532 for (uint32_t i = 0; i < ueVoiceContainer.GetN(); ++i)
534 Ptr<Node> ue = ueVoiceContainer.Get(i);
535 Ptr<NetDevice> ueDevice = ueVoiceNetDev.Get(i);
536 Address ueAddress = ueVoiceIpIface.GetAddress(i);
540 dlClientVoice.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
541 clientApps.Add(dlClientVoice.Install(remoteHost));
544 nrHelper->ActivateDedicatedEpsBearer(ueDevice, voiceBearer, voiceTft);
548 serverApps.Start(udpAppStartTime);
549 clientApps.Start(udpAppStartTime);
550 serverApps.Stop(simTime);
551 clientApps.Stop(simTime);
556 FlowMonitorHelper flowmonHelper;
557 NodeContainer endpointNodes;
558 endpointNodes.Add(remoteHost);
561 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
562 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.001));
563 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
564 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
566 Simulator::Stop(simTime);
577 monitor->CheckForLostPackets();
578 Ptr<Ipv4FlowClassifier> classifier =
579 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
580 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
582 double averageFlowThroughput = 0.0;
583 double averageFlowDelay = 0.0;
585 std::ofstream outFile;
586 std::string filename = outputDir +
"/" + simTag;
587 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
588 if (!outFile.is_open())
590 std::cerr <<
"Can't open file " << filename << std::endl;
594 outFile.setf(std::ios_base::fixed);
596 double flowDuration = (simTime - udpAppStartTime).GetSeconds();
597 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
601 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
602 std::stringstream protoStream;
603 protoStream << (uint16_t)t.protocol;
606 protoStream.str(
"TCP");
608 if (t.protocol == 17)
610 protoStream.str(
"UDP");
612 outFile <<
"Flow " << i->first <<
" (" << t.sourceAddress <<
":" << t.sourcePort <<
" -> "
613 << t.destinationAddress <<
":" << t.destinationPort <<
") proto "
614 << protoStream.str() <<
"\n";
615 outFile <<
" Tx Packets: " << i->second.txPackets <<
"\n";
616 outFile <<
" Tx Bytes: " << i->second.txBytes <<
"\n";
617 outFile <<
" TxOffered: " << i->second.txBytes * 8.0 / flowDuration / 1000.0 / 1000.0
619 outFile <<
" Rx Bytes: " << i->second.rxBytes <<
"\n";
620 if (i->second.rxPackets > 0)
623 averageFlowThroughput += i->second.rxBytes * 8.0 / flowDuration / 1000 / 1000;
624 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
626 outFile <<
" Throughput: " << i->second.rxBytes * 8.0 / flowDuration / 1000 / 1000
628 outFile <<
" Mean delay: "
629 << 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets <<
" ms\n";
632 outFile <<
" Mean jitter: "
633 << 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets <<
" ms\n";
637 outFile <<
" Throughput: 0 Mbps\n";
638 outFile <<
" Mean delay: 0 ms\n";
639 outFile <<
" Mean jitter: 0 ms\n";
641 outFile <<
" Rx Packets: " << i->second.rxPackets <<
"\n";
644 double meanFlowThroughput = averageFlowThroughput / stats.size();
645 double meanFlowDelay = averageFlowDelay / stats.size();
647 outFile <<
"\n\n Mean flow throughput: " << meanFlowThroughput <<
"\n";
648 outFile <<
" Mean flow delay: " << meanFlowDelay <<
"\n";
652 std::ifstream f(filename.c_str());
656 std::cout << f.rdbuf();
659 Simulator::Destroy();
663 double toleranceMeanFlowThroughput = 0.0001 * 56.258560;
664 double toleranceMeanFlowDelay = 0.0001 * 0.553292;
666 if (meanFlowThroughput >= 56.258560 - toleranceMeanFlowThroughput &&
667 meanFlowThroughput <= 56.258560 + toleranceMeanFlowThroughput &&
668 meanFlowDelay >= 0.553292 - toleranceMeanFlowDelay &&
669 meanFlowDelay <= 0.553292 + toleranceMeanFlowDelay)
678 else if (argc == 1 and ueNumPergNb == 9)
680 double toleranceMeanFlowThroughput = 0.0001 * 47.858536;
681 double toleranceMeanFlowDelay = 0.0001 * 10.504189;
683 if (meanFlowThroughput >= 47.858536 - toleranceMeanFlowThroughput &&
684 meanFlowThroughput <= 47.858536 + toleranceMeanFlowThroughput &&
685 meanFlowDelay >= 10.504189 - toleranceMeanFlowDelay &&
686 meanFlowDelay <= 10.504189 + toleranceMeanFlowDelay)
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 GridScenarioHelper class.
void SetRows(uint32_t r)
SetRows.
void SetHorizontalBsDistance(double d)
SetHorizontalBsDistance.
void SetVerticalBsDistance(double d)
SetVerticalBsDistance.
void CreateScenario() override
Create the scenario, with the configured parameter.
int64_t AssignStreams(int64_t stream)
void SetColumns(uint32_t c)
SetColumns.
const NodeContainer & GetUserTerminals() const
Get the list of user nodes.
void SetBsNumber(std::size_t n)
Set the number of 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.
This class contains the specification of EPS Bearers.
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
@ GBR_CONV_VOICE
GBR Conversational Voice.
void SetBsHeight(double h)
SetGnbHeight.
void SetUtHeight(double h)
SetUeHeight.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
uint16_t localPortStart
start of the port number range of the UE
uint16_t localPortEnd
end of the port number range of the UE
Operation band information structure.