Buscar

tcc-kelwin-final

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 60 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 60 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 60 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Kelwin Passos Ferreira
Desenvolvimento de uma biblioteca Python
para simulações computacionais de Sistemas
de Telecomunicações
Natal – RN
Abril de 2021
Kelwin Passos Ferreira
Desenvolvimento de uma biblioteca Python para
simulações computacionais de Sistemas de
Telecomunicações
Trabalho de Conclusão de Curso de Engenha-
ria de Computação da Universidade Federal
do Rio Grande do Norte, apresentado como
requisito parcial para a obtenção do grau de
Bacharel em Engenharia de Computação
Orientador: Prof. Dr. Luiz Felipe de
Queiroz Silveira
Co-orientador: MSc. Yuri Pedro dos
Santos
Universidade Federal do Rio Grande do Norte – UFRN
Departamento de Engenharia de Computação e Automação – DCA
Curso de Engenharia de Computação
Natal – RN
Abril de 2021
Kelwin Passos Ferreira
Desenvolvimento de uma biblioteca Python para
simulações computacionais de Sistemas de
Telecomunicações
Trabalho de Conclusão de Curso de Engenha-
ria de Computação da Universidade Federal
do Rio Grande do Norte, apresentado como
requisito parcial para a obtenção do grau de
Bacharel em Engenharia de Computação
Orientador: Prof. Dr. Luiz Felipe de
Queiroz Silveira
Co-orientador: MSc. Yuri Pedro dos
Santos
Trabalho aprovado. Natal – RN, 29 de Abril de 2021:
Prof. Dr. Luiz Felipe de Queiroz Silveira - Orientador
UFRN
Prof. Dr. Vicente Angelo de Sousa Junior - Convidado
UFRN
Prof. Dr. Joilson Batista de Almeida Rego - Convidado
UFRN
Natal – RN
Abril de 2021
Ferreira, Kelwin Passos.
 Desenvolvimento de uma biblioteca Python para simulações
computacionais de Sistemas de Telecomunicações / Kelwin Passos
Ferreira. - 2021.
 59f.: il.
 Monografia (Graduação) - Universidade Federal do Rio Grande
do Norte, Centro de Tecnologia, Departamento de Engenharia de
Computação e Automação, Engenharia de Computação, Natal, 2021.
 Orientador: Dr. Luiz Felipe de Queiroz Silveira.
 Coorientador: MSc. Yuri Pedro dos Santos.
 1. Simulação Computacional - Monografia. 2. Sistemas de
Telecomunicações - Monografia. 3. Python - Monografia. I.
Silveira, Dr. Luiz Felipe de Queiroz. II. Santos, MSc. Yuri
Pedro dos. III. Título.
RN/UF/BCZM CDU 004
Universidade Federal do Rio Grande do Norte - UFRN
Sistema de Bibliotecas - SISBI
Catalogação de Publicação na Fonte. UFRN - Biblioteca Central Zila Mamede
Elaborado por RAIMUNDO MUNIZ DE OLIVEIRA - CRB-15/429
Dedico este trabalho à minha família
AGRADECIMENTOS
Primeiramente gostaria de agradecer a Deus.
Agradeço aos meus pais Jânio e Java que sempre estiveram ao meu lado me apoiando
ao longo de toda a minha trajetória.
Agradeço ao meu irmão Mairon pelo apoio e amizade.
Agradeço ao meu co-orientador, Yuri Pedro dos Santos pela atenção e disponibili-
dade.
Agradeço ao meu orientador, Luiz Felipe de Queiroz Silveira pela oportunidade.
Agradeço aos docentes do curso de Engenharia de Computação da Universidade
Federal do Rio Grande do Norte por todo aprendizado e assistência na minha formação.
Agradeço aos meu amigos e colegas de curso que sempre estiveram ao meu lado,
pela amizade e apoio demonstrado.
“Mas, sejam fortes e não desanimem,
pois o trabalho de vocês será recompensado”
(Bíblia Sagrada, 2 Crônicas 15:7)
RESUMO
As simulações computacionais são de grande importância para área de sistemas de te-
lecomunicações, pois possibilitam o estudo de comportamento, criação de hipóteses e
representações de modelos. Apesar disso, a quantidade de ferramentas acessíveis que possi-
bilitam esse estudo ainda é pequena, pois estão incompletas ou necessitam de obtenção de
uma licença paga para uso. Por isso, este trabalho tem como objetivo o desenvolvimento de
uma biblioteca em Python para auxílio no desenvolvimento de simulações computacionais
de sistemas de telecomunicações. Foram desenvolvidas cinco funções, que dentre elas, três
modulações (BSPK,OFDM,OFDMA), um modelo de canal sem fio com desvanecimento de
Rayleigh e um codificador de canal de Hamming. Além disso, as funções serão analisadas
em termos de desempenho, com o objetivo de compará-las com funções semelhantes da
biblioteca CommPy, que é um conjunto de algoritmos de simulação de comunicação digital
desenvolvido em Python com uso dos pacotes NumPy e SciPy, para levantamento das
vantagens e desvantagens de cada biblioteca.
Palavras-chaves: Simulação Computacional; Sistemas de Telecomunicações; Python;
ABSTRACT
Computer simulations are of great importance for the area of telecommunications systems,
as they enable the study of behavior, creation of hypotheses and model representations. In
spite of this, the amount of tools to gain that make this study possible is still small, as it is
incomplete or prepared to obtain a paid licence for use. This work has a objective to develop
a Python library to aid in the development of computer simulations of telecommunications
systems. Five functions were developed, among which, three modulations (BSPK, OFDM,
OFDMA), a wireless channel model with Rayleigh fading and a Hamming channel encoder.
In addition, the functions will be analyzed in terms of performance, in order to compare
them with similar functions of the CommPy library, which is a set of digital communication
simulation algorithms developed in Python using the NumPy and SciPy packages, to
survey of the advantages and disadvantages of each library.
Keywords: Computational Simultion; Telecommunications Systems; Python;
LISTA DE ILUSTRAÇÕES
Figura 1 – Elementos de um sistema de comunicação . . . . . . . . . . . . . . . . 13
Figura 2 – (a) Sequência binária de dados. (b) Chaveamento de fase . . . . . . . . 15
Figura 3 – (a) Modulador BPSK (b) Detector coerente BPSK . . . . . . . . . . . 16
Figura 4 – Subportadoras de um sinal OFDM. Frequencia normalizada em relação
ao valor 1/T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Figura 5 – Relação do espectro de um sinal FDM e OFDM . . . . . . . . . . . . . 18
Figura 6 – Digrama de blocos OFDM . . . . . . . . . . . . . . . . . . . . . . . . . 18
Figura 7 – Constelação 16 QAM com código Gray . . . . . . . . . . . . . . . . . . 19
Figura 8 – Símbolo OFDM adicionado por um prefixo cíclico . . . . . . . . . . . . 19
Figura 9 – Ilustração dos conceitos do OFDM e OFDMA . . . . . . . . . . . . . . 20
Figura 10 – Diagrama de blocos do OFDMA . . . . . . . . . . . . . . . . . . . . . 21
Figura 11 – Exemplos de esquemas alocação . . . . . . . . . . . . . . . . . . . . . . 22
Figura 12 – Modelo de sistema de comunicação digital . . . . . . . . . . . . . . . . 25
Figura 13 – Simulação da modulação BPSK . . . . . . . . . . . . . . . . . . . . . . 38
Figura 14 – Simulação da demodulação BPSK . . . . . . . . . . . . . . . . . . . . . 38
Figura 15 – Distribuição das subportadoras . . . . . . . . . . . . . . . . . . . . . . 40
Figura 16 – Sinal após o canal e taxa de erro de bit . . . . . . . . . . . . . . . . . . 41
Figura 17 – Distribuição das subportadoras . . . . . . . . . . . . . . . . . . . . . . 42
Figura 18 – Distribuição das subportadoras . . . . . . . . . . . . . . . . . . . . . . 43
Figura 19 – Modulação OFDMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Figura 20 – Saída do codificador de Hamming . . . . . . . . . . . . . . . . . . . . . 44
Figura 21 – Saída do decodificador de Hamming . . . . . . . . . . . . . . . . . . . . 44
LISTA DE TABELAS
Tabela 1 – Análise de desempenho - Modulação BPSK . . . . . . . . . . . . . . . 39
Tabela 2 – Análise de desempenho - Modulação OFDM . . . . . . . . . . . . . . . 41
Tabela 3 – Análise de desempenho - Modulação OFDMA . . . . . . . . . . . . . . 44
Tabela 4 – Análise de desempenho - Codificador de Hamming . . . . . . . . . . . 45
Tabela 5 – Análise de desempenho - Canal . . . . . . . . . . . . . . . . . . . . . . 45
LISTA DE ABREVIATURAS E SIGLAS
PSK Phase Shift Keying
BPSK Binary Phase Shift Keying
FDM Frequency-Division Multiplexing
OFDM Orthogonal Frequency-Division Multiplexing
OFDMA Orthogonal Frequency-Division Multiple Access
QAM QuadratureAmplitude Modulation
SP Serial-Parallel Converter
IDFT Inverse Discrete Fourier Transform
IFFT Inverse Fast Fourier Transform
FFT Fast Fourier Transform
CP Cyclic Prefix
GWSSUS Gaussian Wide Sense Stationary Uncorrelated Scattering
WSSUS Wide Sense Stationary Uncorrelated Scattering
NRZ Non Return to Zero
BER Bit Error Rate
SUMÁRIO
1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3 Estrutura do Trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2 REFERENCIAL TEÓRICO . . . . . . . . . . . . . . . . . . . . . . . 15
2.1 Modulação de chaveamento binário de fase . . . . . . . . . . . . . . 15
2.1.1 Geração de sinais BPSK . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.1.2 Detecção coerente de sinais BPSK . . . . . . . . . . . . . . . . . . . . . . 16
2.2 Multiplexação por Divisão de Frequências Ortogonais . . . . . . . . 17
2.2.1 Transmissão e Recepção do sinal OFDM . . . . . . . . . . . . . . . . . . . 18
2.2.1.1 Transmissão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.1.2 Recepção . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3 Acesso Múltiplo por Divisão de Frequência Ortogonal . . . . . . . . 20
2.3.1 Transmissão e Recepcção OFDMA . . . . . . . . . . . . . . . . . . . . . . 21
2.3.1.1 Alocação de subportadoras . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3.1.2 Transmissão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.1.3 Recepção . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.4 Canal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.4.1 Técnica de Monte-Carlo . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.4.2 Canal multipercurso com desvanecimento Rayleigh . . . . . . . . . . . . . 24
2.5 Codificador de canal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.5.1 Código de Hamming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3 METODOLOGIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.1 Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.1.1 BPSK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.1.1.1 Modulação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.1.1.2 demodulação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.1.2 OFDM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.1.2.1 Modulação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.1.2.2 Demodulação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.1.3 OFDMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.1.3.1 Modulação e Demodulação . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.1.4 Canal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.1.5 Codificador Hamming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.1.5.1 Codificação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.1.5.2 Decodificação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4 RESULTADOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.1 Modulação e Demodulação BPSK . . . . . . . . . . . . . . . . . . . . 37
4.1.1 Análise de desempenho . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.2 Modulação e Demodulação OFDM . . . . . . . . . . . . . . . . . . . 39
4.2.1 Análise de desempenho . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3 Modulação OFDMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.3.1 Análise de desempenho . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.4 Codificador Hamming . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.4.1 Análise de desempenho . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.5 Canal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.5.1 Análise de desempenho . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5 CONCLUSÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
REFERÊNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
A APÊNDICE - CÓDIGOS FONTE . . . . . . . . . . . . . . . . . . . . 50
A.1 Classe BPSK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
A.2 Classe OFDM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
A.3 Classe OFDMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
A.4 Classe do Canal multipercurso com desvanecimento Rayleigh . . . . 56
A.5 Classe do codificador Hamming . . . . . . . . . . . . . . . . . . . . . 57
13
1 INTRODUÇÃO
Ao Longo das últimas décadas, a rápida expansão das tecnologias de comunicação foi
considerável. (LATHI B. P.; DING, 2012). O rádio, o telefone, a televisão, são exemplos de
algumas das várias aplicações dos sistemas de comunicação, mesmo que algumas já pararam
de funcionar, outras como a internet comandam como nos comunicamos atualmente. Sendo
assim, a lista de aplicações que envolvem a utilização comunicações é muito grande.
A Figura 1 ilustra um diagrama de blocos que representa um modelo básico de
um sistema de comunicação. O transmissor, converte o sinal da mensagem em uma forma
adequada para a transmissão no canal, o canal transporta o sinal de mensagem e a entrega
para o receptor (HAYKIN; MOHER, 2008). Devido às imperfeições do canal o sinal é
distorcido e ao longo da transmissão do canal são adicionados ruídos e sinais de interferência
de outras fontes, e por isso se tem uma versão corrompida do sinal transmitido. O receptor
possui a tarefa de operar no sinal recebido, de forma a produzir uma estimativa do sinal
original da mensagem para o usuário da informação (HAYKIN; MOHER, 2008).
Figura 1 – Elementos de um sistema de comunicação.
Fonte – (HAYKIN; MOHER, 2008, p. 15)
Por meio da simulação computacional, um modelo de sistema de comunicação pode
ser analisado, possibilitando incorporar características reais, de modo a obter resultados
estatísticos que descrevam o seu comportamento em diversos tipos de condições. Desta
forma, a simulação não é somente a construção do modelo, mas também um método
experimental que busca representar, criar hipóteses e estudar comportamentos.
Apesar da grande importância das simulações nessa área, ainda é difícil encontrar
ferramentas gratuitas e completas que auxiliem nessa finalidade. Com isso, o propósito deste
trabalho é contribuir com desenvolvimento de modelos para simulações computacionais
de sistemas de telecomunicação, além de analisar em termos de desempenho as funções
criadas.
Capítulo 1. Introdução 14
1.1 Motivação
Diante da importância das simulações computacionais em sistemas de telecomu-
nicações, se faz necessário o desenvolvimento de ferramentas que auxiliem e contribuam
com o avanço da área. Atualmente já existem ferramentas para simulações de sistemas
de comunicação, porém, parte delas necessita de compra de licença para uso ou estão
incompletas, diante deste problema, é proposta a criação de uma biblioteca em Python
para simulações computacionais de sistemas de telecomunicações.
1.2 Objetivos
Este projeto tem como objetivo contribuir com a criação de uma biblioteca em
Python, para auxílio no desenvolvimento de simulações computacionais de sistemas de
telecomunicações, serão desenvolvidas as seguintes funções:
• Modulador e Demodulador BPSK.
• Modulador e Demodulador OFDM.
• Modulador e Demodulador OFDMA.
• Canal com desvanecimento Rayleigh.
• Codificador de canal Hamming.
De modo que cada uma das funções desenvolvidas seja fiel ao seu referencial teórico,
e além disso, serão analisadas em termos de desempenho para fins de comparação.
1.3 Estruturado Trabalho
Este trabalho está organizado em cinco capítulos, no qual, o primeiro capítulo
apresenta um introdução sobre o tema, apresentando a motivação e objetivos.
Em sequência o Capítulo 2 aborda o referencial teórico dos sistemas de comunicação
usados nas simulações.
O Capítulo 3, por sua vez, explica a metodologia usada para desenvolvimento das
simulações na linguagem Python.
O Capítulo 4 apresenta os resultados das simulações.
E finalmente, o Capítulo 5 traz as conclusões e contribuições deste trabalho.
15
2 REFERENCIAL TEÓRICO
Neste capítulo, são apresentados os conceitos fundamentais relacionados a modulação
de chaveamento binário de fase (BPSK), as técnicas de transmissão de dados Multiplexação
ortogonal por divisão em freqüência (OFDM) e sua versão multiusuário, a Multiplexação
ortogonal por divisão em freqüência de acesso multiplo (OFDMA), além de um canal
multipercurso com desevanecimento de Rayleigh e um codificador de canal de Hamming.
2.1 Modulação de chaveamento binário de fase
O método de modulação de chaveamento binário de fase (BPSK) é uma forma
de modulação binária, na qual a frequência e a amplitude da portadora são preservadas
constantes e a fase da portadora é mantida em dois possíveis valores para representar os
símbolos 1 e 0 (por exemplo, 0◦ e 180◦).
Para representar os símbolos 0 e 1, são utilizados dois sinais s1(t) e s2(t), que podem
ser definidos como:
si(t) =

√
2Eb
Tb
cos(2πfct), para o símbolo 1, i = 1√
2Eb
Tb
cos(2πfct+ π) = −
√
2Eb
Tb
cos(2πfct), para o símbolo 0, i = 2
(2.1)
na qual 0 ≤ t ≤ Tb, com Tb representando a duração do bit, Eb representando a
energia por bit do sinal transmitido e fc é a frequência da portadora (HAYKIN; MOHER,
2008). A Figura 2(b) mostra a forma de onda BPSK corresponde à sequencia binária de
dados de entrada da Figura 2(a).
Figura 2 – (a) Sequência binária de dados. (b) Chaveamento de fase.
Fonte – (HAYKIN; MOHER, 2008, p. 277)
Segundo (HAYKIN; MOHER, 2008) para geração e detecção de um sinal BPSK, é
necessário seguir os passos ilustrados na Figura 3, que são explicados em seguida.
Capítulo 2. Referencial Teórico 16
Figura 3 – (a) Mobudalor BPSK (b) Detector coerente BPSK.
Fonte – (HAYKIN; MOHER, 2008, p. 279)
2.1.1 Geração de sinais BPSK
1. Codificador de nìvel sem retorno para zero: em que a sequência binária de dados na
entrada é codificada para a forma polar com os símbolos 0 e 1 representados pelos
níveis de amplitude −
√
Eb e
√
Eb respectivamente.
2. Modulador de produto: que multiplica a onda binária codificada em nível pela onda
portadora senoidal
√
2
Tb
cos(2πfct) para produzir o sinal BPSK.
2.1.2 Detecção coerente de sinais BPSK
1. Modulador de produto: que também multiplica a onda binária codificada em nível
pela onda portadora senoidal
√
2Eb
Tb
cos(2πfct).
2. Filtro passa-baixa: para remover as as componentes centradas em 2fc e passar as
componentes de freqüência nula.
3. Amostrador: amostra uniformemente a saída do filtro passa-baixa em t = iTb, na
qual i = 0, ±1, ±2,... .
4. Dispositivo de tomada de decisão: compara os valores amostrados do filtro passa-
baixa com um limiar, se o limiar não for ultrapassado o dispositivo escolhe o símbolo
0, caso contrário, o símbolo 1.
O receptor é dito ser coerente, no sentido de que o sinal senoidal de referência
aplicado ao modulador de produto no demodulador está em sincronismo de fase (e, de
freqüência) com a onda portadora utilizada no modulador (HAYKIN; MOHER, 2008).
Capítulo 2. Referencial Teórico 17
2.2 Multiplexação por Divisão de Frequências Ortogonais
O esquema de modulação baseado na multiplexação por divisão de frequências
ortogonais (OFDM), é uma técnica que usa a sua banda dividida em várias portadoras
ortogonais, que são chamadas de subportadoras, e habitualmente são equidistantes na
frequência.
A técnica OFDM fundamenta-se na conversão de um fluxo de dados em série que
possui alta taxa de transmissão, em sub-fluxos paralelos de dados em várias subporta-
doras que são moduladas (geralmente em QAM ou PSK), que possuem baixa taxa de
transmissão de acordo com a maior quantidade de destas empregadas. Esta redução na
taxa de transmissão (aumento na duração dos simbolos) causa uma menor sensibilidade à
seletividade em frequência (PINTO; ALBUQUERQUE, 2002).
No sistema OFDM, o espaçamento estre as subportadoras é selecionado de forma
que cada subportadora seja locada em pontos de cruzamento de zero do espectro das
demais (PINTO; ALBUQUERQUE, 2002), conforme ilustrado na Figura 4, sendo T a
duração de um símbolo.
Figura 4 – Subportadoras de um sinal OFDM. Frequencia normalizada em relação ao valor
1/T.
Fonte – (PINTO; ALBUQUERQUE, 2002)
A transmissão OFDM surgiu como uma evolução da FDM (Multiplexação por divi-
são de frequência), que para separar as frequências dos sinais, usava bandas de segurança,
que causavam uma perda de espectro. O sistema OFDM com o uso de subportadoras otogo-
nais, traz uma grande eficiência espectral em relação ao FDM (PINTO; ALBUQUERQUE,
2002) como mostrado na Figura 5.
Capítulo 2. Referencial Teórico 18
Figura 5 – Relação do espectro de um sinal FDM e OFDM.
Fonte – (PINTO; ALBUQUERQUE, 2002)
2.2.1 Transmissão e Recepção do sinal OFDM
A Figura 6 apresenta o diagrama em blocos de um sistema OFDM, com o uso da
IFFT/FFT no transmissor e receptor, respectivamente.
Figura 6 – Digrama de blocos OFDM.
Fonte – Própio Autor
2.2.1.1 Transmissão
Primeiramente, é realizada uma conversão série-paralelo(SP) na cadeia de dados
obtida, os bits irão ser agrupados em conjuntos de palavras, o tamanho destas palavras
varia de acordo com a quantidade de bits por simbolo, após isso, as palavras são mapeadas,
em um tipo específico, como por exemplo QAM ou PSK, gerando um conjunto de símbolos
complexos representados por uma constelação, e cada ponto da constelação corresponde a
um símbolo, que representa uma palavra de tamanho dependente do tipo de modolação
usado (CHO et al., 2010). A Figura 7 ilustra um exemplo de uma constelação de modulação
16 QAM usando codificação de Gray.
Capítulo 2. Referencial Teórico 19
Figura 7 – Constelação 16 QAM com código Gray.
Fonte – (BROWN; PASUPATHY; PLATANIOTIS, 2006)
Os símbolos complexos determinam os pontos da constelação de cada subportadora.
Após isto, as subportadoras são somadas por uma implementação computacional eficiente
da IDFT, a IFFT , que transforma os símbolos para o dominio do tempo (CHO et al.,
2010), em seguida é realizada uma conversão paralelo-série e é adicionado o prefixo cíclico,
que é uma extensão cíclica do símbolo OFDM para o intervalo de guarda , Ou seja, inserir
no início do símbolo OFDM o conteúdo da parte final do mesmo (ARNDT, 2012) de forma
a evitar interferência intersimbólica, como ilustra a Figura 8.
Figura 8 – Símbolo OFDM adicionado por um prefixo cíclico.
Fonte – (ARNDT, 2012)
2.2.1.2 Recepção
Como ilustrado na Figura 6, inicialmente é retirado o prefixo cíclico (CP), em
seguida é usada a Transformada Rápida de Fourier (FFT), para transformar o sinal de volta
para o domínio da frequência (CHO et al., 2010), logo após, é feita uma estimação do canal,
pois as subportadoras ainda estão sujeitas a perdas de ortogonalidade e distorções devido
ao canal, estas interferências causam alterações na amplitude da constelação (Coleri et al.,
Capítulo 2. Referencial Teórico 20
2002), a técnica de estimação de canal usada neste trabalho é a inserção de subportadoras
pilotos no símbolo OFDM , as subportadoras pilotos não carregam nenhuma informação
útil, apenas o conteúdo destas é conhecido pelo receptor, tornando possível obter a função
de transferência do canal (Coleri et al., 2002). Para realizar a estimação do canal, é
necessário primeiramente determinar o desvanecimento nas subportadoras pilotos por meio
de um estimador. Como esse valor é conhecido pelo receptor é possível estimar as variações
do sinal recebido , e em seguida a estimação para todas as subportadoras de informação
útil (CHO et al., 2010), e por fim é realizado o demapeamentoe conversão paralelo-serie.
2.3 Acesso Múltiplo por Divisão de Frequência Ortogonal
O sistema OFDMA é muito similar ao OFDM, no qual a maior diferença entre os
dois sistemas, é que ao invés de serem alocadas todas as subportadoras disponíveis para um
único usuário como ocorre no OFDM, o OFDMA aloca um subconjunto de subportadoras
para cada um dos usuários, com o objetivo de uma transmissão simultânea de múltiplos
usuários (AL-RAWI, 2017), esta diferença é ilustrada na Figura 9.
Figura 9 – Ilustração dos conceitos do OFDM e OFDMA.
Fonte – (PARKER, 2017)
Capítulo 2. Referencial Teórico 21
A alocação de subconjuntos de subportadoras para os usuários pode variar, na
próxima subseção será abordado as duas principais estratégias para alocação.
2.3.1 Transmissão e Recepcção OFDMA
Como dito anteriormente, o sistema OFDMA é semelhante ao OFDM, o que difere é
que no ofdma existem multiplos usuários e as subportadoras são alocadas em subconjuntos
para cada usuário. Dito isto, o diagrama de blocos a seguir ilustra um sistema OFDMA.
Figura 10 – Diagrama de blocos do OFDMA.
Fonte – (ALI; SUKAR; PAL, 2014)
Como pode ser visto na Figura 10, compararado ao digrama de blocos do OFDM,
se tem a adição de um novo bloco, o do mapeamento de subportadoras.
2.3.1.1 Alocação de subportadoras
Existem dois principais de como distribuir as subportadoas aos usuários (MORELLI;
KUO; PUN, 2007), como é ilustrado na Figura 11. Neste exemplo é usado 16 subportadoras,
4 usuários e 4 símbolos por usuário como parâmetros do sistema, no primeiro esquema
Figura 11 (a) as subportadoras são associadas a cada usuário em grupos adjacentes, a
principal desvantagem dessa abordagem é que ela não explora a diversidade de frequência
oferecida pelo canal, uma vez que um desvanecimento profundo pode atingir um número
substancial de subportadoras de um determinado usuário (MORELLI; KUO; PUN, 2007),
como solução para isto, pode-se adotar o esquema que está ilustrado na Figura 11 (b),
em que as subportadoras são espaçadas uniformemente sobre a largura de banda de sinal,
explorando totalmente a diversidade de frequência do canal.
Capítulo 2. Referencial Teórico 22
Figura 11 – Exemplos de esquemas alocação.
Fonte – (MORELLI; KUO; PUN, 2007)
2.3.1.2 Transmissão
Para a etapa de transmissão, primeiramente realiza-se uma conversão série-paralelo
(SP) na cadeia de dados obtida, os bits irão ser agrupados em conjuntos de palavras, o
tamanho destas palavras varia de acordo com a quantidade de bits por simbolo , após
isso, as palavras são mapeadas , em um tipo específico como por exemplo, QAM ou PSK,
gerando um conjunto de simbolos complexos representados por uma constelação, e cada
ponto da constelação corresponde a um símbolo que representa uma palavra de tamanho
dependente do tipo de modolação usado. Após a isto, as subportadoras são somadas por
uma implementação computacional eficiente da IDFT, a IFFT , que transforma os símbolos
para o dominio do tempo (CHO et al., 2010), em seguida é há uma conversão paralelo-série
e é adicionado o prefixo cíclico, que é uma extensão cíclica do símbolo OFDMA para o
intervalo de guarda, Ou seja, inserir no início do símbolo OFDMA o conteúdo da parte
final do mesmo (ARNDT, 2012)
2.3.1.3 Recepção
Como ilustrado na Figura 10, inicialmente é retirado o prefixo cíclico (CP), em
seguida é usada a Transformada Rápida de Fourier (FFT), para transformar o sinal de
volta para o domínio da frequência, logo após é feita uma estimação do canal, pois as
subportadoras ainda estão sujeitas a perdas de ortogonalidade e distorções devido ao
canal, estas interferências causam alterações na amplitude da constelação (Coleri et al.,
2002), a técnica de estimação de canal usada neste trabalho é a inserção de subportadoras
pilotos no símbolo OFDMA. As portadoras pilotos não carregam nenhuma informação útil,
apenas o conteúdo destas é conhecido pelo receptor, tornando possível obter a função de
transferência do canal (Coleri et al., 2002). Para realizar a estimação do canal, é necessário
primeiramente determinar o desvanecimento nas subportadoras pilotos por meio de um
Capítulo 2. Referencial Teórico 23
estimador . Como esse valor é conhecido pelo receptor é possível estimar as variações do
sinal recebido, e em seguida a estimação para todas as subportadoras de informação útil
(CHO et al., 2010), e por fim é realizado o demapeamento e conversão paralelo-serie.
2.4 Canal
Um canal é o meio físico que se comporta parcialmente como um filtro que, em
geral, atenua o sinal e distorce as formas de onda transmitidas. A atenuação do sinal
aumenta com o comprimento do canal, variando de uma pequena porcentagem, no caso
de curtas distâncias, a ordens de magnitude, no caso de comunicação interplanetária
(LATHI B. P.; DING, 2012). Quando a resposta impulsiva do canal móvel é modelado
como um processo gaussiano de valor complexo e média nula, este é chamado de canal com
desvanecimento Rayleigh. O tipo de distorção introduzida pelo canal pode ser classificada
em desvanecimento plano ou desvanecimento seletivo em frequência, e esta depende da
relação da largura de banda do sinal transmitido com relação a banda de coerência do
canal. Se a largura de banda do sinal for maior que a banda de coerência do canal, o
desvanecimento é seletivo em frequência, caso contrário, o desvanecimento é plano.
A modelagem e caracterização de canais são bastante estudados no campo da
pesquisa de sistemas de comunicações. O grande motivo disso é devido as característi-
cas de propagação deste meio que causam grande parte dos problemas existentes nos
sistemas móveis. Por outro lado, existe uma complexidade considerável desenvolver estas
característcas, visto que, possuem componentes de difícil tratamento formal, que possuem
características aleatoriamente variantes no tempo. Por isso a utilização de técnicas de
simulação, é fundamental.
2.4.1 Técnica de Monte-Carlo
A técnica de simulação de monte-carlo foi originalmente proposta por (SCHULZE,
1989), ao longo dos anos, foi estudada e usada em vários trabalhos que envolviam simulações
de sistemas de comunicações com canais GWSSUS. Esta técnica tem como fundamento
um modelo estocástico que reflete diretamente a estrutura de múltiplos percursos do canal
móvel. A geração da resposta do canal é dada pela superposição linear de N percursos
elementares, individualmente caracterizados pelo valor de atraso τn, deslocamento de
doppler υn e amplitude complexa an (GUIMARÃES; PINTO, 2001), a resposta ao impulso
do canal simulado é dada por:
h(τ, t) =
√
1
N
N−1∑
n=0
anδ(τ − τn)ej2πυnt (2.2)
Capítulo 2. Referencial Teórico 24
Em que, as amplitudes complexas an são variáveis aleatórias não nulas de media nula
e variância unitária, já as variáveis υn e τn são aleatórias independentes e indenticamente
distribuídas, em que, no geral são consideradas independentes entre si, e em muitas
aplicações, a geração da variável τn é dispensada, para usar um modelo de retardos
pré-fixados (GUIMARÃES; PINTO, 2001).
É demonstrado em (Muller, 1994) que, considerando as hipóteses acima, o pro-
cesso aleatório gerado em (2.2) possui propriedades estatisticas de segunda ordem que
correspondem às características da resposta de um canal WSSUS.
2.4.2 Canal multipercurso com desvanecimento Rayleigh
Um canal multipercurso com desvanecimento Rayleigh pode ser simulado por meio
do método do Ruído branco filtrado, passando um ruído braco gaussiano por meio de um
filtro gaussiano com frequência igual a raiz quadrada do espectro Doppler, o espectro de
potência Doppler para o desvanecimento de Rayleigh pode ser representado pela seguinte
equação (CLARKE, 1968):
S(v) = 1
πfd
√
1− ( v
fd
)2
(2.3)
Em que v é a mudança de frequência em relação à frequência portadora e fd é o
deslocamento Doppler. Segundo (SAVAUX, 2013) para simulação do canal é necessario
seguir os seguintes passos.
Para cada percurso e para o processo de tamanho N:
1. Gerar um processo Gaussiano de tamanho N.
2. Realizar uma DFT do processo.
3. Filtrar por meio daraiz quadrada do espectro Doppler a saída do item anterior
4. Realizar uma IDFT para obtenção dos coeficientes do canal.
2.5 Codificador de canal
O canal de comunicação está sujeito a interferências, ruído e estabimento, podendo
causar alteração, ou até mesmo, perda de parte da mensagem. Desta forma é necessário
prover uma forma capaz de transmitir informações de uma extremidade a outra do sistema,
com nivel de confiabilidade e qualidade aceitáveis. O controle de erro para integridade de
dados pode ser exercido por meio de correção direta de erros (FEC) (HAYKIN, 2004). A
Figura 12 demonstra um modelo de sistema de comunicação digital que usa esta abordagem,
Capítulo 2. Referencial Teórico 25
em que o codificador de canal adiciona redundância aos bits de mensagem com uma regra
predefinida e o decodificador de canal explora essa redundância para escolher quais bits
da mansegem foram transmitidos de verdade.
Figura 12 – Modelo de sistema de comunicação digital.
Fonte – próprio autor
A meta conjunta do codificador e decodificador de canal é minimizar o efeito de
ruído do canal, ou seja, o número de erros entre a entrada do codificador de canal (originado
da fonte) e a saída do decodificador de canal (entregue ao usuário) é minimizado (HAYKIN,
2004).
2.5.1 Código de Hamming
O código de Hamming foi desenvolvido por Richard Hamming e é considerado
um código de bloco linear, é uma codificação que é usada no processaento de sinal e em
telecomunicações. Seu uso permite o armazenamento e transferência de dados de forma
segura e eficiente. Os modelos de código de Hamming mais usados em telecomunicações,
são generalizações do Hamming(7,4) que pode corrigir erros de até um bit.
O código Hamming se baseia em inserir bits de paridade sobre uma mensagem de
dados de tamanho fixo. Em cada palavra de dados, de comprimento n, são inseridos um
número fixo k, de bits de paridade, gerando uma mensagem de comprimento N = n+k.
Permitindo a detecção e correcção dos erros.
A relação entre N e k é descrita pela seguinte equação:
Capítulo 2. Referencial Teórico 26
N = 2k − 1
E o tamanho da palavra de dados é:
n = 2k − k − 1
27
3 METODOLOGIA
Por meio da linguagem Python, foi proposto contribuir com o desenvolvimento de
funções que auxiliem as simulações de sistemas de telecomunicações, ao todo, as contribui-
ções foram: Modulador e Demodulador BPSK, Transmissor e Receptor OFDM/OFDMA,
Canal com desvanecimento de Rayleigh e um codificador de canal de Hamming.
Como dito anteriormente, a linguagem de programação usada é o Python, que é
uma liguagem livre e de código aberto, possui uma sintaxe simples, pois foi projetada com a
idéia de enfatizar a importância do esforço do programador sobre o esforço computacional.
É uma linguagem de propósito geral de alto nível, suporta o paradigma orientado a objetos.
Apresenta tipagem dinâmica e uma de suas principais particularidades é a fácil leitura
e de código e exige menos linhas de código se comparada com outras linguagems de
programação.
Numpy1 é uma biblioteca Python que é usada principalmente para cálculos em
arrays multidimensionais. Fornece um grande conjunto de funções e operações que auxiliam
a execução de diversos tipos de cálculos numéricos.
Scipy2 é uma biblioteca Python que possui várias ferramentas dedicadas a problemas
comuns em computação científica. Seus diferentes sub-módulos correspondem a várias
aplicações, como por exemplo interpolação, integração, otimização, processamento de
imagens, estatísticas, etc.
Matplotlib3 é uma biblioteca Python desenvolvida para geração de gráficos e vizua-
lização de dados, foi usada neste projeto para apresentação dos resultados e visualização
dos dados, de forma a ajudar na compreensão do que foi desenvolvido.
IPython4 é um interpretador interativo, que é focado na linguagem Python, foi
usado pois possui funções para medição de tempo de um trecho de código.
3.1 Implementação
As simulações foram inspiradas nos diagramas de blocos mostrados no capítulo
anterior.
1https://numpy.org/
2https://www.scipy.org/
3https://matplotlib.org/
4https://ipython.org/
Capítulo 3. Metodologia 28
3.1.1 BPSK
A classe que simula a BPSK possui dois métodos (modulação e demodulação) e
recebe como parâmetros:
• energy_per_bit, que representa a energia por bit.
• bit_duration, que representa a duração do bit.
• carrier_frequency, que representa a frequência da portadora.
• sampling_frequency, que representa a frequência de amostragem.
Cabe considerar, que a duração do bit bit_duration, para esse modelo, é constante
para todos os bits de entrada, portanto foi possível determinar o parâmetro de amplitude√
2Eb
Tb
da portadora no método de inicialização da classe:
1 import numpy as np
2 import scipy. signal as signal
3
4 class bpsk:
5 def __init__ (self , energy_per_bit , bit_duration ,
carrier_frequency , sampling_frequency ):
6
7 self. carrier_frequency = carrier_frequency
8 self. bit_duration = bit_duration
9 self. energy_per_bit = energy_per_bit
10 self. sampling_frequency = sampling_frequency
11 self. sqrt_Eb_Bd = np.sqrt ((2* self. energy_per_bit )/self.
bit_duration )
Listing 3.1 – Classe BPSK
3.1.1.1 Modulação
O primeiro passo para desenvolvimento do método de modulação BPSK, foi a
codificação da sequência binária de dados por meio de um conversor sem retorno para zero
(NRZ), de forma a alterar a entrada de simbolos compostos por 0 e 1 para a forma polar,
representados pelos niveis de amplitude -1 e 1, após isso, foi necessário criar um array
para representar as amostras do tempo, com a distribuição de acordo com a frequência
de amostragem, tamanho da sequência binária e duração do bit, em seguida, é necessário
fazer com que o array obtido na codificação NRZ seja disposto também no tempo, e por
fim, é realizada a multiplicação pela onda portadora senoidal, como demonstrado no trecho
de código a seguir:
Capítulo 3. Metodologia 29
1 def modulation (self , bit_sequence ):
2
3 nrtn = 2* bit_sequence - 1
4 t = np. linspace (0, len( bit_sequence )*self. bit_duration ,
self. sampling_frequency *len( bit_sequence ))
5 nrtn_fs = np. repeat (nrtn , self. sampling_frequency )
6 return nrtn_fs *( self. sqrt_Eb_Bd *np.cos (2* np.pi*self.
carrier_frequency *t))
Listing 3.2 – Método de modulação BPSK
3.1.1.2 demodulação
Para o método de demodulação BPSK, foi necessário criar um array para representar
as amostras do tempo de acordo com a freqûencia de amostragem, para logo após, realizar a
multiplicação do sinal recebido com onda portadora senoidal, em seguida é usada a função
signal.butter da biblioteca signal, para obtenção dos coeficientes do filtro passa-baixa
e filtragem através da função signal.filtfilt, após isso, é feita a amostragem através da
obtenção da média da amplitude do sinal dentro do período de cada bit, para por fim,
aplicar o dispositivo de tomada de decisão, por meio da função where da biblioteca numpy,
como pode-se verificar a seguir:
1 def demodulation (self ,bpsk_sign ,cutoff ,order =2):
2 nb = len( bpsk_sign )// self. sampling_frequency
3 t = np. linspace (0,nb*self. bit_duration ,len( bpsk_sign ))
4
5 carrier = self. sqrt_Eb_Bd * np.cos (2* np.pi * self.
carrier_frequency * t)
6 mult = bpsk_sign * carrier
7
8 w = ( cutoff ) / (self. sampling_frequency / 2)
9 b, a = signal . butter (order , w, ’low ’)
10 output = signal . filtfilt (b, a, mult)
11 sum_split = np.mean(np.split(output ,nb), axis = 1,dtype=np.
float32 )
12 decision = np.where( sum_split > 0, 1, 0)
13
14 return decision
Listing 3.3 – Método de demodulação BPSK
Capítulo 3. Metodologia 30
3.1.2 OFDM
A classe que simula a OFDM possui dois métodos (modulação e demodulação) e
recebe como parâmetros:
• subcarrier_spacing, que representa o espaçamento entre as subportadoras.
• sampling_rate, que representa a taxa de amostragem.
• n_subcarriers, que representa a quantidade de subportadoras.
• n_pilots, que representa a quantidade de subportadoras piloto.
• pilot_value, que representa o valor queas subportadoras pilotos carregam.
• cp_length, que representa o tamanho do prefixo cíclico, em unidades de subportado-
ras.
• bits_per_symbol, que representa a quantidade de bits que um símbolo carrega.
No método de inicialização da classe OFDM, além da atribuição dos parâmetros, é
realizado um cálculo para definição das posições das subportadoras piloto e subportadoras
de dados:
1 self. FFTsize = int(np. round (self. sampling_rate /self.
subcarrier_spacing ))
2 self. sub_carriers = np. arange (self. FFTsize )
3 self. pilot_carriers = np. linspace (0, self.FFTsize -1, num=self.
n_pilots ,dtype=int)
4 self. subcarriers_no_pilots = np. delete (self. sub_carriers , self.
pilot_carriers )
5 self. data_carriers = self. subcarriers_no_pilots [:( self.
n_subcarriers -self. n_pilots ) ,...]
Listing 3.4 – Definição das subportadoras
Além disso, também é definido o vetor de símbolos mapeados, em que, o tipo de
mapeamento depende da quantidade de bits por símbolo, caso seja 1 será o mapeamento
BPSK, caso contrário, é mapeado em QAM com os símbolos codificados com o código de
Gray, como ilustrado no trecho de código a seguir:
1 if bits_per_symbol == 1:
2 self. symbols = np.array ([ -1 ,1])
3 self. bits_mapped = np.array ([[0] ,[1]])
4 else:
Capítulo 3. Metodologia 31
5 q_i = 1 + (np. arange (np.sqrt(self. qam_order ))*2) - np.sqrt(
self. qam_order )
6 q, i = np. meshgrid (q_i ,q_i)
7 symbols = i. reshape (self. qam_order ) + 1j * q. reshape (self.
qam_order )
8 symbols = symbols /np.sqrt(np.mean(np.abs( symbols )**2))
9
10 sequence = np.array( range (self. qam_order ))
11 gray_constellation = np. bitwise_xor (sequence , np.floor(
sequence /2). astype (int))
12
13 bits = ()
14 size_string = "{0:0"+str( bits_per_symbol )+"b}"
15
16 for i in gray_constellation :
17 bits = bits + (tuple ([ int(x) for x in list( size_string .
format (i))]) ,)
18 bits_mapped = np. fliplr (np.array(bits))
19
20 self. symbols = symbols [np. argsort ( gray_constellation )]
21 self. bits_mapped = bits_mapped . astype (float )[np. argsort (
gray_constellation ) ,:]
Listing 3.5 – Modelo de mapeamento
3.1.2.1 Modulação
Para implementar a modulação OFDM, o primeiro passo foi converter a entrada
sequencial de bits em grupos , cada grupo de bits é uma subportadora e possui o tamanho
igual ao número de bits por símbolo, ou seja, é uma matriz com quantidade de linhas
igual o número de subportadoras e de colunas igual a número de bits por símbolo. Em
seguida os grupos de bits são mapeados em simbolos de acordo com a quantidade de bits
por simbolo, o próximo passo é alocar esses simbolos nas posições das subportadoras de
dados e para as pilotos é alocado o valor definido pelo usuário pilot_value, e por fim as
subportadoras são convertidas para o domínio do tempo por meio de uma IFFT e o prefixo
cíclico é adicionado de acordo com o cp_length, como demonstrado no seguinte trecho de
código:
1 def ofdm_transmitter (self ,bits):
2
3 bits_SP = bits. reshape (len(self. data_carriers ), self.
bits_per_symbol )
Capítulo 3. Metodologia 32
4 bits = self. symbols [np.sum( bits_SP * 2** np. arange (self.
bits_per_symbol ), axis =1, dtype=int)]
5
6 symbols = np.zeros(self.FFTsize , dtype= complex )
7 symbols [self. pilot_carriers ] = self. pilot_value
8 symbols [self. data_carriers ] = bits. reshape ((-1,))
9
10 signal = np.fft.ifft( symbols )
11
12 if self.cp_length >0:
13 signal = np. concatenate ([ signal [-self. cp_length :], signal
])
14
15 return signal
Listing 3.6 – Método do transmissor OFDM
3.1.2.2 Demodulação
Para a demodulação OFDM, inicialmente foi preciso remover o prefixo cíclico, em
seguida converter o sinal para o domínio da frequência com a FFT para que, logo após,
seja feita a estimativa do canal por meio das subportadoras piloto, que possuem valor e
posição conhecidos, dessa forma é possivel saber o efeito do canal nessa subportadora, e
com o efeito conhecido, é possivel estimar o efeito do canal também nas subportadoras de
dados por meio de uma interpolação, para por fim, realizar o demapeamento através da
menor distância dos símbolos originais, com relação ao valor estimado das subportadoras
de dados.
1 def ofdm_receiver (self , signal ):
2 if self.cp_length >0:
3 signal = signal [self. cp_length :len(self. sub_carriers )+
self. cp_length ]
4 signal_f = np.fft.fft( signal )
5
6 channel_influence = signal_f [self. pilot_carriers ]/ self.
pilot_value
7
8 interp = scipy. interpolate . interp1d (self. pilot_carriers ,
channel_influence )
9 equalize = ( signal_f [self. data_carriers ]/ interp (self.
data_carriers )). reshape (-1,1)
10
Capítulo 3. Metodologia 33
11 distance_symbols_to_constellation = np. absolute (equalize -
self. symbols )
12 return self. bits_mapped [np. argmin (
distance_symbols_to_constellation ,axis =1) ]. reshape (-1)
Listing 3.7 – Método do receptor OFDM
3.1.3 OFDMA
A classe que simula a transmissão e recepção OFDMA possui como parâmetros:
• subcarriers_pacing, que representa o espaçamento entre as subportadoras.
• sampling_rate, que representa a taxa de amostragem.
• n_subcarriers, que representa a quantidade de subportadoras.
• n_pilots, que representa a quantidade de subportadoras piloto.
• pilot_value, que representa o valor complexo que as subportadoras pilotos carregam.
• cp_length, que representa o tamanho do prefixo cíclico, em unidades de subportado-
ras.
• bits_per_symbol, que representa a quantidade de bits que um símbolo carrega.
• resource_units, que representa o tamanho dos subconjuntos de subportadoras dos
usuários.
• sc_mapping, que representa o tipo de alocação de subportadoras.
A classe OFDMA é muito semelhante com relação a OFDM, a diferença é que
possui a alocação de subportadoras. Na qual está demonstrada no trecho de código a
seguir, em que, caso o parâmetro scmap seja igual a 0, é usado o modelo de atribuição
das subportadoras de forma localizada, caso seja igual a 1, são realizadas operações com
o vetor de subportadoras, para que os índices sejam definidos de forma distribuída para
cada usuário, como demonstrado:
1 self. subcarrier_mapping = np.zeros(self. FFTsize )
2
3 if sc_map == 1:
4
5 self. subcarrier_mapping = self. data_carriers [:: -1]
6 index = int(self. subcarrier_mapping .size/self.
resource_units .size)
Capítulo 3. Metodologia 34
7 self. subcarrier_mapping = self. subcarrier_mapping . reshape
(index ,self. resource_units .size)
8
9 subcarriers_mapped_w_zeros = self. subcarrier_mapping
[:: -1].T. reshape (-1)
10 self. subcarriers_mapped = subcarriers_mapped_w_zeros [
subcarriers_mapped_w_zeros != 0]
11 else:
12
13 self. subcarrier_mapping = self. data_carriers
14 self. subcarriers_mapped = self. subcarrier_mapping [self.
subcarrier_mapping != 0]
Listing 3.8 – Alocação de subportadoras
3.1.3.1 Modulação e Demodulação
Como explicado anteriormente, os métodos de transmissão OFDM e OFDMA
são semelhantes, a diferença é que após a conversão serial-paralelo é adicionada uma
alocação de subportadoras a diferentes usuários podendo ser distribuidas em ordem para
cada usuario ou em blocos dependendo do tamanho dos subconjuntos definidos para
cada usuário resource_units e em seguida os simbolos são mapeados nas subportadoras
alocadas e o resto do processo é semelhante à modulação OFDM. Do mesmo modo a
função de demodulação OFDMA também é bastante semelhante a OFDM, a diferença é
que é realizado o demapeamento das subportadoras dos usuários de modo a retornar a
mesma sequência de dados da entrada.
3.1.4 Canal
A classe de simulação do canal recebe os seguintes parâmetros:
• fft_size, que representa o tamanho do processo.
• tau, que representa o delay dos percursos.
• pdb, que representa a potência ao longo de cada percurso.
• doppler_frequency, que representa a frequência doppler.
• sampling_period, que representa o período de amostragem.
O único método dessa classe, tem o objetivo de retornar os coeficientes do canal,
em que, para cada percurso, foi gerado um vetorde média nula gaussiano de tamanho
Capítulo 3. Metodologia 35
fft_size, em seguida foi obtido o vetor na frequência por meio da FFT que foi filtrado
pelo espectro doppler do desvanecimento Rayleigh e multiplicado pela ganho de cada
percurso para retornar um array com os coeficientes do canal de acordo com o delay
amostrado no período, como ilustrado no trecho de código a seguir:
1 for x in np. arange (len(self.pdb)):
2 gaussian = (np. random .randn(self. fft_size ) + 1j*np. random .
randn(self. fft_size ));
3 filtered_taps [x ,:] = np.fft.fft( gaussian )*np.sqrt(S);
4 taps_pdb_time [x ,:] = self.pdb[x]*np.fft.ifft( filtered_taps [x
,:]);
5 taps[self. sampled_tau [x]] = taps_pdb_time [x, self. sampled_tau
[x]];
Listing 3.9 – Geração dos coeficientes do canal
3.1.5 Codificador Hamming
A classe de simulação de Hamming, não possui nenhum parâmetro, como parâmetro
apenas os médotos de codificação e decodificação, que recebem o conjunto de dados binário.
3.1.5.1 Codificação
Para codificação Hamming, o primeiro passo é verificar a quantidade de bits de
paridade, de acordo com a relação do tamanho da mensagem inicial e a quantidade de
bits de paridade, de acordo com o demonstrado no seguinte trecho de código:
1 for i in np. arange (data.size):
2 if (2**i - i - 1 >= data.size):
3 n_parity_bits = i
4 break
Listing 3.10 – Verificação da quantidade de bits de paridade
Em seguida, é criado um array com tamanho do conjunto de dados somado com
o número de bits de paridade, e nas posições de potência de 2 dos bits de paridade, e
por fim, é realizado o cálculo do valor dos bits de paridade, através de um OR entre as
posições dos bits que possuem valor 1, para obtenção de um valor binário que corresponde
ao valor dos bits de paridade.
1 ones = np. nonzero ( data_pbits )[0]
2 value = 0;
3 for x in range(len(ones)):
4 value ^= ones[x]+1
5
Capítulo 3. Metodologia 36
6 parity_values = np.array(list(bin(value)[2:]. zfill(
n_parity_bits ))). astype (int)
7
8 data_pbits [ parity_index -1] = parity_values [:: -1]
Listing 3.11 – Definição do valor dos bits de paridade
3.1.5.2 Decodificação
O primeiro passo para a decodificação, é realizar a verificação da quantidade de bits
de paridade, mas, por meio da relação entre o tamanho total da mensagem e a quantidade
de bits de paridade:
1 size = 0
2 for i in np. arange (data.size):
3 if (2**i >= data.size):
4 size = i
5 break
Listing 3.12 – Verificação da quantidade de bits de paridade
Por fim, por meio do OR entre todos os bits de valor 1, é possível obter a posição
de um bit errôneo, e em seguida é feita a remoção dos bits de paridade:
1 ones = np. nonzero (data)[0]
2 parity_bits = 2** np. arange (size) -1
3 value = 0
4 for x in range(len(ones)):
5 value ^= ones[x]+1
6 if(value !=0):
7 data[value - 1] = not(data[value - 1])
8 decoded = np. delete (data , parity_bits )
Listing 3.13 – Obtenção da possível possição de erro e remoção de bits de paridade
37
4 RESULTADOS
Neste capítulo, são apresentados os resultados das simulações e comparações de
desempenho com a biblioteca CommPy para demonstrar o tempo de execução das funções
desenvolvidas.
Para a análise do tempo de execução, foi usada a função %timeit do IPython, que
pode ser usada para mensuração de tempo de uma parte específica do código, que realiza
multiplas execuções no código e retorna a média do tempo de execução.
Nas simulações OFDM e OFDMA, foi demonstrado também a taxa de erro de
bit (BER), que indica a proporção de bits errôneos recebidos pelo total de bits enviados
durante determinado intervalo de tempo.
4.1 Modulação e Demodulação BPSK
Para a simulação da modulação BPSK, foram usados os seguintes valores:
• Duração do bit: Tb = 1s
• Energia por bit: Eb = 0.5
• Frequência da portadora: fc = 4Hz
• Frequência de amostragem: fs = 200Hz
• Frequência de corte do filtro: cutoff = fc
• Ordem do filtro: order = 2
• Vetor binário de dados: np.array([0, 0, 1, 0])
E foi obtido o seguinte resultado como demonstrado na Figura 13, em que o gráfico
superior demonstra o sinal digital no tempo, e o inferior o sinal modulado:
Capítulo 4. Resultados 38
Figura 13 – Simulação da modulação BPSK.
Fonte – Próprio Autor
E por meio da demodulação, que recebe como parâmetro o sinal modulado, o vetor
binário de dados pode ser obtido novamente:
Figura 14 – Simulação da demodulação BPSK.
Fonte – Próprio Autor
4.1.1 Análise de desempenho
Para a análise de desempenho, foram usados os seguintes parâmetros de simulação:
Capítulo 4. Resultados 39
• Tamanho da sequência de bits: 10000 bits
• Número total de execuções: 100
• função BPSK desenvolvida neste trabalho com Tb = 1s, Eb = 0.5, fc = 4Hz, fs =
50Hz
A função PSK da bibloteca CommPy possui apenas o parâmetro m que é o tamanho
da constelação PSK (que para essa análise foi usado o valor 2) e o método de modulação
recebe apenas os bits que devem ser modulados.
E foram obtidos os seguintes resultados:
Tabela 1 – Análise de desempenho - Modulação BPSK
Método (biblioteca) tempo de execução médio
Modulação BPSK (Commpy) 21ms
Modulação BPSK (Projeto) 18ms
Demodulação BPSK (Commpy) 236ms
Demodulação BPSK (Projeto) 81ms
Cabe considerar que tempo de execução da função criada pode variar de acordo
com os parâmetros, como o aumento da frequência da amostragem, que retornará mais
amostras no tempo.
4.2 Modulação e Demodulação OFDM
A simulação da modulação OFDM desenvolvida nessa trabalho possui os seguintes
parâmetros:
• Espaço entre subportadoras: subcarrier_spacing = 60Hz
• Frequência de amostragem: sampling_rate = 3840Hz
• Número de subportadoras total: n_subcarriers = 64
• Número de subportadoras piloto: n_pilots = 8
• Valor da subportadora piloto: pilot_value = 1
• Tamanho do prefixo cíclico: cp_length = 8
• Bits por Símbolo: bits_per_symbol = 1
• bits de entrada:bits randômicos de tamanho (n_subcarriers−n_pilots)∗bits_per_symbol)
Capítulo 4. Resultados 40
A Figura 15 ilustra como são definidos os índices das portadoras piloto em vermelho,
que são distribuidas de forma equidistante para transmitir o valor conhecido.
Figura 15 – Distribuição das subportadoras.
Fonte – Próprio Autor
E a Figura 16 demontra a saída com o sinal modulado, além do resultado do sinal
após o canal de 5 percursos que gerou os coficientes com os seguintes parâmetros:
• Tamanho do processo fft = 512
• Delay de cada path tau = [0, 2.106, 8.106, 14.106, 20.106]s
• Frequência Doppler fd = 7.5Hz
• Potência de cada path pdb = [0.5, 0.25, 0.2, 0.1, 0.05]
• Período de amostragem Ts = 2.106s
E foi obtido os seguintes resultados, como demonstrado na Figura 16, em que o
gráfico demonstra o sinal após o canal e a taxa de erro de bit (BER):
Capítulo 4. Resultados 41
Figura 16 – Sinal após o canal e taxa de erro de bit.
Fonte – Próprio Autor
4.2.1 Análise de desempenho
Para a modulação OFDM com a bibloteca CommPy foram usados os seguintes
parâmetros:
• Tamanho da FFT nfft = 64
• Número de subportadoras nsc = 64
• Tamanho do prefixo cíclico cp_length = 8
• Número total de execuções: 10000
Os seguintes resultados foram obtidos, ao tentar executar a função da biblioteca
CommPy para gerar o sinal OFDM, ocorreu um erro e por isso não foi possível medir o
tempo de execução como indicado na Tabela 2:
Tabela 2 – Análise de desempenho - Modulação OFDM
Método (biblioteca) tempo de execução médio
Modulação OFDM(Commpy) −
Modulação OFDM(Projeto) 28µs
Demodulação OFDM(Commpy) −
Demodulação OFDM(Projeto) 243µs
A biblioteca commpy possui funções de transmissão e recepção OFDM, mas ao tentar
executar foram obtidos erros tando na modulação quanto na demodulação, impossibilitando
a medição de tempo.
Capítulo 4. Resultados 42
4.3 Modulação OFDMA
Na simulação da modulação OFDMA desenvolvida neste trabalho, foram usados os
seguintes parâmetros:
• Espaço entre subportadoras subcarrier_spacing = 60Hz
• Frequência de amostragem sampling_rate = 3840Hz
• Número de subportadoras total n_subcarriers = 64
• Número de subportadoras piloton_pilots = 8
• Valor da subportadora piloto pilot_value = 1
• Tamanho do prefixo cíclico cp_length = 8
• Bits por símbolo bits_per_symbol = 1
• 4 usuários com 14 subportadoras cada um RUs = np.array([14, 14, 14, 14])
• bits de entrada:bits randômicos de tamanho (np.sum(RUs)) ∗ bits_per_symbol)
As Figuras 17 e 18 ilustram como ficam mapeadas as subportadoras dependendo
do modelo adotado, com mapeamento localizado e distribuído respectivamente.
Figura 17 – Distribuição das subportadoras.
Fonte – Próprio Autor
E com os parâmetros definidos anteriormente, após a saída do sinal modulado eu
usei a função do canal desenvovido neste projeto para gerar os coeficientes e usar o canal
para a entrada da demodulação, o canal possui 5 percursos e os seguintes parâmetros:
• Tamanho do processo fft_size = 512
• Delay de cada path tau = [0, 2.106, 8.106, 14.106, 20.106]s
Capítulo 4. Resultados 43
Figura 18 – Distribuição das subportadoras (mapeamento distribuído).
Fonte – Próprio Autor
• Frequência Doppler fd = 7.5Hz
• Potência de cada path pdb = [0.5, 0.25, 0.2, 0.1, 0.05]
• Período de amostragem Ts = 2.106s
E foi obtido os seguintes resultados na Figura 20, no qual o gráfico demonstra o
sinal após o canal e a taxa de erro de bit de cada usuário e do símbolo OFDMA.
Figura 19 – Modulação OFDMA
Fonte – Próprio Autor
4.3.1 Análise de desempenho
Como a biblioteca CommPy não possui a modulação OFDMA, apenas foram
medidos os desempenhos da modulação desenvolvida, para obter a média do tempo de
execução:
Capítulo 4. Resultados 44
Tabela 3 – Análise de desempenho - Modulação OFDMA
Método (biblioteca) tempo de execução médio
Modulação OFDMA (Projeto) 36µs
Demodulação OFDMA (Projeto) 257µs
4.4 Codificador Hamming
O simulador da codificação de Hamming recebe como parâmetro apenas os bits de
entrada, como descrito abaixo:
• Palavra de bits de tamanho 20: np.array([1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0])
Após a codificação, foi retornada a saída do conjunto de dados de entrada, como
demonstra a Figura 19:
Figura 20 – Saída do codificador de Hamming.
Fonte – Próprio Autor
Em seguida, foi realizada a decodificação com o resultado obtido na codificação,
retornando o a mesma palavra de dados que foi usada na codificação:
Figura 21 – Saída do decodificador de Hamming.
Fonte – Próprio Autor
4.4.1 Análise de desempenho
Para a análise desempenho do codificador de Hamming, foi usada uma entrada com
10000 bits e o trecho de código foi executado 100 vezes para obtenção das médias, como a
biblioteca commpy não possui esse tipo de codificação, foram realizados os testes apenas
com a codificação desenvolvida.
4.5 Canal
Os seguintes parâmetros foram usados para simulação do canal com 5 percursos:
Capítulo 4. Resultados 45
Tabela 4 – Análise de desempenho - Codificador de Hamming
Método tempo de execução médio
Codificação Hamming 8.3ms
Decodificação Hamming 28.5µs
• Tamanho do processo fft_size = 512
• Delay de cada percurso tau = [0, 2.106, 8.106, 14.106, 20.106]s
• Frequência Doppler fd = 7.5Hz
• Potência de cada percurso pdb = [0.5, 0.25, 0.2, 0.1, 0.05]
• Período de amostragem Ts = 2.106s
E foram obtidos os seguintes coeficientes:
Figura 22
Fonte – Próprio Autor
4.5.1 Análise de desempenho
O canal da biblioteca Commpy (SISOFlatChannel) é flat, por isso foi realizada a
comparação com o canal desenvovido com 1 percurso, a análise de desempenho levou em
conta os seguintes parâmetros:
• Canal com tamanho do processo fft = 64, Delay de cada percurso tau = 0s,
Frequência Doppler fd = 7.5Hz, Potência de cada percurso pdb = 0.5 e Período de
amostragem Ts = 2.106s.
• Canal da biblioteca CommPy com desvanecimento de Rayleigh e 64 símbolos.
Tabela 5 – Análise de desempenho - Canal
Método (biblioteca) tempo de execução médio
Canal (Projeto) 139µs
Canal (CommPy) 18.5µs
Capítulo 4. Resultados 46
Apesar do tempo ser praticamente 8 vezes maior, é preciso considerar que o canal
deste projeto, é mais flexível para simulações pois possui uma maior quantidade de
parâmetros que podem ser defindos, além disso, a biblioteca CommPy não possui funções
para canal multipercurso, enquanto o canal desenvolvido neste projeto, tem capacidade
para ser multipercurso dependendo dos parâmetros informados.
47
5 CONCLUSÃO
Este trabalho teve como objetivo o desenvovimento de uma biblioteca Python para
contribuição no desenvolvimento de simulações de sistemas de telecomunicações. Em que,
as funções criadas foram simuladas e analisadas em termos de desempenho.
Com relação à análise de desempenho, nas funções que foi possível realizar a
comparação, os resultados se mostraram bastante satisfatórios, pois mesmo que, o tempo
de execução possa ser maior, as funções permitem uma simulação mais flexível, pois
possuem uma maior quantidade de parâmetros, permitindo uma exploração dos resultados
melhor para simulações computacionais.
Para trabalhos futuros, pode-se continuar com o desenvovimento de funções de
simulação de sistemas de telecomunicações para a biblioteca, como por exemplo, acesso
ultiplo não ortogonal (NOMA), cancelamento sucessivo de interferência, codificador con-
volucional. Pois a área de sistemas de telecomunicações é vasta, e mesmo que existam
algumas poucas bibliotecas na linguagem Python, elas possuem limitações e podem não
atender completamente ao escopo de simulações computacionais.
48
REFERÊNCIAS
AL-RAWI, M. Performance analysis of ofdma and sc-fdma. International Review of
Applied Sciences and Engineering, v. 8, p. 113–116, 12 2017.
ALI, M.; SUKAR, N.; PAL, M. Sc-fdma and ofdma in lte physical layer. international
journal of engineering trends and technology, v. 12, p. 74–84, 2014.
ARNDT, D. M. Análise comparativa entre os sistemas ofdm e fbmc na transmissão de tv
digital. Florianópolis, 2012.
BROWN, J.; PASUPATHY, S.; PLATANIOTIS, K. Adaptive demodulation using rateless
erasure codes. Communications, IEEE Transactions on, v. 54, p. 1574 – 1585, 10 2006.
CHO, Y. et al. MIMO-OFDM Wireless Communications with MATLAB®:
Cho/MIMO-OFDM Wireless Communications with MATLAB®. [S.l.: s.n.], 2010. ISBN
9780470825617.
CLARKE, R. H. A statistical theory of mobile-radio reception. The Bell System Technical
Journal, v. 47, n. 6, p. 957–1000, 1968.
Coleri, S. et al. Channel estimation techniques based on pilot arrangement in ofdm
systems. IEEE Transactions on Broadcasting, v. 48, n. 3, p. 223–229, 2002.
GUIMARÃES, A.; PINTO, E. Técnicas de simulação de canais rádio móveis. Revista
Inatel, v. 4, n. 1, 2001.
HAYKIN, S. Sistemas de Comunicação Analógicos e Digitais. 4. ed. [S.l.]: BOOKMAN
COMPANHIA ED, 2004.
HAYKIN, S.; MOHER, M. Introdução aos Sistemas de Comunicação. 2. ed. [S.l.]:
BOOKMAN COMPANHIA ED, 2008.
LATHI B. P.; DING, Z. Sistemas de comunicações analógicos e digitais modernos. 4. ed.
[S.l.]: Editora LTC, 2012.
MORELLI, M.; KUO, C.-C. J.; PUN, M. Synchronization techniques for orthogonal
frequency division multiple access (ofdma): A tutorial review. Proceedings of the IEEE,
v. 95, p. 1394 – 1427, 08 2007.
Muller, A. Simulation of multipath fading channels using the monte-carlo method.
In: Proceedings of ICC/SUPERCOMM’94 - 1994 International Conference on
Communications. [S.l.: s.n.], 1994. p. 1536–1540 vol.3.
PARKER, M. Chapter 17 - orthogonal frequency division multiple access wireless
communications. In: PARKER, M. (Ed.). Digital Signal Processing 101 (Second Edition).
Second edition. Newnes, 2017. p. 209 – 230. ISBN 978-0-12-811453-7. Disponível em:
<http://www.sciencedirect.com/science/article/pii/B9780128114537000172>.
PINTO, E. L.; ALBUQUERQUE, C. P. de. A técnica de transmissão ofdm. Revista
Científica Periódica-Telecomunicações ISSN, v. 1516, p. 2338, 2002.
http://www.sciencedirect.com/science/article/pii/B9780128114537000172
Referências 49
SAVAUX, V. Contributions à l’estimation de canal mutli-trajets dans un contexte de
modulation OFDM. Tese (Doutorado), 11 2013.
SCHULZE, H. Stochastic models and digital simulation of mobile channels (in german),.U.R.S.I./ITG Conf. in Kleinheubach 1988, Germany (FR),Proc. Kleinheubacher Berichte
by the German PlT, Darmstadt,, v. 32, p. 473–483, 1989.
50
A APÊNDICE - CÓDIGOS FONTE
A.1 Classe BPSK
1 import numpy as np
2 import scipy. signal as signal
3
4 class bpsk:
5 def __init__ (self , energy_per_bit , bit_duration ,
carrier_frequency , sampling_frequency ):
6
7 self. carrier_frequency = carrier_frequency
8 self. bit_duration = bit_duration
9 self. energy_per_bit = energy_per_bit
10 self. sampling_frequency = sampling_frequency
11 self. sqrt_Eb_Bd = np.sqrt ((2* self. energy_per_bit )/self.
bit_duration )
12
13 def modulation (self , bit_sequence ):
14
15 nrtn = 2* bit_sequence - 1
16 t = np. linspace (0, len( bit_sequence ), self.
sampling_frequency *len( bit_sequence ))
17 nrtn_fs = np. repeat (nrtn , self. sampling_frequency )
18 return nrtn_fs *( self. sqrt_Eb_Bd *np.cos (2* np.pi * self.
carrier_frequency * t))
19
20 def demodulation (self ,bpsk_sign ,cutoff ,order =2):
21 nb = len( bpsk_sign )// self. sampling_frequency
22 t = np. linspace (0,nb ,len( bpsk_sign ))
23
24 carrier = self. sqrt_Eb_Bd * np.cos (2* np.pi * self.
carrier_frequency * t)
25 mult = bpsk_sign * carrier
26
27 w = ( cutoff ) / (self. sampling_frequency / 2)
28 b, a = signal . butter (order , w, ’low ’)
29 output = signal . filtfilt (b, a, mult)
30 sum_split = np.mean(np.split(output ,nb), axis = 1,dtype=np.
Apêndice A. APÊNDICE - CÓDIGOS FONTE 51
float32 )
31 decision = np.where( sum_split > 0, 1, 0)
32
33 return decision
Listing A.1 – Classe BPSK
A.2 Classe OFDM
1 import numpy as np
2 import scipy. interpolate
3
4 class OFDM:
5
6 def __init__ (self , subcarrier_spacing , sampling_rate ,
n_subcarriers , n_pilots , pilot_value , cp_length ,
bits_per_symbol ):
7
8 self. cp_length = cp_length
9 self. n_subcarriers = n_subcarriers
10 self. subcarrier_spacing = subcarrier_spacing
11 self. sampling_rate = sampling_rate
12 self. n_pilots = n_pilots
13 self. pilot_value = pilot_value
14
15 self. bits_per_symbol = bits_per_symbol
16 self. qam_order = 2** bits_per_symbol
17
18 self. FFTsize = int(np. round (self. sampling_rate /self.
subcarrier_spacing ))
19
20 self. sub_carriers = np. arange (self. FFTsize )
21 self. pilot_carriers = np. linspace (0, self.FFTsize -1, num=
self.n_pilots ,dtype=int)
22 self. subcarriers_no_pilots = np. delete (self. sub_carriers ,
self. pilot_carriers )
23 self. data_carriers = self. subcarriers_no_pilots [:( self.
n_subcarriers -self. n_pilots ) ,...]
24
25 if bits_per_symbol == 1:
26 self. symbols = np.array ([ -1 ,1])
27 self. bits_mapped = np.array ([[0] ,[1]])
Apêndice A. APÊNDICE - CÓDIGOS FONTE 52
28 else:
29 q_i = 1 + (np. arange (np.sqrt(self. qam_order ))*2) - np.
sqrt(self. qam_order )
30 q, i = np. meshgrid (q_i ,q_i)
31 symbols = i. reshape (self. qam_order ) + 1j * q. reshape (self
. qam_order )
32 symbols = symbols /np.sqrt(np.mean(np.abs( symbols )**2))
33
34 sequence = np.array( range (self. qam_order ))
35 gray_constellation = np. bitwise_xor (sequence , np.floor(
sequence /2). astype (int))
36
37 bits = ()
38 size_string = "{0:0"+str( bits_per_symbol )+"b}"
39
40 for i in gray_constellation :
41 bits = bits + (tuple ([ int(x) for x in list( size_string .
format (i))]) ,)
42 bits_mapped = np. fliplr (np.array(bits))
43
44 self. symbols = symbols [np. argsort ( gray_constellation )]
45 self. bits_mapped = bits_mapped . astype (float )[np. argsort (
gray_constellation ) ,:]
46
47 def ofdm_transmitter (self ,bits):
48
49 bits_SP = bits. reshape (len(self. data_carriers ), self.
bits_per_symbol )
50 bits = self. symbols [np.sum( bits_SP * 2** np. arange (self.
bits_per_symbol ), axis =1, dtype=int)]
51
52 symbols = np.zeros(self.FFTsize , dtype= complex )
53 symbols [self. pilot_carriers ] = self. pilot_value
54 symbols [self. data_carriers ] = bits. reshape ((-1,))
55
56 signal = np.fft.ifft( symbols )
57
58 if self.cp_length >0:
59 signal = np. concatenate ([ signal [-self. cp_length :], signal
])
60
Apêndice A. APÊNDICE - CÓDIGOS FONTE 53
61 return signal
62
63 def ofdm_receiver (self , signal ):
64 if self.cp_length >0:
65 signal = signal [self. cp_length :len(self. sub_carriers )+
self. cp_length ]
66 signal_f = np.fft.fft( signal )
67
68 channel_influence = signal_f [self. pilot_carriers ]/ self.
pilot_value
69
70 interp = scipy. interpolate . interp1d (self. pilot_carriers ,
channel_influence )
71 equalize = ( signal_f [self. data_carriers ]/ interp (self.
data_carriers )). reshape (-1,1)
72
73 distance_symbols_to_constellation = np. absolute (equalize -
self. symbols )
74 return self. bits_mapped [np. argmin (
distance_symbols_to_constellation ,axis =1) ]. reshape (-1)
Listing A.2 – Classe OFDM
A.3 Classe OFDMA
1 import numpy as np
2 import scipy. interpolate
3
4 class OFDMA:
5
6 def __init__ (self , subcarrier_spacing , sampling_rate ,
n_subcarriers , n_pilots , pilot_value , cp_length ,
bits_per_symbol , resource_units , sc_map = 1):
7
8 self. cp_length = cp_length
9 self. n_subcarriers = n_subcarriers
10 self. subcarrier_spacing = subcarrier_spacing
11 self. sampling_rate = sampling_rate
12 self. n_pilots = n_pilots
13 self. pilot_value = pilot_value
14 self. resource_units = resource_units
15 self. bits_per_symbol = bits_per_symbol
Apêndice A. APÊNDICE - CÓDIGOS FONTE 54
16 self. qam_order = 2** bits_per_symbol
17 self. sc_map = sc_map ;
18
19 self. FFTsize = int(np. round (self. sampling_rate /self.
subcarrier_spacing ))
20
21 self. sub_carriers = np. arange (self. FFTsize )
22 self. pilot_carriers = np. linspace (0, self.FFTsize -1, num=
self.n_pilots ,dtype=int)
23 self. subcarriers_no_pilots = np. delete (self. sub_carriers ,
self. pilot_carriers )
24 self. data_carriers = self. subcarriers_no_pilots [:( np.sum(
self. resource_units )) ,...]
25
26 if bits_per_symbol == 1:
27 self. symbols = np.array ([ -1 ,1])
28 self. bits_mapped = np.array ([[0] ,[1]])
29 else:
30 q_i = 1 + (np. arange (np.sqrt(self. qam_order ))*2) - np.
sqrt(self. qam_order )
31 q, i = np. meshgrid (q_i ,q_i)
32 symbols = i. reshape (self. qam_order ) + 1j * q. reshape (self
. qam_order )
33 symbols = symbols /np.sqrt(np.mean(np.abs( symbols )**2))
34
35 sequence = np.array( range (self. qam_order ))
36 gray_constellation = np. bitwise_xor (sequence , np.floor(
sequence /2). astype (int))
37
38 bits = ()
39 size_string = "{0:0"+str( bits_per_symbol )+"b}"
40
41 for i in gray_constellation :
42 bits = bits + (tuple ([ int(x) for x in list( size_string .
format (i))]) ,)
43 bits_mapped = np. fliplr (np.array(bits))
44
45 self. symbols = symbols [np. argsort ( gray_constellation )]
46 self. bits_mapped = bits_mapped . astype (float )[np. argsort (
gray_constellation ) ,:]
47
Apêndice A. APÊNDICE - CÓDIGOS FONTE 55
48 self. subcarrier_mapping = np.zeros(self. FFTsize )
49
50 if sc_map == 1:
51
52 self. subcarrier_mapping = self. data_carriers [:: -1]
53 index = int(self. subcarrier_mapping .size/self.
resource_units .size)
54 self. subcarrier_mapping = self. subcarrier_mapping . reshape
(index ,self. resource_units .size)
55
56 subcarriers_mapped_w_zeros = self. subcarrier_mapping
[:: -1].T. reshape (-1)
57 self. subcarriers_mapped = subcarriers_mapped_w_zeros [
subcarriers_mapped_w_zeros != 0]
58 else:
59
60 self. subcarrier_mapping = self. data_carriers
61 self. subcarriers_mapped = self. subcarrier_mapping [self.
subcarrier_mapping != 0]
62
63 def ofdma_transmitter (self ,bits):
64 bits = bits. reshape (np.sum(self. resource_units ), self.
bits_per_symbol )
65
66 bits_mapped = self. symbols [np.sum(bits * 2** np. arange (self.
bits_per_symbol ), axis =1, dtype=int)]
67
68 symbols = np.zeros(self.FFTsize , dtype= complex )
69 symbols [self. pilot_carriers ] = self. pilot_value
70
71 symbols [np.array(self. subcarriers_mapped ,dtype=int)] =
bits_mapped . reshape ((-1,))72
73 signal = np.fft.ifft( symbols )
74
75 if self.cp_length >0:
76 signal = np. concatenate ([ signal [-self. cp_length :], signal
])
77 return signal
78
79 def ofdma_receiver (self , signal ):
Apêndice A. APÊNDICE - CÓDIGOS FONTE 56
80 if self.cp_length >0:
81 signal = signal [self. cp_length :len(self. sub_carriers )+
self. cp_length ]
82
83 signal_f = np.fft.fft( signal )
84
85 channel_influence = signal_f [self. pilot_carriers ]/ self.
pilot_value
86 interp = scipy. interpolate . interp1d (self. pilot_carriers ,
channel_influence )
87 equalize = ( signal_f [np.array(self. subcarriers_mapped ,dtype
=int)]/ interp (np.array(self. subcarriers_mapped ,dtype=int
))). reshape (-1,1)
88
89 distance_symbols_to_constellation = np. absolute ( equalize -
self. symbols )
90 return self. bits_mapped [np. argmin (
distance_symbols_to_constellation ,axis =1) ]. reshape (-1)
Listing A.3 – Classe OFDMA
A.4 Classe do Canal multipercurso com desvanecimento Rayleigh
1 import numpy as np
2 import math
3
4 class rayleigh_chan :
5 def __init__ (self ,fft_size ,tau , freq_doppler ,pdb ,Ts):
6
7 self. fft_size = fft_size
8 self.tau = tau;
9 self. freq_doppler = freq_doppler ;
10 self.pdb = pdb;
11 self.Ts = Ts;
12 self. sampled_tau = np. divide (self.tau ,self.Ts). astype (int)
13 def get_coef (self):
14
15 taps = np.zeros(self. sampled_tau [ -1]+1 , dtype= complex );
16 filtered_taps = np.zeros (( len(self.pdb), self. fft_size ),
dtype= complex );
17 taps_pdb_time = np.zeros (( len(self.pdb), self. fft_size ),
dtype= complex );
Apêndice A. APÊNDICE - CÓDIGOS FONTE 57
18
19 f = np. linspace (-self. freq_doppler ,self. freq_doppler ,self.
fft_size )
20
21 with np. errstate ( divide =’ignore ’):
22 S = 1/( np.pi*self. freq_doppler *np.sqrt (1 -((f/self.
freq_doppler )**2)));
23
24 S[0] = S[1]+(S[1]-S[2]);
25 S[-1] = S[ -2]+(S[-2]-S[ -3]);
26
27 for x in np. arange (len(self.pdb)):
28 gaussian = (np. random .randn(self. fft_size ) + 1j*np. random
.randn(self. fft_size ));
29 filtered_taps [x ,:] = np.dot(np.fft.fft( gaussian ),np.sqrt(
S));
30 taps_pdb_time [x ,:] = self.pdb[x]*np.fft.ifft(
filtered_taps [x ,:]);
31 taps[self. sampled_tau [x]] = taps_pdb_time [x, self.
sampled_tau [x]];
32 return taps
Listing A.4 – Classe do Canal multipercurso com desvanecimento Rayleigh
A.5 Classe do codificador Hamming
1 import numpy as np
2
3 class Hamming :
4
5 def encoder (data):
6 for i in np. arange (data.size):
7 if (2**i - i - 1 >= data.size):
8 n_parity_bits = i
9 break
10
11 data_size = data.size
12 data_pbits = np.zeros( data_size + n_parity_bits ,dtype=int);
13 bits_index = np. arange (1, data_size + n_parity_bits +1)
14 parity_index = 2 ** np. arange (0, n_parity_bits )
15 diff_index = np. setdiff1d (bits_index , 2 ** np. arange (0, data
.size))
Apêndice A. APÊNDICE - CÓDIGOS FONTE 58
16 data_pbits [diff_index -1] = data
17 teste = np. bitwise_or (data_pbits ,np. arange (1, data_pbits .
size + 1))
18
19 ones = np. nonzero ( data_pbits )[0]
20 value = 0;
21 for x in range(len(ones)):
22 value ^= ones[x]+1
23
24 parity_values = np.array(list(bin(value)[2:]. zfill(
n_parity_bits ))). astype (int)
25 data_pbits [ parity_index -1] = parity_values [:: -1]
26 return data_pbits
27
28 def decoder (data):
29 size = 0
30 for i in np. arange (data.size):
31 if (2**i >= data.size):
32 size = i
33 break
34 ones = np. nonzero (data)[0]
35 parity_bits = 2** np. arange (size) -1
36 value = 0
37 for x in range(len(ones)):
38 value ^= ones[x]+1
39 if(value !=0):
40 data[value - 1] = not(data[value - 1])
41 decoded = np. delete (data , parity_bits )
42 return decoded
Listing A.5 – Classe do codificador Hamming

Outros materiais