5G-LENA nr-v4.0
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
gsoc-nr-channel-models.cc
Go to the documentation of this file.
1// Copyright (c) 2024 LASSE / Universidade Federal do ParĂ¡ (UFPA)
2// Copyright (c) 2024 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3//
4// SPDX-License-Identifier: GPL-2.0-only
5
6#include "ns3/command-line.h"
7#include "ns3/constant-velocity-mobility-model.h"
8#include "ns3/flow-monitor-module.h"
9#include "ns3/isotropic-antenna-model.h"
10#include "ns3/multi-model-spectrum-channel.h"
11#include "ns3/nr-module.h"
12#include "ns3/parabolic-antenna-model.h"
13#include "ns3/point-to-point-helper.h"
14#include "ns3/pointer.h"
15#include "ns3/udp-client-server-helper.h"
16
17using namespace ns3;
18
19NS_LOG_COMPONENT_DEFINE("GsocNrChannelModels");
20
51int
52main(int argc, char* argv[])
53{
54 int64_t randomStream = 1;
55 double centralFrequency = 30.5e9; // 30.5 GHz
56 double bandwidth = 100e6; // 100 MHz
57 Time simTime = Seconds(1.0); // 1 second simulation time
58 Time udpTime = MilliSeconds(0); // 0 ms
59 Time maxDelay = MilliSeconds(100); // 100 ms
60 std::string scenario = "UMa"; // Urban Macro
61 std::string channelModel = "ThreeGpp"; // 3GPP channel model
62 uint32_t numUes = 1; // Number of UEs
63 uint32_t numGnbs = 1; // Number of gNBs
64 bool logging = false; // Enable logging
65 uint16_t numerology = 1; // Numerology
66
72 std::string channelConditionModel = "Default";
73 // Output file with the statistics
74 std::ofstream outputFile("channels-example-flows.txt");
75
76 CommandLine cmd(__FILE__);
77 // cmd.Usage(""); Leave it empty until we decide the final example
78 cmd.AddValue("channelModel",
79 "The channel model for the simulation, which can be 'NYU', "
80 "'ThreeGpp', 'TwoRay', 'Friis'. ",
81 channelModel);
82 cmd.AddValue("channelConditionModel",
83 "The channel condition model for the simulation. Choose among 'Default', 'LOS',"
84 "'NLOS', 'Buildings'.",
85 channelConditionModel);
86 cmd.AddValue("ueNum", "Number of UEs in the simulation.", numUes);
87 cmd.AddValue("gNbNum", "Number of gNBs in the simulation.", numGnbs);
88 cmd.AddValue("frequency", "The central carrier frequency in Hz.", centralFrequency);
89 cmd.AddValue("logging", "Enable logging", logging);
90 cmd.Parse(argc, argv);
91
92 if (logging)
93 {
94 LogComponentEnable("GsocNrChannelModels", LOG_LEVEL_INFO);
95 }
96
97 // Create the simulated scenario
105 hexGrid.SetUtHeight(1.5); // Height of the UE in meters
106 hexGrid.SetBsHeight(25); // Height of the gNB in meters
107 hexGrid.SetSectorization(1); // Number of sectors
108 hexGrid.m_isd = 200; // Inter-site distance in meters
109 uint32_t ueTxPower = 23; // UE transmission power in dBm
110 uint32_t bsTxPower = 41; // gNB transmission power in dBm
111 double ueSpeed = 0.8333; // in m/s (3 km/h)
112 // Antenna parameters
113 uint32_t ueNumRows = 1; // Number of rows for the UE antenna
114 uint32_t ueNumCols = 1; // Number of columns for the UE antenna
115 uint32_t gnbNumRows = 4; // Number of rows for the gNB antenna
116 uint32_t gnbNumCols = 8; // Number of columns for the gNB antenna
117 // Set the number of UEs and gNBs nodes in the scenario
118 hexGrid.SetUtNumber(numUes); // Number of UEs
119 hexGrid.SetBsNumber(numGnbs); // Number of gNBs
120 // Create a scenario with mobility
121 hexGrid.CreateScenarioWithMobility(Vector(ueSpeed, 0.0, 0.0),
122 0); // move UE with 3 km/h in x-axis
123
124 auto ueNodes = hexGrid.GetUserTerminals();
125 auto gNbNodes = hexGrid.GetBaseStations();
126
127 NS_LOG_INFO("Number of UEs: " << ueNodes.GetN() << ", Number of gNBs: " << gNbNodes.GetN());
128 for (size_t ueIndex = 0; ueIndex < ueNodes.GetN(); ueIndex++)
129 {
130 NS_LOG_INFO("UE [" << ueNodes.Get(ueIndex) << "] at "
131 << ueNodes.Get(ueIndex)->GetObject<MobilityModel>()->GetPosition());
132 }
133 for (size_t gnbIndex = 0; gnbIndex < gNbNodes.GetN(); gnbIndex++)
134 {
135 NS_LOG_INFO("gNB [" << gNbNodes.Get(gnbIndex) << "] at "
136 << gNbNodes.Get(gnbIndex)->GetObject<MobilityModel>()->GetPosition());
137 }
138 /*
139 * Setup the NR module:
140 * - NrHelper, which takes care of creating and connecting the various
141 * part of the NR stack
142 * - NrChannelHelper, which takes care of the spectrum channel
143 */
144 Ptr<NrPointToPointEpcHelper> epcHelper = CreateObject<NrPointToPointEpcHelper>();
145 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
146 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
147 nrHelper->SetEpcHelper(epcHelper);
148
149 uint8_t numCc = 1; // Number of component carriers
150 CcBwpCreator ccBwpCreator;
151 auto band = ccBwpCreator.CreateOperationBandContiguousCc({centralFrequency, bandwidth, numCc});
152
153 if (channelModel == "ThreeGpp" || channelModel == "NYU" || channelModel == "TwoRay")
154 {
155 // Create the ideal beamforming helper in case of a non-phased array model
156 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
157 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
158 // First configure the channel helper object factories
159 channelHelper->ConfigureFactories(scenario, channelConditionModel, channelModel);
160 // Set channel condition attributes
161 channelHelper->SetChannelConditionModelAttribute("UpdatePeriod",
162 TimeValue(MilliSeconds(100)));
163 // Beamforming method
164 idealBeamformingHelper->SetAttribute("BeamformingMethod",
165 TypeIdValue(DirectPathBeamforming::GetTypeId()));
166
167 // Antennas for all the UEs
168 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(ueNumRows));
169 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(ueNumCols));
170 nrHelper->SetUeAntennaAttribute("AntennaElement",
171 PointerValue(CreateObject<IsotropicAntennaModel>()));
172
173 // Antennas for all the gNbs
174 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(gnbNumRows));
175 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(gnbNumCols));
176 nrHelper->SetGnbAntennaAttribute("AntennaElement",
177 PointerValue(CreateObject<IsotropicAntennaModel>()));
178 }
179 else if (channelModel == "Friis")
180 {
181 // Override the default antenna model with ParabolicAntennaModel
182 nrHelper->SetUeAntennaTypeId(ParabolicAntennaModel::GetTypeId().GetName());
183 nrHelper->SetGnbAntennaTypeId(ParabolicAntennaModel::GetTypeId().GetName());
184 // Configure Friis propagation loss model before assign it to band
185 channelHelper->ConfigurePropagationFactory(FriisPropagationLossModel::GetTypeId());
186 }
187 else
188 {
189 NS_FATAL_ERROR("Invalid channel model: "
190 << channelModel << ". Choose among 'ThreeGpp', 'NYU', 'TwoRay', 'Friis'.");
191 }
192
193 // After configuring the factories, create and assign the spectrum channels to the bands
194 channelHelper->AssignChannelsToBands({band});
195
196 // Get all the BWPs
197 auto allBwps = CcBwpCreator::GetAllBwps({band});
198 // Set the numerology and transmission powers attributes to all the gNBs and UEs
199 nrHelper->SetGnbPhyAttribute("TxPower", DoubleValue(bsTxPower));
200 nrHelper->SetGnbPhyAttribute("Numerology", UintegerValue(numerology));
201 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(ueTxPower));
202
203 // Install and get the pointers to the NetDevices
204 NetDeviceContainer gNbNetDev = nrHelper->InstallGnbDevice(gNbNodes, allBwps);
205 NetDeviceContainer ueNetDev = nrHelper->InstallUeDevice(ueNodes, allBwps);
206
207 randomStream += nrHelper->AssignStreams(gNbNetDev, randomStream);
208 randomStream += nrHelper->AssignStreams(ueNetDev, randomStream);
209
210 // create the internet and install the IP stack on the UEs
211 // get SGW/PGW and create a single RemoteHost
212 Ptr<Node> pgw = epcHelper->GetPgwNode();
213 Ptr<Node> remoteHost = CreateObject<Node>();
214 InternetStackHelper internet;
215 internet.Install(remoteHost);
216
217 // connect a remoteHost to pgw. Setup routing too
218 PointToPointHelper p2ph;
219 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
220 p2ph.SetDeviceAttribute("Mtu", UintegerValue(2500));
221 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
222 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
223
224 Ipv4AddressHelper ipv4h;
225 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
226 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
227 Ipv4StaticRoutingHelper ipv4RoutingHelper;
228
229 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
230 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
231 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
232 internet.Install(ueNodes);
233
234 Ipv4InterfaceContainer ueIpIface;
235 ueIpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDev));
236
237 // assign IP address to UEs, and install UDP downlink applications
238 uint16_t dlPort = 1234;
239 ApplicationContainer clientApps;
240 ApplicationContainer serverApps;
241 for (size_t i = 0; i < ueNodes.GetN(); i++)
242 {
243 UdpServerHelper dlPacketSinkHelper(dlPort);
244 serverApps.Add(dlPacketSinkHelper.Install(ueNodes.Get(i)));
245 UdpClientHelper dlClient(ueIpIface.GetAddress(i), dlPort);
246 dlClient.SetAttribute("Interval", TimeValue(MilliSeconds(1)));
247 dlClient.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
248 dlClient.SetAttribute("PacketSize", UintegerValue(100));
249 clientApps.Add(dlClient.Install(remoteHost));
250 }
251 // attach UEs to the closest eNB
252 nrHelper->AttachToClosestGnb(ueNetDev, gNbNetDev);
253 // start UDP server and client apps
254 serverApps.Start(udpTime);
255 clientApps.Start(udpTime);
256 serverApps.Stop(simTime);
257 clientApps.Stop(simTime);
258
259 // Check pathloss traces
260 nrHelper->EnablePathlossTraces();
261 FlowMonitorHelper flowmonHelper;
262 NodeContainer flowNodes;
263 flowNodes.Add(remoteHost);
264 flowNodes.Add(ueNodes);
265
266 auto monitor = flowmonHelper.Install(flowNodes);
267 monitor->SetAttribute("DelayBinWidth", DoubleValue(0.001));
268 monitor->SetAttribute("JitterBinWidth", DoubleValue(0.001));
269 monitor->SetAttribute("PacketSizeBinWidth", DoubleValue(1));
270 Simulator::Stop(simTime);
271 Simulator::Run();
272
273 monitor->CheckForLostPackets(maxDelay);
274 auto stats = monitor->GetFlowStats();
275 auto classifier = DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
276 double flowDuration = (simTime - udpTime).GetSeconds();
277 for (auto stat = stats.begin(); stat != stats.end(); stat++)
278 {
279 auto flow = classifier->FindFlow(stat->first);
280 outputFile << "Flow ID: " << stat->first << " Src Addr " << flow.sourceAddress
281 << " Dst Addr " << flow.destinationAddress << " Src Port " << flow.sourcePort
282 << " Dst Port " << flow.destinationPort << std::endl;
283 outputFile << "Tx Packets: " << stat->second.txPackets << std::endl;
284 outputFile << "Rx Packets: " << stat->second.rxPackets << std::endl;
285 outputFile << "Lost Packets: " << stat->second.lostPackets << std::endl;
286 outputFile << "Throughput: " << stat->second.rxBytes * 8.0 / flowDuration / 1000 / 1000
287 << " Mbps\n"
288 << std::endl;
289 outputFile << "Mean delay: "
290 << 1000 * stat->second.delaySum.GetSeconds() / stat->second.rxPackets
291 << std::endl;
292 outputFile << "Mean jitter: "
293 << 1000 * stat->second.jitterSum.GetSeconds() / stat->second.rxPackets
294 << " ms\n";
295 }
296}
Manages the correct creation of operation bands, component carriers and bandwidth parts.
OperationBandInfo CreateOperationBandContiguousCc(const SimpleOperationBandConf &conf)
Create an operation band with the CC specified.
static BandwidthPartInfoPtrVector GetAllBwps(const std::vector< std::reference_wrapper< OperationBandInfo > > &operationBands)
Get all the BWP pointers from the specified vector of operation bands.
static TypeId GetTypeId()
Get the type id.
The HexagonalGridScenarioHelper class.
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,...
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.
void SetBsHeight(double h)
SetGnbHeight.
double m_isd
Inter-site distance (ISD) in meters.
void SetUtHeight(double h)
SetUeHeight.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.