Mise en Forme

Ce chapitre traite de la mise en forme, des interfĂ©rences inter-symboles, du filtrage adaptĂ© et des filtres Ă  cosinus surĂ©levĂ©. À la fin, nous utilisons Python pour ajouter la mise en forme aux symboles BPSK. Vous pouvez considĂ©rer cette section comme la deuxiĂšme partie du chapitre sur les filtres, oĂč nous approfondissons les mises en forme.

InterfĂ©rence inter-symboles (ISI)

Dans le chapitre Filtres, nous avons appris que les symboles/impulsions en forme de blocs utilisent une quantitĂ© excessive de spectre, et que nous pouvons rĂ©duire considĂ©rablement la quantitĂ© de spectre utilisĂ©e en «  façonnant «  nos impulsions. Cependant, vous ne pouvez pas utiliser n’importe quel filtre passe-bas, sinon vous risquez d’obtenir des interfĂ©rences inter-symboles (ISI), oĂč les symboles se mĂ©langent et interfĂšrent les uns avec les autres.

Lorsque nous transmettons des symboles numĂ©riques, nous les transmettons dos Ă  dos (au lieu d’attendre un certain temps entre eux). Lorsque vous appliquez un filtre de mise en forme, il allonge l’impulsion dans le domaine temporel (afin de la condenser en frĂ©quence), ce qui entraĂźne un chevauchement des symboles adjacents. Ce chevauchement n’est pas un problĂšme, Ă  condition que votre filtre de mise en forme rĂ©ponde Ă  un critĂšre: la somme de toutes les impulsions doit ĂȘtre Ă©gale Ă  zĂ©ro Ă  chaque multiple de notre pĂ©riode de symbole \(T\), sauf pour l’une des impulsions. L’idĂ©e est mieux comprise grĂące Ă  la visualisation suivante:

_images/pulse_train.svg

Comme vous pouvez le voir, Ă  chaque intervalle de \(T\), il y a un pic d’une impulsion tandis que le reste des impulsions sont Ă  0 (elles traversent l’axe des x). Lorsque le rĂ©cepteur Ă©chantillonne le signal, il le fait au moment parfait (au pic des impulsions), ce qui signifie que c’est le seul point dans le temps qui compte. Il existe gĂ©nĂ©ralement un bloc de synchronisation des symboles au niveau du rĂ©cepteur qui garantit que les symboles sont Ă©chantillonnĂ©s aux pics.

Filtre AdaptĂ©ïƒ

Une astuce que nous utilisons dans les communications sans fil s’appelle le filtrage adaptĂ©. Pour comprendre le filtrage adaptĂ©, vous devez d’abord comprendre ces deux points:

  1. Les impulsions dont nous avons parlĂ© ci-dessus doivent seulement ĂȘtre parfaitement alignĂ©es au niveau du rĂ©cepteur avant l’échantillonnage. Jusqu’à ce moment-lĂ , l’existence d’une ISI n’a pas vraiment d’importance, c’est-Ă -dire que les signaux peuvent ĂȘtre envoyĂ©s dans l’air avec une ISI et tout va bien.

  2. Nous voulons un filtre passe-bas dans notre Ă©metteur pour rĂ©duire la quantitĂ© de spectre que notre signal utilise. Mais le rĂ©cepteur a Ă©galement besoin d’un filtre passe-bas pour Ă©liminer autant de bruit/interfĂ©rences que possible Ă  cĂŽtĂ© du signal. Par consĂ©quent, nous avons un filtre passe-bas Ă  l’émetteur (Tx) et un autre au rĂ©cepteur (Rx), puis l’échantillonnage se produit aprĂšs les deux filtres (et les effets du canal sans fil).

Ce que nous faisons dans les communications modernes est de diviser le filtre de mise en forme des impulsions de maniĂšre Ă©gale entre la Tx et la Rx. Il n’est pas nĂ©cessaire qu’il s’agisse de filtres identiques, mais, en thĂ©orie, le filtre linĂ©aire optimal pour maximiser le rapport signal/bruit en prĂ©sence d’un bruit blanc gaussien (AWGN) est d’utiliser le mĂȘme filtre Ă  la fois Ă  la Tx et Ă  la Rx. Cette stratĂ©gie est appelĂ©e le concept de « filtre adapté ».

Une autre façon d’envisager les filtres appariĂ©s est que le rĂ©cepteur corrĂšle le signal reçu avec le signal modĂšle connu. Le signal modĂšle est essentiellement constituĂ© des impulsions envoyĂ©es par l’émetteur, indĂ©pendamment des dĂ©phasages/amplitudes qui leur sont appliquĂ©s. Rappelez-vous que le filtrage est effectuĂ© par convolution, qui est en fait une corrĂ©lation (en fait, elles sont mathĂ©matiquement identiques lorsque le modĂšle est symĂ©trique). Ce processus de corrĂ©lation du signal reçu avec le modĂšle nous donne notre meilleure chance de rĂ©cupĂ©rer ce qui a Ă©tĂ© envoyĂ©, et c’est pourquoi il est thĂ©oriquement optimal. Par analogie, pensez Ă  un systĂšme de reconnaissance d’images qui recherche des visages Ă  l’aide d’un modĂšle de visage et d’une corrĂ©lation 2D :

_images/face_template.png

Diviser un Filtre en Deux

Comment fait-on pour diviser un filtre en deux? La convolution est associative, ce qui signifie:

\[(f * g) * h = f * (g * h)\]

Imaginons que \(f\) soit notre signal d’entrĂ©e, et que \(g\) et \(h\) soient des filtres. Filtrer \(f\) avec \(g\), puis \(h\) revient Ă  filtrer avec un filtre Ă©gal Ă  \(g * h\).

Rappelons également que la convolution dans le domaine temporel est une multiplication dans le domaine fréquentiel:

\[g(t) * h(t) \leftrightarrow G(f)H(f)\]

Pour diviser un filtre en deux, vous pouvez prendre la racine carrée de la réponse en fréquence.

\[X(f) = X_H(f) X_H(f) \quad \mathrm{where} \quad X_H(f) = \sqrt{X(f)}\]

Filtres de Mise en Forme SpĂ©cifiques

Nous savons que nous voulons :

  1. Concevoir un filtre qui rĂ©duit la largeur de bande de notre signal (pour utiliser moins de spectre) et toutes les impulsions sauf une doivent s’additionner Ă  zĂ©ro Ă  chaque intervalle de symbole.

  2. Diviser le filtre en deux, en plaçant une moitiĂ© dans la Tx et l’autre dans la Rx.

Examinons quelques filtres spécifiques qui sont couramment utilisés pour la mise en forme.

Filtre Cosinus SurĂ©levĂ©ïƒ

Le filtre de mise en forme le plus populaire semble ĂȘtre le filtre « cosinus surĂ©levé ». C’est un bon filtre passe-bas pour limiter la largeur de bande que notre signal occupera, et il a aussi la propriĂ©tĂ© de ramener la somme Ă  zĂ©ro Ă  des intervalles de \(T\):

_images/raised_cosine.svg

Notez que le graphique ci-dessus est dans le domaine temporel. Il représente la réponse impulsionnelle du filtre. Le paramÚtre \(beta\) est le seul paramÚtre du filtre à cosinus surélevé. Il détermine la vitesse à laquelle le filtre se réduit dans le domaine temporel, ce qui est inversement proportionnel à la vitesse à laquelle il se réduit en fréquence:

_images/raised_cosine_freq.svg

La raison pour laquelle on l’appelle le filtre Ă  cosinus surĂ©levĂ© est que le domaine de frĂ©quence lorsque \(\beta = 1\) est un demi-cycle d’une onde cosinusoĂŻdale, surĂ©levĂ©e pour s’asseoir sur l’axe des abscisses.

L’équation qui dĂ©finit la rĂ©ponse impulsionnelle du filtre Ă  cosinus surĂ©levĂ© est la suivante:

\[h(t) = \frac{1}{T} \mathrm{sinc}\left( \frac{t}{T} \right) \frac{\cos\left(\frac{\pi\beta t}{T}\right)}{1 - \left( \frac{2 \beta t}{T} \right)^2}\]

Vous trouverez de plus amples informations sur la fonction \(\mathrm{sinc}()\) ici.

Rappelez-vous: nous partageons ce filtre entre la Tx et la Rx de maniÚre égale. Entrez dans le filtre racine cosinus surélevé (RRC en anglais pour Root Raised Cosine)!

Filtre Racine Cosinus SurĂ©levĂ©ïƒ

Le filtre racine cosinus surĂ©levĂ© (RRC) est ce que nous mettons rĂ©ellement en Ɠuvre dans nos Tx et Rx. CombinĂ©s, ils forment un filtre normal Ă  cosinus surĂ©levĂ©, comme nous l’avons vu. Comme la division d’un filtre en deux implique une racine carrĂ©e dans le domaine de la frĂ©quence,la rĂ©ponse impulsionnelle devient un peu dĂ©sordonnĂ©e :

_images/rrc_filter.png

Heureusement, il s’agit d’un filtre trĂšs utilisĂ© et il existe de nombreuses implĂ©mentations, dont les suivantes in Python.

Autres Filtres de Mise en Forme des Impulsions

Parmi les autres filtres, citons le filtre gaussien, dont la rĂ©ponse impulsionnelle ressemble Ă  une fonction gaussienne. Il existe Ă©galement un filtre sinc qui est Ă©quivalent au filtre Ă  cosinus surĂ©levĂ© lorsque \(\beta = 0\). Le filtre sinc est plutĂŽt un filtre idĂ©al, c’est-Ă -dire qu’il Ă©limine les frĂ©quences nĂ©cessaires sans grande rĂ©gion de transition.

Facteur Roll-Off

Examinons le paramĂštre \(\beta\). Il s’agit d’un nombre compris entre 0 et 1, appelĂ© facteur de « roll-off » ou parfois « excĂšs de bande passante ». Il dĂ©termine Ă  quelle vitesse, dans le domaine temporel, le filtre se rĂ©duit Ă  zĂ©ro. Rappelez-vous que, pour ĂȘtre utilisĂ©e comme un filtre, la rĂ©ponse impulsionnelle doit dĂ©croĂźtre jusqu’à zĂ©ro des deux cĂŽtĂ©s :

_images/rrc_rolloff.svg

Plus le nombre de taps du filtre requis est Ă©levĂ©, plus \(\beta\) est faible. Lorsque \(\beta = 0\), la rĂ©ponse impulsionnelle n’atteint jamais complĂštement zĂ©ro, nous essayons donc d’obtenir \(\beta\) aussi bas que possible sans causer d’autres problĂšmes. Plus le roll-off est faible, plus nous pouvons crĂ©er un signal compact en frĂ©quence pour un dĂ©bit de symboles donnĂ©, ce qui est toujours important.

Une équation courante utilisée pour calculer approximativement la largeur de bande, en Hz, pour un débit de symboles et un facteur Roll-Off donnés est la suivante :

\[\mathrm{BW} = R_S(\beta + 1)\]

\(R_S\) est le dĂ©bit de symboles en Hz. Pour les communications sans fil, nous aimons gĂ©nĂ©ralement un roll-off entre 0,2 et 0,5. En rĂšgle gĂ©nĂ©rale, un signal numĂ©rique qui utilise le rythme symbole \(R_S\) va occuper un peu plus de \(R_S\) de spectre, y compris les parties positives et nĂ©gatives du spectre. Une fois que nous convertissons et transmettons notre signal, les deux cĂŽtĂ©s sont certainement importants. Si nous transmettons une QPSK Ă  1 million de symboles par seconde (MSps), elle occupera environ 1,3 MHz. Le dĂ©bit de donnĂ©es sera de 2 Mbps (rappelons que la QPSK utilise 2 bits par symbole), y compris les redondances du codage de canal et les en-tĂȘtes de trame.

Exercise Python

En guise d’exercice Python, filtrons et façonnons quelques impulsions. Nous utiliserons des symboles BPSK afin de faciliter la visualisation. Avant l’étape de mise en forme des impulsions, la BPSK consiste Ă  transmettre des 1 ou des -1 avec la partie « Q » Ă©gale Ă  zĂ©ro. Avec Q Ă©gal Ă  zĂ©ro, nous pouvons tracer la partie I uniquement, et c’est plus facile Ă  regarder.

Dans cette simulation, nous utiliserons 8 Ă©chantillons par symbole et, au lieu d’utiliser un signal de type onde carrĂ©e composĂ© de 1 et de -1, nous utiliserons un train d’impulsions. Lorsque vous faites passer une impulsion dans un filtre, la sortie est la rĂ©ponse impulsionnelle (d’oĂč le nom). Par consĂ©quent, si vous voulez une sĂ©rie d’impulsions, vous devez utiliser des impulsions entrecoupĂ©es de zĂ©ros pour Ă©viter les impulsions carrĂ©es.

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

num_symbols = 10
sps = 8

bits = np.random.randint(0, 2, num_symbols) # les données a envoyées de 1's and 0's

x = np.array([])
for bit in bits:
    pulse = np.zeros(sps)
    pulse[0] = bit*2-1 # définir la premiÚre valeur à 1 ou -1
    x = np.concatenate((x, pulse)) # ajouter les 8 échantillons au signal
plt.figure(0)
plt.plot(x, '.-')
plt.grid(True)
plt.show()
_images/pulse_shaping_python1.png

A ce stade, nos symboles sont toujours des 1 et des -1. Ne vous laissez pas emporter par le fait que nous avons utilisĂ© des impulsions. En fait, il est peut-ĂȘtre plus facile de ne pas visualiser la rĂ©ponse des impulsions, mais plutĂŽt d’y penser comme Ă  un tableau :

bits: [0, 1, 1, 1, 1, 0, 0, 0, 1, 1]
Symboles BPSK: [-1, 1, 1, 1, 1, -1, -1, -1, 1, 1]
Application de 8 échantillons par symbole: [-1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, ...]

Nous allons crĂ©er un filtre en cosinus surĂ©levĂ© en utilisant un \(\beta\) de 0.35, et nous allons le faire durer 101 taps pour donner au signal suffisamment de temps pour dĂ©croĂźtre jusqu’à zĂ©ro. Bien que l’équation du cosinus surĂ©levĂ© a besoin de la pĂ©riode du symbole et d’un vecteur temporel \(t\), nous pouvons supposer une pĂ©riode d’échantillon** de 1 seconde pour « normaliser » notre simulation. Cela signifie que notre pĂ©riode de symbole \(Ts\) est de 8 car nous avons 8 Ă©chantillons par symbole. Notre vecteur temps sera donc une liste d’entiers. Avec la façon dont l’équation du cosinus surĂ©levĂ© fonctionne, nous voulons que \(t=0\) soit au centre. Nous allons gĂ©nĂ©rer un vecteur temporel de 101 longueurs, commençant Ă  -51 et finissant Ă  +51.

# Créer notre filtre à base de cosinus surélevé
num_taps = 101
beta = 0.35
Ts = sps # Supposons que la fréquence d'échantillonnage soit de 1 Hz, donc que la période d'échantillonnage soit de 1, donc que la période du symbole soit de 8.
t = np.arange(-50, 51) # n'oubliez pas que le nombre final n'est pas inclus
h = 1/Ts*np.sinc(t/Ts) * np.cos(np.pi*beta*t/Ts) / (1 - (2*beta*t/Ts)**2)
plt.figure(1)
plt.plot(t, h, '.')
plt.grid(True)
plt.show()
_images/pulse_shaping_python2.png

Notez comment la sortie dĂ©croĂźt dĂ©finitivement vers zĂ©ro. Le fait que nous utilisions 8 Ă©chantillons par symbole dĂ©termine l’étroitesse de ce filtre et la vitesse Ă  laquelle il dĂ©croĂźt vers zĂ©ro. La rĂ©ponse impulsionnelle ci-dessus ressemble Ă  un filtre passe-bas typique, et il n’y a vraiment aucun moyen pour nous de savoir qu’il s’agit d’un filtre spĂ©cifique de mise en forme d’impulsion par rapport Ă  n’importe quel autre filtre passe-bas.

Enfin, nous pouvons filtrer notre signal \(x\) et examiner le rĂ©sultat. Ne vous focalisez pas trop sur l’introduction d’une boucle for dans le code fourni. Nous verrons pourquoi elle est lĂ  aprĂšs le bloc de code.

# Filtrer notre signal, afin d'appliquer la mise en forme
x_shaped = np.convolve(x, h)
plt.figure(2)
plt.plot(x_shaped, '.-')
for i in range(num_symbols):
    plt.plot([i*sps+num_taps//2+1,i*sps+num_taps//2+1], [0, x_shaped[i*sps+num_taps//2+1]])
plt.grid(True)
plt.show()
_images/pulse_shaping_python3.svg

Le signal rĂ©sultant est additionnĂ© Ă  partir d’un grand nombre de nos rĂ©ponses impulsionnelles, dont la moitiĂ© environ est d’abord multipliĂ©e par -1. Cela peut sembler compliquĂ©, mais nous allons le faire ensemble.

Tout d’abord, il y a des Ă©chantillons transitoires avant et aprĂšs les donnĂ©es Ă  cause du filtre et de la façon dont la convolution fonctionne. Ces Ă©chantillons supplĂ©mentaires sont inclus dans notre transmission, mais ils ne contiennent pas rĂ©ellement de « pics » d’impulsions.

DeuxiĂšmement, les lignes verticales ont Ă©tĂ© créées dans la boucle for pour des raisons de visualisation. Elles sont destinĂ©es Ă  montrer oĂč se trouvent les intervalles de \(Ts\). Ces intervalles reprĂ©sentent l’endroit oĂč ce signal sera Ă©chantillonnĂ© par le rĂ©cepteur. Observez que pour les intervalles \(Ts\) la courbe a la valeur exacte de 1.0 ou -1.0, ce qui en fait les points idĂ©aux dans le temps pour l’échantillonnage.

Si nous devions convertir et transmettre ce signal, le rĂ©cepteur devrait dĂ©terminer quand se trouvent les positions de \(Ts\), par exemple, en utilisant un algorithme de synchronisation des symboles. De cette façon, le rĂ©cepteur sait exactement quand il doit Ă©chantillonner pour obtenir les bonnes donnĂ©es. Si le rĂ©cepteur Ă©chantillonne un peu trop tĂŽt ou trop tard, il obtiendra des valeurs lĂ©gĂšrement faussĂ©es Ă  cause de l’ISI, et s’il se trompe, il obtiendra un tas de nombres bizarres.

Voici un exemple, créé Ă  l’aide de GNU Radio, qui illustre ce Ă  quoi ressemble le tracĂ© IQ (ou constellation) lorsque nous Ă©chantillonnons au bon et au mauvais moment. Les impulsions originales ont leurs valeurs binaires annotĂ©es.

_images/symbol_sync1.png

Le graphique ci-dessous représente la position idéale dans le temps pour échantillonner, ainsi que le tracé du QI :

_images/symbol_sync2.png

Comparez cela au pire temps d’échantillonnage. Remarquez les trois clusters dans la constellation. Nous Ă©chantillonnons directement entre chaque symbole; nos Ă©chantillons vont ĂȘtre trĂšs diffĂ©rents.

_images/symbol_sync3.png

Voici un autre exemple d’un mauvais temps d’échantillonnage, quelque part entre notre cas idĂ©al et le pire. Tenez compte des quatre groupes. Avec un SNR Ă©levĂ©, nous pourrions nous en sortir avec cet intervalle de temps d’échantillonnage, mais ce n’est pas conseillĂ©.

_images/symbol_sync4.png

Rappelez-vous que nos valeurs Q n’apparaissent pas sur le tracĂ© du domaine temporel parce qu’elles sont Ă  peu prĂšs nulles, ce qui permet aux courbes IQ de s’étendre horizontalement seulement.