A Discrete-Event Network Simulator
API
lr-wpan-per-plot.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Tokushima University, Japan
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  * Authors: Alberto Gallegos Ramonet <alramonet@is.tokushima-u.ac.jp>
18  * Tommaso Pecorella <tommaso.pecorella@unifi.it>
19  */
20 
21 /*
22  This program produces a gnuplot file that plots the theoretical and experimental packet error
23  rate (PER) as a function of receive signal for the 802.15.4 model. As described by the standard,
24  the PER is calculated with the transmission of frames with a PSDU of 20 bytes. This is equivalent
25  to an MPDU = MAC header (11 bytes) + FCS (2 bytes) + payload (MSDU 7 bytes). In the experimental
26  test, 1000 frames are transmitted for each Rx signal ranging from -130 dBm to -100 dBm with
27  increments of 0.01 dBm. The point before PER is < 1 % is the device receive sensitivity.
28  Theoretical and experimental Rx sensitivity is printed at the end of the end and a plot is
29  generated.
30 
31  Example usage:
32 
33  ./ns3 run "lr-wpan-per-plot --rxSensitivity=-92"
34 
35 */
36 
37 #include <ns3/core-module.h>
38 #include <ns3/gnuplot.h>
39 #include <ns3/lr-wpan-module.h>
40 #include <ns3/mobility-module.h>
41 #include <ns3/network-module.h>
42 #include <ns3/propagation-module.h>
43 #include <ns3/spectrum-module.h>
44 
45 using namespace ns3;
46 
47 uint32_t g_packetsReceived = 0;
48 
49 NS_LOG_COMPONENT_DEFINE("LrWpanErrorDistancePlot");
50 
56 void
58 {
60 }
61 
62 int
63 main(int argc, char* argv[])
64 {
66 
67  std::ostringstream os;
68  std::ofstream perfile("802.15.4-per-vs-rxSignal.plt");
69 
70  double minRxSignal = -111; // dBm
71  double maxRxSignal = -82; // dBm
72  double increment = 0.01;
73  int maxPackets = 1000;
74  int packetSize = 7; // bytes (MPDU payload)
75  double txPower = 0; // dBm
76  uint32_t channelNumber = 11;
77  double rxSensitivity = -106.58; // dBm
78 
79  CommandLine cmd(__FILE__);
80 
81  cmd.AddValue("txPower", "transmit power (dBm)", txPower);
82  cmd.AddValue("packetSize", "packet (MSDU) size (bytes)", packetSize);
83  cmd.AddValue("channelNumber", "channel number", channelNumber);
84  cmd.AddValue("rxSensitivity", "the rx sensitivity (dBm)", rxSensitivity);
85  cmd.Parse(argc, argv);
86 
87  Gnuplot perplot = Gnuplot("802.15.4-per-vs-rxSignal.eps");
88  Gnuplot2dDataset perdatasetExperimental("Experimental");
89  Gnuplot2dDataset perdatasetTheoretical("Theoretical");
90 
91  Ptr<Node> n0 = CreateObject<Node>();
92  Ptr<Node> n1 = CreateObject<Node>();
93  Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice>();
94  Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice>();
95 
96  dev0->SetAddress(Mac16Address("00:01"));
97  dev1->SetAddress(Mac16Address("00:02"));
98  Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel>();
99  Ptr<FixedRssLossModel> propModel = CreateObject<FixedRssLossModel>();
100 
101  channel->AddPropagationLossModel(propModel);
102  dev0->SetChannel(channel);
103  dev1->SetChannel(channel);
104  n0->AddDevice(dev0);
105  n1->AddDevice(dev1);
106  Ptr<ConstantPositionMobilityModel> mob0 = CreateObject<ConstantPositionMobilityModel>();
107  dev0->GetPhy()->SetMobility(mob0);
108  Ptr<ConstantPositionMobilityModel> mob1 = CreateObject<ConstantPositionMobilityModel>();
109  dev1->GetPhy()->SetMobility(mob1);
110  mob0->SetPosition(Vector(0, 0, 0));
111  mob1->SetPosition(Vector(0, 0, 0));
112 
114  Ptr<SpectrumValue> psd = svh.CreateTxPowerSpectralDensity(txPower, channelNumber);
115  dev0->GetPhy()->SetTxPowerSpectralDensity(psd);
116 
117  // Set Rx sensitivity of the receiving device
118  dev1->GetPhy()->SetRxSensitivity(rxSensitivity);
119 
122  dev1->GetMac()->SetMcpsDataIndicationCallback(cb0);
123 
125  // Experimental PER v.s Signal //
127 
128  double per = 1;
129  double sensitivityExp = 0;
130  bool sensThreshold = true;
131 
132  for (double j = minRxSignal; j < maxRxSignal; j += increment)
133  {
134  propModel->SetRss(j);
135  if (sensThreshold)
136  {
137  sensitivityExp = j;
138  }
139 
140  for (int i = 0; i < maxPackets; i++)
141  {
143  params.m_srcAddrMode = SHORT_ADDR;
144  params.m_dstAddrMode = SHORT_ADDR;
145  params.m_dstPanId = 0;
146  params.m_dstAddr = Mac16Address("00:02");
147  params.m_msduHandle = 0;
148  params.m_txOptions = 0;
149  Ptr<Packet> p;
150  p = Create<Packet>(packetSize);
152  }
153 
154  Simulator::Run();
155 
156  per = (static_cast<double>(maxPackets - g_packetsReceived) / maxPackets) * 100;
157 
158  std::cout << "Experimental Test || Signal: " << j << " dBm | Received " << g_packetsReceived
159  << " pkts"
160  << "/" << maxPackets << " | PER " << per << " %\n";
161 
162  if (per <= 1 && sensThreshold)
163  {
164  sensThreshold = false;
165  }
166 
167  perdatasetExperimental.Add(j, per);
168  g_packetsReceived = 0;
169  }
170 
172  // Theoretical PER v.s. Signal //
174 
175  Ptr<LrWpanErrorModel> lrWpanError = CreateObject<LrWpanErrorModel>();
176  LrWpanSpectrumValueHelper psdHelper;
177 
178  // Calculate the noise that accounts for both thermal noise (floor noise) and
179  // imperfections on the chip or lost before reaching the demodulator.
180  // In O-QPSK 250kbps, the point where PER is <= 1% without
181  // additional noise is -106.58 dBm (Noise Factor = 1)
182  double maxRxSensitivityW = (pow(10.0, -106.58 / 10.0) / 1000.0);
183  long double noiseFactor = (pow(10.0, rxSensitivity / 10.0) / 1000.0) / maxRxSensitivityW;
184 
185  psdHelper.SetNoiseFactor(noiseFactor);
187  double noise = LrWpanSpectrumValueHelper::TotalAvgPower(noisePsd, 11);
188 
189  double signal = 0;
190  double sensitivityTheo = 0;
191  double perTheoretical = 0;
192  double snr = 0;
193  sensThreshold = true;
194 
195  for (double j = minRxSignal; j < maxRxSignal; j += increment)
196  {
197  if (sensThreshold)
198  {
199  sensitivityTheo = j;
200  }
201 
202  signal = pow(10.0, j / 10.0) / 1000.0; // signal in Watts
203  snr = signal / noise;
204 
205  // According to the standard, Packet error rate should be obtained
206  // using a PSDU of 20 bytes using
207  // the equation PER = 1 - (1 - BER)^nbits
208  perTheoretical = (1.0 - lrWpanError->GetChunkSuccessRate(snr, (packetSize + 13) * 8)) * 100;
209  std::cout << "Theoretical Test || Signal: " << j << " dBm | SNR: " << snr << "| PER "
210  << perTheoretical << " % \n";
211 
212  if (perTheoretical <= 1 && sensThreshold)
213  {
214  sensThreshold = false;
215  }
216 
217  perdatasetTheoretical.Add(j, perTheoretical);
218  }
219 
220  std::cout << "_____________________________________________________________________________\n";
221  std::cout << "Experimental Test || Receiving with a current sensitivity of " << sensitivityExp
222  << " dBm\n";
223  std::cout << "Theoretical Test || Receiving with a current sensitivity of " << sensitivityTheo
224  << " dBm\n";
225  std::cout << "Gnu plot generated.";
226 
227  os << "Pkt Payload (MSDU) size = " << packetSize << " bytes | "
228  << "Tx power = " << txPower << " dBm | "
229  << "Rx Sensitivity (Theo) = " << sensitivityTheo << " dBm";
230 
231  perplot.AddDataset(perdatasetExperimental);
232  perplot.AddDataset(perdatasetTheoretical);
233 
234  perplot.SetTitle(os.str());
235  perplot.SetTerminal("postscript eps color enh \"Times-BoldItalic\"");
236  perplot.SetLegend("Rx signal (dBm)", "Packet Error Rate (%)");
237  perplot.SetExtra("set xrange [-110:-82]\n\
238  set logscale y\n\
239  set yrange [0.000000000001:120]\n\
240  set xtics 2\n\
241  set grid\n\
242  set style line 1 linewidth 5\n\
243  set style line 2 linewidth 3\n\
244  set style increment user\n\
245  set arrow from -110,1 to -82,1 nohead lc 'web-blue' front");
246  perplot.GenerateOutput(perfile);
247  perfile.close();
248 
250  return 0;
251 }
Parse command-line arguments.
Definition: command-line.h:232
Class to represent a 2D points plot.
Definition: gnuplot.h:118
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 SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:739
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:727
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:765
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:746
void SetTitle(const std::string &title)
Definition: gnuplot.cc:733
void McpsDataRequest(McpsDataRequestParams params, Ptr< Packet > p) override
IEEE 802.15.4-2006, section 7.1.1.1 MCPS-DATA.request Request to transfer a MSDU.
Definition: lr-wpan-mac.cc:384
void SetChannel(Ptr< SpectrumChannel > channel)
Set the channel to which the NetDevice, and therefore the PHY, should be attached to.
Ptr< LrWpanMac > GetMac() const
Get the MAC used by this NetDevice.
Ptr< LrWpanPhy > GetPhy() const
Get the PHY used by this NetDevice.
void SetAddress(Address address) override
This method indirects to LrWpanMac::SetShortAddress ()
This class defines all functions to create spectrum model for LrWpan.
Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t channel)
create spectrum value for noise
static double TotalAvgPower(Ptr< const SpectrumValue > psd, uint32_t channel)
total average power of the signal is the integral of the PSD using the limits of the given channel
Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double txPower, uint32_t channel)
create spectrum value
void SetNoiseFactor(double f)
Set the noise factor added to the thermal noise.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
@ SHORT_ADDR
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
uint32_t g_packetsReceived
number of packets received
void PacketReceivedCallback(McpsDataIndicationParams params, Ptr< Packet > p)
Function called when a Data indication is invoked.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
LogLevel
Logging severity classes and levels.
Definition: log.h:94
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition: log.h:119
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition: log.h:120
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:320
cmd
Definition: second.py:40
channel
Definition: third.py:88
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
MCPS-DATA.indication params.
MCPS-DATA.request params.
static const uint32_t packetSize
Packet size generated at the AP.