A Discrete-Event Network Simulator
API
table-based-error-rate-model.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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  * Authors: Rohan Patidar <rpatidar@uw.edu>
18  * Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
22 
23 #include "wifi-tx-vector.h"
24 #include "wifi-utils.h"
25 #include "yans-error-rate-model.h"
26 
27 #include "ns3/dsss-error-rate-model.h"
28 #include "ns3/log.h"
29 #include "ns3/pointer.h"
30 #include "ns3/string.h"
31 #include "ns3/uinteger.h"
32 
33 #include <algorithm>
34 #include <cmath>
35 
36 namespace ns3
37 {
38 
39 static const double SNR_PRECISION = 2;
40 static const double TABLED_BASED_ERROR_MODEL_PRECISION = 1e-5;
41 
43 
44 NS_LOG_COMPONENT_DEFINE("TableBasedErrorRateModel");
45 
46 TypeId
48 {
49  static TypeId tid =
50  TypeId("ns3::TableBasedErrorRateModel")
52  .SetGroupName("Wifi")
53  .AddConstructor<TableBasedErrorRateModel>()
54  .AddAttribute("FallbackErrorRateModel",
55  "Ptr to the fallback error rate model to be used when no matching value "
56  "is found in a table",
57  PointerValue(CreateObject<YansErrorRateModel>()),
59  MakePointerChecker<ErrorRateModel>())
60  .AddAttribute("SizeThreshold",
61  "Threshold in bytes over which the table for large size frames is used",
62  UintegerValue(400),
64  MakeUintegerChecker<uint64_t>());
65  return tid;
66 }
67 
69 {
70  NS_LOG_FUNCTION(this);
71 }
72 
74 {
75  NS_LOG_FUNCTION(this);
76  m_fallbackErrorModel = nullptr;
77 }
78 
79 double
80 TableBasedErrorRateModel::RoundSnr(double snr, double precision) const
81 {
82  NS_LOG_FUNCTION(this << snr);
83  double multiplier = std::round(std::pow(10.0, precision));
84  return std::floor(snr * multiplier + 0.5) / multiplier;
85 }
86 
87 std::optional<uint8_t>
89 {
90  std::optional<uint8_t> mcs;
91  WifiModulationClass modulationClass = mode.GetModulationClass();
92  WifiCodeRate codeRate = mode.GetCodeRate();
93  uint16_t constellationSize = mode.GetConstellationSize();
94 
95  if (modulationClass == WIFI_MOD_CLASS_OFDM || modulationClass == WIFI_MOD_CLASS_ERP_OFDM)
96  {
97  if (constellationSize == 2) // BPSK
98  {
99  if (codeRate == WIFI_CODE_RATE_1_2)
100  {
101  mcs = 0;
102  }
103  if (codeRate == WIFI_CODE_RATE_3_4)
104  {
105  // No MCS uses BPSK and a Coding Rate of 3/4
106  }
107  }
108  else if (constellationSize == 4) // QPSK
109  {
110  if (codeRate == WIFI_CODE_RATE_1_2)
111  {
112  mcs = 1;
113  }
114  else if (codeRate == WIFI_CODE_RATE_3_4)
115  {
116  mcs = 2;
117  }
118  }
119  else if (constellationSize == 16) // 16-QAM
120  {
121  if (codeRate == WIFI_CODE_RATE_1_2)
122  {
123  mcs = 3;
124  }
125  else if (codeRate == WIFI_CODE_RATE_3_4)
126  {
127  mcs = 4;
128  }
129  }
130  else if (constellationSize == 64) // 64-QAM
131  {
132  if (codeRate == WIFI_CODE_RATE_2_3)
133  {
134  mcs = 5;
135  }
136  else if (codeRate == WIFI_CODE_RATE_3_4)
137  {
138  mcs = 6;
139  }
140  }
141  }
142  else if (modulationClass >= WIFI_MOD_CLASS_HT)
143  {
144  mcs = mode.GetMcsValue();
145  }
146  return mcs;
147 }
148 
149 double
151  const WifiTxVector& txVector,
152  double snr,
153  uint64_t nbits,
154  uint8_t numRxAntennas,
155  WifiPpduField field,
156  uint16_t staId) const
157 {
158  NS_LOG_FUNCTION(this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
159  uint64_t size = std::max<uint64_t>(1, (nbits / 8));
160  double roundedSnr = RoundSnr(RatioToDb(snr), SNR_PRECISION);
161  uint8_t mcs;
162  if (auto ret = GetMcsForMode(mode); ret.has_value())
163  {
164  mcs = ret.value();
165  }
166  else
167  {
168  NS_LOG_DEBUG("No MCS found for mode " << mode << ": use fallback error rate model");
169  return m_fallbackErrorModel
170  ->GetChunkSuccessRate(mode, txVector, snr, nbits, numRxAntennas, field, staId);
171  }
172  bool ldpc = txVector.IsLdpc();
173  NS_LOG_FUNCTION(this << +mcs << roundedSnr << size << ldpc);
174 
175  // HT: for MCS greater than 7, use 0 - 7 curves for data rate
177  {
178  mcs = mcs % 8;
179  }
180 
182  {
183  NS_LOG_WARN("Table missing for MCS: "
184  << +mcs << " in TableBasedErrorRateModel: use fallback error rate model");
185  return m_fallbackErrorModel
186  ->GetChunkSuccessRate(mode, txVector, snr, nbits, numRxAntennas, field, staId);
187  }
188 
189  auto errorTable = (ldpc ? AwgnErrorTableLdpc1458
191  const auto& itVector = errorTable[mcs];
192  auto itTable = std::find_if(itVector.cbegin(),
193  itVector.cend(),
194  [&roundedSnr](const std::pair<double, double>& element) {
195  return element.first == roundedSnr;
196  });
197  double minSnr = itVector.cbegin()->first;
198  double maxSnr = (--itVector.cend())->first;
199  double per;
200  if (itTable == itVector.cend())
201  {
202  if (roundedSnr < minSnr)
203  {
204  per = 1.0;
205  }
206  else if (roundedSnr > maxSnr)
207  {
208  per = 0.0;
209  }
210  else
211  {
212  double a = 0.0;
213  double b = 0.0;
214  double previousSnr = 0.0;
215  double nextSnr = 0.0;
216  for (auto i = itVector.cbegin(); i != itVector.cend(); ++i)
217  {
218  if (i->first < roundedSnr)
219  {
220  previousSnr = i->first;
221  a = i->second;
222  }
223  else
224  {
225  nextSnr = i->first;
226  b = i->second;
227  break;
228  }
229  }
230  per = a + (roundedSnr - previousSnr) * (b - a) / (nextSnr - previousSnr);
231  }
232  }
233  else
234  {
235  per = itTable->second;
236  }
237 
238  uint16_t tableSize = (ldpc ? ERROR_TABLE_LDPC_FRAME_SIZE
241  if (size != tableSize)
242  {
243  // From IEEE document 11-14/0803r1 (Packet Length for Box 0 Calibration)
244  per = (1.0 - std::pow((1 - per), (static_cast<double>(size) / tableSize)));
245  }
246 
248  {
249  per = 0.0;
250  }
251 
252  return 1.0 - per;
253 }
254 
255 } // namespace ns3
the interface for Wifi's error models
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< ErrorRateModel > m_fallbackErrorModel
Error rate model to fallback to if no value is found in the table.
static std::optional< uint8_t > GetMcsForMode(WifiMode mode)
Utility function to convert WifiMode to an MCS value.
double DoGetChunkSuccessRate(WifiMode mode, const WifiTxVector &txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const override
A pure virtual method that must be implemented in the subclass.
static TypeId GetTypeId()
Get the type ID.
double RoundSnr(double snr, double precision) const
Round SNR (in dB) to the specified precision.
uint64_t m_threshold
Threshold in bytes over which the table for large size frames is used.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
represent a single transmission mode
Definition: wifi-mode.h:51
uint16_t GetConstellationSize() const
Definition: wifi-mode.cc:141
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
WifiCodeRate GetCodeRate() const
Definition: wifi-mode.cc:134
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsLdpc() const
Check if LDPC FEC coding is used or not.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const SnrPerTable AwgnErrorTableBcc32[ERROR_TABLE_BCC_MAX_NUM_MCS]
AWGN error table for BCC with reference size of 32 bytes.
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:52
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
const uint8_t ERROR_TABLE_BCC_MAX_NUM_MCS
maximum number of MCSs for BCC
static const SnrPerTable AwgnErrorTableLdpc1458[ERROR_TABLE_LDPC_MAX_NUM_MCS]
AWGN error table for LDPC with reference size of 1458 bytes.
static const SnrPerTable AwgnErrorTableBcc1458[ERROR_TABLE_BCC_MAX_NUM_MCS]
AWGN error table for BCC with reference size of 1458 bytes.
const uint8_t ERROR_TABLE_LDPC_MAX_NUM_MCS
maximum number of MCSs for LDPC
const uint16_t ERROR_TABLE_BCC_LARGE_FRAME_SIZE
reference size (bytes) of large frames for BCC
const uint16_t ERROR_TABLE_BCC_SMALL_FRAME_SIZE
reference size (bytes) of small frames for BCC
static const double TABLED_BASED_ERROR_MODEL_PRECISION
precision for PER
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
static const double SNR_PRECISION
precision for SNR
const uint16_t ERROR_TABLE_LDPC_FRAME_SIZE
reference size (bytes) for LDPC
WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
@ WIFI_CODE_RATE_2_3
2/3 coding rate
@ WIFI_CODE_RATE_1_2
1/2 coding rate
@ WIFI_CODE_RATE_3_4
3/4 coding rate