-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcttc-3gpp-channel-example.cc
321 lines (279 loc) · 12.2 KB
/
cttc-3gpp-channel-example.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
// Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
//
// SPDX-License-Identifier: GPL-2.0-only
/**
* \file cttc-3gpp-channel-example.cc
* \ingroup examples
* \brief Channel Example
*
* This example describes how to setup a simulation using the 3GPP channel model
* from TR 38.900. Topology consists by default of 2 UEs and 2 gNbs, and can be
* configured to be either mobile or static scenario.
*
* The output of this example are default NR trace files that can be found in
* the root ns-3 project folder.
*/
#include "ns3/applications-module.h"
#include "ns3/config-store.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/log.h"
#include "ns3/mobility-module.h"
#include "ns3/network-module.h"
#include "ns3/nr-helper.h"
#include "ns3/nr-mac-scheduler-tdma-rr.h"
#include "ns3/nr-module.h"
#include "ns3/nr-point-to-point-epc-helper.h"
#include "ns3/point-to-point-helper.h"
#include <ns3/antenna-module.h>
#include <ns3/buildings-helper.h>
using namespace ns3;
int
main(int argc, char* argv[])
{
std::string scenario = "UMa"; // scenario
double frequency = 28e9; // central frequency
double bandwidth = 100e6; // bandwidth
double mobility = false; // whether to enable mobility
double simTime = 1; // in second
double speed = 1; // in m/s for walking UT.
bool logging = true; // whether to enable logging from the simulation, another option is by
// exporting the NS_LOG environment variable
double hBS; // base station antenna height in meters
double hUT; // user antenna height in meters
double txPower = 40; // txPower
enum BandwidthPartInfo::Scenario scenarioEnum = BandwidthPartInfo::UMa;
CommandLine cmd(__FILE__);
cmd.AddValue("scenario",
"The scenario for the simulation. Choose among 'RMa', 'UMa', 'UMi-StreetCanyon', "
"'InH-OfficeMixed', 'InH-OfficeOpen'.",
scenario);
cmd.AddValue("frequency", "The central carrier frequency in Hz.", frequency);
cmd.AddValue("mobility",
"If set to 1 UEs will be mobile, when set to 0 UE will be static. By default, "
"they are mobile.",
mobility);
cmd.AddValue("logging", "If set to 0, log components will be disabled.", logging);
cmd.Parse(argc, argv);
// enable logging
if (logging)
{
// LogComponentEnable ("ThreeGppSpectrumPropagationLossModel", LOG_LEVEL_ALL);
LogComponentEnable("ThreeGppPropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ThreeGppChannelModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ChannelConditionModel", LOG_LEVEL_ALL);
// LogComponentEnable ("UdpClient", LOG_LEVEL_INFO);
// LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
// LogComponentEnable ("LteRlcUm", LOG_LEVEL_LOGIC);
// LogComponentEnable ("LtePdcp", LOG_LEVEL_INFO);
}
/*
* Default values for the simulation. We are progressively removing all
* the instances of SetDefault, but we need it for legacy code (LTE)
*/
Config::SetDefault("ns3::LteRlcUm::MaxTxBufferSize", UintegerValue(999999999));
// set mobile device and base station antenna heights in meters, according to the chosen
// scenario
if (scenario == "RMa")
{
hBS = 35;
hUT = 1.5;
scenarioEnum = BandwidthPartInfo::RMa;
}
else if (scenario == "UMa")
{
hBS = 25;
hUT = 1.5;
scenarioEnum = BandwidthPartInfo::UMa;
}
else if (scenario == "UMi-StreetCanyon")
{
hBS = 10;
hUT = 1.5;
scenarioEnum = BandwidthPartInfo::UMi_StreetCanyon;
}
else if (scenario == "InH-OfficeMixed")
{
hBS = 3;
hUT = 1;
scenarioEnum = BandwidthPartInfo::InH_OfficeMixed;
}
else if (scenario == "InH-OfficeOpen")
{
hBS = 3;
hUT = 1;
scenarioEnum = BandwidthPartInfo::InH_OfficeOpen;
}
else
{
NS_ABORT_MSG("Scenario not supported. Choose among 'RMa', 'UMa', 'UMi-StreetCanyon', "
"'InH-OfficeMixed', and 'InH-OfficeOpen'.");
}
// create base stations and mobile terminals
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create(2);
ueNodes.Create(2);
// position the base stations
Ptr<ListPositionAllocator> enbPositionAlloc = CreateObject<ListPositionAllocator>();
enbPositionAlloc->Add(Vector(0.0, 0.0, hBS));
enbPositionAlloc->Add(Vector(0.0, 80.0, hBS));
MobilityHelper enbmobility;
enbmobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
enbmobility.SetPositionAllocator(enbPositionAlloc);
enbmobility.Install(enbNodes);
// position the mobile terminals and enable the mobility
MobilityHelper uemobility;
uemobility.SetMobilityModel("ns3::ConstantVelocityMobilityModel");
uemobility.Install(ueNodes);
if (mobility)
{
ueNodes.Get(0)->GetObject<MobilityModel>()->SetPosition(
Vector(90, 15, hUT)); // (x, y, z) in m
ueNodes.Get(0)->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(
Vector(0, speed, 0)); // move UE1 along the y axis
ueNodes.Get(1)->GetObject<MobilityModel>()->SetPosition(
Vector(30, 50.0, hUT)); // (x, y, z) in m
ueNodes.Get(1)->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(
Vector(-speed, 0, 0)); // move UE2 along the x axis
}
else
{
ueNodes.Get(0)->GetObject<MobilityModel>()->SetPosition(Vector(90, 15, hUT));
ueNodes.Get(0)->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(Vector(0, 0, 0));
ueNodes.Get(1)->GetObject<MobilityModel>()->SetPosition(Vector(30, 50.0, hUT));
ueNodes.Get(1)->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(Vector(0, 0, 0));
}
/*
* Create NR simulation helpers
*/
Ptr<NrPointToPointEpcHelper> epcHelper = CreateObject<NrPointToPointEpcHelper>();
Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
nrHelper->SetBeamformingHelper(idealBeamformingHelper);
nrHelper->SetEpcHelper(epcHelper);
/*
* Spectrum configuration. We create a single operational band and configure the scenario.
*/
BandwidthPartInfoPtrVector allBwps;
CcBwpCreator ccBwpCreator;
const uint8_t numCcPerBand = 1; // in this example we have a single band, and that band is
// composed of a single component carrier
/* Create the configuration for the CcBwpHelper. SimpleOperationBandConf creates
* a single BWP per CC and a single BWP in CC.
*
* Hence, the configured spectrum is:
*
* |---------------Band---------------|
* |---------------CC-----------------|
* |---------------BWP----------------|
*/
CcBwpCreator::SimpleOperationBandConf bandConf(frequency,
bandwidth,
numCcPerBand,
scenarioEnum);
OperationBandInfo band = ccBwpCreator.CreateOperationBandContiguousCc(bandConf);
// Initialize channel and pathloss, plus other things inside band.
nrHelper->InitializeOperationBand(&band);
allBwps = CcBwpCreator::GetAllBwps({band});
// Configure ideal beamforming method
idealBeamformingHelper->SetAttribute("BeamformingMethod",
TypeIdValue(DirectPathBeamforming::GetTypeId()));
// Configure scheduler
nrHelper->SetSchedulerTypeId(NrMacSchedulerTdmaRR::GetTypeId());
// Antennas for the UEs
nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(2));
nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(4));
nrHelper->SetUeAntennaAttribute("AntennaElement",
PointerValue(CreateObject<IsotropicAntennaModel>()));
// Antennas for the gNbs
nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(8));
nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(8));
nrHelper->SetGnbAntennaAttribute("AntennaElement",
PointerValue(CreateObject<IsotropicAntennaModel>()));
// install nr net devices
NetDeviceContainer enbNetDev = nrHelper->InstallGnbDevice(enbNodes, allBwps);
NetDeviceContainer ueNetDev = nrHelper->InstallUeDevice(ueNodes, allBwps);
int64_t randomStream = 1;
randomStream += nrHelper->AssignStreams(enbNetDev, randomStream);
randomStream += nrHelper->AssignStreams(ueNetDev, randomStream);
nrHelper->GetGnbPhy(enbNetDev.Get(0), 0)->SetTxPower(txPower);
nrHelper->GetGnbPhy(enbNetDev.Get(1), 0)->SetTxPower(txPower);
// When all the configuration is done, explicitly call UpdateConfig ()
for (auto it = enbNetDev.Begin(); it != enbNetDev.End(); ++it)
{
DynamicCast<NrGnbNetDevice>(*it)->UpdateConfig();
}
for (auto it = ueNetDev.Begin(); it != ueNetDev.End(); ++it)
{
DynamicCast<NrUeNetDevice>(*it)->UpdateConfig();
}
// create the internet and install the IP stack on the UEs
// get SGW/PGW and create a single RemoteHost
Ptr<Node> pgw = epcHelper->GetPgwNode();
NodeContainer remoteHostContainer;
remoteHostContainer.Create(1);
Ptr<Node> remoteHost = remoteHostContainer.Get(0);
InternetStackHelper internet;
internet.Install(remoteHostContainer);
// connect a remoteHost to pgw. Setup routing too
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
p2ph.SetDeviceAttribute("Mtu", UintegerValue(2500));
p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
internet.Install(ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDev));
// assign IP address to UEs, and install UDP downlink applications
uint16_t dlPort = 1234;
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
{
Ptr<Node> ueNode = ueNodes.Get(u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting =
ipv4RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv4>());
ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
UdpServerHelper dlPacketSinkHelper(dlPort);
serverApps.Add(dlPacketSinkHelper.Install(ueNodes.Get(u)));
UdpClientHelper dlClient(ueIpIface.GetAddress(u), dlPort);
dlClient.SetAttribute("Interval", TimeValue(MicroSeconds(1)));
// dlClient.SetAttribute ("MaxPackets", UintegerValue(0xFFFFFFFF));
dlClient.SetAttribute("MaxPackets", UintegerValue(10));
dlClient.SetAttribute("PacketSize", UintegerValue(1500));
clientApps.Add(dlClient.Install(remoteHost));
}
// attach UEs to the closest eNB
nrHelper->AttachToClosestEnb(ueNetDev, enbNetDev);
// start server and client apps
serverApps.Start(Seconds(0.4));
clientApps.Start(Seconds(0.4));
serverApps.Stop(Seconds(simTime));
clientApps.Stop(Seconds(simTime - 0.2));
// enable the traces provided by the nr module
nrHelper->EnableTraces();
Simulator::Stop(Seconds(simTime));
Simulator::Run();
Ptr<UdpServer> serverApp = serverApps.Get(0)->GetObject<UdpServer>();
uint64_t receivedPackets = serverApp->GetReceived();
Simulator::Destroy();
if (receivedPackets == 10)
{
return EXIT_SUCCESS;
}
else
{
return EXIT_FAILURE;
}
}