Laboratorul 5 - Propagarea semnalelor

Materiale ajutătoare

Modelul Log Distance

Acest model calculează puterea la receptor după următoarea formulă descrisă în pagina ns-3

Atributele pe care le putem controla din ns-3 sunt: exponentul, distanța de referință la care atenuarea e calculată și atenuarea de referință.

Modelul Three Log Distance

Este la fel ca log distance însă folosește trei exponenți diferiți pentru “near, middle, far”. Este descris matematic aici. ns-3 ne oferă posibilitatea de a configura distanțele și exponenții pentru “near, middle, far” și atenuarea de referință.

Modelul Nakagami

Este o generalizare a modelului popular Rayleigh. Descrierea lui este aici, dar și în paper-ul scris de M. Nakagami: nakagami1960.pdf.

Modelul Friis

Combaterea pierderilor

Ce arme are un transmițător la dispoziție pentru a combate acest fenomen:

  • puterea de transmisie (măsurată de obicei în dbm - în PCAP-uri Wifi sau iwconfig este Tx Power)
  • MCS-ul de transmisie - cu cât e mai prost cu atât e mai robust la shadowing, dar penalizarea e de performanță (nu vei avea throughput mare cu MCS mic)

dBm este unitatea de nivel absolut în raport cu puterea de 1 mW (miliwatt). Această unitate este utilizată frecvent în telecom.

Valoarea indicată în dB ne indică cu cât această putere este mai mică sau mai mare decât puterea de 1 mW. Nivelului de 0 dB îi corespunde valoarea de 1 mW (miliwatt).

Formula generală pentru dbm este:

$$ \displaystyle \text{Putere}_{dbm} = 10 \log \displaystyle \frac{P}{P_{ref}} $$

În cazul nostru puterea de referință este $$ P_{ref} = 1 \text{mW} $$

Așadar dacă vom dori să transformăm puterea exprimată din dbm în mW folosim

$$ \displaystyle \text{Putere}_{mW} = 10^{\frac{\text{Putere}_{dbm}}{10}} $$

De exemplu: Rulăm iwconfig pe un router cu Linux și ne spune că TX Power este 20 dbm. Cum obținem puterea emisă de acest dispozitiv în mW?

$$ \text{P}_{mW} = 10^{\frac{\text{P}_{dbm}}{10}} = 10^2 = 100 mW $$

Pentru circuitele de radiofrecvenţă se utilizează o impedanţă de 50 de ohmi. Această valoare este importantă pentru proiectarea cablurilor ce leagă antena routerului de procesorul care va interpreta pachetele sosite.

Reamintim că MCS = modulation and coding scheme. Modulația definește modul de organizare a biților pe aer în simboluri pe aer (BPSK, QPSK, 16-QAM, 64-QAM) - a se citi câți biți pot înghesui într-un simbol de date și coding = tehnica de codare a datelor - cât de repede sau de încet se propagă datele astfel încât receptorul să poată decoda simbolurile de pe aer. Pentru a înțelege tehnica de codare: Imaginați-vă un curs în care profesorul vorbește foarte repede: pot toți studenții să îl urmărească?

Ce arme are un receptor la dispoziție pentru a combate acest fenomen:

  • AGC (automatic gain control)
  • capacitatea de a decoda un MCS mare (802.11ac a introdus LDPC coding - o tehnică mai bună de codare a datelor decât cele tradiționale)

Ce arme au atât transmițătorul, cât și receptorul pentru a combate ambele fenomene: MIMO (Multiple Input, Multiple Output) - folosirea de mai multe antene la transmisie și recepție (la 802.11ac avem un maxim de 4×4) și STBC (Space Time Block Coding) - o tehnică de a transmite mai multe copii ale unui stream de date pe mai multe antene pentru a asigura fiabilitatea datelor transmise. Cele două capabilități sunt advertised de AP (access point) în beacon, iar stațiile îi transmit AP-ului dacă le au în cadrul probe request-ului.

În laboratorul următor vom studia algoritmi de adaptare a MCS-ului folosiți de driverele de rețea la nivel L2 pentru reglarea ratelor tx (putere, mcs, tip pachet etc.) și vom vedea comportamentul acestora versus o rată fixată.

Ce vom face la laborator

Modelul de la acest laborator este alcătuit dintr-o STA (stație) mobilă care se îndepărtează liniar cu un număr de metri pe care îl putem alege față de un AP (access point).

Vom folosi o simulare realizată în ns-3 care ne permite să schimbăm între 4 modele de propagare. Vom alege pe rand cate unul din modele.

Opțional/Bonus: Dacă vreți puteți modifica punctual codul sursă pentru a vă juca cu unii parametrii și a observa comportamentul modelului de propagare a semnalelor.

După aceasta ne vom concentra pe un singur model de propagare și vom vedea cum se comportă traficul TCP sau UDP în anumite condiții suplimentare ce nu țin de mediu.

Plan de organizare a datelor intermediare

  1. citiți toate cerințele din secțiunea Task-uri de mai jos înainte de a decide un plan de măsurători. Strategia optimă este de a extrage mai mulți parametri în urma unei simulări pentru a putea răspunde mai multor cerințe.
  2. decideți structura fișierului text care va conține datele din care se pot produce graficele cerute.
    • ce avem pe axele x, y?
    • ce reprezintă fiecare coloană?
    • ce parametri se pot obține ca o funcție de coloane? Exemplu $probabilitate_{livrare} = primite/trimise$
    • ce grafice au axe care nu corespund direct unoar coloane din fișierul generat? cum se pot obține acele axe?
  3. prelucrați output-ul obtinut in urma rularilor succesive pentru a obține un fișier text de date intermediare cu semnificații clare pentru linii și coloane. Exemplu: fiecare linie e pentru o distanță, fiecare coloană e un counter de cadre sau un debit în Mbps

Pregătirea laboratorului

student@isrm:~$ git clone https://gitlab.com/b12mihai1/ns-3-dev.git
student@isrm:~$ cd ns-3-dev/
student@isrm:~/ns-3-dev$ git checkout -b isrm_2020 remotes/origin/isrm_2020
student@isrm:~/ns-3-dev$ git submodule init
student@isrm:~/ns-3-dev$ git submodule update --remote --merge
student@isrm:~/ns-3-dev$ git submodule foreach git pull origin master
student@isrm:~/ns-3-dev$ cd scratch/
student@isrm:~/ns-3-dev/scratch$ ln -s ../examples/ns3-labs/lab-05-06-mcs/lab5.cc lab5.cc
student@isrm:~/ns-3-dev/scratch$ cd ..
student@isrm:~/ns-3-dev$ ./waf configure --build-profile=debug --enable-examples --enable-tests && ./waf build -j4
student@isrm:~/ns-3-dev$ ./waf --run "lab5 --apManager=ns3::ConstantRateWifiManager --phyRate=ErpOfdmRate54Mbps --propagationModel=0"

Parametrii pe care simularea noastră îi primește:

cmd.AddValue("phyRate", "Wifi Phy Rate (MCS) for DATA Packets in case of constant wifi", phyRate);
cmd.AddValue("apManager", "Adaptive algorithm to be used", apManager);
cmd.AddValue("stepsSize", "How many meters each iteration STA goes away", stepsSize);
cmd.AddValue("steps", "How many different distances to try", steps);
cmd.AddValue("stepsTime", "Time on each step", stepsTime);
cmd.AddValue("isTcp", "If true is TCP traffic if false is UDP", isTcp);
cmd.AddValue("useRtsCts", "toggle usage of RTS/CTS", useRtsCts);
cmd.AddValue("propagationModel", "Pick propagation model, refer to enum class PropagationModel for values", propagationModel);
cmd.AddValue("pcap", "Enable/disable PCAP Tracing", pcapTracing);
cmd.AddValue("tries", "Max number of attempts to send frame (Short and Long Retry limit for station)", tries);

Pentru a realiza grafice, trebuie sa instalam si pachetele de Python:

student@isrm-vm-2020:~$ sudo apt-get update
student@isrm-vm-2020:~$ sudo apt-get install python3-pip
student@isrm-vm-2020:~$ pip3 install matplotlib jupyter
student@isrm-vm-2020:~$ sudo ln -s ~/.local/bin/jupyter-notebook /usr/bin/jupyter-notebook

Pentru a lansa aplicatia de Jupyter Notebook, rulati urmatoarea comanda:

student@isrm-vm-2020:~$ jupyter-notebook

Task-uri

[01] Throughput în funcție de distanță al modelelor

Pentru acest task ne propunem să vedem evoluția throughputului în funcție de distanță. Implicit modelul pornește de la o distanță de 20 de metri între noduri și la fiecare secundă crește cu parametrul stepSize (implicit 5 metri). Scenariul din viața reală e simplu: un utilizator cu telefon conectat la un access point într-un mediu în care are clădiri, pereți, geamuri etc. și se deplasează în acest mediu în timp ce face video streaming.

AP-ul nu are algoritmi adaptivi, modelul este 802.11g așadar vom cere modelului să încerce cea mai mare rată suportată de acest standard - 54 Mbps. Modelul se schimbă prin setarea unui întreg conform schemei de mai jos:

enum PropagationModel {
  NAKAGAMI_3LOG = 0,
  LOG_DIST_LOSS = 1,
  THREE_LOG_DIST = 2,
  FRIIS = 3
};

Exemplu de rulare pentru Friis:

./waf --run "lab5 --apManager=ns3::ConstantRateWifiManager --phyRate=ErpOfdmRate54Mbps --propagationModel=3" 

Sarcina voastră este să plotați pe axa X distanța și pe axa Y throughput în Mbps - deci funcția throughput(distanță) pentru cele 4 modele prezentate mai sus în laborator.

Va puteti folosi de urmatorul template:

import copy
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
 
# Calea absoluta catre fisierul de date din care citim
# TODO - trebuie inlocuita cu calea corecta
DATA_FILE_NAKAGAMI = '/home/student/ns-3-dev/nakagami.txt'
DATA_FILE_LOG = '/home/student/ns-3-dev/log.txt'
DATA_FILE_LOG3 = '/home/student/ns-3-dev/log3.txt'
DATA_FILE_FRIIS = '/home/student/ns-3-dev/friis.txt'
columns = ['distance', 'throughput']
 
# Citim datele din fisier
# Argumentul delimiter precizeaza care este delimitatorul dintre coloane
# Argumentul skip_header precizeaza cate linii nu vor fi citite pornind cu inceputul fisierului
# Argumentul names este unul foarte util deoarece permite asocierea de nume pentru coloanele din fisier si
# de asemenea duce la un acces foarte usor al datelor in script. In acest exemplu, names va fi egal cu ['x', 'y']
# ceea ce inseamna ca putem accesa valorile din prima coloana prin sim_data['x'].
# Argumentul dtype setat specifica modul in care vor fi interpretate coloanele (string-urile ca string-uri, float-urile ca float-uri).
# In absenta acestui argument, valorile din coloane vor fi interpretate ca float.
sim_data_nakagami = np.genfromtxt(DATA_FILE_NAKAGAMI, delimiter=' ', names=columns, dtype=None)
sim_data_log = np.genfromtxt(DATA_FILE_LOG, delimiter=' ', names=columns, dtype=None)
sim_data_log3 = np.genfromtxt(DATA_FILE_LOG3, delimiter=' ', names=columns, dtype=None)
sim_data_friis = np.genfromtxt(DATA_FILE_FRIIS, delimiter=' ', names=columns, dtype=None)
 
def plot_distance_throughput_correlation(sim_data_nakagami, sim_data_log, sim_data_log3, sim_data_friis):
    # Apelul subplots poate fi folosit pentru a crea mai multe subgrafice in cadrul aceluiasi grafic sau in cadrul unor grafice diferite
    # Prin figsize se specifica dimensiunea graficului
    fig, ax = plt.subplots(figsize=(12,12))
    # Valori stilistice pentru grafic
    ax.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
    # Denumirile axelor Ox si Oy, precum si titlul graficului
    plt.xlabel('Distance (m)')
    plt.ylabel('Throughput [Mbps]')
    plt.title('Throughput distance correlation')
 
    # Aici este construit efectiv graficul. Campul label va fi folosit in cadrul legendei graficului
    # Daca in fisierul de output aveti toate valorile de distanta si de throughput, o sa remarcati ca pentru aceeasi distanta
    # o sa aveti mai multe valori de throughput (din cauza ca in scenariul din script se avanseaza cu cate 5 metri si se sta pe loc
    # o anumita durata de timp). Pentru simplitate, o sa alegem oricare valoare de throughput pentru o anumita distanta. Din moment ce
    # pentru fiecare distanta se printeaza 10 valori, este suficient sa ne folosim de Python slicing si sa luam valorile din lista din 
    # 10 in 10. sim_data_nakagami['distance'][::10] inseamna ca din lista sim_data_nakagami['distance'] o sa iau elementele de pe
    # pozitia 0, 10, 20 si tot asa.
    ax.plot(sim_data_nakagami['distance'][::10], sim_data_nakagami['throughput'][::10], label='Nakagami')
    ax.plot(sim_data_log['distance'][::10], sim_data_log['throughput'][::10], label='Log')
    ax.plot(sim_data_log3['distance'][::10], sim_data_log3['throughput'][::10], label='3 Log')
    ax.plot(sim_data_friis['distance'][::10], sim_data_friis['throughput'][::10], label='Friis')
    ax.legend()
 
    plt.show()
 
 
if __name__ == '__main__':
    plot_distance_throughput_correlation(sim_data_nakagami, sim_data_log, sim_data_log3, sim_data_friis)

[02] Packet delivery ratio UDP

Plotați packet delivery ratio la nivel fizic (tries=1) și la nivel MAC (tries=4,10) in functie de distanta pentru distanțele implicite din model, pentru trafic UDP. Prin packet delivery ratio se intelege raportul dintre numarul de pachete primite si numarul de pachete trimise (RX/TX).

Pentru tries=1 alegeți ultimele două coloane pentru a contoriza pachetele trimise/primite - sunt extrase la nivel PHY. Pentru tries=4,10 alegeți coloanele 3-4 pentru a contoriza pachetele trimise/primite - sunt extrase la nivel MAC.

Parametrul tries setează numărul maxim de încercări de transmitere a cadrului de date. Mai precis în model are loc următoarea setare pentru STA:

/* STA long retry count - relevant for DATA packets - how many retransmits for DATA */
Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (tries));
/* STA short retry count - relevant for RTS/CTS - max number of attempts for RTS packets */
Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (tries));

Dacă vreți să citiți mai multe detalii despre STA short retry count (SSRC) și STA long retry count (SRLC): https://support.mangocomm.com/docs/wlan-user-guide/mac/low_dcf.html

Analiză: dacă probabilitatea de livrare la nivel fizic este p, la MAC, după r încercări avem $PDR(p,r)= 1-(1-p)^r$. De ce? Comparați cu datele obținute mai sus.

[03] Packet delivery ratio TCP

Plotați capacitatea obținută de TCP pentru tries=1 la distanțe implicite din model. Justificați relația cu graficele precedente.

  • De ce la tries=1 (nu se reîncearcă), TCP nu atinge capacitatea maximă chiar când canalul este perfect, de exemplu la 20 m?
  • Activați RTS/CTS pentru acest caz (tries=1). De ce nu se îmbunătățește situația TCP-ului?

Plotați capacitatea si packet delivery ratio obținute de TCP pentru tries=4, 10. Explicați diferențele față de comportarea UDP în același setup. Observație: Capacitatea TCP crește când reîncercările la nivel MAC ascund pierderile.

Bonus: Vă puteți adăuga trace pentru pachete pierdute la nivel MAC în simulare astfel (vedeți și documentația ns-3 - All TraceSources):

Config::ConnectWithoutContext("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTxDrop", MakeCallback(&MacTxDrop));
Config::ConnectWithoutContext("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop", MakeCallback(&PhyRxDrop));

Pe callbackurile mai sus definiți două funcții simple care incrementează un contor global. Cu acest tracing: Analizați pachetele pierdute și justificați folosind timpii de emisie ai pachetelor.

[04 - Bonus] ACK L2 vs L4

Repetați experimentele cu TCP și UDP activând PCAP tracing. Urmăriți în PCAP momentul în care transmițătorul pachetelor de date UDP/TCP (adică AP-ul) nu mai primește ACK-urile de L2:

  • Cum reacționează TCP în acel caz, dar UDP?
  • Ce parametru observați că se schimbă în PCAP? Ce puteți spune despre puterea semnalului la recepție în acest caz?

În standardele pre-802.11n orice pachet wifi trebuie să primească un ACK la nivel MAC în timpul SIFS. Dacă nu se primește ACK în SIFS atunci pachetul se consideră pierdut și transmisia se reia pe baza setărilor SLRC SSRC. Dacă tot nu primim ACK declarăm cadrul pierdut. Chiar dacă pachetele de date se trimit cu dataRate=54Mbps ACK-ul se trimite cu cea mai slaba rata (din motive de robustețe) suportată de STA și AP negociată în beacon/probeRequest/probeReponse. Analizați aceste pachete pentru a identifica rata respectivă. Apoi analizați cu ce MCS (sau dataRate) se trimit pachetele UDP/TCP și ACK-urile de L2.

În 802.11n și 802.11ac unde se folosește agregare se folosește ceea ce se numește BlockACK - un pachet special care identifică pachetele agregate pe bază de sequence number și setează biți de 1 pentru sequence number-urile recepționate cu succes.

Nu confundați ACK-urile din TCP cu ACK-urile MAC ale WiFi.

isrm/laboratoare/new/05.txt · Last modified: 2020/03/30 19:02 by vlad.traista
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0