【信号处理】Python实现BPSK、QPSK、8PSK、8QAM、16QAM、
64QAM。。。
⽬录
1 引⾔
本⽂不涉及原理讲解,只提供实现⽅法。需要借助Commpy开源包去实现通信中的各种处理。
源码下载地址
安装⽅法
⽅法⼀
pip install scikit-commpy
⽅法⼆
git clone github/veeresht/CommPy.git
modulatecd CommPy
python setup.py install
2 实现
2.1 调制
import commpy as cpy
bits = np.random.binomial(n=1,p=0.5,size=(128))
Modulation_type ="BPSK"
if Modulation_type=="BPSK":
bpsk = cpy.PSKModem(2)
symbol = dulate(bits)
return symbol
elif Modulation_type=="QPSK":
qpsk = cpy.PSKModem(4)
symbol = dulate(bits)
return symbol
elif Modulation_type=="8PSK":
psk8 = cpy.PSKModem(8)
symbol = dulate(bits)
return symbol
elif Modulation_type=="16QAM":
qam16 = cpy.QAMModem(16)
symbol = dulate(bits)
return symbol
elif Modulation_type=="64QAM":
qam64 = cpy.QAMModem(64)
symbol = dulate(bits)
return symbol
注意8QAM,不能⽤Commpy实现,实现如下
import numpy as np
import matplotlib.pyplot as plt
import math
def split_by_len(str, length):
return[str[i:i+length]for i in range(0,len(str), length)]
def generate_8qam(signal):
SAMP =1
fc =4
qam =[]
t = np.arange(0, SAMP)
wave =[]
for i in range(8):
if i %2==0:
amp =0.5
else:
amp =1
wave.append(amp * np.exp(1j*(fc * np.pi * t/SAMP + math.floor(i/2)* np.pi/2)))
s_bits = split_by_len(signal,3)
for s in s_bits:
qam = np.array(qam)
return qam
bits = np.random.binomial(n=1,p=0.5,size=(128,))
if Modulation_type=="64QAM":
signal =''
for i in range(bits.shape[0]):
signal = signal+str(bits[i])
symbol = generate_8qam(signal)
return symbol
2.2 解调
# 和调制⼀样,需要先定义调制⽅法的类,再去调⽤解调的函数。
import commpy as cpy
bits = np.random.binomial(n=1,p=0.5,size=(128))
# Modem : QPSK
modem = mod.QAMModem(4)
signal = dulate(bits)
modem.demodulate(signal,'hard')
3 完整编码和解码的例⼦
来源
# Authors: CommPy contributors
# License: BSD 3-Clause
from __future__ import division, print_function # Python 2 compatibility
import math
import matplotlib.pyplot as plt
import numpy as np
import vcode as cc
import commpy.channels as chan
import commpy.links as lk
dulation as mod
import commpy.utilities as util
# ============================================================================= # Convolutional Code 1: G(D) = [1+D^2, 1+D+D^2]
# Convolutional Code 1: G(D) = [1+D^2, 1+D+D^2]
# Standard code with rate 1/2
# =============================================================================
# Number of delay elements in the convolutional encoder
memory = np.array(2, ndmin=1)
# Generator matrix
g_matrix = np.array((0o5,0o7), ndmin=2)
# Create trellis data structure
trellis1 = cc.Trellis(memory, g_matrix)
# ============================================================================= # Convolutional Code 1: G(D) = [1+D^2, 1+D^2+D^3]
# Standard code with rate 1/2
# =============================================================================
# Number of delay elements in the convolutional encoder
memory = np.array(3, ndmin=1)
# Generator matrix (1+D^2+D^3 <-> 13 or 0o15)
g_matrix = np.array((0o5,0o15), ndmin=2)
# Create trellis data structure
trellis2 = cc.Trellis(memory, g_matrix)
# ============================================================================= # Convolutional Code 2: G(D) = [[1, 0, 0], [0, 1, 1+D]]; F(D) = [[D, D], [1+D, 1]]
# RSC with rate 2/3
# =============================================================================
# Number of delay elements in the convolutional encoder
memory = np.array((1,1))
# Generator matrix & feedback matrix
g_matrix = np.array(((1,0,0),(0,1,3)))
feedback = np.array(((2,2),(3,1)))
# Create trellis data structure
trellis3 = cc.Trellis(memory, g_matrix, feedback,'rsc')
# ============================================================================= # Basic example using homemade counting and hard decoding
# =============================================================================
# Traceback depth of the decoder
tb_depth =None# Default value is 5 times the number or memories
for trellis in(trellis1, trellis2, trellis3):
for i in range(10):
# Generate random message bits to be encoded
message_bits = np.random.randint(0,2,1000)
# Encode message bits
coded_bits = cc.conv_encode(message_bits, trellis)
# Introduce bit errors (channel)
coded_bits[np.random.randint(0,1000)]=0
coded_bits[np.random.randint(0,1000)]=0
coded_bits[np.random.randint(0,1000)]=1
coded_bits[np.random.randint(0,1000)]=1
# Decode the received bits
decoded_bits = cc.viterbi_decode(coded_bits.astype(float), trellis, tb_depth)
num_bit_errors = util.hamming_dist(message_bits, decoded_bits[:len(message_bits)])
if num_bit_errors !=0:
print(num_bit_errors,"Bit Errors found!")
elif i ==9:
print("No Bit Errors :)")
# ================================================================================================== # Complete example using Commpy features and compare hard and soft demodulation. Example with code 1
# ==================================================================================================
# Modem : QPSK
modem = mod.QAMModem(4)
# AWGN channel
channels = chan.SISOFlatChannel(None,(1+0j,0j))
# SNR range to test
SNRs = np.arange(0,6)+10* math.log10(modem.num_bits_symbol)
# Modulation function
def modulate(bits):
v_encode(bits, trellis1,'cont'))
# Receiver function (no process required as there are no fading)
def receiver_hard(y, h, constellation, noise_var):
return modem.demodulate(y,'hard')
# Receiver function (no process required as there are no fading)
def receiver_soft(y, h, constellation, noise_var):
return modem.demodulate(y,'soft', noise_var)
# Decoder function
def decoder_hard(msg):
return cc.viterbi_decode(msg, trellis1)
# Decoder function
def decoder_soft(msg):
return cc.viterbi_decode(msg, trellis1, decoding_type='soft')
# Build model from parameters
code_rate = trellis1.k / trellis1.n
model_hard = lk.LinkModel(modulate, channels, receiver_hard,
modem.num_bits_symbol, stellation, modem.Es,
decoder_hard, code_rate)
model_soft = lk.LinkModel(modulate, channels, receiver_soft,
modem.num_bits_symbol, stellation, modem.Es,
decoder_soft, code_rate)
# Test
BERs_hard = model_hard.link_performance(SNRs,10000,600,5000, code_rate)
BERs_soft = model_soft.link_performance(SNRs,10000,600,5000, code_rate)
plt.semilogy(SNRs, BERs_hard,'o-', SNRs, BERs_soft,'o-')
plt.xlabel('Signal to Noise Ration (dB)')
plt.ylabel('Bit Error Rate')
plt.legend(('Hard demodulation','Soft demodulation'))
plt.show()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论