1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2014 Piotr Gawlowicz
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
19 *
20 */
21
22 #include "ns3/core-module.h"
23 #include "ns3/network-module.h"
24 #include "ns3/mobility-module.h"
25 #include "ns3/lte-module.h"
26 #include "ns3/config-store.h"
27 #include <ns3/buildings-helper.h>
28 #include <ns3/spectrum-module.h>
29 #include <ns3/log.h>
30
31 using namespace ns3;
32
33 NS_LOG_COMPONENT_DEFINE ("LenaFrequencyReuse");
34
35 void
PrintGnuplottableUeListToFile(std::string filename)36 PrintGnuplottableUeListToFile (std::string filename)
37 {
38 std::ofstream outFile;
39 outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
40 if (!outFile.is_open ())
41 {
42 NS_LOG_ERROR ("Can't open file " << filename);
43 return;
44 }
45 for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
46 {
47 Ptr<Node> node = *it;
48 int nDevs = node->GetNDevices ();
49 for (int j = 0; j < nDevs; j++)
50 {
51 Ptr<LteUeNetDevice> uedev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
52 if (uedev)
53 {
54 Vector pos = node->GetObject<MobilityModel> ()->GetPosition ();
55 outFile << "set label \"" << uedev->GetImsi ()
56 << "\" at " << pos.x << "," << pos.y << " left font \"Helvetica,4\" textcolor rgb \"grey\" front point pt 1 ps 0.3 lc rgb \"grey\" offset 0,0"
57 << std::endl;
58 }
59 }
60 }
61 }
62
63 void
PrintGnuplottableEnbListToFile(std::string filename)64 PrintGnuplottableEnbListToFile (std::string filename)
65 {
66 std::ofstream outFile;
67 outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
68 if (!outFile.is_open ())
69 {
70 NS_LOG_ERROR ("Can't open file " << filename);
71 return;
72 }
73 for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
74 {
75 Ptr<Node> node = *it;
76 int nDevs = node->GetNDevices ();
77 for (int j = 0; j < nDevs; j++)
78 {
79 Ptr<LteEnbNetDevice> enbdev = node->GetDevice (j)->GetObject <LteEnbNetDevice> ();
80 if (enbdev)
81 {
82 Vector pos = node->GetObject<MobilityModel> ()->GetPosition ();
83 outFile << "set label \"" << enbdev->GetCellId ()
84 << "\" at " << pos.x << "," << pos.y
85 << " left font \"Helvetica,4\" textcolor rgb \"white\" front point pt 2 ps 0.3 lc rgb \"white\" offset 0,0"
86 << std::endl;
87 }
88 }
89 }
90 }
91
main(int argc,char * argv[])92 int main (int argc, char *argv[])
93 {
94 Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (true));
95 Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (true));
96 Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (true));
97 Config::SetDefault ("ns3::LteHelper::UsePdschForCqiGeneration", BooleanValue (true));
98
99 //Uplink Power Control
100 Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (true));
101 Config::SetDefault ("ns3::LteUePowerControl::ClosedLoop", BooleanValue (true));
102 Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (false));
103
104 uint32_t runId = 3;
105 uint16_t numberOfRandomUes = 0;
106 double simTime = 2.500;
107 bool generateSpectrumTrace = false;
108 bool generateRem = false;
109 int32_t remRbId = -1;
110 uint16_t bandwidth = 25;
111 double distance = 1000;
112 Box macroUeBox = Box (-distance * 0.5, distance * 1.5, -distance * 0.5, distance * 1.5, 1.5, 1.5);
113
114 // Command line arguments
115 CommandLine cmd (__FILE__);
116 cmd.AddValue ("numberOfUes", "Number of random UEs", numberOfRandomUes);
117 cmd.AddValue ("simTime", "Total duration of the simulation (in seconds)", simTime);
118 cmd.AddValue ("generateSpectrumTrace", "if true, will generate a Spectrum Analyzer trace", generateSpectrumTrace);
119 cmd.AddValue ("generateRem", "if true, will generate a REM and then abort the simulation", generateRem);
120 cmd.AddValue ("remRbId", "Resource Block Id, for which REM will be generated,"
121 "default value is -1, what means REM will be averaged from all RBs", remRbId);
122 cmd.AddValue ("runId", "runId", runId);
123 cmd.Parse (argc, argv);
124
125 RngSeedManager::SetSeed (1);
126 RngSeedManager::SetRun (runId);
127
128 Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
129
130 // Create Nodes: eNodeB and UE
131 NodeContainer enbNodes;
132 NodeContainer centerUeNodes;
133 NodeContainer edgeUeNodes;
134 NodeContainer randomUeNodes;
135 enbNodes.Create (3);
136 centerUeNodes.Create (3);
137 edgeUeNodes.Create (3);
138 randomUeNodes.Create (numberOfRandomUes);
139
140
141 /* the topology is the following:
142 * eNB3
143 * / \
144 * / \
145 * / \
146 * / \
147 * distance / \ distance
148 * / UEs \
149 * / \
150 * / \
151 * / \
152 * / \
153 * eNB1-------------------------eNB2
154 * distance
155 */
156
157 // Install Mobility Model
158 Ptr<ListPositionAllocator> enbPositionAlloc = CreateObject<ListPositionAllocator> ();
159 enbPositionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNB1
160 enbPositionAlloc->Add (Vector (distance, 0.0, 0.0)); // eNB2
161 enbPositionAlloc->Add (Vector (distance * 0.5, distance * 0.866, 0.0)); // eNB3
162 MobilityHelper mobility;
163 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
164 mobility.SetPositionAllocator (enbPositionAlloc);
165 mobility.Install (enbNodes);
166
167
168 Ptr<ListPositionAllocator> edgeUePositionAlloc = CreateObject<ListPositionAllocator> ();
169 edgeUePositionAlloc->Add (Vector (distance * 0.5, distance * 0.28867, 0.0)); // edgeUE1
170 edgeUePositionAlloc->Add (Vector (distance * 0.5, distance * 0.28867, 0.0)); // edgeUE2
171 edgeUePositionAlloc->Add (Vector (distance * 0.5, distance * 0.28867, 0.0)); // edgeUE3
172 mobility.SetPositionAllocator (edgeUePositionAlloc);
173 mobility.Install (edgeUeNodes);
174
175
176 Ptr<ListPositionAllocator> centerUePositionAlloc = CreateObject<ListPositionAllocator> ();
177 centerUePositionAlloc->Add (Vector (0.0, 0.0, 0.0)); // centerUE1
178 centerUePositionAlloc->Add (Vector (distance, 0.0, 0.0)); // centerUE2
179 centerUePositionAlloc->Add (Vector (distance * 0.5, distance * 0.866, 0.0)); // centerUE3
180 mobility.SetPositionAllocator (centerUePositionAlloc);
181 mobility.Install (centerUeNodes);
182
183
184 Ptr<RandomBoxPositionAllocator> randomUePositionAlloc = CreateObject<RandomBoxPositionAllocator> ();
185 Ptr<UniformRandomVariable> xVal = CreateObject<UniformRandomVariable> ();
186 xVal->SetAttribute ("Min", DoubleValue (macroUeBox.xMin));
187 xVal->SetAttribute ("Max", DoubleValue (macroUeBox.xMax));
188 randomUePositionAlloc->SetAttribute ("X", PointerValue (xVal));
189 Ptr<UniformRandomVariable> yVal = CreateObject<UniformRandomVariable> ();
190 yVal->SetAttribute ("Min", DoubleValue (macroUeBox.yMin));
191 yVal->SetAttribute ("Max", DoubleValue (macroUeBox.yMax));
192 randomUePositionAlloc->SetAttribute ("Y", PointerValue (yVal));
193 Ptr<UniformRandomVariable> zVal = CreateObject<UniformRandomVariable> ();
194 zVal->SetAttribute ("Min", DoubleValue (macroUeBox.zMin));
195 zVal->SetAttribute ("Max", DoubleValue (macroUeBox.zMax));
196 randomUePositionAlloc->SetAttribute ("Z", PointerValue (zVal));
197 mobility.SetPositionAllocator (randomUePositionAlloc);
198 mobility.Install (randomUeNodes);
199
200 // Create Devices and install them in the Nodes (eNB and UE)
201 NetDeviceContainer enbDevs;
202 NetDeviceContainer edgeUeDevs;
203 NetDeviceContainer centerUeDevs;
204 NetDeviceContainer randomUeDevs;
205 lteHelper->SetSchedulerType ("ns3::PfFfMacScheduler");
206 lteHelper->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
207 lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (bandwidth));
208 lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (bandwidth));
209
210 std::string frAlgorithmType = lteHelper->GetFfrAlgorithmType ();
211 NS_LOG_DEBUG ("FrAlgorithmType: " << frAlgorithmType);
212
213 if (frAlgorithmType == "ns3::LteFrHardAlgorithm")
214 {
215
216 //Nothing to configure here in automatic mode
217
218 }
219 else if (frAlgorithmType == "ns3::LteFrStrictAlgorithm")
220 {
221
222 lteHelper->SetFfrAlgorithmAttribute ("RsrqThreshold", UintegerValue (32));
223 lteHelper->SetFfrAlgorithmAttribute ("CenterPowerOffset",
224 UintegerValue (LteRrcSap::PdschConfigDedicated::dB_6));
225 lteHelper->SetFfrAlgorithmAttribute ("EdgePowerOffset",
226 UintegerValue (LteRrcSap::PdschConfigDedicated::dB3));
227 lteHelper->SetFfrAlgorithmAttribute ("CenterAreaTpc", UintegerValue (0));
228 lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaTpc", UintegerValue (3));
229
230 //ns3::LteFrStrictAlgorithm works with Absolute Mode Uplink Power Control
231 Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (false));
232
233 }
234 else if (frAlgorithmType == "ns3::LteFrSoftAlgorithm")
235 {
236
237 lteHelper->SetFfrAlgorithmAttribute ("AllowCenterUeUseEdgeSubBand", BooleanValue (true));
238 lteHelper->SetFfrAlgorithmAttribute ("RsrqThreshold", UintegerValue (25));
239 lteHelper->SetFfrAlgorithmAttribute ("CenterPowerOffset",
240 UintegerValue (LteRrcSap::PdschConfigDedicated::dB_6));
241 lteHelper->SetFfrAlgorithmAttribute ("EdgePowerOffset",
242 UintegerValue (LteRrcSap::PdschConfigDedicated::dB3));
243 lteHelper->SetFfrAlgorithmAttribute ("CenterAreaTpc", UintegerValue (0));
244 lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaTpc", UintegerValue (3));
245
246 //ns3::LteFrSoftAlgorithm works with Absolute Mode Uplink Power Control
247 Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (false));
248
249 }
250 else if (frAlgorithmType == "ns3::LteFfrSoftAlgorithm")
251 {
252
253 lteHelper->SetFfrAlgorithmAttribute ("CenterRsrqThreshold", UintegerValue (30));
254 lteHelper->SetFfrAlgorithmAttribute ("EdgeRsrqThreshold", UintegerValue (25));
255 lteHelper->SetFfrAlgorithmAttribute ("CenterAreaPowerOffset",
256 UintegerValue (LteRrcSap::PdschConfigDedicated::dB_6));
257 lteHelper->SetFfrAlgorithmAttribute ("MediumAreaPowerOffset",
258 UintegerValue (LteRrcSap::PdschConfigDedicated::dB_1dot77));
259 lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaPowerOffset",
260 UintegerValue (LteRrcSap::PdschConfigDedicated::dB3));
261 lteHelper->SetFfrAlgorithmAttribute ("CenterAreaTpc", UintegerValue (1));
262 lteHelper->SetFfrAlgorithmAttribute ("MediumAreaTpc", UintegerValue (2));
263 lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaTpc", UintegerValue (3));
264
265 //ns3::LteFfrSoftAlgorithm works with Absolute Mode Uplink Power Control
266 Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (false));
267
268 }
269 else if (frAlgorithmType == "ns3::LteFfrEnhancedAlgorithm")
270 {
271
272 lteHelper->SetFfrAlgorithmAttribute ("RsrqThreshold", UintegerValue (25));
273 lteHelper->SetFfrAlgorithmAttribute ("DlCqiThreshold", UintegerValue (10));
274 lteHelper->SetFfrAlgorithmAttribute ("UlCqiThreshold", UintegerValue (10));
275 lteHelper->SetFfrAlgorithmAttribute ("CenterAreaPowerOffset",
276 UintegerValue (LteRrcSap::PdschConfigDedicated::dB_6));
277 lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaPowerOffset",
278 UintegerValue (LteRrcSap::PdschConfigDedicated::dB3));
279 lteHelper->SetFfrAlgorithmAttribute ("CenterAreaTpc", UintegerValue (0));
280 lteHelper->SetFfrAlgorithmAttribute ("EdgeAreaTpc", UintegerValue (3));
281
282 //ns3::LteFfrEnhancedAlgorithm works with Absolute Mode Uplink Power Control
283 Config::SetDefault ("ns3::LteUePowerControl::AccumulationEnabled", BooleanValue (false));
284
285 }
286 else if (frAlgorithmType == "ns3::LteFfrDistributedAlgorithm")
287 {
288
289 NS_FATAL_ERROR ("ns3::LteFfrDistributedAlgorithm not supported in this example. Please run lena-distributed-ffr");
290
291 }
292 else
293 {
294 lteHelper->SetFfrAlgorithmType ("ns3::LteFrNoOpAlgorithm");
295 }
296
297 lteHelper->SetFfrAlgorithmAttribute ("FrCellTypeId", UintegerValue (1));
298 enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (0)));
299
300 lteHelper->SetFfrAlgorithmAttribute ("FrCellTypeId", UintegerValue (2));
301 enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (1)));
302
303 lteHelper->SetFfrAlgorithmAttribute ("FrCellTypeId", UintegerValue (3));
304 enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (2)));
305
306 //FR algorithm reconfiguration if needed
307 PointerValue tmp;
308 enbDevs.Get (0)->GetAttribute ("LteFfrAlgorithm", tmp);
309 Ptr<LteFfrAlgorithm> ffrAlgorithm = DynamicCast<LteFfrAlgorithm> (tmp.GetObject ());
310 ffrAlgorithm->SetAttribute ("FrCellTypeId", UintegerValue (1));
311
312
313 //Install Ue Device
314 edgeUeDevs = lteHelper->InstallUeDevice (edgeUeNodes);
315 centerUeDevs = lteHelper->InstallUeDevice (centerUeNodes);
316 randomUeDevs = lteHelper->InstallUeDevice (randomUeNodes);
317
318 // Attach edge UEs to eNbs
319 for (uint32_t i = 0; i < edgeUeDevs.GetN (); i++)
320 {
321 lteHelper->Attach (edgeUeDevs.Get (i), enbDevs.Get (i));
322 }
323 // Attach center UEs to eNbs
324 for (uint32_t i = 0; i < centerUeDevs.GetN (); i++)
325 {
326 lteHelper->Attach (centerUeDevs.Get (i), enbDevs.Get (i));
327 }
328
329 // Attach UE to a eNB
330 lteHelper->AttachToClosestEnb (randomUeDevs, enbDevs);
331
332 // Activate a data radio bearer
333 enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
334 EpsBearer bearer (q);
335 lteHelper->ActivateDataRadioBearer (edgeUeDevs, bearer);
336 lteHelper->ActivateDataRadioBearer (centerUeDevs, bearer);
337 lteHelper->ActivateDataRadioBearer (randomUeDevs, bearer);
338
339 //Spectrum analyzer
340 NodeContainer spectrumAnalyzerNodes;
341 spectrumAnalyzerNodes.Create (1);
342 SpectrumAnalyzerHelper spectrumAnalyzerHelper;
343
344 if (generateSpectrumTrace)
345 {
346 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
347 //position of Spectrum Analyzer
348 // positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNB1
349 // positionAlloc->Add (Vector (distance, 0.0, 0.0)); // eNB2
350 positionAlloc->Add (Vector (distance * 0.5, distance * 0.866, 0.0)); // eNB3
351
352 MobilityHelper mobility;
353 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
354 mobility.SetPositionAllocator (positionAlloc);
355 mobility.Install (spectrumAnalyzerNodes);
356
357 Ptr<LteSpectrumPhy> enbDlSpectrumPhy = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetPhy ()->GetDownlinkSpectrumPhy ()->GetObject<LteSpectrumPhy> ();
358 Ptr<SpectrumChannel> dlChannel = enbDlSpectrumPhy->GetChannel ();
359
360 spectrumAnalyzerHelper.SetChannel (dlChannel);
361 Ptr<SpectrumModel> sm = LteSpectrumValueHelper::GetSpectrumModel (100, bandwidth);
362 spectrumAnalyzerHelper.SetRxSpectrumModel (sm);
363 spectrumAnalyzerHelper.SetPhyAttribute ("Resolution", TimeValue (MicroSeconds (10)));
364 spectrumAnalyzerHelper.SetPhyAttribute ("NoisePowerSpectralDensity", DoubleValue (1e-15)); // -120 dBm/Hz
365 spectrumAnalyzerHelper.EnableAsciiAll ("spectrum-analyzer-output");
366 spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes);
367 }
368
369 Ptr<RadioEnvironmentMapHelper> remHelper;
370 if (generateRem)
371 {
372 PrintGnuplottableEnbListToFile ("enbs.txt");
373 PrintGnuplottableUeListToFile ("ues.txt");
374
375 remHelper = CreateObject<RadioEnvironmentMapHelper> ();
376 remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
377 remHelper->SetAttribute ("OutputFile", StringValue ("lena-frequency-reuse.rem"));
378 remHelper->SetAttribute ("XMin", DoubleValue (macroUeBox.xMin));
379 remHelper->SetAttribute ("XMax", DoubleValue (macroUeBox.xMax));
380 remHelper->SetAttribute ("YMin", DoubleValue (macroUeBox.yMin));
381 remHelper->SetAttribute ("YMax", DoubleValue (macroUeBox.yMax));
382 remHelper->SetAttribute ("Z", DoubleValue (1.5));
383 remHelper->SetAttribute ("XRes", UintegerValue (500));
384 remHelper->SetAttribute ("YRes", UintegerValue (500));
385 if (remRbId >= 0)
386 {
387 remHelper->SetAttribute ("UseDataChannel", BooleanValue (true));
388 remHelper->SetAttribute ("RbId", IntegerValue (remRbId));
389 }
390
391 remHelper->Install ();
392 // simulation will stop right after the REM has been generated
393 }
394 else
395 {
396 Simulator::Stop (Seconds (simTime));
397 }
398
399 Simulator::Run ();
400 Simulator::Destroy ();
401 return 0;
402 }
403