Cleaned up localization code for the 3rd time!

This commit is contained in:
Malik Ali 2025-12-05 11:52:02 +01:00
parent f4442a05f5
commit 705a63e161

View File

@ -3,7 +3,7 @@ import matplotlib.pyplot as plt # For plotting for tests
from scipy.io import wavfile # For reading .wav files for testing
from scipy.signal import find_peaks # For cropping the microphone recordings
from scipy.fft import fft, ifft # For channel estimation
from scipy.fft import fft, ifft, fftshift # For channel estimation
from scipy.optimize import least_squares # For estimating KITT's location
def recording_crop_normalize(recordings, ref_mic):
@ -13,8 +13,8 @@ def recording_crop_normalize(recordings, ref_mic):
ref_peak = ref_peaks[-1]
# Cropping all recordings to show only the peaks around the reference peak
start = ref_peak - 1500
end = ref_peak + 1500
start = ref_peak - 3600
end = ref_peak + 3600
recordings = recordings[start:end]
# Normalizing all recordings after they are cropped
@ -28,15 +28,15 @@ def recording_crop_normalize(recordings, ref_mic):
def channel_estimation(recording, reference_recording, epsilon):
# Finding both the recording and the reference recording in the frequency domain
padded_length = max(len(recording), len(reference_recording))
rec_freq = fft(recording, padded_length-len(recording))
ref_rec_freq = fft(reference_recording, padded_length-len(reference_recording))
rec_freq = fft(recording, padded_length)
ref_rec_freq = fft(reference_recording, padded_length)
# Performing the deconvolution in the frequency domain
ch_est_freq = (ref_rec_freq*np.conj(rec_freq))/(np.abs(rec_freq)**2+epsilon)
# Finding the channel estimation in the time domain and centre it
channel_estimate = np.real(ifft(ch_est_freq))
channel_estimate = np.fft.fftshift(channel_estimate)
channel_estimate = abs(ifft(ch_est_freq))
channel_estimate = fftshift(channel_estimate)
return channel_estimate
def distance_calc(channel_estimate, sampling_rate):
@ -57,16 +57,17 @@ def location_estimation(mic_locations, ref_mic, distances, start_point = None):
# Using the location of the reference microphone as the refence point
ref_point = mic_locations[ref_mic]
other_indices = [i for i in range(mic_locations.shape[0]) if i != ref_mic]
# Generating the residuals function that is to be minimized. This residual is the difference between the "guessed" location and the location calculated from the microphone recordings
def residuals_function(guess):
guess = np.array([guess[0],guess[1],0])
residuals = []
for i, idx in enumerate(other_indices):
mic = mic_locations[idx]
residual = (np.linalg.norm(guess-mic) - np.linalg.norm(guess-ref_point)) - distances[i]
residuals.append(residual)
mic, axs = mic_locations.shape
for i in range(mic):
if i != ref_mic:
mic_location = mic_locations[i]
residual = (np.linalg.norm(guess-mic_location) - np.linalg.norm(guess-ref_point)) + distances[i]
residuals.append(residual)
return residuals
# Using the least squares method to minimize the residuals function
@ -85,9 +86,7 @@ def localization(recordings, sampling_rate):
channel_estimates = []
recording, mic = recordings.shape
for i in range(mic):
if i == ref_mic:
continue
else:
if i != ref_mic:
channel_estimates.append(channel_estimation(recordings[:, i], recordings[:, ref_mic], epsilon))
# Finding the distances that correspond to the Time Difference of Arrival (TDOA) for each channel estimate