examples: Add parameter to select 80+80MHz or 160MHz in wifi network examples

This commit is contained in:
Sébastien Deronne
2024-05-09 08:44:28 +02:00
parent fc0f624bd4
commit 921a5eb6c7
3 changed files with 113 additions and 50 deletions

View File

@@ -145,6 +145,7 @@ main(int argc, char* argv[])
bool udp{true};
bool downlink{true};
bool useRts{false};
bool use80Plus80{false};
uint16_t mpduBufferSize{512};
std::string emlsrLinks;
uint16_t paddingDelayUsec{32};
@@ -218,6 +219,7 @@ main(int argc, char* argv[])
"Generate downlink flows if set to 1, uplink flows otherwise",
downlink);
cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts);
cmd.AddValue("use80Plus80", "Enable/disable use of 80+80 MHz", use80Plus80);
cmd.AddValue("mpduBufferSize",
"Size (in number of MPDUs) of the BlockAck buffer",
mpduBufferSize);
@@ -298,6 +300,9 @@ main(int argc, char* argv[])
int minGi = enableUlOfdma ? 1600 : 800;
for (int channelWidth = 20; channelWidth <= maxChannelWidth;) // MHz
{
const auto is80Plus80 = (use80Plus80 && (channelWidth == 160));
const std::string widthStr = is80Plus80 ? "80+80" : std::to_string(channelWidth);
const auto segmentWidthStr = is80Plus80 ? "80" : widthStr;
for (int gi = 3200; gi >= minGi;) // Nanoseconds
{
if (!udp)
@@ -335,7 +340,7 @@ main(int argc, char* argv[])
{
break;
}
channelStr[nLinks] = "{0, " + std::to_string(channelWidth) + ", ";
channelStr[nLinks] = "{0, " + segmentWidthStr + ", ";
if (freq == 6)
{
channelStr[nLinks] += "BAND_6GHZ, 0}";
@@ -379,6 +384,12 @@ main(int argc, char* argv[])
{
NS_FATAL_ERROR("Wrong frequency value!");
}
if (is80Plus80)
{
channelStr[nLinks] += std::string(";") + channelStr[nLinks];
}
nLinks++;
}
@@ -389,12 +400,6 @@ main(int argc, char* argv[])
Ssid ssid = Ssid("ns3-80211be");
/*
* SingleModelSpectrumChannel cannot be used with 802.11be because two
* spectrum models are required: one with 78.125 kHz bands for HE PPDUs
* and one with 312.5 kHz bands for, e.g., non-HT PPDUs (for more details,
* see issue #408 (CLOSED))
*/
SpectrumWifiPhyHelper phy(nLinks);
phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.Set("ChannelSwitchDelay", TimeValue(MicroSeconds(channelSwitchDelayUsec)));
@@ -580,8 +585,9 @@ main(int argc, char* argv[])
Simulator::Destroy();
std::cout << mcs << "\t\t\t" << channelWidth << " MHz\t\t\t" << gi << " ns\t\t\t"
<< throughput << " Mbit/s" << std::endl;
std::cout << +mcs << "\t\t\t" << widthStr << " MHz\t\t"
<< (widthStr.size() > 3 ? "" : "\t") << gi << " ns\t\t\t" << throughput
<< " Mbit/s" << std::endl;
// test first element
if (mcs == minMcs && channelWidth == 20 && gi == 3200)

View File

@@ -72,6 +72,7 @@ main(int argc, char* argv[])
bool udp{true};
bool downlink{true};
bool useRts{false};
bool use80Plus80{false};
bool useExtendedBlockAck{false};
Time simulationTime{"10s"};
double distance{1.0}; // meters
@@ -101,6 +102,7 @@ main(int argc, char* argv[])
"Generate downlink flows if set to 1, uplink flows otherwise",
downlink);
cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts);
cmd.AddValue("use80Plus80", "Enable/disable use of 80+80 MHz", use80Plus80);
cmd.AddValue("useExtendedBlockAck", "Enable/disable use of extended BACK", useExtendedBlockAck);
cmd.AddValue("nStations", "Number of non-AP HE stations", nStations);
cmd.AddValue("dlAckType",
@@ -119,7 +121,8 @@ main(int argc, char* argv[])
cmd.AddValue("mcs", "if set, limit testing to a specific MCS (0-11)", mcs);
cmd.AddValue("payloadSize", "The application payload size in bytes", payloadSize);
cmd.AddValue("phyModel",
"PHY model to use when OFDMA is disabled (Yans or Spectrum). If OFDMA is enabled "
"PHY model to use when OFDMA is disabled (Yans or Spectrum). If 80+80 MHz or "
"OFDMA is enabled "
"then Spectrum is automatically selected",
phyModel);
cmd.AddValue("minExpectedThroughput",
@@ -161,9 +164,9 @@ main(int argc, char* argv[])
{
NS_ABORT_MSG("Invalid PHY model (must be Yans or Spectrum)");
}
if (dlAckSeqType != "NO-OFDMA")
if (use80Plus80 || (dlAckSeqType != "NO-OFDMA"))
{
// SpectrumWifiPhy is required for OFDMA
// SpectrumWifiPhy is required for 80+80 MHz and OFDMA
phyModel = "Spectrum";
}
@@ -191,6 +194,9 @@ main(int argc, char* argv[])
int minGi = enableUlOfdma ? 1600 : 800;
for (int channelWidth = 20; channelWidth <= maxChannelWidth;) // MHz
{
const auto is80Plus80 = (use80Plus80 && (channelWidth == 160));
const std::string widthStr = is80Plus80 ? "80+80" : std::to_string(channelWidth);
const auto segmentWidthStr = is80Plus80 ? "80" : widthStr;
for (int gi = 3200; gi >= minGi;) // Nanoseconds
{
if (!udp)
@@ -207,7 +213,7 @@ main(int argc, char* argv[])
NetDeviceContainer staDevices;
WifiMacHelper mac;
WifiHelper wifi;
std::string channelStr("{0, " + std::to_string(channelWidth) + ", ");
std::string channelStr("{0, " + segmentWidthStr + ", ");
StringValue ctrlRate;
auto nonHtRefRateMbps = HePhy::GetNonHtReferenceRate(mcs) / 1e6;
@@ -216,7 +222,6 @@ main(int argc, char* argv[])
if (frequency == 6)
{
wifi.SetStandard(WIFI_STANDARD_80211ax);
ctrlRate = StringValue(ossDataMode.str());
channelStr += "BAND_6GHZ, 0}";
Config::SetDefault("ns3::LogDistancePropagationLossModel::ReferenceLoss",
@@ -224,7 +229,6 @@ main(int argc, char* argv[])
}
else if (frequency == 5)
{
wifi.SetStandard(WIFI_STANDARD_80211ax);
std::ostringstream ossControlMode;
ossControlMode << "OfdmRate" << nonHtRefRateMbps << "Mbps";
ctrlRate = StringValue(ossControlMode.str());
@@ -232,7 +236,6 @@ main(int argc, char* argv[])
}
else if (frequency == 2.4)
{
wifi.SetStandard(WIFI_STANDARD_80211ax);
std::ostringstream ossControlMode;
ossControlMode << "ErpOfdmRate" << nonHtRefRateMbps << "Mbps";
ctrlRate = StringValue(ossControlMode.str());
@@ -245,6 +248,12 @@ main(int argc, char* argv[])
NS_FATAL_ERROR("Wrong frequency value!");
}
if (is80Plus80)
{
channelStr += std::string(";") + channelStr;
}
wifi.SetStandard(WIFI_STANDARD_80211ax);
wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
"DataMode",
StringValue(ossDataMode.str()),
@@ -257,17 +266,9 @@ main(int argc, char* argv[])
if (phyModel == "Spectrum")
{
/*
* SingleModelSpectrumChannel cannot be used with 802.11ax because two
* spectrum models are required: one with 78.125 kHz bands for HE PPDUs
* and one with 312.5 kHz bands for, e.g., non-HT PPDUs (for more details,
* see issue #408 (CLOSED))
*/
Ptr<MultiModelSpectrumChannel> spectrumChannel =
CreateObject<MultiModelSpectrumChannel>();
auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
Ptr<LogDistancePropagationLossModel> lossModel =
CreateObject<LogDistancePropagationLossModel>();
auto lossModel = CreateObject<LogDistancePropagationLossModel>();
spectrumChannel->AddPropagationLossModel(lossModel);
SpectrumWifiPhyHelper phy;
@@ -301,7 +302,7 @@ main(int argc, char* argv[])
}
else
{
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
auto channel = YansWifiChannelHelper::Default();
YansWifiPhyHelper phy;
phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.SetChannel(channel.Create());
@@ -454,8 +455,9 @@ main(int argc, char* argv[])
Simulator::Destroy();
std::cout << mcs << "\t\t\t" << channelWidth << " MHz\t\t\t" << gi << " ns\t\t\t"
<< throughput << " Mbit/s" << std::endl;
std::cout << +mcs << "\t\t\t" << widthStr << " MHz\t\t"
<< (widthStr.size() > 3 ? "" : "\t") << gi << " ns\t\t\t" << throughput
<< " Mbit/s" << std::endl;
// test first element
if (mcs == minMcs && channelWidth == 20 && gi == 3200)

View File

@@ -26,9 +26,11 @@
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/log.h"
#include "ns3/mobility-helper.h"
#include "ns3/multi-model-spectrum-channel.h"
#include "ns3/on-off-helper.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/packet-sink.h"
#include "ns3/spectrum-wifi-helper.h"
#include "ns3/ssid.h"
#include "ns3/string.h"
#include "ns3/udp-client-server-helper.h"
@@ -64,9 +66,11 @@ main(int argc, char* argv[])
{
bool udp{true};
bool useRts{false};
bool use80Plus80{false};
Time simulationTime{"10s"};
double distance{1.0}; // meters
int mcs{-1}; // -1 indicates an unset value
std::string phyModel{"Yans"};
double minExpectedThroughput{0.0};
double maxExpectedThroughput{0.0};
@@ -77,7 +81,12 @@ main(int argc, char* argv[])
cmd.AddValue("simulationTime", "Simulation time", simulationTime);
cmd.AddValue("udp", "UDP if set to 1, TCP otherwise", udp);
cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts);
cmd.AddValue("use80Plus80", "Enable/disable use of 80+80 MHz", use80Plus80);
cmd.AddValue("mcs", "if set, limit testing to a specific MCS (0-9)", mcs);
cmd.AddValue("phyModel",
"PHY model to use (Yans or Spectrum). If 80+80 MHz is enabled, then Spectrum is "
"automatically selected",
phyModel);
cmd.AddValue("minExpectedThroughput",
"if set, simulation fails if the lowest throughput is below this value",
minExpectedThroughput);
@@ -86,6 +95,16 @@ main(int argc, char* argv[])
maxExpectedThroughput);
cmd.Parse(argc, argv);
if (phyModel != "Yans" && phyModel != "Spectrum")
{
NS_ABORT_MSG("Invalid PHY model (must be Yans or Spectrum)");
}
if (use80Plus80)
{
// SpectrumWifiPhy is required for 80+80 MHz
phyModel = "Spectrum";
}
if (useRts)
{
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
@@ -118,6 +137,9 @@ main(int argc, char* argv[])
channelWidth *= 2;
continue;
}
const auto is80Plus80 = (use80Plus80 && (channelWidth == 160));
const std::string widthStr = is80Plus80 ? "80+80" : std::to_string(channelWidth);
const auto segmentWidthStr = is80Plus80 ? "80" : widthStr;
for (auto sgi : {false, true})
{
uint32_t payloadSize; // 1500 byte IP packet
@@ -136,16 +158,11 @@ main(int argc, char* argv[])
NodeContainer wifiApNode;
wifiApNode.Create(1);
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
YansWifiPhyHelper phy;
phy.SetChannel(channel.Create());
phy.Set("ChannelSettings",
StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}"));
WifiHelper wifi;
wifi.SetStandard(WIFI_STANDARD_80211ac);
NetDeviceContainer apDevice;
NetDeviceContainer staDevice;
WifiMacHelper mac;
WifiHelper wifi;
std::string channelStr{"{0, " + segmentWidthStr + ", BAND_5GHZ, 0}"};
std::ostringstream ossControlMode;
auto nonHtRefRateMbps = VhtPhy::GetNonHtReferenceRate(mcs) / 1e6;
@@ -153,6 +170,13 @@ main(int argc, char* argv[])
std::ostringstream ossDataMode;
ossDataMode << "VhtMcs" << mcs;
if (is80Plus80)
{
channelStr += std::string(";") + channelStr;
}
wifi.SetStandard(WIFI_STANDARD_80211ac);
wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
"DataMode",
StringValue(ossDataMode.str()),
@@ -164,19 +188,49 @@ main(int argc, char* argv[])
Ssid ssid = Ssid("ns3-80211ac");
mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
if (phyModel == "Spectrum")
{
auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
auto lossModel = CreateObject<LogDistancePropagationLossModel>();
spectrumChannel->AddPropagationLossModel(lossModel);
NetDeviceContainer staDevice;
staDevice = wifi.Install(phy, mac, wifiStaNode);
SpectrumWifiPhyHelper phy;
phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.SetChannel(spectrumChannel);
mac.SetType("ns3::ApWifiMac",
"EnableBeaconJitter",
BooleanValue(false),
"Ssid",
SsidValue(ssid));
phy.Set("ChannelSettings",
StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}"));
NetDeviceContainer apDevice;
apDevice = wifi.Install(phy, mac, wifiApNode);
mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
staDevice = wifi.Install(phy, mac, wifiStaNode);
mac.SetType("ns3::ApWifiMac",
"EnableBeaconJitter",
BooleanValue(false),
"Ssid",
SsidValue(ssid));
apDevice = wifi.Install(phy, mac, wifiApNode);
}
else
{
auto channel = YansWifiChannelHelper::Default();
YansWifiPhyHelper phy;
phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.SetChannel(channel.Create());
phy.Set("ChannelSettings",
StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}"));
mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
staDevice = wifi.Install(phy, mac, wifiStaNode);
mac.SetType("ns3::ApWifiMac",
"EnableBeaconJitter",
BooleanValue(false),
"Ssid",
SsidValue(ssid));
apDevice = wifi.Install(phy, mac, wifiApNode);
}
int64_t streamNumber = 150;
streamNumber += WifiHelper::AssignStreams(apDevice, streamNumber);
@@ -283,8 +337,9 @@ main(int argc, char* argv[])
Simulator::Destroy();
std::cout << mcs << "\t\t\t" << channelWidth << " MHz\t\t\t" << std::boolalpha
<< sgi << "\t\t\t" << throughput << " Mbit/s" << std::endl;
std::cout << +mcs << "\t\t\t" << widthStr << " MHz\t\t"
<< (widthStr.size() > 3 ? "" : "\t") << (sgi ? "400 ns" : "800 ns")
<< "\t\t\t" << throughput << " Mbit/s" << std::endl;
// test first element
if (mcs == minMcs && channelWidth == 20 && !sgi)