A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-spatial-reuse.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 University of Washington
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: Sébastien Deronne <sebastien.deronne@gmail.com>
18 */
19
20//
21// This example program can be used to experiment with spatial
22// reuse mechanisms of 802.11ax.
23//
24// The geometry is as follows:
25//
26// STA1 STA1
27// | |
28// d1 | |d2
29// | d3 |
30// AP1 -----------AP2
31//
32// STA1 and AP1 are in one BSS (with color set to 1), while STA2 and AP2 are in
33// another BSS (with color set to 2). The distances are configurable (d1 through d3).
34//
35// STA1 is continuously transmitting data to AP1, while STA2 is continuously sending data to AP2.
36// Each STA has configurable traffic loads (inter packet interval and packet size).
37// It is also possible to configure TX power per node as well as their CCA-ED tresholds.
38// OBSS_PD spatial reuse feature can be enabled (default) or disabled, and the OBSS_PD
39// threshold can be set as well (default: -72 dBm).
40// A simple Friis path loss model is used and a constant PHY rate is considered.
41//
42// In general, the program can be configured at run-time by passing command-line arguments.
43// The following command will display all of the available run-time help options:
44// ./ns3 run "wifi-spatial-reuse --help"
45//
46// According to the Wi-Fi models of ns-3.36 release, throughput with
47// OBSS PD enabled (--enableObssPd=True) was roughly 6.5 Mbps, and with
48// it disabled (--enableObssPd=False) was roughly 3.5 Mbps.
49//
50// This difference between those results is because OBSS_PD spatial
51// reuse enables to ignore transmissions from another BSS when the
52// received power is below the configured threshold, and therefore
53// either defer during ongoing transmission or transmit at the same
54// time.
55//
56// Note that, by default, this script configures a network using a
57// channel width of 20 MHz. Changing this value alone (through
58// the --channelWidth argument) without properly adjusting other
59// parameters will void the effect of spatial reuse: since energy is
60// measured over the 20 MHz primary channel regardless of the channel
61// width, doubling the transmission bandwidth creates a 3 dB drop in
62// the measured energy level (i.e., a halving of the measured
63// energy). Because of this, when using the channelWidth argument
64// users should also adjust the CCA-ED Thresholds (via --ccaEdTrSta1,
65// --ccaEdTrSta2, --ccaEdTrAp1, and --ccaEdTrAp2), the Minimum RSSI
66// for preamble detection (via --minimumRssi), and the OBSS PD
67// Threshold (via --obssPdThreshold) appropriately. For instance,
68// this can be accomplished for a channel width of 40 MHz by lowering
69// all these values by 3 dB compared to their defaults.
70//
71// In addition, consider that adapting the adjustments shown above
72// for an 80 MHz channel width (using a 6 dB threshold adjustment instead
73// of 3 dB) will not produce any changes when enableObssPd is enabled
74// or disabled. The cause for this is the insufficient amount of
75// traffic that is generated by default in the example: increasing
76// the channel width shortens the frame durations, and lowers the
77// collision probability. Collisions between BSSs are a necessary
78// condition to see the improvements brought by spatial reuse, and
79// thus increasing the amount of generated traffic by setting the
80// interval argument to a lower value is necessary to see the
81// benefits of spatial reuse in this scenario. This can, for
82// instance, be accomplished by setting --interval=0.0001.
83//
84
85#include "ns3/abort.h"
86#include "ns3/ap-wifi-mac.h"
87#include "ns3/application-container.h"
88#include "ns3/command-line.h"
89#include "ns3/config.h"
90#include "ns3/double.h"
91#include "ns3/he-configuration.h"
92#include "ns3/mobility-helper.h"
93#include "ns3/multi-model-spectrum-channel.h"
94#include "ns3/packet-socket-client.h"
95#include "ns3/packet-socket-helper.h"
96#include "ns3/packet-socket-server.h"
97#include "ns3/spectrum-wifi-helper.h"
98#include "ns3/ssid.h"
99#include "ns3/string.h"
100#include "ns3/wifi-net-device.h"
101
102using namespace ns3;
103
104std::vector<uint32_t> bytesReceived(4);
105
107ContextToNodeId(std::string context)
108{
109 std::string sub = context.substr(10);
110 uint32_t pos = sub.find("/Device");
111 return std::stoi(sub.substr(0, pos));
112}
113
114void
115SocketRx(std::string context, Ptr<const Packet> p, const Address& addr)
116{
117 uint32_t nodeId = ContextToNodeId(context);
118 bytesReceived[nodeId] += p->GetSize();
119}
120
121int
122main(int argc, char* argv[])
123{
124 double duration = 10.0; // seconds
125 double d1 = 30.0; // meters
126 double d2 = 30.0; // meters
127 double d3 = 150.0; // meters
128 double powSta1 = 10.0; // dBm
129 double powSta2 = 10.0; // dBm
130 double powAp1 = 21.0; // dBm
131 double powAp2 = 21.0; // dBm
132 double ccaEdTrSta1 = -62; // dBm
133 double ccaEdTrSta2 = -62; // dBm
134 double ccaEdTrAp1 = -62; // dBm
135 double ccaEdTrAp2 = -62; // dBm
136 double minimumRssi = -82; // dBm
137 int channelWidth = 20; // MHz
138 uint32_t payloadSize = 1500; // bytes
139 uint32_t mcs = 0; // MCS value
140 double interval = 0.001; // seconds
141 bool enableObssPd = true;
142 double obssPdThreshold = -72.0; // dBm
143
144 CommandLine cmd(__FILE__);
145 cmd.AddValue("duration", "Duration of simulation (s)", duration);
146 cmd.AddValue("interval", "Inter packet interval (s)", interval);
147 cmd.AddValue("enableObssPd", "Enable/disable OBSS_PD", enableObssPd);
148 cmd.AddValue("d1", "Distance between STA1 and AP1 (m)", d1);
149 cmd.AddValue("d2", "Distance between STA2 and AP2 (m)", d2);
150 cmd.AddValue("d3", "Distance between AP1 and AP2 (m)", d3);
151 cmd.AddValue("powSta1", "Power of STA1 (dBm)", powSta1);
152 cmd.AddValue("powSta2", "Power of STA2 (dBm)", powSta2);
153 cmd.AddValue("powAp1", "Power of AP1 (dBm)", powAp1);
154 cmd.AddValue("powAp2", "Power of AP2 (dBm)", powAp2);
155 cmd.AddValue("ccaEdTrSta1", "CCA-ED Threshold of STA1 (dBm)", ccaEdTrSta1);
156 cmd.AddValue("ccaEdTrSta2", "CCA-ED Threshold of STA2 (dBm)", ccaEdTrSta2);
157 cmd.AddValue("ccaEdTrAp1", "CCA-ED Threshold of AP1 (dBm)", ccaEdTrAp1);
158 cmd.AddValue("ccaEdTrAp2", "CCA-ED Threshold of AP2 (dBm)", ccaEdTrAp2);
159 cmd.AddValue("minimumRssi",
160 "Minimum RSSI for the ThresholdPreambleDetectionModel",
161 minimumRssi);
162 cmd.AddValue("channelWidth", "Bandwidth of the channel in MHz [20, 40, or 80]", channelWidth);
163 cmd.AddValue("obssPdThreshold", "Threshold for the OBSS PD Algorithm", obssPdThreshold);
164 cmd.AddValue("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
165 cmd.Parse(argc, argv);
166
168 wifiStaNodes.Create(2);
169
170 NodeContainer wifiApNodes;
171 wifiApNodes.Create(2);
172
173 SpectrumWifiPhyHelper spectrumPhy;
174 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
175 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
176 spectrumChannel->AddPropagationLossModel(lossModel);
178 CreateObject<ConstantSpeedPropagationDelayModel>();
179 spectrumChannel->SetPropagationDelayModel(delayModel);
180
181 spectrumPhy.SetChannel(spectrumChannel);
182 spectrumPhy.SetErrorRateModel("ns3::YansErrorRateModel");
183 switch (channelWidth)
184 {
185 case 20:
186 spectrumPhy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
187 break;
188 case 40:
189 spectrumPhy.Set("ChannelSettings", StringValue("{62, 40, BAND_5GHZ, 0}"));
190 break;
191 case 80:
192 spectrumPhy.Set("ChannelSettings", StringValue("{171, 80, BAND_5GHZ, 0}"));
193 break;
194 default:
195 NS_ABORT_MSG("Unrecognized channel width: " << channelWidth);
196 break;
197 }
198 spectrumPhy.SetPreambleDetectionModel("ns3::ThresholdPreambleDetectionModel",
199 "MinimumRssi",
200 DoubleValue(minimumRssi));
201
203 wifi.SetStandard(WIFI_STANDARD_80211ax);
204 if (enableObssPd)
205 {
206 wifi.SetObssPdAlgorithm("ns3::ConstantObssPdAlgorithm",
207 "ObssPdLevel",
208 DoubleValue(obssPdThreshold));
209 }
210
212 std::ostringstream oss;
213 oss << "HeMcs" << mcs;
214 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
215 "DataMode",
216 StringValue(oss.str()),
217 "ControlMode",
218 StringValue(oss.str()));
219
220 spectrumPhy.Set("TxPowerStart", DoubleValue(powSta1));
221 spectrumPhy.Set("TxPowerEnd", DoubleValue(powSta1));
222 spectrumPhy.Set("CcaEdThreshold", DoubleValue(ccaEdTrSta1));
223 spectrumPhy.Set("RxSensitivity", DoubleValue(-92.0));
224
225 Ssid ssidA = Ssid("A");
226 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssidA));
227 NetDeviceContainer staDeviceA = wifi.Install(spectrumPhy, mac, wifiStaNodes.Get(0));
228
229 spectrumPhy.Set("TxPowerStart", DoubleValue(powAp1));
230 spectrumPhy.Set("TxPowerEnd", DoubleValue(powAp1));
231 spectrumPhy.Set("CcaEdThreshold", DoubleValue(ccaEdTrAp1));
232 spectrumPhy.Set("RxSensitivity", DoubleValue(-92.0));
233
234 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssidA));
235 NetDeviceContainer apDeviceA = wifi.Install(spectrumPhy, mac, wifiApNodes.Get(0));
236
237 Ptr<WifiNetDevice> apDevice = apDeviceA.Get(0)->GetObject<WifiNetDevice>();
238 Ptr<ApWifiMac> apWifiMac = apDevice->GetMac()->GetObject<ApWifiMac>();
239 if (enableObssPd)
240 {
241 apDevice->GetHeConfiguration()->SetAttribute("BssColor", UintegerValue(1));
242 }
243
244 spectrumPhy.Set("TxPowerStart", DoubleValue(powSta2));
245 spectrumPhy.Set("TxPowerEnd", DoubleValue(powSta2));
246 spectrumPhy.Set("CcaEdThreshold", DoubleValue(ccaEdTrSta2));
247 spectrumPhy.Set("RxSensitivity", DoubleValue(-92.0));
248
249 Ssid ssidB = Ssid("B");
250 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssidB));
251 NetDeviceContainer staDeviceB = wifi.Install(spectrumPhy, mac, wifiStaNodes.Get(1));
252
253 spectrumPhy.Set("TxPowerStart", DoubleValue(powAp2));
254 spectrumPhy.Set("TxPowerEnd", DoubleValue(powAp2));
255 spectrumPhy.Set("CcaEdThreshold", DoubleValue(ccaEdTrAp2));
256 spectrumPhy.Set("RxSensitivity", DoubleValue(-92.0));
257
258 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssidB));
259 NetDeviceContainer apDeviceB = wifi.Install(spectrumPhy, mac, wifiApNodes.Get(1));
260
261 Ptr<WifiNetDevice> ap2Device = apDeviceB.Get(0)->GetObject<WifiNetDevice>();
262 apWifiMac = ap2Device->GetMac()->GetObject<ApWifiMac>();
263 if (enableObssPd)
264 {
265 ap2Device->GetHeConfiguration()->SetAttribute("BssColor", UintegerValue(2));
266 }
267
269 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
270 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // AP1
271 positionAlloc->Add(Vector(d3, 0.0, 0.0)); // AP2
272 positionAlloc->Add(Vector(0.0, d1, 0.0)); // STA1
273 positionAlloc->Add(Vector(d3, d2, 0.0)); // STA2
274 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
275 mobility.SetPositionAllocator(positionAlloc);
276 mobility.Install(wifiApNodes);
277 mobility.Install(wifiStaNodes);
278
279 PacketSocketHelper packetSocket;
280 packetSocket.Install(wifiApNodes);
281 packetSocket.Install(wifiStaNodes);
283
284 // BSS 1
285 {
286 PacketSocketAddress socketAddr;
287 socketAddr.SetSingleDevice(staDeviceA.Get(0)->GetIfIndex());
288 socketAddr.SetPhysicalAddress(apDeviceA.Get(0)->GetAddress());
289 socketAddr.SetProtocol(1);
290 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
291 client->SetRemote(socketAddr);
292 wifiStaNodes.Get(0)->AddApplication(client);
293 client->SetAttribute("PacketSize", UintegerValue(payloadSize));
294 client->SetAttribute("MaxPackets", UintegerValue(0));
295 client->SetAttribute("Interval", TimeValue(Seconds(interval)));
296 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
297 server->SetLocal(socketAddr);
298 wifiApNodes.Get(0)->AddApplication(server);
299 }
300
301 // BSS 2
302 {
303 PacketSocketAddress socketAddr;
304 socketAddr.SetSingleDevice(staDeviceB.Get(0)->GetIfIndex());
305 socketAddr.SetPhysicalAddress(apDeviceB.Get(0)->GetAddress());
306 socketAddr.SetProtocol(1);
307 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
308 client->SetRemote(socketAddr);
309 wifiStaNodes.Get(1)->AddApplication(client);
310 client->SetAttribute("PacketSize", UintegerValue(payloadSize));
311 client->SetAttribute("MaxPackets", UintegerValue(0));
312 client->SetAttribute("Interval", TimeValue(Seconds(interval)));
313 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
314 server->SetLocal(socketAddr);
315 wifiApNodes.Get(1)->AddApplication(server);
316 }
317
318 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::PacketSocketServer/Rx",
320
321 Simulator::Stop(Seconds(duration));
323
325
326 for (uint32_t i = 0; i < 2; i++)
327 {
328 double throughput = static_cast<double>(bytesReceived[2 + i]) * 8 / 1000 / 1000 / duration;
329 std::cout << "Throughput for BSS " << i + 1 << ": " << throughput << " Mbit/s" << std::endl;
330 }
331
332 return 0;
333}
a polymophic address class
Definition: address.h:100
Wi-Fi AP state machine.
Definition: ap-wifi-mac.h:65
holds a vector of ns3::Application pointers.
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
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Hold variables of type string.
Definition: string.h:56
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
create MAC layers for a ns3::WifiNetDevice.
Hold together all Wifi-related objects.
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
Definition: wifi-helper.h:550
void SetPreambleDetectionModel(std::string type, Args &&... args)
Helper function used to set the preamble detection model.
Definition: wifi-helper.h:586
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
@ WIFI_STANDARD_80211ax
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:702
ns cmd
Definition: second.py:33
ns wifi
Definition: third.py:88
ns mac
Definition: third.py:85
ns mobility
Definition: third.py:96
ns wifiStaNodes
Definition: third.py:77
uint32_t bytesReceived
Counter of the received bytes.
Definition: object-names.cc:36
uint32_t ContextToNodeId(std::string context)
void SocketRx(std::string context, Ptr< const Packet > p, const Address &addr)