A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
main-propagation-loss.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 Timo Bingmann
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Timo Bingmann <timo.bingmann@student.kit.edu>
7 */
8
9#include "ns3/boolean.h"
10#include "ns3/command-line.h"
11#include "ns3/config.h"
12#include "ns3/constant-position-mobility-model.h"
13#include "ns3/double.h"
14#include "ns3/gnuplot.h"
15#include "ns3/jakes-propagation-loss-model.h"
16#include "ns3/pointer.h"
17#include "ns3/propagation-loss-model.h"
18#include "ns3/simulator.h"
19#include "ns3/string.h"
20
21#include <map>
22
23using namespace ns3;
24
25/**
26 * Round a double number to the given precision. e.g. dround(0.234, 0.1) = 0.2
27 * and dround(0.257, 0.1) = 0.3
28 *
29 * \param number The number to round.
30 * \param precision The precision.
31 * \return the rounded number
32 */
33static double
34dround(double number, double precision)
35{
36 number /= precision;
37 if (number >= 0)
38 {
39 number = floor(number + 0.5);
40 }
41 else
42 {
43 number = ceil(number - 0.5);
44 }
45 number *= precision;
46 return number;
47}
48
49/**
50 * Test the model by sampling over a distance.
51 *
52 * \param model The model to test.
53 * \param targetDistance The target distance.
54 * \param step The step.
55 * \return a Gnuplot object to be plotted.
56 */
57static Gnuplot
58TestDeterministic(Ptr<PropagationLossModel> model, double targetDistance, double step)
59{
62
63 Gnuplot plot;
64
65 plot.AppendExtra("set xlabel 'Distance'");
66 plot.AppendExtra("set ylabel 'rxPower (dBm)'");
67 plot.AppendExtra("set key top right");
68
69 double txPowerDbm = +20; // dBm
70
71 Gnuplot2dDataset dataset;
72
74
75 {
76 a->SetPosition(Vector(0.0, 0.0, 0.0));
77
78 for (double distance = 0.0; distance < targetDistance; distance += step)
79 {
80 b->SetPosition(Vector(distance, 0.0, 0.0));
81
82 // CalcRxPower() returns dBm.
83 double rxPowerDbm = model->CalcRxPower(txPowerDbm, a, b);
84
85 dataset.Add(distance, rxPowerDbm);
86
89 }
90 }
91
92 std::ostringstream os;
93 os << "txPower " << txPowerDbm << "dBm";
94 dataset.SetTitle(os.str());
95
96 plot.AddDataset(dataset);
97
98 plot.AddDataset(Gnuplot2dFunction("-94 dBm CSThreshold", "-94.0"));
99
100 return plot;
101}
102
103/**
104 * Test the model by sampling over a distance.
105 *
106 * \param model The model to test.
107 * \param targetDistance The target distance.
108 * \param step The step.
109 * \param samples Number of samples.
110 * \return a Gnuplot object to be plotted.
111 */
112static Gnuplot
114 double targetDistance,
115 double step,
116 unsigned int samples)
117{
120
121 Gnuplot plot;
122
123 plot.AppendExtra("set xlabel 'Distance'");
124 plot.AppendExtra("set ylabel 'rxPower (dBm)'");
125 plot.AppendExtra("set zlabel 'Probability' offset 0,+10");
126 plot.AppendExtra("set view 50, 120, 1.0, 1.0");
127 plot.AppendExtra("set key top right");
128
129 plot.AppendExtra("set ticslevel 0");
130 plot.AppendExtra("set xtics offset -0.5,0");
131 plot.AppendExtra("set ytics offset 0,-0.5");
132 plot.AppendExtra("set xrange [100:]");
133
134 double txPowerDbm = +20; // dBm
135
136 Gnuplot3dDataset dataset;
137
138 dataset.SetStyle("with linespoints");
139 dataset.SetExtra("pointtype 3 pointsize 0.5");
140
141 typedef std::map<double, unsigned int> rxPowerMapType;
142
143 // Take given number of samples from CalcRxPower() and show probability
144 // density for discrete distances.
145 {
146 a->SetPosition(Vector(0.0, 0.0, 0.0));
147
148 for (double distance = 100.0; distance < targetDistance; distance += step)
149 {
150 b->SetPosition(Vector(distance, 0.0, 0.0));
151
152 rxPowerMapType rxPowerMap;
153
154 for (unsigned int samp = 0; samp < samples; ++samp)
155 {
156 // CalcRxPower() returns dBm.
157 double rxPowerDbm = model->CalcRxPower(txPowerDbm, a, b);
158 rxPowerDbm = dround(rxPowerDbm, 1.0);
159
160 rxPowerMap[rxPowerDbm]++;
161
164 }
165
166 for (auto i = rxPowerMap.begin(); i != rxPowerMap.end(); ++i)
167 {
168 dataset.Add(distance, i->first, (double)i->second / (double)samples);
169 }
170 dataset.AddEmptyLine();
171 }
172 }
173
174 std::ostringstream os;
175 os << "txPower " << txPowerDbm << "dBm";
176 dataset.SetTitle(os.str());
177
178 plot.AddDataset(dataset);
179
180 return plot;
181}
182
183/**
184 * Test the model by sampling over time.
185 *
186 * \param model The model to test.
187 * \param timeStep The time step.
188 * \param timeTotal The total time.
189 * \param distance The distance.
190 * \return a Gnuplot object to be plotted.
191 */
192static Gnuplot
194 Time timeStep,
195 Time timeTotal,
196 double distance)
197{
200
201 Gnuplot plot;
202
203 plot.AppendExtra("set xlabel 'Time (s)'");
204 plot.AppendExtra("set ylabel 'rxPower (dBm)'");
205 plot.AppendExtra("set key center right");
206
207 double txPowerDbm = +20; // dBm
208
209 Gnuplot2dDataset dataset;
210
212
213 {
214 a->SetPosition(Vector(0.0, 0.0, 0.0));
215 b->SetPosition(Vector(distance, 0.0, 0.0));
216
217 Time start = Simulator::Now();
218 while (Simulator::Now() < start + timeTotal)
219 {
220 // CalcRxPower() returns dBm.
221 double rxPowerDbm = model->CalcRxPower(txPowerDbm, a, b);
222
223 Time elapsed = Simulator::Now() - start;
224 dataset.Add(elapsed.GetSeconds(), rxPowerDbm);
225
226 Simulator::Stop(timeStep);
228 }
229 }
230
231 std::ostringstream os;
232 os << "txPower " << txPowerDbm << "dBm";
233 dataset.SetTitle(os.str());
234
235 plot.AddDataset(dataset);
236
237 plot.AddDataset(Gnuplot2dFunction("-94 dBm CSThreshold", "-94.0"));
238
239 return plot;
240}
241
242int
243main(int argc, char* argv[])
244{
245 bool test = false;
246 CommandLine cmd(__FILE__);
247 cmd.AddValue("test", "Run as a test, sample the models only once", test);
248 cmd.Parse(argc, argv);
249
250 double testDeterministicDistance = 2500.0;
251 double testProbabilisticDistance = 2500.0;
252 unsigned int testProbabilisticSamples = 100000;
253 Time testJakesTimeOneMsRes = Seconds(1.0);
254 Time testJakesTimeZeroDotOneMsRes = Seconds(0.1);
255
256 if (test)
257 {
258 testDeterministicDistance = 10;
259 testProbabilisticDistance = 200;
260 testProbabilisticSamples = 1;
261 testJakesTimeOneMsRes = Seconds(0.001);
262 testJakesTimeZeroDotOneMsRes = Seconds(0.0001);
263 }
264
265 GnuplotCollection gnuplots("main-propagation-loss.pdf");
266
267 {
269
270 Gnuplot plot = TestDeterministic(friis, testDeterministicDistance, 10.0);
271 plot.SetTitle("ns3::FriisPropagationLossModel (Default Parameters)");
272 gnuplots.AddPlot(plot);
273 }
274
275 {
277 log->SetAttribute("Exponent", DoubleValue(2.5));
278
279 Gnuplot plot = TestDeterministic(log, testDeterministicDistance, 10.0);
280 plot.SetTitle("ns3::LogDistancePropagationLossModel (Exponent = 2.5)");
281 gnuplots.AddPlot(plot);
282 }
283
284 {
288 random->SetAttribute("Variable", PointerValue(expVar));
289
290 Gnuplot plot = TestDeterministic(random, testDeterministicDistance, 10.0);
291 plot.SetTitle("ns3::RandomPropagationLossModel with Exponential Distribution");
292 gnuplots.AddPlot(plot);
293 }
294
295 {
297
298 // doppler frequency shift for 5.15 GHz at 100 km/h
299 Config::SetDefault("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue(477.9));
300
301 Gnuplot plot = TestDeterministicByTime(jakes, Seconds(0.001), testJakesTimeOneMsRes, 100.0);
302 plot.SetTitle(
303 "ns3::JakesPropagationLossModel (with 477.9 Hz shift and 1 millisec resolution)");
304 gnuplots.AddPlot(plot);
305 // Usually objects are aggregated either to a Node or a Channel, and this aggregation
306 // ensures a proper call to Dispose. Here we must call it manually, since the
307 // PropagationLossModel is not aggregated to anything.
308 jakes->Dispose();
309 }
310
311 {
313
314 // doppler frequency shift for 5.15 GHz at 100 km/h
315 Config::SetDefault("ns3::JakesProcess::DopplerFrequencyHz", DoubleValue(477.9));
316
317 Gnuplot plot =
318 TestDeterministicByTime(jakes, Seconds(0.0001), testJakesTimeZeroDotOneMsRes, 100.0);
319 plot.SetTitle(
320 "ns3::JakesPropagationLossModel (with 477.9 Hz shift and 0.1 millisec resolution)");
321 gnuplots.AddPlot(plot);
322 // Usually objects are aggregated either to a Node or a Channel, and this aggregation
323 // ensures a proper call to Dispose. Here we must call it manually, since the
324 // PropagationLossModel is not aggregated to anything.
325 jakes->Dispose();
326 }
327
328 {
331
332 Gnuplot plot = TestDeterministic(log3, testDeterministicDistance, 10.0);
333 plot.SetTitle("ns3::ThreeLogDistancePropagationLossModel (Defaults)");
334 gnuplots.AddPlot(plot);
335 }
336
337 {
340 // more prominent example values:
341 log3->SetAttribute("Exponent0", DoubleValue(1.0));
342 log3->SetAttribute("Exponent1", DoubleValue(3.0));
343 log3->SetAttribute("Exponent2", DoubleValue(10.0));
344
345 Gnuplot plot = TestDeterministic(log3, testDeterministicDistance, 10.0);
346 plot.SetTitle("ns3::ThreeLogDistancePropagationLossModel (Exponents 1.0, 3.0 and 10.0)");
347 gnuplots.AddPlot(plot);
348 }
349
350 {
352
353 Gnuplot plot =
354 TestProbabilistic(nak, testProbabilisticDistance, 100.0, testProbabilisticSamples);
355 plot.SetTitle("ns3::NakagamiPropagationLossModel (Default Parameters)");
356 gnuplots.AddPlot(plot);
357 }
358
359 {
362
364 log3->SetNext(nak);
365
366 Gnuplot plot =
367 TestProbabilistic(log3, testProbabilisticDistance, 100.0, testProbabilisticSamples);
368 plot.SetTitle("ns3::ThreeLogDistancePropagationLossModel and "
369 "ns3::NakagamiPropagationLossModel (Default Parameters)");
370 gnuplots.AddPlot(plot);
371 }
372
373 gnuplots.GenerateOutput(std::cout);
374
375 // produce clean valgrind
377 return 0;
378}
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Class to represent a 2D points plot.
Definition gnuplot.h:105
void SetStyle(Style style)
Definition gnuplot.cc:348
void Add(double x, double y)
Definition gnuplot.cc:366
Class to represent a 2D function expression plot.
Definition gnuplot.h:233
Class to represent a 3D points plot.
Definition gnuplot.h:261
void AddEmptyLine()
Add an empty line in the data output sequence.
Definition gnuplot.cc:622
void Add(double x, double y, double z)
Definition gnuplot.cc:611
void SetStyle(const std::string &style)
Definition gnuplot.cc:605
a simple class to group together multiple gnuplots into one file, e.g.
Definition gnuplot.h:473
void SetExtra(const std::string &extra)
Add extra formatting parameters to this dataset.
Definition gnuplot.cc:149
void SetTitle(const std::string &title)
Change line title.
Definition gnuplot.cc:137
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition gnuplot.h:359
void AddDataset(const GnuplotDataset &dataset)
Definition gnuplot.cc:785
void AppendExtra(const std::string &extra)
Definition gnuplot.cc:778
void SetTitle(const std::string &title)
Definition gnuplot.cc:759
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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.
-ns3 Test suite for the ns3 wrapper script