A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-rate-adaptation-distance.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Universidad de la República - Uruguay
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Matías Richart <mrichart@fing.edu.uy>
7 */
8
9/**
10 * This example program is designed to illustrate the behavior of
11 * rate-adaptive WiFi rate controls such as Minstrel. Power-adaptive
12 * rate controls can be illustrated also, but separate examples exist for
13 * highlighting the power adaptation.
14 *
15 * This simulation consist of 2 nodes, one AP and one STA.
16 * The AP generates UDP traffic with a CBR of 400 Mbps to the STA.
17 * The AP can use any power and rate control mechanism and the STA uses
18 * only Minstrel rate control.
19 * The STA can be configured to move away from (or towards to) the AP.
20 * By default, the AP is at coordinate (0,0,0) and the STA starts at
21 * coordinate (5,0,0) (meters) and moves away on the x axis by 1 meter every
22 * second.
23 *
24 * The output consists of:
25 * - A plot of average throughput vs. distance.
26 * - (if logging is enabled) the changes of rate to standard output.
27 *
28 * Example usage:
29 * ./ns3 run "wifi-rate-adaptation-distance --standard=802.11a --staManager=ns3::MinstrelWifiManager
30 * --apManager=ns3::MinstrelWifiManager --outputFileName=minstrel"
31 *
32 * Another example (moving towards the AP):
33 * ./ns3 run "wifi-rate-adaptation-distance --standard=802.11a --staManager=ns3::MinstrelWifiManager
34 * --apManager=ns3::MinstrelWifiManager --outputFileName=minstrel --stepsSize=1 --STA1_x=-200"
35 *
36 * Example for HT rates with SGI and channel width of 40MHz:
37 * ./ns3 run "wifi-rate-adaptation-distance --staManager=ns3::MinstrelHtWifiManager
38 * --apManager=ns3::MinstrelHtWifiManager --outputFileName=minstrelHt --shortGuardInterval=true
39 * --channelWidth=40"
40 *
41 * To enable the log of rate changes:
42 * export NS_LOG=RateAdaptationDistance=level_info
43 */
44
45#include "ns3/boolean.h"
46#include "ns3/command-line.h"
47#include "ns3/config.h"
48#include "ns3/double.h"
49#include "ns3/gnuplot.h"
50#include "ns3/internet-stack-helper.h"
51#include "ns3/ipv4-address-helper.h"
52#include "ns3/log.h"
53#include "ns3/mobility-helper.h"
54#include "ns3/mobility-model.h"
55#include "ns3/on-off-helper.h"
56#include "ns3/packet-sink-helper.h"
57#include "ns3/ssid.h"
58#include "ns3/string.h"
59#include "ns3/uinteger.h"
60#include "ns3/yans-wifi-channel.h"
61#include "ns3/yans-wifi-helper.h"
62
63using namespace ns3;
64
65NS_LOG_COMPONENT_DEFINE("RateAdaptationDistance");
66
67/** Node statistics */
69{
70 public:
71 /**
72 * Constructor
73 * \param aps AP devices
74 * \param stas STA devices
75 */
77
78 /**
79 * RX callback
80 * \param path path
81 * \param packet received packet
82 * \param from sender
83 */
84 void RxCallback(std::string path, Ptr<const Packet> packet, const Address& from);
85 /**
86 * Set node position
87 * \param node the node
88 * \param position the position
89 */
90 void SetPosition(Ptr<Node> node, Vector position);
91 /**
92 * Advance node position
93 * \param node the node
94 * \param stepsSize the size of a step
95 * \param stepsTime the time interval between steps
96 */
97 void AdvancePosition(Ptr<Node> node, int stepsSize, int stepsTime);
98 /**
99 * Get node position
100 * \param node the node
101 * \return the position
102 */
103 Vector GetPosition(Ptr<Node> node);
104 /**
105 * \return the gnuplot 2d dataset
106 */
108
109 private:
110 uint32_t m_bytesTotal; //!< total bytes
111 Gnuplot2dDataset m_output; //!< gnuplot 2d dataset
112};
113
115{
116 m_bytesTotal = 0;
117}
118
119void
120NodeStatistics::RxCallback(std::string path, Ptr<const Packet> packet, const Address& from)
121{
122 m_bytesTotal += packet->GetSize();
123}
124
125void
126NodeStatistics::SetPosition(Ptr<Node> node, Vector position)
127{
128 Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
129 mobility->SetPosition(position);
130}
131
132Vector
134{
135 Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
136 return mobility->GetPosition();
137}
138
139void
140NodeStatistics::AdvancePosition(Ptr<Node> node, int stepsSize, int stepsTime)
141{
142 Vector pos = GetPosition(node);
143 double mbs = ((m_bytesTotal * 8.0) / (1000000 * stepsTime));
144 m_bytesTotal = 0;
145 m_output.Add(pos.x, mbs);
146 pos.x += stepsSize;
147 SetPosition(node, pos);
148 Simulator::Schedule(Seconds(stepsTime),
150 this,
151 node,
152 stepsSize,
153 stepsTime);
154}
155
158{
159 return m_output;
160}
161
162/**
163 * Callback for 'Rate' trace source
164 *
165 * \param oldRate old MCS rate (bits/sec)
166 * \param newRate new MCS rate (bits/sec)
167 */
168void
169RateCallback(uint64_t oldRate, uint64_t newRate)
170{
171 NS_LOG_INFO("Rate " << newRate / 1000000.0 << " Mbps");
172}
173
174int
175main(int argc, char* argv[])
176{
177 uint32_t rtsThreshold{65535};
178 std::string staManager{"ns3::MinstrelHtWifiManager"};
179 std::string apManager{"ns3::MinstrelHtWifiManager"};
180 std::string standard{"802.11n-5GHz"};
181 std::string outputFileName{"minstrelHT"};
182 uint32_t BeMaxAmpduSize{65535};
183 bool shortGuardInterval{false};
184 uint32_t chWidth{20};
185 int ap1_x{0};
186 int ap1_y{0};
187 int sta1_x{5};
188 int sta1_y{0};
189 int steps{100};
190 int stepsSize{1};
191 int stepsTime{1};
192
193 CommandLine cmd(__FILE__);
194 cmd.AddValue("staManager", "Rate adaptation manager of the STA", staManager);
195 cmd.AddValue("apManager", "Rate adaptation manager of the AP", apManager);
196 cmd.AddValue("standard", "Wifi standard (a/b/g/n/ac only)", standard);
197 cmd.AddValue("shortGuardInterval",
198 "Enable Short Guard Interval in all stations",
199 shortGuardInterval);
200 cmd.AddValue("channelWidth", "Channel width of all the stations", chWidth);
201 cmd.AddValue("rtsThreshold", "RTS threshold", rtsThreshold);
202 cmd.AddValue("BeMaxAmpduSize", "BE Mac A-MPDU size", BeMaxAmpduSize);
203 cmd.AddValue("outputFileName", "Output filename", outputFileName);
204 cmd.AddValue("steps", "How many different distances to try", steps);
205 cmd.AddValue("stepsTime", "Time on each step", stepsTime);
206 cmd.AddValue("stepsSize", "Distance between steps", stepsSize);
207 cmd.AddValue("AP1_x", "Position of AP1 in x coordinate", ap1_x);
208 cmd.AddValue("AP1_y", "Position of AP1 in y coordinate", ap1_y);
209 cmd.AddValue("STA1_x", "Position of STA1 in x coordinate", sta1_x);
210 cmd.AddValue("STA1_y", "Position of STA1 in y coordinate", sta1_y);
211 cmd.Parse(argc, argv);
212
213 int simuTime = steps * stepsTime;
214
215 if (standard != "802.11a" && standard != "802.11b" && standard != "802.11g" &&
216 standard != "802.11n-2.4GHz" && standard != "802.11n-5GHz" && standard != "802.11ac")
217 {
218 NS_FATAL_ERROR("Standard " << standard << " is not supported by this program");
219 }
220
221 // Define the APs
222 NodeContainer wifiApNodes;
223 wifiApNodes.Create(1);
224
225 // Define the STAs
227 wifiStaNodes.Create(1);
228
229 YansWifiPhyHelper wifiPhy;
231 wifiPhy.SetChannel(wifiChannel.Create());
232 // Channel configuration via ChannelSettings attribute can be performed here
233 std::string frequencyBand;
234 if (standard == "802.11b" || standard == "802.11g" || standard == "802.11n-2.4GHz")
235 {
236 frequencyBand = "BAND_2_4GHZ";
237 }
238 else
239 {
240 frequencyBand = "BAND_5GHZ";
241 }
242 wifiPhy.Set("ChannelSettings",
243 StringValue("{0, " + std::to_string(chWidth) + ", " + frequencyBand + ", 0}"));
244
245 // By default, the CCA sensitivity is -82 dBm, meaning if the RSS is
246 // below this value, the receiver will reject the Wi-Fi frame.
247 // However, we want to allow the rate adaptation to work down to low
248 // SNR values. To allow this, we need to do three things: 1) disable
249 // the noise figure (set it to 0 dB) so that the noise level in 20 MHz
250 // is around -101 dBm, 2) lower the CCA sensitivity to a value that
251 // disables it (e.g. -110 dBm), and 3) disable the Wi-Fi preamble
252 // detection model.
253 wifiPhy.Set("CcaSensitivity", DoubleValue(-110));
254 wifiPhy.Set("RxNoiseFigure", DoubleValue(0));
256
257 NetDeviceContainer wifiApDevices;
258 NetDeviceContainer wifiStaDevices;
259 NetDeviceContainer wifiDevices;
260
262 if (standard == "802.11a" || standard == "802.11b" || standard == "802.11g")
263 {
264 if (standard == "802.11a")
265 {
266 wifi.SetStandard(WIFI_STANDARD_80211a);
267 }
268 else if (standard == "802.11b")
269 {
270 wifi.SetStandard(WIFI_STANDARD_80211b);
271 }
272 else if (standard == "802.11g")
273 {
274 wifi.SetStandard(WIFI_STANDARD_80211g);
275 }
276 WifiMacHelper wifiMac;
277
278 // Configure the STA node
279 wifi.SetRemoteStationManager(staManager, "RtsCtsThreshold", UintegerValue(rtsThreshold));
280
281 Ssid ssid = Ssid("AP");
282 wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
283 wifiStaDevices.Add(wifi.Install(wifiPhy, wifiMac, wifiStaNodes.Get(0)));
284
285 // Configure the AP node
286 wifi.SetRemoteStationManager(apManager, "RtsCtsThreshold", UintegerValue(rtsThreshold));
287
288 ssid = Ssid("AP");
289 wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
290 wifiApDevices.Add(wifi.Install(wifiPhy, wifiMac, wifiApNodes.Get(0)));
291 }
292 else if (standard == "802.11n-2.4GHz" || standard == "802.11n-5GHz" || standard == "802.11ac")
293 {
294 if (standard == "802.11n-2.4GHz" || standard == "802.11n-5GHz")
295 {
296 wifi.SetStandard(WIFI_STANDARD_80211n);
297 }
298 else if (standard == "802.11ac")
299 {
300 wifi.SetStandard(WIFI_STANDARD_80211ac);
301 }
302
303 WifiMacHelper wifiMac;
304
305 // Configure the STA node
306 wifi.SetRemoteStationManager(staManager, "RtsCtsThreshold", UintegerValue(rtsThreshold));
307
308 Ssid ssid = Ssid("AP");
309 wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
310 wifiStaDevices.Add(wifi.Install(wifiPhy, wifiMac, wifiStaNodes.Get(0)));
311
312 // Configure the AP node
313 wifi.SetRemoteStationManager(apManager, "RtsCtsThreshold", UintegerValue(rtsThreshold));
314
315 ssid = Ssid("AP");
316 wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
317 wifiApDevices.Add(wifi.Install(wifiPhy, wifiMac, wifiApNodes.Get(0)));
318
319 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize",
320 UintegerValue(BeMaxAmpduSize));
321 }
322
323 wifiDevices.Add(wifiStaDevices);
324 wifiDevices.Add(wifiApDevices);
325
326 // Set guard interval
328 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported",
329 BooleanValue(shortGuardInterval));
330
331 // Configure the mobility.
334 // Initial position of AP and STA
335 positionAlloc->Add(Vector(ap1_x, ap1_y, 0.0));
336 positionAlloc->Add(Vector(sta1_x, sta1_y, 0.0));
337 mobility.SetPositionAllocator(positionAlloc);
338 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
339 mobility.Install(wifiApNodes.Get(0));
340 mobility.Install(wifiStaNodes.Get(0));
341
342 // Statistics counter
343 NodeStatistics atpCounter = NodeStatistics(wifiApDevices, wifiStaDevices);
344
345 // Move the STA by stepsSize meters every stepsTime seconds
346 Simulator::Schedule(Seconds(0.5 + stepsTime),
348 &atpCounter,
349 wifiStaNodes.Get(0),
350 stepsSize,
351 stepsTime);
352
353 // Configure the IP stack
355 stack.Install(wifiApNodes);
356 stack.Install(wifiStaNodes);
358 address.SetBase("10.1.1.0", "255.255.255.0");
359 Ipv4InterfaceContainer i = address.Assign(wifiDevices);
360 Ipv4Address sinkAddress = i.GetAddress(0);
361 uint16_t port = 9;
362
363 // Configure the CBR generator
364 PacketSinkHelper sink("ns3::UdpSocketFactory", InetSocketAddress(sinkAddress, port));
365 ApplicationContainer apps_sink = sink.Install(wifiStaNodes.Get(0));
366
367 OnOffHelper onoff("ns3::UdpSocketFactory", InetSocketAddress(sinkAddress, port));
368 onoff.SetConstantRate(DataRate("400Mb/s"), 1420);
369 onoff.SetAttribute("StartTime", TimeValue(Seconds(0.5)));
370 onoff.SetAttribute("StopTime", TimeValue(Seconds(simuTime)));
371 ApplicationContainer apps_source = onoff.Install(wifiApNodes.Get(0));
372
373 apps_sink.Start(Seconds(0.5));
374 apps_sink.Stop(Seconds(simuTime));
375
376 //------------------------------------------------------------
377 //-- Setup stats and data collection
378 //--------------------------------------------
379
380 // Register packet receptions to calculate throughput
381 Config::Connect("/NodeList/1/ApplicationList/*/$ns3::PacketSink/Rx",
383
384 // Callbacks to print every change of rate
386 "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" + apManager + "/Rate",
388
389 Simulator::Stop(Seconds(simuTime));
391
392 std::ofstream outfile("throughput-" + outputFileName + ".plt");
393 Gnuplot gnuplot = Gnuplot("throughput-" + outputFileName + ".eps", "Throughput");
394 gnuplot.SetTerminal("post eps color enhanced");
395 gnuplot.SetLegend("Distance (meters)", "Throughput (Mb/s)");
396 gnuplot.SetTitle("Throughput (AP to STA) vs distance");
397 gnuplot.AddDataset(atpCounter.GetDatafile());
398 gnuplot.GenerateOutput(outfile);
399
401
402 return 0;
403}
Class to collect node statistics.
void SetPosition(Ptr< Node > node, Vector position)
Set node position.
Gnuplot2dDataset GetDatafile()
void RxCallback(std::string path, Ptr< const Packet > packet, const Address &from)
RX callback.
NodeStatistics(NetDeviceContainer aps, NetDeviceContainer stas)
Constructor.
uint32_t m_bytesTotal
Number of received bytes on a given state.
void AdvancePosition(Ptr< Node > node, int stepsSize, Time stepsTime)
Move a node.
Vector GetPosition(Ptr< Node > node)
Get node position.
Gnuplot2dDataset m_output
Throughput output data.
a polymophic address class
Definition address.h:90
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
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 Add(double x, double y)
Definition gnuplot.cc:366
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 SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition gnuplot.cc:765
void SetTerminal(const std::string &terminal)
Definition gnuplot.cc:753
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition gnuplot.cc:791
void SetTitle(const std::string &title)
Definition gnuplot.cc:759
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
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
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
Hold variables of type string.
Definition string.h:45
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
void Set(std::string name, const AttributeValue &v)
void DisablePreambleDetectionModel()
Disable the preamble detection model on all links.
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
uint16_t port
Definition dsdv-manet.cc:33
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:953
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
address
Definition first.py:36
stack
Definition first.py:33
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:684
ssid
Definition third.py:82
wifi
Definition third.py:84
mobility
Definition third.py:92
wifiStaNodes
Definition third.py:73
void RateCallback(uint64_t oldRate, uint64_t newRate)
Callback for 'Rate' trace source.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition wifi-tcp.cc:44