Trying to debug issues with carrier estimation
This commit is contained in:
parent
bd3535d7d7
commit
dbdf45ef05
55
channel.py
55
channel.py
@ -4,13 +4,13 @@ import scipy.interpolate
|
|||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
# Dirac delta function response, no change
|
# Dirac delta function response, no change
|
||||||
#channel_response = np.array([0, 0, 0, 1, 0, 0, 0])
|
channel_response = np.array([0, 0, 0, 1, 0, 0, 0])
|
||||||
channel_response = np.array([-1 + 1j, 0, 1, 0.5, 0.25])
|
#channel_response = np.array([-1 + 1j, 0, 1, 0.5, 0.25])
|
||||||
|
|
||||||
|
|
||||||
# How do I sync this across two files?
|
# How do I sync this across two files?
|
||||||
# figure it out later
|
# figure it out later
|
||||||
pilot_value = 1 + 1j
|
pilot_value = 5 + 5j
|
||||||
|
|
||||||
# 15dB seems to be around the minimum for error-free transmission
|
# 15dB seems to be around the minimum for error-free transmission
|
||||||
snr_db = 300
|
snr_db = 300
|
||||||
@ -65,6 +65,8 @@ def estimate(in_data, pilots=0):
|
|||||||
every time. This also has the advantage of being able to synchronise the symbols. Since I
|
every time. This also has the advantage of being able to synchronise the symbols. Since I
|
||||||
will be implementing some sort of protocol anyways, I think this will be a good idea. As well,
|
will be implementing some sort of protocol anyways, I think this will be a good idea. As well,
|
||||||
we move slow enough that the channel will not likely change significantly over a single packet.
|
we move slow enough that the channel will not likely change significantly over a single packet.
|
||||||
|
|
||||||
|
Actually maybe not? Looked at a paper, check the drive.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
all_carriers = np.arange(len(in_data[0]))
|
all_carriers = np.arange(len(in_data[0]))
|
||||||
@ -73,24 +75,50 @@ def estimate(in_data, pilots=0):
|
|||||||
pilot_carriers = all_carriers[::(len(all_carriers)) // pilots]
|
pilot_carriers = all_carriers[::(len(all_carriers)) // pilots]
|
||||||
pilot_carriers = np.delete(pilot_carriers, 0)
|
pilot_carriers = np.delete(pilot_carriers, 0)
|
||||||
|
|
||||||
|
print(pilot_carriers)
|
||||||
|
|
||||||
# start averaging
|
# start averaging
|
||||||
H_est = 0
|
H_est = 0
|
||||||
|
|
||||||
for i in range(len(in_data)):
|
# for i in range(len(in_data)):
|
||||||
# Obtain channel response at pilot carriers
|
# # Obtain channel response at pilot carriers
|
||||||
H_est_pilots = in_data[i][pilot_carriers] / pilot_value
|
# H_est_pilots = in_data[i][pilot_carriers] / pilot_value
|
||||||
|
|
||||||
# Interpolate estimates based on what we get from the few pilot values
|
|
||||||
H_est_abs = scipy.interpolate.interp1d(pilot_carriers, abs(H_est_pilots), kind='linear', fill_value='extrapolate')(all_carriers)
|
|
||||||
H_est_phase = scipy.interpolate.interp1d(pilot_carriers, np.angle(H_est_pilots), kind='linear', fill_value='extrapolate')(all_carriers)
|
|
||||||
|
|
||||||
# Take angular form and turn into rectangular form
|
# # Interpolate estimates based on what we get from the few pilot values
|
||||||
H_est += H_est_abs * np.exp(1j*H_est_phase)
|
# H_est_abs = scipy.interpolate.interp1d(pilot_carriers, abs(H_est_pilots), kind='linear', fill_value='extrapolate')(all_carriers)
|
||||||
|
# H_est_phase = scipy.interpolate.interp1d(pilot_carriers, np.angle(H_est_pilots), kind='linear', fill_value='extrapolate')(all_carriers)
|
||||||
|
|
||||||
H_est = H_est / len(in_data)
|
# # Take angular form and turn into rectangular form
|
||||||
|
# H_est += H_est_abs * np.exp(1j*H_est_phase)
|
||||||
|
|
||||||
|
H_est_pilots = np.ndarray((len(pilot_carriers)), dtype=np.csingle)
|
||||||
|
|
||||||
|
j = 0
|
||||||
|
# Obtain channel response at pilot carriers
|
||||||
|
for i in pilot_carriers:
|
||||||
|
H_est_pilots[j] = in_data[0][i] / pilot_value
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
|
||||||
|
# Interpolate estimates based on what we get from the few pilot values
|
||||||
|
H_est_abs = scipy.interpolate.interp1d(pilot_carriers, abs(H_est_pilots), kind='linear', fill_value='extrapolate')(all_carriers)
|
||||||
|
H_est_phase = scipy.interpolate.interp1d(pilot_carriers, np.angle(H_est_pilots), kind='linear', fill_value='extrapolate')(all_carriers)
|
||||||
|
|
||||||
|
# Take angular form and turn into rectangular form
|
||||||
|
H_est += H_est_abs * np.exp(1j*H_est_phase)
|
||||||
|
|
||||||
|
# for an average channel estimate
|
||||||
|
# H_est = H_est / len(in_data)
|
||||||
|
|
||||||
# Exact channel response
|
# Exact channel response
|
||||||
H_exact = np.fft.fft(channel_response, len(in_data[0]))
|
H_exact = np.fft.fft(channel_response, len(in_data[0]))
|
||||||
|
|
||||||
|
for i in range(3):
|
||||||
|
plt.plot(abs(in_data[i]), "b")
|
||||||
|
plt.plot(np.abs(in_data[i]), "r")
|
||||||
|
plt.show(block=True)
|
||||||
|
|
||||||
plt.plot(all_carriers, np.real(H_exact), "b")
|
plt.plot(all_carriers, np.real(H_exact), "b")
|
||||||
plt.plot(all_carriers, np.real(H_est), "r")
|
plt.plot(all_carriers, np.real(H_est), "r")
|
||||||
plt.plot(pilot_carriers, np.real(H_est_pilots), "go")
|
plt.plot(pilot_carriers, np.real(H_est_pilots), "go")
|
||||||
@ -101,6 +129,9 @@ def estimate(in_data, pilots=0):
|
|||||||
plt.plot(pilot_carriers, np.imag(H_est_pilots), "go")
|
plt.plot(pilot_carriers, np.imag(H_est_pilots), "go")
|
||||||
plt.show(block=True)
|
plt.show(block=True)
|
||||||
|
|
||||||
|
print(H_est_pilots)
|
||||||
|
print(H_exact[pilot_carriers])
|
||||||
|
|
||||||
return H_est
|
return H_est
|
||||||
|
|
||||||
|
|
||||||
|
7
main.py
7
main.py
@ -20,7 +20,6 @@ Right now though it's just proof of concept to see if I can get a reliable signa
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
plt.ion()
|
|
||||||
|
|
||||||
import channel
|
import channel
|
||||||
import qam
|
import qam
|
||||||
@ -69,7 +68,7 @@ if __name__ == '__main__':
|
|||||||
parallel = parallelise(64, bytes)
|
parallel = parallelise(64, bytes)
|
||||||
|
|
||||||
# modulate data with a QAM scheme
|
# modulate data with a QAM scheme
|
||||||
modulated = qam.modulate(parallel, pilots=20)
|
modulated = qam.modulate(parallel, pilots=10)
|
||||||
|
|
||||||
# Run IFFT to get a time-domain signal to send
|
# Run IFFT to get a time-domain signal to send
|
||||||
ofdm_time = np.fft.ifft(modulated)
|
ofdm_time = np.fft.ifft(modulated)
|
||||||
@ -87,13 +86,13 @@ if __name__ == '__main__':
|
|||||||
to_equalize = np.fft.fft(ofdm_cp_removed)
|
to_equalize = np.fft.fft(ofdm_cp_removed)
|
||||||
|
|
||||||
# Find an estimate for channel effect
|
# Find an estimate for channel effect
|
||||||
H_est = channel.estimate(to_equalize, pilots=20)
|
H_est = channel.estimate(to_equalize, pilots=10)
|
||||||
|
|
||||||
# Equalise based on estimated channel
|
# Equalise based on estimated channel
|
||||||
to_decode = channel.equalize(to_equalize, H_est)
|
to_decode = channel.equalize(to_equalize, H_est)
|
||||||
|
|
||||||
# Demodulate symbol into output data
|
# Demodulate symbol into output data
|
||||||
to_serialise = qam.demodulate(to_decode, pilots=20)
|
to_serialise = qam.demodulate(to_decode, pilots=10)
|
||||||
|
|
||||||
# Turn data back into string
|
# Turn data back into string
|
||||||
data = serialise(64, to_serialise)
|
data = serialise(64, to_serialise)
|
||||||
|
9
modem.py
Normal file
9
modem.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
"""
|
||||||
|
The modem for communications.
|
||||||
|
|
||||||
|
I need to define my protocol here first.
|
||||||
|
|
||||||
|
Packet:
|
||||||
|
|
||||||
|
Prefix
|
||||||
|
"""
|
3
qam.py
3
qam.py
@ -1,7 +1,7 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.spatial.distance import euclidean
|
from scipy.spatial.distance import euclidean
|
||||||
|
|
||||||
pilot_value = 1 + 1j
|
pilot_value = 5 + 5j
|
||||||
|
|
||||||
qam_mapping_table = {
|
qam_mapping_table = {
|
||||||
0 : 1 + 1j,
|
0 : 1 + 1j,
|
||||||
@ -36,6 +36,7 @@ def modulate(in_data, pilots=0):
|
|||||||
pilot_carriers = all_carriers[::(num_data_carriers + pilots)//pilots]
|
pilot_carriers = all_carriers[::(num_data_carriers + pilots)//pilots]
|
||||||
pilot_carriers = np.delete(pilot_carriers, 0) # not sure how to not have this line
|
pilot_carriers = np.delete(pilot_carriers, 0) # not sure how to not have this line
|
||||||
data_carriers = np.delete(all_carriers, pilot_carriers)
|
data_carriers = np.delete(all_carriers, pilot_carriers)
|
||||||
|
print(pilot_carriers)
|
||||||
else:
|
else:
|
||||||
data_carriers = all_carriers
|
data_carriers = all_carriers
|
||||||
|
|
||||||
|
@ -67,7 +67,10 @@ def serialise(n, in_data):
|
|||||||
new_byte = np.uint8(0)
|
new_byte = np.uint8(0)
|
||||||
|
|
||||||
for k in range(4):
|
for k in range(4):
|
||||||
|
#try:
|
||||||
new_byte |= in_data[i][(j*4) + k] << (k * 2)
|
new_byte |= in_data[i][(j*4) + k] << (k * 2)
|
||||||
|
#except:
|
||||||
|
# print(i)
|
||||||
|
|
||||||
out_data.append(new_byte)
|
out_data.append(new_byte)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user