Skip to content

Commit 7323fc1

Browse files
committed
feat: refactored music
1 parent c63a256 commit 7323fc1

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/music.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# =================================================================================================================================== #
2+
# ----------------------------------------------------------- DESCRIPTION ----------------------------------------------------------- #
3+
# This script contains the functions for analyzing Angle of Arrival (AoA) measurements from RFID systems, using the classical #
4+
# antenna-array method "MUSIC Algorithm". #
5+
# =================================================================================================================================== #
6+
7+
8+
# =================================================================================================================================== #
9+
# --------------------------------------------------------- EXTERNAL IMPORTS -------------------------------------------------------- #
10+
import numpy as np # Mathematical functions. #
11+
# =================================================================================================================================== #
12+
13+
14+
# =================================================================================================================================== #
15+
# ---------------------------------------------------------- MUSIC FUNCTION --------------------------------------------------------- #
16+
def music_algorithm(phasor1, phasor2, L, wavelength, aoa_scan):
17+
"""
18+
Implement the MUSIC (MUltiple SIgnal Classification) algorithm for RFID AoA estimation.
19+
20+
Parameters:
21+
phasor1 [np.ndarray] : Complex phasors from antenna 1
22+
phasor2 [np.ndarray] : Complex phasors from antenna 2
23+
L [float] : Antenna separation distance (in meters)
24+
wavelength [float] : Signal wavelength (in meters)
25+
aoa_scan [np.ndarray] : Array of angles to scan (in degrees)
26+
27+
Returns:
28+
- tuple : (theta_music, P_music)
29+
- theta_music : Estimated angle using MUSIC algorithm
30+
- P_music : MUSIC spectrum
31+
"""
32+
# STEP 1: Form spatial covariance matrix
33+
# Reshape phasors to column vectors and combine
34+
x1 = phasor1.reshape(-1, 1)
35+
x2 = phasor2.reshape(-1, 1)
36+
X = np.hstack((x1, x2)) # Combine signals from both antennas
37+
# Calculate spatial covariance matrix
38+
R = X.conj().T @ X / X.shape[0]
39+
# STEP 2: Eigendecomposition
40+
eigenvalues, eigenvectors = np.linalg.eig(R)
41+
# Sort eigenvectors by eigenvalues in descending order
42+
idx = np.argsort(eigenvalues)[::-1]
43+
eigenvectors = eigenvectors[:, idx]
44+
# STEP 3: Noise subspace (assuming 1 signal, so 1 eigenvector for signal)
45+
# Take all eigenvectors except the first one
46+
En = eigenvectors[:, 1:]
47+
# STEP 4: MUSIC spectrum calculation
48+
k = 2 * np.pi / wavelength
49+
P_music = np.zeros(len(aoa_scan))
50+
for i in range(len(aoa_scan)):
51+
# Array steering vector
52+
a = np.array([1, np.exp(-1j * k * L * np.sin(np.deg2rad(aoa_scan[i])))])
53+
a = a.reshape(-1, 1)
54+
# MUSIC pseudospectrum - FIX: Extract scalar value using .item()
55+
denominator = a.conj().T @ (En @ En.conj().T) @ a
56+
P_music[i] = 1 / np.abs(denominator.item()) # Use .item() to extract scalar value
57+
# STEP 5: Normalize spectrum
58+
P_music = P_music / np.max(P_music) if np.max(P_music) > 0 else P_music
59+
# STEP 6: Find peak
60+
theta_music = aoa_scan[np.argmax(P_music)]
61+
62+
return theta_music, P_music

0 commit comments

Comments
 (0)