A Discrete-Event Network Simulator
API
main-propagation-loss.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 Timo Bingmann
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Timo Bingmann <timo.bingmann@student.kit.edu>
18  */
19 
20 #include "ns3/boolean.h"
21 #include "ns3/command-line.h"
22 #include "ns3/config.h"
23 #include "ns3/constant-position-mobility-model.h"
24 #include "ns3/double.h"
25 #include "ns3/gnuplot.h"
26 #include "ns3/jakes-propagation-loss-model.h"
27 #include "ns3/pointer.h"
28 #include "ns3/propagation-loss-model.h"
29 #include "ns3/simulator.h"
30 #include "ns3/string.h"
31 
32 #include <map>
33 
34 using namespace ns3;
35 
44 static double
45 dround(double number, double precision)
46 {
47  number /= precision;
48  if (number >= 0)
49  {
50  number = floor(number + 0.5);
51  }
52  else
53  {
54  number = ceil(number - 0.5);
55  }
56  number *= precision;
57  return number;
58 }
59 
68 static Gnuplot
69 TestDeterministic(Ptr<PropagationLossModel> model, double targetDistance, double step)
70 {
71  Ptr<ConstantPositionMobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
72  Ptr<ConstantPositionMobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
73 
74  Gnuplot plot;
75 
76  plot.AppendExtra("set xlabel 'Distance'");
77  plot.AppendExtra("set ylabel 'rxPower (dBm)'");
78  plot.AppendExtra("set key top right");
79 
80  double txPowerDbm = +20; // dBm
81 
82  Gnuplot2dDataset dataset;
83 
85 
86  {
87  a->SetPosition(Vector(0.0, 0.0, 0.0));
88 
89  for (double distance = 0.0; distance < targetDistance; distance += step)
90  {
91  b->SetPosition(Vector(distance, 0.0, 0.0));
92 
93  // CalcRxPower() returns dBm.
94  double rxPowerDbm = model->CalcRxPower(txPowerDbm, a, b);
95 
96  dataset.Add(distance, rxPowerDbm);
97 
100  }
101  }
102 
103  std::ostringstream os;
104  os << "txPower " << txPowerDbm << "dBm";
105  dataset.SetTitle(os.str());
106 
107  plot.AddDataset(dataset);
108 
109  plot.AddDataset(Gnuplot2dFunction("-94 dBm CSThreshold", "-94.0"));
110 
111  return plot;
112 }
113 
123 static Gnuplot
125  double targetDistance,
126  double step,
127  unsigned int samples)
128 {
129  Ptr<ConstantPositionMobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
130  Ptr<ConstantPositionMobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
131 
132  Gnuplot plot;
133 
134  plot.AppendExtra("set xlabel 'Distance'");
135  plot.AppendExtra("set ylabel 'rxPower (dBm)'");
136  plot.AppendExtra("set zlabel 'Probability' offset 0,+10");
137  plot.AppendExtra("set view 50, 120, 1.0, 1.0");
138  plot.AppendExtra("set key top right");
139 
140  plot.AppendExtra("set ticslevel 0");
141  plot.AppendExtra("set xtics offset -0.5,0");
142  plot.AppendExtra("set ytics offset 0,-0.5");
143  plot.AppendExtra("set xrange [100:]");
144 
145  double txPowerDbm = +20; // dBm
146 
147  Gnuplot3dDataset dataset;
148 
149  dataset.SetStyle("with linespoints");
150  dataset.SetExtra("pointtype 3 pointsize 0.5");
151 
152  typedef std::map<double, unsigned int> rxPowerMapType;
153 
154  // Take given number of samples from CalcRxPower() and show probability
155  // density for discrete distances.
156  {
157  a->SetPosition(Vector(0.0, 0.0, 0.0));
158 
159  for (double distance = 100.0; distance < targetDistance; distance += step)
160  {
161  b->SetPosition(Vector(distance, 0.0, 0.0));
162 
163  rxPowerMapType rxPowerMap;
164 
165  for (unsigned int samp = 0; samp < samples; ++samp)
166  {
167  // CalcRxPower() returns dBm.
168  double rxPowerDbm = model->CalcRxPower(txPowerDbm, a, b);
169  rxPowerDbm = dround(rxPowerDbm, 1.0);
170 
171  rxPowerMap[rxPowerDbm]++;
172 
173  Simulator::Stop(Seconds(0.01));
174  Simulator::Run();
175  }
176 
177  for (auto i = rxPowerMap.begin(); i != rxPowerMap.end(); ++i)
178  {
179  dataset.Add(distance, i->first, (double)i->second / (double)samples);
180  }
181  dataset.AddEmptyLine();
182  }
183  }
184 
185  std::ostringstream os;
186  os << "txPower " << txPowerDbm << "dBm";
187  dataset.SetTitle(os.str());
188 
189  plot.AddDataset(dataset);
190 
191  return plot;
192 }
193 
203 static Gnuplot
205  Time timeStep,
206  Time timeTotal,
207  double distance)
208 {
209  Ptr<ConstantPositionMobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
210  Ptr<ConstantPositionMobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
211 
212  Gnuplot plot;
213 
214  plot.AppendExtra("set xlabel 'Time (s)'");
215  plot.AppendExtra("set ylabel 'rxPower (dBm)'");
216  plot.AppendExtra("set key center right");
217 
218  double txPowerDbm = +20; // dBm
219 
220  Gnuplot2dDataset dataset;
221 
223 
224  {
225  a->SetPosition(Vector(0.0, 0.0, 0.0));
226  b->SetPosition(Vector(distance, 0.0, 0.0));
227 
229  while (Simulator::Now() < start + timeTotal)
230  {
231  // CalcRxPower() returns dBm.
232  double rxPowerDbm = model->CalcRxPower(txPowerDbm, a, b);
233 
234  Time elapsed = Simulator::Now() - start;
235  dataset.Add(elapsed.GetSeconds(), rxPowerDbm);
236 
237  Simulator::Stop(timeStep);
238  Simulator::Run();
239  }
240  }
241 
242  std::ostringstream os;
243  os << "txPower " << txPowerDbm << "dBm";
244  dataset.SetTitle(os.str());
245 
246  plot.AddDataset(dataset);
247 
248  plot.AddDataset(Gnuplot2dFunction("-94 dBm CSThreshold", "-94.0"));
249 
250  return plot;
251 }
252 
253 int
254 main(int argc, char* argv[])
255 {
256  bool test = false;
257  CommandLine cmd(__FILE__);
258  cmd.AddValue("test", "Run as a test, sample the models only once", test);
259  cmd.Parse(argc, argv);
260 
261  double testDeterministicDistance = 2500.0;
262  double testProbabilisticDistance = 2500.0;
263  unsigned int testProbabilisticSamples = 100000;
264  Time testJakesTimeOneMsRes = Seconds(1.0);
265  Time testJakesTimeZeroDotOneMsRes = Seconds(0.1);
266 
267  if (test)
268  {
269  testDeterministicDistance = 10;
270  testProbabilisticDistance = 200;
271  testProbabilisticSamples = 1;
272  testJakesTimeOneMsRes = Seconds(0.001);
273  testJakesTimeZeroDotOneMsRes = Seconds(0.0001);
274  }
275 
276  GnuplotCollection gnuplots("main-propagation-loss.pdf");
277 
278  {
279  Ptr<FriisPropagationLossModel> friis = CreateObject<FriisPropagationLossModel>();
280 
281  Gnuplot plot = TestDeterministic(friis, testDeterministicDistance, 10.0);
282  plot.SetTitle("ns3::FriisPropagationLossModel (Default Parameters)");
283  gnuplots.AddPlot(plot);
284  }
285 
286  {
287  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel>();
288  log->SetAttribute("Exponent", DoubleValue(2.5));
289 
290  Gnuplot plot = TestDeterministic(log, testDeterministicDistance, 10.0);
291  plot.SetTitle("ns3::LogDistancePropagationLossModel (Exponent = 2.5)");
292  gnuplots.AddPlot(plot);
293  }
294 
295  {
296  Ptr<RandomPropagationLossModel> random = CreateObject<RandomPropagationLossModel>();
298  CreateObjectWithAttributes<ExponentialRandomVariable>("Mean", DoubleValue(50.0));
299  random->SetAttribute("Variable", PointerValue(expVar));
300 
301  Gnuplot plot = TestDeterministic(random, testDeterministicDistance, 10.0);
302  plot.SetTitle("ns3::RandomPropagationLossModel with Exponential Distribution");
303  gnuplots.AddPlot(plot);
304  }
305 
306  {
307  Ptr<JakesPropagationLossModel> jakes = CreateObject<JakesPropagationLossModel>();
308 
309  // doppler frequency shift for 5.15 GHz at 100 km/h
310  Config::SetDefault("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue(477.9));
311 
312  Gnuplot plot = TestDeterministicByTime(jakes, Seconds(0.001), testJakesTimeOneMsRes, 100.0);
313  plot.SetTitle(
314  "ns3::JakesPropagationLossModel (with 477.9 Hz shift and 1 millisec resolution)");
315  gnuplots.AddPlot(plot);
316  // Usually objects are aggregated either to a Node or a Channel, and this aggregation
317  // ensures a proper call to Dispose. Here we must call it manually, since the
318  // PropagationLossModel is not aggregated to anything.
319  jakes->Dispose();
320  }
321 
322  {
323  Ptr<JakesPropagationLossModel> jakes = CreateObject<JakesPropagationLossModel>();
324 
325  // doppler frequency shift for 5.15 GHz at 100 km/h
326  Config::SetDefault("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue(477.9));
327 
328  Gnuplot plot =
329  TestDeterministicByTime(jakes, Seconds(0.0001), testJakesTimeZeroDotOneMsRes, 100.0);
330  plot.SetTitle(
331  "ns3::JakesPropagationLossModel (with 477.9 Hz shift and 0.1 millisec resolution)");
332  gnuplots.AddPlot(plot);
333  // Usually objects are aggregated either to a Node or a Channel, and this aggregation
334  // ensures a proper call to Dispose. Here we must call it manually, since the
335  // PropagationLossModel is not aggregated to anything.
336  jakes->Dispose();
337  }
338 
339  {
341  CreateObject<ThreeLogDistancePropagationLossModel>();
342 
343  Gnuplot plot = TestDeterministic(log3, testDeterministicDistance, 10.0);
344  plot.SetTitle("ns3::ThreeLogDistancePropagationLossModel (Defaults)");
345  gnuplots.AddPlot(plot);
346  }
347 
348  {
350  CreateObject<ThreeLogDistancePropagationLossModel>();
351  // more prominent example values:
352  log3->SetAttribute("Exponent0", DoubleValue(1.0));
353  log3->SetAttribute("Exponent1", DoubleValue(3.0));
354  log3->SetAttribute("Exponent2", DoubleValue(10.0));
355 
356  Gnuplot plot = TestDeterministic(log3, testDeterministicDistance, 10.0);
357  plot.SetTitle("ns3::ThreeLogDistancePropagationLossModel (Exponents 1.0, 3.0 and 10.0)");
358  gnuplots.AddPlot(plot);
359  }
360 
361  {
362  Ptr<NakagamiPropagationLossModel> nak = CreateObject<NakagamiPropagationLossModel>();
363 
364  Gnuplot plot =
365  TestProbabilistic(nak, testProbabilisticDistance, 100.0, testProbabilisticSamples);
366  plot.SetTitle("ns3::NakagamiPropagationLossModel (Default Parameters)");
367  gnuplots.AddPlot(plot);
368  }
369 
370  {
372  CreateObject<ThreeLogDistancePropagationLossModel>();
373 
374  Ptr<NakagamiPropagationLossModel> nak = CreateObject<NakagamiPropagationLossModel>();
375  log3->SetNext(nak);
376 
377  Gnuplot plot =
378  TestProbabilistic(log3, testProbabilisticDistance, 100.0, testProbabilisticSamples);
379  plot.SetTitle("ns3::ThreeLogDistancePropagationLossModel and "
380  "ns3::NakagamiPropagationLossModel (Default Parameters)");
381  gnuplots.AddPlot(plot);
382  }
383 
384  gnuplots.GenerateOutput(std::cout);
385 
386  // produce clean valgrind
388  return 0;
389 }
Parse command-line arguments.
Definition: command-line.h:232
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Class to represent a 2D points plot.
Definition: gnuplot.h:118
void SetStyle(enum Style style)
Definition: gnuplot.cc:345
void Add(double x, double y)
Definition: gnuplot.cc:362
Class to represent a 2D function expression plot.
Definition: gnuplot.h:245
Class to represent a 3D points plot.
Definition: gnuplot.h:274
void AddEmptyLine()
Add an empty line in the data output sequence.
Definition: gnuplot.cc:607
void Add(double x, double y, double z)
Definition: gnuplot.cc:596
void SetStyle(const std::string &style)
Definition: gnuplot.cc:590
a simple class to group together multiple gnuplots into one file, e.g.
Definition: gnuplot.h:489
void SetExtra(const std::string &extra)
Add extra formatting parameters to this dataset.
Definition: gnuplot.cc:152
void SetTitle(const std::string &title)
Change line title.
Definition: gnuplot.cc:141
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:373
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:759
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:752
void SetTitle(const std::string &title)
Definition: gnuplot.cc:733
Hold objects of type Ptr<T>.
Definition: pointer.h:37
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
static double dround(double number, double precision)
Round a double number to the given precision.
static Gnuplot TestDeterministicByTime(Ptr< PropagationLossModel > model, Time timeStep, Time timeTotal, double distance)
Test the model by sampling over time.
static Gnuplot TestDeterministic(Ptr< PropagationLossModel > model, double targetDistance, double step)
Test the model by sampling over a distance.
static Gnuplot TestProbabilistic(Ptr< PropagationLossModel > model, double targetDistance, double step, unsigned int samples)
Test the model by sampling over a distance.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:40