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 "Beamforming". It includes the classic delay-and-sum (DS) beamforming and the weighted DS beamforming, using #
5+ # RSSI data for the weights. #
6+ # =================================================================================================================================== #
7+
8+
9+ # =================================================================================================================================== #
10+ # --------------------------------------------------------- EXTERNAL IMPORTS -------------------------------------------------------- #
11+ import numpy as np # Mathematical functions. #
12+ # =================================================================================================================================== #
13+
14+
15+ # =================================================================================================================================== #
16+ # ------------------------------------------------------- BEAMFORMING FUNCTION ------------------------------------------------------ #
17+ def beamforming_spectrum_calculation (phasor1 , phasor2 , rssi1 , rssi2 , L , wavelength , aoa_scan ):
18+ """
19+ Calculate the beamforming spectrum (both standard and RSSI-weighted) for RFID AoA estimation.
20+
21+ Parameters:
22+ - phasor1 [np.ndarray] : Complex phasors from antenna 1
23+ - phasor2 [np.ndarray] : Complex phasors from antenna 2
24+ - rssi1 [np.ndarray] : RSSI values from antenna 1 (in dBm)
25+ - rssi2 [np.ndarray] : RSSI values from antenna 2 (in dBm)
26+ - L [float] : Antenna separation distance (in meters)
27+ - wavelength [float] : Signal wavelength (in meters)
28+ - aoa_scan [np.ndarray] : Array of angles to scan (in degrees)
29+
30+ Returns:
31+ - tuple : (B_ds, B_w, theta_ds, theta_w)
32+ - B_ds : Standard delay-and-sum beamforming spectrum
33+ - B_w : RSSI-weighted beamforming spectrum
34+ - theta_ds : Estimated angle using standard beamforming
35+ - theta_w : Estimated angle using RSSI-weighted beamforming
36+ """
37+ # STEP 1: Align phasors to the same length
38+ N = min (len (phasor1 ), len (phasor2 ))
39+ phasor1 = phasor1 [:N ]
40+ phasor2 = phasor2 [:N ]
41+ # STEP 2: Transform RSSI from dBm to linear scale, and normalize by minimum value
42+ all_rssi = [rssi1 , rssi2 ]
43+ rssi_min = min ([np .min (r ) for r in all_rssi ])
44+ w1 = np .sqrt (10 ** ((rssi1 - rssi_min ) / 10 )) # Weight for antenna 1
45+ w2 = np .sqrt (10 ** ((rssi2 - rssi_min ) / 10 )) # Weight for antenna 2
46+ # STEP 3: Calculate the beamforming spectrum
47+ k = 2 * np .pi / wavelength # Wave number
48+ M = len (aoa_scan )
49+ B_ds = np .zeros (M ) # Standard delay-and-sum spectrum
50+ B_w = np .zeros (M ) # RSSI-weighted spectrum
51+ for m in range (M ):
52+ # Phase shift based on angle
53+ dphi = k * L * np .sin (np .deg2rad (aoa_scan [m ]))
54+ # Standard delay-and-sum beamforming
55+ y_ds = phasor1 + np .exp (- 1j * dphi ) * phasor2
56+ B_ds [m ] = np .mean (np .abs (y_ds )** 2 )
57+ # RSSI-weighted beamforming
58+ y_w = w1 * phasor1 + np .exp (- 1j * dphi ) * (w2 * phasor2 )
59+ B_w [m ] = np .mean (np .abs (y_w )** 2 )
60+ # STEP 4: Normalize spectra
61+ B_ds = B_ds / np .max (B_ds ) if np .max (B_ds ) > 0 else B_ds
62+ B_w = B_w / np .max (B_w ) if np .max (B_w ) > 0 else B_w
63+ # STEP 5: Find peak angles
64+ theta_ds = aoa_scan [np .argmax (B_ds )]
65+ theta_w = aoa_scan [np .argmax (B_w )]
66+ return B_ds , B_w , theta_ds , theta_w
67+ # =================================================================================================================================== #
0 commit comments