11import math
2+ from typing import List
23
34import numpy as np
45
@@ -33,7 +34,10 @@ class Wifi80211:
3334 memory = np .array (6 , ndmin = 1 )
3435 generator_matrix = np .array ((133 , 171 ), ndmin = 2 ) # from 802.11 standard, page 2295
3536
36- def get_modem (self ):
37+ def get_modem (self ) -> mod .Modem :
38+ """
39+ Gets the modem that is going to be used for this particular WiFi simulation according to the MCS
40+ """
3741 qpsks = [
3842 2 ,
3943 4 ,
@@ -53,7 +57,7 @@ def get_modem(self):
5357 return mod .QAMModem (qpsks [self .mcs ])
5458
5559 @staticmethod
56- def get_puncture_matrix (numerator , denominator ) :
60+ def _get_puncture_matrix (numerator : int , denominator : int ) -> List :
5761 if numerator == 1 and denominator == 2 :
5862 return None
5963 # from the standard 802.11 2016
@@ -68,7 +72,7 @@ def get_puncture_matrix(numerator, denominator):
6872 return [1 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ]
6973 return None
7074
71- def get_coding (self ):
75+ def _get_coding (self ):
7276 coding = [
7377 (1 , 2 ),
7478 (1 , 2 ),
@@ -84,22 +88,70 @@ def get_coding(self):
8488 return coding [self .mcs ]
8589
8690 @staticmethod
87- def get_trellis ():
91+ def _get_trellis ():
8892 return cc .Trellis (Wifi80211 .memory , Wifi80211 .generator_matrix )
8993
90- def __init__ (self , mcs ):
94+ def __init__ (self , mcs : int ):
95+ """
96+ Build WiFi 802.11 simulation class
97+ Parameters
98+ ----------
99+ mcs : int
100+ The Modulation Coding Scheme (MCS) to simulate.
101+ A list of MCS and which coding and modulations they correspond to
102+ """
91103 self .mcs = mcs
92104 self .modem = None
93105
94- def link_performance (self , channels : _FlatChannel , SNRs , tx_max , err_min , send_chunk = None ,
106+ def link_performance (self , channel : _FlatChannel , SNRs , tx_max , err_min , send_chunk = None ,
95107 frame_aggregation = 1 , receiver = None , stop_on_surpass_error = True ):
96- trellis1 = Wifi80211 .get_trellis ()
97- coding = self .get_coding ()
108+ """
109+ Estimate the BER performance of a link model with Monte Carlo simulation as in commpy.links.link_performance
110+
111+ Parameters
112+ ----------
113+ channel : _FlatChannel
114+ The channel to be used for the simulation
115+
116+ SNRs : 1D arraylike
117+ Signal to Noise ratio in dB defined as :math:`SNR_{dB} = (E_b/N_0)_{dB} + 10 \log_{10}(R_cM_c)`
118+ where :math:`Rc` is the code rate and :math:`Mc` the modulation rate.
119+
120+ tx_max : int
121+ Maximum number of transmissions for each SNR.
122+
123+ err_min : int
124+ link_performance send bits until it reach err_min errors (see also send_max).
125+
126+ send_chunk : int
127+ Number of bits to be send at each frame. This is also the frame length of the decoder if available
128+ so it should be large enough regarding the code type.
129+ *Default*: send_chunck = err_min
130+
131+ frame_aggregation : int
132+ Number of frames aggregated per transmission (each frame with size send_chunk)
133+
134+ receiver : function
135+ Specify a custom receiver function to be used in the simulation.
136+ This is particular useful for MIMO simulations.
137+
138+ stop_on_surpass_error : bool
139+ Controls if during simulation of a SNR it should break and move to the next SNR when
140+ the bit error is above the err_min parameter
141+
142+ Returns
143+ -------
144+ BERs : 1d ndarray
145+ Estimated Bit Error Ratio corresponding to each SNRs
146+ """
147+
148+ trellis1 = Wifi80211 ._get_trellis ()
149+ coding = self ._get_coding ()
98150 modem = self .get_modem ()
99151
100152 def modulate (bits ):
101153 res = cc .conv_encode (bits , trellis1 , 'cont' )
102- puncture_matrix = Wifi80211 .get_puncture_matrix (coding [0 ], coding [1 ])
154+ puncture_matrix = Wifi80211 ._get_puncture_matrix (coding [0 ], coding [1 ])
103155 res_p = res
104156 if puncture_matrix :
105157 res_p = cc .puncturing (res , puncture_matrix )
@@ -116,7 +168,7 @@ def _receiver(y, h, constellation, noise_var):
116168 # Decoder function
117169 def decoder_soft (msg ):
118170 msg_d = msg
119- puncture_matrix = Wifi80211 .get_puncture_matrix (coding [0 ], coding [1 ])
171+ puncture_matrix = Wifi80211 ._get_puncture_matrix (coding [0 ], coding [1 ])
120172 if puncture_matrix :
121173 try :
122174 msg_d = cc .depuncturing (msg , puncture_matrix , math .ceil (len (msg ) * coding [0 ] / coding [1 ] * 2 ))
@@ -127,12 +179,12 @@ def decoder_soft(msg):
127179 print ("Coding %d/%d" % (coding [0 ], coding [1 ]))
128180 return cc .viterbi_decode (msg_d , trellis1 , decoding_type = 'soft' )
129181
130- self .model = lk .LinkModel (modulate , channels , receiver ,
182+ self .model = lk .LinkModel (modulate , channel , receiver ,
131183 modem .num_bits_symbol , modem .constellation , modem .Es ,
132184 decoder_soft , coding [0 ] / coding [1 ])
133- return self .model .link_performance (SNRs , tx_max ,
134- err_min = err_min , send_chunk = send_chunk ,
135- code_rate = coding [0 ] / coding [1 ],
136- number_chunks_per_send = frame_aggregation ,
137- stop_on_surpass_error = stop_on_surpass_error
138- )
185+ return self .model .link_performance_full_metrics (SNRs , tx_max ,
186+ err_min = err_min , send_chunk = send_chunk ,
187+ code_rate = coding [0 ] / coding [1 ],
188+ number_chunks_per_send = frame_aggregation ,
189+ stop_on_surpass_error = stop_on_surpass_error
190+ )
0 commit comments