wifi: Add TableBasedErrorRateModel class
This commit is contained in:
committed by
Sebastien Deronne
parent
b4f88cd33d
commit
3d21933f2c
@@ -964,6 +964,7 @@ WifiHelper::EnableLogComponents (void)
|
||||
LogComponentEnable ("SpectrumWifiPhy", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("StaWifiMac", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("SupportedRates", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("TableBasedErrorRateModel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("ThresholdPreambleDetectionModel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("WifiMac", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("WifiMacQueueItem", LOG_LEVEL_ALL);
|
||||
|
||||
217
src/wifi/model/table-based-error-rate-model.cc
Normal file
217
src/wifi/model/table-based-error-rate-model.cc
Normal file
@@ -0,0 +1,217 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Rohan Patidar <rpatidar@uw.edu>
|
||||
* Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/string.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "table-based-error-rate-model.h"
|
||||
#include "wifi-utils.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
#include "dsss-error-rate-model.h"
|
||||
#include "yans-error-rate-model.h"
|
||||
|
||||
static const double SNR_PRECISION = 2;
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (TableBasedErrorRateModel);
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TableBasedErrorRateModel");
|
||||
|
||||
TypeId
|
||||
TableBasedErrorRateModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::TableBasedErrorRateModel")
|
||||
.SetParent<ErrorRateModel> ()
|
||||
.SetGroupName ("Wifi")
|
||||
.AddConstructor<TableBasedErrorRateModel> ()
|
||||
.AddAttribute ("FallbackErrorRateModel",
|
||||
"Ptr to the fallback error rate model to be used when no matching value is found in a table",
|
||||
PointerValue (CreateObject<YansErrorRateModel> ()),
|
||||
MakePointerAccessor (&TableBasedErrorRateModel::m_fallbackErrorModel),
|
||||
MakePointerChecker <ErrorRateModel> ())
|
||||
.AddAttribute ("SizeThreshold",
|
||||
"Threshold in bytes over which the table for large size frames is used",
|
||||
UintegerValue (400),
|
||||
MakeUintegerAccessor (&TableBasedErrorRateModel::m_threshold),
|
||||
MakeUintegerChecker<uint64_t> ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TableBasedErrorRateModel::TableBasedErrorRateModel ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
TableBasedErrorRateModel::~TableBasedErrorRateModel ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_fallbackErrorModel = 0;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
TableBasedErrorRateModel::RoundSnr (double snr, double precision) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr);
|
||||
double multiplier = std::round (std::pow (10.0, precision));
|
||||
return std::floor (snr * multiplier + 0.5) / multiplier;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
TableBasedErrorRateModel::GetMcsForMode (WifiMode mode)
|
||||
{
|
||||
uint8_t mcs = 0xff; // Initialize to invalid mcs
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM || mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
|
||||
{
|
||||
if (mode.GetConstellationSize () == 2)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
|
||||
{
|
||||
mcs = 0;
|
||||
}
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_3_4)
|
||||
{
|
||||
mcs = 1;
|
||||
}
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 4)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
|
||||
{
|
||||
mcs = 2;
|
||||
}
|
||||
else if (mode.GetCodeRate () == WIFI_CODE_RATE_3_4)
|
||||
{
|
||||
mcs = 3;
|
||||
}
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 16)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
|
||||
{
|
||||
mcs = 4;
|
||||
}
|
||||
else if (mode.GetCodeRate () == WIFI_CODE_RATE_3_4)
|
||||
{
|
||||
mcs = 5;
|
||||
}
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 64)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
|
||||
{
|
||||
mcs = 6;
|
||||
}
|
||||
else if (mode.GetCodeRate () == WIFI_CODE_RATE_3_4)
|
||||
{
|
||||
mcs = 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT || mode.GetModulationClass () == WIFI_MOD_CLASS_HE)
|
||||
{
|
||||
mcs = mode.GetMcsValue ();
|
||||
}
|
||||
NS_ABORT_MSG_IF (mcs == 0xff, "Error, MCS value for mode not found");
|
||||
return mcs;
|
||||
}
|
||||
|
||||
double
|
||||
TableBasedErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode << txVector << snr << nbits);
|
||||
uint64_t size = std::max<uint64_t> (1, (nbits / 8));
|
||||
double roundedSnr = RoundSnr (RatioToDb (snr), SNR_PRECISION);
|
||||
uint8_t mcs = GetMcsForMode (mode);
|
||||
NS_LOG_FUNCTION (this << +mcs << roundedSnr << size);
|
||||
|
||||
// HT: for mcs greater than 7, use 0 - 7 curves for data rate
|
||||
if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|
||||
{
|
||||
mcs = mcs % 8;
|
||||
}
|
||||
|
||||
if (mcs > ERROR_TABLE_MAX_NUM_MCS)
|
||||
{
|
||||
NS_LOG_WARN ("Table missing for MCS: " << +mcs << " in TableBasedErrorRateModel: use fallback error rate model");
|
||||
return m_fallbackErrorModel->GetChunkSuccessRate (mode, txVector, snr, nbits);
|
||||
}
|
||||
|
||||
auto errorTable = size < m_threshold ? AwgnErrorTable32 : AwgnErrorTable1458;
|
||||
auto itVector = errorTable[mcs];
|
||||
auto itTable = std::find_if (itVector.begin(), itVector.end(),
|
||||
[&roundedSnr](const std::pair<double, double>& element) {
|
||||
return element.first == roundedSnr;
|
||||
});
|
||||
double minSnr = itVector.begin ()->first;
|
||||
double maxSnr = (--itVector.end ())->first;
|
||||
double per;
|
||||
if (itTable == itVector.end ())
|
||||
{
|
||||
if (roundedSnr < minSnr)
|
||||
{
|
||||
per = 1.0;
|
||||
}
|
||||
else if (roundedSnr > maxSnr)
|
||||
{
|
||||
per = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double a = 0.0, b = 0.0, previousSnr = 0.0, nextSnr = 0.0;
|
||||
for (auto i = itVector.begin (); i != itVector.end (); ++i)
|
||||
{
|
||||
if (i->first < roundedSnr)
|
||||
{
|
||||
previousSnr = i->first;
|
||||
a = i->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextSnr = i->first;
|
||||
b = i->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
per = a + (roundedSnr - previousSnr) * (b - a) / (nextSnr - previousSnr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
per = itTable->second;
|
||||
}
|
||||
|
||||
uint16_t tableSize = size < m_threshold ? ERROR_TABLE_SMALL_FRAME_SIZE : ERROR_TABLE_LARGE_FRAME_SIZE;
|
||||
if (size != tableSize)
|
||||
{
|
||||
// From IEEE document 11-14/0803r1 (Packet Length for Box 0 Calibration)
|
||||
per = (1.0 - std::pow ((1 - per), (static_cast<double> (size) / tableSize)));
|
||||
}
|
||||
|
||||
return 1.0 - per;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
88
src/wifi/model/table-based-error-rate-model.h
Normal file
88
src/wifi/model/table-based-error-rate-model.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Rohan Patidar <rpatidar@uw.edu>
|
||||
* Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef TABLE_BASED_ERROR_RATE_MODEL_H
|
||||
#define TABLE_BASED_ERROR_RATE_MODEL_H
|
||||
|
||||
#include "ns3/error-rate-tables.h"
|
||||
#include "error-rate-model.h"
|
||||
#include "wifi-mode.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class WifiTxVector;
|
||||
|
||||
/*
|
||||
* \ingroup wifi
|
||||
* \brief the interface for the table-driven OFDM error model
|
||||
*
|
||||
*/
|
||||
class TableBasedErrorRateModel : public ErrorRateModel
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
TableBasedErrorRateModel ();
|
||||
~TableBasedErrorRateModel ();
|
||||
|
||||
//Inherited from ErrorRateModel
|
||||
double DoGetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const;
|
||||
|
||||
/**
|
||||
* \brief Utility function to convert WifiMode to an MCS value
|
||||
* \param mode the WifiMode
|
||||
* \return the MCS value
|
||||
*/
|
||||
static uint8_t GetMcsForMode (WifiMode mode);
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* Round SNR (in dB) to the specified precision
|
||||
*
|
||||
* \param snr the SNR to round (in dB)
|
||||
* \param precision the precision to use
|
||||
* \return the rounded SNR (in dB) to the specified precision
|
||||
*/
|
||||
double RoundSnr (double snr, double precision) const;
|
||||
|
||||
/**
|
||||
* Fetch the frame success rate for a given Wi-Fi mode, TXVECTOR, SNR and frame size.
|
||||
* \param mode the Wi-Fi mode
|
||||
* \param txVector the TXVECTOR
|
||||
* \param snr the SNR (linear scale)
|
||||
* \param nbits the number of bits
|
||||
* \return the frame success rate for a given Wi-Fi mode, TXVECTOR, SNR and frame size
|
||||
*/
|
||||
double FetchFsr (WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const;
|
||||
|
||||
Ptr<ErrorRateModel> m_fallbackErrorModel; //!< Error rate model to fallback to if no value is found in the table
|
||||
|
||||
uint64_t m_threshold; //!< Threshold in bytes over which the table for large size frames is used
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* TABLE_BASED_ERROR_RATE_MODEL_H */
|
||||
@@ -14,6 +14,7 @@ def build(bld):
|
||||
'model/yans-error-rate-model.cc',
|
||||
'model/nist-error-rate-model.cc',
|
||||
'model/dsss-error-rate-model.cc',
|
||||
'model/table-based-error-rate-model.cc',
|
||||
'model/interference-helper.cc',
|
||||
'model/yans-wifi-phy.cc',
|
||||
'model/yans-wifi-channel.cc',
|
||||
@@ -173,6 +174,7 @@ def build(bld):
|
||||
'model/yans-error-rate-model.h',
|
||||
'model/nist-error-rate-model.h',
|
||||
'model/dsss-error-rate-model.h',
|
||||
'model/table-based-error-rate-model.h',
|
||||
'model/wifi-mac-queue.h',
|
||||
'model/txop.h',
|
||||
'model/wifi-phy-header.h',
|
||||
|
||||
Reference in New Issue
Block a user