工具与软件:
最近、我一直对我使用 AWR1843BOOST 传感器采集的原始 IQ 数据进行一些后处理。
虽然我已经成功地加载了数据、但我已经通过将原始 IQ 和距离多普勒图与 mmWave Studio 的后处理数据进行比较来验证了这一点、 我有点难以估算 AoA、坦率地说、需要您的帮助、因为我不确定应该如何设计合适的 AoA 信号链。
首先、让我们比较完整的距离-角度图。 我的图解看起来与 mmWave Studio 创建的图类似、其中 MVDR 图具有(正如预期的那样)更高的分辨率。


我很难 计算检测到的目标的 AoA。 首先、我在距离多普勒地图上运行 CA-CFAR、并得到目标列表(range_bin、dopple_bin)。 接下来、我将检测馈送到两个函数 TARGET_AoA_mvdr (...) 和 TARGET_AoA_ANGLE_FFT (……)生成。 我对于这两个职能的问题是:
- 输入数据类型: 我的每个目标 AoA 计算的输入是原始 IQ_DATA 还是 RANGE_多 普勒? 根据 Wikipedia:"延迟和和波束形成是一种时域方法。 它易于实现、但可能无法很好地估算到达方向(DOA)。 对此的解决方案是频域方法。" 基于此、距离-多普勒数据似乎更合适。 但是、从 TI 的介绍视频中、我了解到原始 IQ_DATA 是理想之选。 哪项正确?
- 输入数据形状: 输入数据是否只包含检测坐标处的数据(即、形状为(N_Rx,))? 或者应该采用检测距离区间 bin 处的所有线性调频脉冲(即、具有(N_Rx、N_chirps)的形状、从而产生更可靠的协方差矩阵 Rxx。
- 解析多个目标: 对于检测到的单个目标、AoA 算法应能够返回多个角度。 因此解决了模糊问题、即位于相同距离和 v_rel 处的不同目标、但 AoA 不同。 应使用哪种算法来确定角度 FFT 功率频谱中是否存在单个目标? 一维 CA-CFAR 是否能起作用?
请查看我针对检测到的目标生成的 AoA 图。 我不清楚为什么这些峰看起来偏了、而且这些峰的位置似乎有轻微的偏移。 如果您有任何想法、我很高兴知道。

下面是我用于生成这些图表的代码部分:
DEF TARGET_AoA_ANGLE_FFT (TARGET、FRAME_OI、RAW_FFT_RANGE_多 普勒):
""
: param targets:指定 CA-CFAR 检测的元组列表[(T1_rb、t1_vb )、(T2_rb、T2_vb )、...]
: param FRAME_OI:指定感兴趣的帧
: param raw_fft_range_doppler:距离-多普勒计算的输出。 移动但未采用 ABS 值。
""
range_bins、vel_bins = zip (*目标)
n_targets = len (range_bins)
ANGES_OUT = NP.ZERS (n_targets、dtype=float)
Padding_size = int (90 - N_Rx/2)
对于 i (r_bin、d_bin)、枚举(zip (range_bins、vel_bins)):
# snapshot_iq = IQ_data[FRAME_OI、:、d_bin、r_bin]#形状(N_rx、)
Snapshot_rd = RAW_FFT_RANGE_Doppler[d_bin、r_bin、:]#形状(N_Rx、)
#选择合适的
快照= SNAPSHOT_rd
#垫穿过 Rx DIM
Snapshot_padded = Np.pad (snapshot、pad_width=[(padding_size、padding_size + 1)]、mode='constant')
#执行角度 FFT
ANGLE_FFT_SHIFT = NP.FFT.fftshift (NP.FFT.FFT (SNAPSHOT_PAKED、Axis=0)、Axis=0)
ANGLE_POWER = NP.ABS (ANGLE_FFT_SHIFT)** 2.
ANGLE_POWER_dB = 10 * np.log10 (ANGLE_POWER + 1e-12)
detection_angles = np.argmax (ANGLE_POWER_dB)
ANGLE_OUT[i]= detection_angles
PLT.Figure ()
plt.plot(angle_power_dB)
plt.xlabel ('AoA (deg)')
plt.ylabel ("Angle-FFT 功率谱")
plt.title (f"AoA spectrum for:target No.{i}<-> Range bin{range_bin[0]}")
plt.xtick (ANGLE_TICK_POSITIONS、ANGLE_TICK_labels)
plt.grid ()
PLT.show (块=假)
返回 ANGLE_OUT
DEF TARGET_AoA_mvdr (TARGETS、FRAME_OI、RAW_FFT_RANGE_多 普勒):
range_bins、vel_bins = zip (*目标)
n_targets = len (range_bins)
steering _array = compute_steering _vector (num_ant=N_Rx、angle_res=1.0、angle_rng=90.0)现在(181、4)形状(N_ANGLES、N_Rx)
ANGES_OUT = NP.ZERS (n_targets、dtype=float)
对于 i (r_bin、d_bin)、枚举(zip (range_bins、vel_bins)):
Snapshot_iq = IQ_DATA[FRAME_OI、:、d_bin、r_bin]#形状(N_Rx、)
Snapshot_rd = RAW_FFT_RANGE_Doppler[d_bin、r_bin、:]#形状(N_Rx、)
Snapshot_bins_iq = IQ_DATA[FRAME_OI、:、:、r_bin]#形状(N_Rx、N_chirps)
Snapshot_bins_rd = RAW_FFT_RANGE_多 普勒[:、r_bin、:].T 转换前的形状(N_chirps、N_rx)
#选择合适的
input_data = snapshot_bins_rd
#计算目标距离库(或坐标(即 range_bin、vel_bin)的 MVDR 频谱???)
mvdr_spectrum = np.zers (steering _array.shape[0]、dtype='complex')
Rxx = INPUT_DATA @ NP.conj (INPUT_DATA).t
Rxx_fb = forward_background_avg (Rxx)
rxx_inv = np.linalg.inv(Rxx_fb + 1e-9 * np.eye (N_Rx))
对于 RANGE (steading_array.shape[0])中的 ANGLE_idx:
s_vector = steering _array[angle_idx、:]
power_mvdr = np.倒数(s_vector.conj ().T @ rxx_inv @ s_vector)
mvdr_spectrum[angle_idx]= power_mvdr
#将 MVDR 频谱转换为 dB
mvdr_spectrum_power = np.abs (mvdr_spectrum)** 2.
mvdr_dspectr_db = 10 * np.log10 (mvdr_dspectr_power + 1e-12)
PLT.Figure ()
plt.plot(mvdr_spectrum_dB)
plt.xlabel ('AoA (deg)')
plt.ylabel ('MVDR 功率频谱')
PLT.TITLE (f"MVDR spectrum for:target No.{i}<-> Range bin{range_bin[0]}")
plt.xtick (ANGLE_TICK_POSITIONS、ANGLE_TICK_labels)
plt.grid ()
PLT.show (块=假)
返回 ANGLE_OUT