A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
45using namespace ns3;
46using namespace ns3::lrwpan;
47
48uint32_t g_packetsReceived = 0; //!< number of packets received
49
50NS_LOG_COMPONENT_DEFINE("LrWpanErrorDistancePlot");
51
52/**
53 * Function called when a Data indication is invoked
54 * \param params MCPS data indication parameters
55 * \param p packet
56 */
57void
59{
61}
62
63int
64main(int argc, char* argv[])
65{
67
68 std::ostringstream os;
69 std::ofstream perfile("802.15.4-per-vs-rxSignal.plt");
70
71 double minRxSignal = -111; // dBm
72 double maxRxSignal = -82; // dBm
73 double increment = 0.01;
74 int maxPackets = 1000;
75 int packetSize = 7; // bytes (MPDU payload)
76 double txPower = 0; // dBm
77 uint32_t channelNumber = 11;
78 double rxSensitivity = -106.58; // dBm
79
80 CommandLine cmd(__FILE__);
81
82 cmd.AddValue("txPower", "transmit power (dBm)", txPower);
83 cmd.AddValue("packetSize", "packet (MSDU) size (bytes)", packetSize);
84 cmd.AddValue("channelNumber", "channel number", channelNumber);
85 cmd.AddValue("rxSensitivity", "the rx sensitivity (dBm)", rxSensitivity);
86 cmd.Parse(argc, argv);
87
88 Gnuplot perplot = Gnuplot("802.15.4-per-vs-rxSignal.eps");
89 Gnuplot2dDataset perdatasetExperimental("Experimental");
90 Gnuplot2dDataset perdatasetTheoretical("Theoretical");
91
92 Ptr<Node> n0 = CreateObject<Node>();
93 Ptr<Node> n1 = CreateObject<Node>();
94 Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice>();
95 Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice>();
96
97 dev0->SetAddress(Mac16Address("00:01"));
98 dev1->SetAddress(Mac16Address("00:02"));
99 Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel>();
100 Ptr<FixedRssLossModel> propModel = CreateObject<FixedRssLossModel>();
101
102 channel->AddPropagationLossModel(propModel);
103 dev0->SetChannel(channel);
104 dev1->SetChannel(channel);
105 n0->AddDevice(dev0);
106 n1->AddDevice(dev1);
107 Ptr<ConstantPositionMobilityModel> mob0 = CreateObject<ConstantPositionMobilityModel>();
108 dev0->GetPhy()->SetMobility(mob0);
109 Ptr<ConstantPositionMobilityModel> mob1 = CreateObject<ConstantPositionMobilityModel>();
110 dev1->GetPhy()->SetMobility(mob1);
111 mob0->SetPosition(Vector(0, 0, 0));
112 mob1->SetPosition(Vector(0, 0, 0));
113
115 Ptr<SpectrumValue> psd = svh.CreateTxPowerSpectralDensity(txPower, channelNumber);
116 dev0->GetPhy()->SetTxPowerSpectralDensity(psd);
117
118 // Set Rx sensitivity of the receiving device
119 dev1->GetPhy()->SetRxSensitivity(rxSensitivity);
120
123 dev1->GetMac()->SetMcpsDataIndicationCallback(cb0);
124
125 //////////////////////////////////
126 // Experimental PER v.s Signal //
127 //////////////////////////////////
128
129 double per = 1;
130 double sensitivityExp = 0;
131 bool sensThreshold = true;
132
133 for (double j = minRxSignal; j < maxRxSignal; j += increment)
134 {
135 propModel->SetRss(j);
136 if (sensThreshold)
137 {
138 sensitivityExp = j;
139 }
140
141 for (int i = 0; i < maxPackets; i++)
142 {
144 params.m_srcAddrMode = SHORT_ADDR;
145 params.m_dstAddrMode = SHORT_ADDR;
146 params.m_dstPanId = 0;
147 params.m_dstAddr = Mac16Address("00:02");
148 params.m_msduHandle = 0;
149 params.m_txOptions = 0;
150 Ptr<Packet> p;
151 p = Create<Packet>(packetSize);
152 Simulator::Schedule(Seconds(i), &LrWpanMac::McpsDataRequest, dev0->GetMac(), params, p);
153 }
154
156
157 per = (static_cast<double>(maxPackets - g_packetsReceived) / maxPackets) * 100;
158
159 std::cout << "Experimental Test || Signal: " << j << " dBm | Received " << g_packetsReceived
160 << " pkts"
161 << "/" << maxPackets << " | PER " << per << " %\n";
162
163 if (per <= 1 && sensThreshold)
164 {
165 sensThreshold = false;
166 }
167
168 perdatasetExperimental.Add(j, per);
170 }
171
172 /////////////////////////////////
173 // Theoretical PER v.s. Signal //
174 /////////////////////////////////
175
176 Ptr<LrWpanErrorModel> lrWpanError = CreateObject<LrWpanErrorModel>();
178
179 // Calculate the noise that accounts for both thermal noise (floor noise) and
180 // imperfections on the chip or lost before reaching the demodulator.
181 // In O-QPSK 250kbps, the point where PER is <= 1% without
182 // additional noise is -106.58 dBm (Noise Factor = 1)
183 double maxRxSensitivityW = (pow(10.0, -106.58 / 10.0) / 1000.0);
184 long double noiseFactor = (pow(10.0, rxSensitivity / 10.0) / 1000.0) / maxRxSensitivityW;
185
186 psdHelper.SetNoiseFactor(noiseFactor);
188 double noise = LrWpanSpectrumValueHelper::TotalAvgPower(noisePsd, 11);
189
190 double signal = 0;
191 double sensitivityTheo = 0;
192 double perTheoretical = 0;
193 double snr = 0;
194 sensThreshold = true;
195
196 for (double j = minRxSignal; j < maxRxSignal; j += increment)
197 {
198 if (sensThreshold)
199 {
200 sensitivityTheo = j;
201 }
202
203 signal = pow(10.0, j / 10.0) / 1000.0; // signal in Watts
204 snr = signal / noise;
205
206 // According to the standard, Packet error rate should be obtained
207 // using a PSDU of 20 bytes using
208 // the equation PER = 1 - (1 - BER)^nbits
209 perTheoretical = (1.0 - lrWpanError->GetChunkSuccessRate(snr, (packetSize + 13) * 8)) * 100;
210 std::cout << "Theoretical Test || Signal: " << j << " dBm | SNR: " << snr << "| PER "
211 << perTheoretical << " % \n";
212
213 if (perTheoretical <= 1 && sensThreshold)
214 {
215 sensThreshold = false;
216 }
217
218 perdatasetTheoretical.Add(j, perTheoretical);
219 }
220
221 std::cout << "_____________________________________________________________________________\n";
222 std::cout << "Experimental Test || Receiving with a current sensitivity of " << sensitivityExp
223 << " dBm\n";
224 std::cout << "Theoretical Test || Receiving with a current sensitivity of " << sensitivityTheo
225 << " dBm\n";
226 std::cout << "Gnu plot generated.";
227
228 os << "Pkt Payload (MSDU) size = " << packetSize << " bytes | "
229 << "Tx power = " << txPower << " dBm | "
230 << "Rx Sensitivity (Theo) = " << sensitivityTheo << " dBm";
231
232 perplot.AddDataset(perdatasetExperimental);
233 perplot.AddDataset(perdatasetTheoretical);
234
235 perplot.SetTitle(os.str());
236 perplot.SetTerminal("postscript eps color enh \"Times-BoldItalic\"");
237 perplot.SetLegend("Rx signal (dBm)", "Packet Error Rate (%)");
238 perplot.SetExtra("set xrange [-110:-82]\n\
239 set logscale y\n\
240 set yrange [0.000000000001:120]\n\
241 set xtics 2\n\
242 set grid\n\
243 set style line 1 linewidth 5\n\
244 set style line 2 linewidth 3\n\
245 set style increment user\n\
246 set arrow from -110,1 to -82,1 nohead lc 'web-blue' front");
247 perplot.GenerateOutput(perfile);
248 perfile.close();
249
251 return 0;
252}
Parse command-line arguments.
Definition: command-line.h:232
Class to represent a 2D points plot.
Definition: gnuplot.h:116
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:370
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:796
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:776
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:764
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:802
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:783
void SetTitle(const std::string &title)
Definition: gnuplot.cc:770
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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
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:386
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.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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:706
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
ns cmd
Definition: second.py:40
ns channel
Definition: third.py:88
FtrParams params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
MCPS-DATA.indication params.
static const uint32_t packetSize
Packet size generated at the AP.