mirror of
https://gitlab.ewi.tudelft.nl/ee2l1/2025-2026/A.K.03.git
synced 2025-12-12 15:00:55 +01:00
Compare commits
No commits in common. "2c48f12d0e91b371a2ffcd9bcf15e1e67866c224" and "f4442a05f5a62fafa91edb5bf26f3bb5187751fc" have entirely different histories.
2c48f12d0e
...
f4442a05f5
2
.idea/A.K.03.iml
generated
2
.idea/A.K.03.iml
generated
@ -4,7 +4,7 @@
|
|||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.13 (A.K.03)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.11 (A.K.03)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PyDocumentationSettings">
|
<component name="PyDocumentationSettings">
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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.io import wavfile # For reading .wav files for testing
|
||||||
from scipy.signal import find_peaks # For cropping the microphone recordings
|
from scipy.signal import find_peaks # For cropping the microphone recordings
|
||||||
from scipy.fft import fft, ifft, fftshift # For channel estimation
|
from scipy.fft import fft, ifft # For channel estimation
|
||||||
from scipy.optimize import least_squares # For estimating KITT's location
|
from scipy.optimize import least_squares # For estimating KITT's location
|
||||||
|
|
||||||
def recording_crop_normalize(recordings, ref_mic):
|
def recording_crop_normalize(recordings, ref_mic):
|
||||||
@ -13,8 +13,8 @@ def recording_crop_normalize(recordings, ref_mic):
|
|||||||
ref_peak = ref_peaks[-1]
|
ref_peak = ref_peaks[-1]
|
||||||
|
|
||||||
# Cropping all recordings to show only the peaks around the reference peak
|
# Cropping all recordings to show only the peaks around the reference peak
|
||||||
start = ref_peak - 3600
|
start = ref_peak - 1500
|
||||||
end = ref_peak + 3600
|
end = ref_peak + 1500
|
||||||
recordings = recordings[start:end]
|
recordings = recordings[start:end]
|
||||||
|
|
||||||
# Normalizing all recordings after they are cropped
|
# 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):
|
def channel_estimation(recording, reference_recording, epsilon):
|
||||||
# Finding both the recording and the reference recording in the frequency domain
|
# Finding both the recording and the reference recording in the frequency domain
|
||||||
padded_length = max(len(recording), len(reference_recording))
|
padded_length = max(len(recording), len(reference_recording))
|
||||||
rec_freq = fft(recording, padded_length)
|
rec_freq = fft(recording, padded_length-len(recording))
|
||||||
ref_rec_freq = fft(reference_recording, padded_length)
|
ref_rec_freq = fft(reference_recording, padded_length-len(reference_recording))
|
||||||
|
|
||||||
# Performing the deconvolution in the frequency domain
|
# Performing the deconvolution in the frequency domain
|
||||||
ch_est_freq = (ref_rec_freq*np.conj(rec_freq))/(np.abs(rec_freq)**2+epsilon)
|
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
|
# Finding the channel estimation in the time domain and centre it
|
||||||
channel_estimate = abs(ifft(ch_est_freq))
|
channel_estimate = np.real(ifft(ch_est_freq))
|
||||||
channel_estimate = fftshift(channel_estimate)
|
channel_estimate = np.fft.fftshift(channel_estimate)
|
||||||
return channel_estimate
|
return channel_estimate
|
||||||
|
|
||||||
def distance_calc(channel_estimate, sampling_rate):
|
def distance_calc(channel_estimate, sampling_rate):
|
||||||
@ -57,17 +57,16 @@ def location_estimation(mic_locations, ref_mic, distances, start_point = None):
|
|||||||
|
|
||||||
# Using the location of the reference microphone as the refence point
|
# Using the location of the reference microphone as the refence point
|
||||||
ref_point = mic_locations[ref_mic]
|
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
|
# 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):
|
def residuals_function(guess):
|
||||||
guess = np.array([guess[0],guess[1],0])
|
guess = np.array([guess[0],guess[1],0])
|
||||||
residuals = []
|
residuals = []
|
||||||
mic, axs = mic_locations.shape
|
for i, idx in enumerate(other_indices):
|
||||||
for i in range(mic):
|
mic = mic_locations[idx]
|
||||||
if i != ref_mic:
|
residual = (np.linalg.norm(guess-mic) - np.linalg.norm(guess-ref_point)) - distances[i]
|
||||||
mic_location = mic_locations[i]
|
residuals.append(residual)
|
||||||
residual = (np.linalg.norm(guess-mic_location) - np.linalg.norm(guess-ref_point)) + distances[i]
|
|
||||||
residuals.append(residual)
|
|
||||||
return residuals
|
return residuals
|
||||||
|
|
||||||
# Using the least squares method to minimize the residuals function
|
# Using the least squares method to minimize the residuals function
|
||||||
@ -86,7 +85,9 @@ def localization(recordings, sampling_rate):
|
|||||||
channel_estimates = []
|
channel_estimates = []
|
||||||
recording, mic = recordings.shape
|
recording, mic = recordings.shape
|
||||||
for i in range(mic):
|
for i in range(mic):
|
||||||
if i != ref_mic:
|
if i == ref_mic:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
channel_estimates.append(channel_estimation(recordings[:, i], recordings[:, ref_mic], epsilon))
|
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
|
# Finding the distances that correspond to the Time Difference of Arrival (TDOA) for each channel estimate
|
||||||
@ -118,7 +119,6 @@ if __name__ == "__main__":
|
|||||||
real_y = record_y[i]
|
real_y = record_y[i]
|
||||||
filenames.append(f"../files/Student Recordings/record_x{real_x}_y{real_y}.wav")
|
filenames.append(f"../files/Student Recordings/record_x{real_x}_y{real_y}.wav")
|
||||||
|
|
||||||
# Performing the location estimation on each file
|
|
||||||
for i in range(len(filenames)):
|
for i in range(len(filenames)):
|
||||||
sampling_rate, recordings = wavfile.read(filenames[i])
|
sampling_rate, recordings = wavfile.read(filenames[i])
|
||||||
print(f"\nRecording {i+1}: {filenames[i]}")
|
print(f"\nRecording {i+1}: {filenames[i]}")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user