# 6.ns3 wifi 模型配置
在本节中,将介绍 ns3 中 wifi 模型扩展所需的一些内容,
# Using the WifiNetDevice
使用底层 ns3 API 添加一个 WifiNetDevice 到节点上,必须创建一个 WifiNetDevice 实例,和许多构成的对象,以一种合适的方式绑定在一起( WifiNetDevice 为未来的可扩展性,在某种程度上已经非常模块化)。在底层 api,这需要大约 20 行代码( ns3::WifiHelper::Install,ns3::YansWifiPhyHelper::Create )。一个信道 WifiChannel 必须被创建,也包含了一些构成的对象(请看 ns3::YansWifiChannelHelper::Create )。
然而,一些可用的帮助类可以使用,如果愿意使用默认值的话,添加设备和信道只用几行代码就能完成。当然也可以使用额外的 api 允许通过属性系统来改变默认值。
接下来,我们描述创建一个 WifiNetDevice 从底层 (WifiChannel) 到设备层 (WifiNetDevice) 的通常的步骤。
为了创建一个 WifiNetDevice ,用户主要需要配置五步:
- 配置
WifiChannel:WifiChannel关系到信号在相同的信道上从一个设备到另一个设备。WifiChannel主要的配置是传播损耗模型和传播延时模型。 - 配置
WifiPhy:WifiPhy关系到从WifiChannel发送和接收无线信号。这里,WifiPhy依赖于接收的信号的强度和噪声决定每一帧是否被成功解码。所以,WifiPhy的主要配置是误码率模型,该模型就是最后计算基于信号的成功解码帧的概率。 - 配置
WifiMac:这一步更多的是与the architecture and device level有关。用户配置wifi architecture(例如adhoc or ap-sta)和是否支持Qos(802.11e),HT(802.11n),VHT(802.11ac)特性。 - 创建
WifiDevice: 在这一步,用户配置期望的wifi标准(例如802.11b,802.11g,802.11a,802.11n or 802.11ac)和速率控制算法。 - 配置
mobility: 最后,mobility模型通常需要在WifiNetDevice可用之前配置。
# YansWifiChannelHelper
YansWifiChannelHelper 具有一个不同寻常的名字。读者可能会疑惑为什么使用这样的名字。该模型是从 yans simulator 提取出来的,名字也是引用自它。该帮助类可以创建一个带有默认传播损耗模型 (PropagationLoss) 和传播延时模型 (PropagationDelay) 的 WifiChannel 。
用户所使用的经典代码如下:
YansWifiChannelHelper wifiChannelHelper = YansWifiChannelHelper::Default (); | |
Ptr<WifiChannel> wifiChannel = wifiChannelHelper.Create (); |
特别的是,默认的信道模型使用的是 3 的指数的信道模型,所用的传播时延等于一个常数值,就是光速 (ns3::ConstantSpeedPropagationDelayModel) ,所用的传播损耗是基于一个默认的 log distance model(ns3::LogDistancePropagationLossModel) 。请注意,默认的 log distance model is configured with a reference loss of 46.6777 dB at reference distance of 1m 。 The reference loss of 46.6777 dB was calculated using Friis propagation loss model at 5.15 GHz . The reference loss 模型如果使用 802.11b,802.11g,802.11n (由于它们工作在 2.4GHZ ) 必须被改变。
注意上面在创建一个帮助对象和一个实际的仿真对象的区别。在 ns3 中,帮助对象(仅仅用于帮助 APP)是在栈(它们可以使用 new 操作符创建和使用 deleted 销毁)中创建的。然而,实际的 ns3 对象继承自 ns3::Object 类,并且分配一个智能指针。
下面的两个方法在配置 YansWifiChannelHelper 是有用的:
• YansWifiChannelHelper::AddPropagationLoss adds a PropagationLossModel to a chain of PropagationLossModel | |
• YansWifiChannelHelper::SetPropagationDelay sets a PropagationDelayModel |
# YansWifiPhyHelper
物理层设备(基类 ns3::WifiPhy )在 ns3 中是与 ns3::WifiChannel 相连接的。我们需要为 YansWifiChannel 创建合适的 WifiPhy 对象。这里 YansWifiPhyHelper 就可以胜任这个工作。
YansWifiPhyHelper 类配置了一个对象工厂来创建一个 YansWifiPhy 实例,并添加一些其他的对象到该实例中,包括可能补充的 ErrorRateModel 误码率模型和指向 MobilityModel 移动模型的指针。典型的用户代码如下:
YansWifiPhyHelper wifiPhyHelper = YansWifiPhyHelper::Default (); | |
wifiPhyHelper.SetChannel (wifiChannel); |
YansWifiPhyHelper 默认配置 NistErrorRateModel(ns3::NistErrorRateModel) 误码率模型。你可以使用 YansWifiPhyHelper::SetErrorRateModel 方法更改误码率模型。
可选的是,如果 pcap 跟踪记录是需要的话,用户可以使用下面的代码使得 pcap 跟踪可用:
YansWifiPhyHelper::SetPcapDataLinkType (enum SupportedPcapDataLinkTypes dlt) | |
ns3支持802.11的RadioTap和Prism轨迹扩展。 |
注意,我们还没有实际创建一个 WifiPhy 对象;我们只是准备了告诉 YansWifiPhyHelper 与之连接的信道。 Phy 对象会在下一步创建。
802.11n/ac PHY 层可以使用长 800ns 或者短 400ns 的 OFDM guard intervals 。为了配置这个参数,可以使用下面的一行的代码(这个例子中,使用的是 short guard interval 的支持):
wifiPhyHelper.Set ("ShortGuardEnabled", BooleanValue(true)); |
更多的是, 802.11 提供了一种可选的模式 (GreenField mode) 来减少 preamble durations (前沿持续时间),并且这也是唯一一种与 802.11n 设备兼容的模式。可以使用下面的代码启用这种模式:
wifiPhyHelper.Set ("GreenfieldEnabled",BooleanValue(true)); |
802.11nPHY 层可以支持 20(默认)或者 40MHZ 信道带宽, 802.11ac PHY 层可以使用 20,40,80(默认),160MHZ 信道带宽。由于信道带宽值被 WifiHelper::SetStandard 重写,可以使用下面 Config::Set 代码在安装后进行配置:
WifiHelper wifi = WifiHelper::Default (); | |
wifi.SetStandard (WIFI_PHY_STANDARD_80211ac); | |
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", | |
StringValue("VHtMcs9"), "ControlMode",StringValue("VHtMcs9")); | |
VhtWifiMacHelper mac = VhtWifiMacHelper::Default (); | |
//Install PHY and MAC | |
Ssid ssid = Ssid ("ns3-wifi"); | |
mac.SetType ("ns3::StaWifiMac", | |
"Ssid", SsidValue (ssid), | |
"ActiveProbing", BooleanValue (false)); | |
NetDeviceContainer staDevice; | |
staDevice = wifi.Install (phy, mac, wifiStaNode); | |
mac.SetType ("ns3::ApWifiMac", | |
"Ssid", SsidValue (ssid)); | |
NetDeviceContainer apDevice; | |
apDevice = wifi.Install (phy, mac, wifiApNode); | |
//Once install is done, we overwrite the channel width value | |
//(一旦安装之后,我们可以重写信道带宽) | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", UintegerValue (160)); |
# WifiMacHelper
下一步是配置 MAC 模型。我们使用 WifiMacHelper 来完成。 WifiMacHelper 可以完成 MAC low 模型和 MAC high 模型。用户必须决定采用哪种模型: 802.11/WMM-style Qos , 802.11n-style Hight throughput(HT) , 802.11ac-style Very High throughput(VHT)
# NqosWifiMacHelper and QosWifiMacHelper
ns3::NqosWifiMacHelper 和 ns3::QosWifiMacHelper 均可以配置一个对象工厂来创建一个 ns3::WifiMac 实例。它们用来配置像 MAC 类型的参数。
前者 ns3::NqosWifiMacHelper 不支持以下类型的 MAC 实例的创建: 802.11e/WMM-style QoS,802.11n-style High throughput (HT),802.11ac-style Very High throughput (VHT) 。
例如下面的用户代码配置了一个不支持 QOs 和 HT 的 MAC 类型实例,并且没有 AP ,仅有 STA 的一个基础设施网络, SSID 设置为 ns-3-ssid :
NqosWifiMacHelper wifiMacHelper = NqosWifiMacHelper::Default (); | |
Ssid ssid = Ssid ("ns-3-ssid"); | |
wifiMacHelper.SetType ("ns3::StaWifiMac", | |
"Ssid", SsidValue (ssid), | |
"ActiveProbing", BooleanValue (false)); | |
可以使用ns3::QosWifiMacHelper来代替ns3::NqosWifiMacHelper来创建一个支持Qos的MAC实例。 | |
下面的代码使用ns3::QosWifiMacHelper创建了一个支持Qos的AP: | |
QosWifiMacHelper wifiMacHelper = QosWifiMacHelper::Default (); | |
wifiMacHelper.SetType ("ns3::ApWifiMac", | |
"Ssid", SsidValue (ssid), | |
"BeaconGeneration", BooleanValue (true), | |
"BeaconInterval", TimeValue (Seconds (2.5))); |
支持 Qos 的 MAC 模型可以工作在流量属于四种不同访问策略下: AC_VO 语音流, AC_VI 视频流, AC_BE 尽最大努力流, AC_BK 后台流。为了使 MAC 为 MSDU 决定一个合适的 AC ,转发到这些 MAC 层的包应该被使用一个 TID(traffic id) 的 ns3::QosTag 标记,否则该包将被属于 AC_BE 策略。
为了创建一个 ad-hoc MAC 实例,简单的使用 ns3::AdhocWifiMac 代替 ns3::StaWifiMac 和 ns3::ApWifiMac 即可。
# HtWifiMacHelper
ns3::HtWifiMacHelper 配置一个对象工厂来创建一个 ns3::WifiMac 实例。它用于支持创建 802.11n-style High throughput (HT) 和支持 QoS 类型的 MAC 实例。特别的,该对象也可以用来设置:
1. 为了使用802.11n MSDU聚合特性,为特定的访问策略AC设置MSDU聚合 | |
2. 可以设置像threshold(阈值)(块ACK机制应该被使用的包的数量)的块ACK参数和闲置超时。 |
例如,下面的代码配置了一个 HT MAC ,不支持 AP ,支持 STA , QOS 保证,聚合 AC_VO , 和 AC_BE 的块 ACK ,这样的基础设施网络,它的 AP 的 SSID 为 ns-3-ssid :
HtWifiMacHelper wifiMacHelper = HtWifiMacHelper::Default (); | |
Ssid ssid = Ssid ("ns-3-ssid"); | |
wifiMacHelper.SetType ("ns3::StaWifiMac", | |
"Ssid", SsidValue (ssid), | |
"ActiveProbing", BooleanValue (false)); | |
wifiMacHelper.SetMsduAggregatorForAc (AC_VO, "ns3::MsduStandardAggregator", | |
"MaxAmsduSize", UintegerValue (3839)); | |
wifiMacHelper.SetBlockAckThresholdForAc (AC_BE, 10); | |
wifiMacHelper.SetBlockAckInactivityTimeoutForAc (AC_BE, 5); |
这个对象也可以使用 ns3::QosWifiMacHelper 以相同的方式进行设置。
# VhtWifiMacHelper
ns3::VhtWifiMacHelper 配置一个对象工厂来创建一个 ns3::WifiMac 实例。用于支持创建以下类型的 MAC 实例: 802.11ac-style Very High throughput (VHT) 和支持 QoS 保证。这个对象与 HtWifiMacHelper 很相似。
# WifiHelper
我们现在准备创建 WifiNetDevices . 首先,让我们创建一个默认设置的 WifiHelper :
WifiHelper wifiHelper = WifiHelper::Default (); |
这一步都做了什么呢?它默认设置 802.11a WIFI 标准,和设置 ns3::ArfWifiManager 作为 RemoteStationManager 。你可以通过调用 WifiHelper::SetRemoteStationManager 方法改变 RemoteStationManager 。为了改变采用的 wifi 标准,可以调用 WifiHelper::SetStandard 方法来设置想要的标准。
现在,让我们使用上面所描述的对象 wifiPhyHelper 和 wifiMacHelper ,安装到在一系列节点 c 上的 WifiNetDevices :
NetDeviceContainer wifiContainer = WifiHelper::Install (wifiPhyHelper, wifiMacHelper, c); |
这样就创建了一个 WifiNetDevice,它包含 WifiRemoteStationManager,WifiMac,WifiPhy(连接到匹配的 WifiChannel 上的)。
WifiHelper::SetStandard 方法设置了定义在已选的标准版本中的可变的默认的定时参数,可重写已经存在的或者已经配置过的值。为了改变已经给 WifiHelper::SetStandard 重写的参数,应该在安装后使用 Config::Set 来配置:
WifiHelper wifi = WifiHelper::Default (); | |
wifi.SetStandard (WIFI_PHY_STANDARD_80211n_2_4GHZ); | |
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", | |
StringValue("HtMcs7"), "ControlMode",StringValue("HtMcs7")); | |
HtWifiMacHelper mac = HtWifiMacHelper::Default (); | |
//Install PHY and MAC | |
Ssid ssid = Ssid ("ns3-wifi"); | |
mac.SetType ("ns3::StaWifiMac", | |
"Ssid", SsidValue (ssid), | |
"ActiveProbing", BooleanValue (false)); | |
NetDeviceContainer staDevice; | |
staDevice = wifi.Install (phy, mac, wifiStaNode); | |
mac.SetType ("ns3::ApWifiMac", | |
"Ssid", SsidValue (ssid)); | |
NetDeviceContainer apDevice; | |
apDevice = wifi.Install (phy, mac, wifiApNode); | |
//Once install is done, we overwrite the standard timing values | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/Slot", TimeValue (MicroSeconds (slot)) | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/Sifs", TimeValue (MicroSeconds (sifs)) | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/AckTimeout", TimeValue (MicroSeconds ( | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/CtsTimeout", TimeValue (MicroSeconds ( | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/Rifs", TimeValue (MicroSeconds (rifs)) | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BasicBlockAckTimeout", TimeValue (Micr | |
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/CompressedBlockAckTimeout", TimeValue |
有许多 ns3 属性可以被上面的 helpers 对象使用来改变默认的行为,例子脚本程序展示了如何改变默认行为。
# Mobility configuration
最后,一个移动模型必须在 wifi device 上进行配置。移动模型被用于计算传播损耗和传播时延。在下一节中提供了两个例子。用户可以引用 Mobility 模块一章获取更多细节。
# Example configuration
ns3 提供了两个典型的配置 wifi 网络的例子程序 - 一个例子程序使用 adhoc 网络,一个例子程序使用基础设施网络。两个例子程序在 examples/wireless 目录( wifi-simple-adhoc.cc 和 wifi-simple-infra.cc )。鼓励用户学习 examples/wireless 目录下的例子。
# AdHoc WifiNetDevice configuration
在这个例子中,我们创建了两个 adhoc 节点,配置了 802.11a wifi 设备。我们使用 ns3::ConstantSpeedPropagationDelayModel 作为传播延时模型,使用带有 3 的指数的 ns3::LogDistancePropagationLossModel 作为传播损耗模型。两个设备都配置 12Mbps 固定速率的 ConstantRateWifiManager 。最后,我们使用 ns3::ListPositionAllocator 手动放置节点位置:
std::string phyMode ("OfdmRate12Mbps"); | |
NodeContainer c; | |
c.Create (2); | |
WifiHelper wifi; | |
wifi.SetStandard (WIFI_PHY_STANDARD_80211a); | |
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); | |
// ns-3 supports RadioTap and Prism tracing extensions for 802.11 | |
wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); | |
YansWifiChannelHelper wifiChannel; | |
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); | |
wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel", | |
"Exponent", DoubleValue (3.0)); | |
wifiPhy.SetChannel (wifiChannel.Create ()); | |
// Add a non-QoS upper mac, and disable rate control (i.e. ConstantRateWifiManager) | |
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default (); | |
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", | |
"DataMode",StringValue (phyMode), | |
"ControlMode",StringValue (phyMode)); | |
// Set it to adhoc mode | |
wifiMac.SetType ("ns3::AdhocWifiMac"); | |
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c); | |
// Configure mobility | |
MobilityHelper mobility; | |
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> (); | |
positionAlloc->Add (Vector (0.0, 0.0, 0.0)); | |
positionAlloc->Add (Vector (5.0, 0.0, 0.0)); | |
mobility.SetPositionAllocator (positionAlloc); | |
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); | |
mobility.Install (c); | |
// other set up (e.g. InternetStack, Application)Infrastructure (access point and clients) | |
// WifiNetDevice configuration |
这是一个典型的代码,展示了用户如何配置一个接入点 AP 和一系列客户端。在这个例子中,我们创建一个接入点和两个客户端。每一个节点配置 802.11 b wifi 设备:
std::string phyMode ("DsssRate1Mbps"); | |
NodeContainer ap; | |
ap.Create (1); | |
NodeContainer sta; | |
sta.Create (2); | |
WifiHelper wifi; | |
wifi.SetStandard (WIFI_PHY_STANDARD_80211b); | |
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); | |
// ns-3 supports RadioTap and Prism tracing extensions for 802.11 | |
wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); | |
YansWifiChannelHelper wifiChannel; | |
// reference loss must be changed since 802.11b is operating at 2.4GHz | |
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); | |
wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel", | |
"Exponent", DoubleValue (3.0), | |
"ReferenceLoss", DoubleValue (40.0459)); | |
wifiPhy.SetChannel (wifiChannel.Create ()); | |
// Add a non-QoS upper mac, and disable rate control | |
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default (); | |
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", | |
"DataMode",StringValue (phyMode), | |
"ControlMode",StringValue (phyMode)); | |
// Setup the rest of the upper mac | |
Ssid ssid = Ssid ("wifi-default"); | |
// setup ap. | |
wifiMac.SetType ("ns3::ApWifiMac", | |
"Ssid", SsidValue (ssid)); | |
NetDeviceContainer apDevice = wifi.Install (wifiPhy, wifiMac, ap); | |
NetDeviceContainer devices = apDevice; | |
// setup sta. | |
wifiMac.SetType ("ns3::StaWifiMac", | |
"Ssid", SsidValue (ssid), | |
"ActiveProbing", BooleanValue (false)); | |
NetDeviceContainer staDevice = wifi.Install (wifiPhy, wifiMac, sta); | |
devices.Add (staDevice); | |
// Configure mobility | |
MobilityHelper mobility; | |
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> (); | |
positionAlloc->Add (Vector (0.0, 0.0, 0.0)); | |
positionAlloc->Add (Vector (5.0, 0.0, 0.0)); | |
positionAlloc->Add (Vector (0.0, 5.0, 0.0)); | |
mobility.SetPositionAllocator (positionAlloc); | |
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); | |
mobility.Install (ap); | |
mobility.Install (sta); | |
// other set up (e.g. InternetStack, Application) |