1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
| import numpy as np from scipy import signal from typing import Tuple
class FR3VitalSignsSimulator: """ FR3频段生命体征感知仿真器 论文核心方法实现: 1. 建模胸腔运动(呼吸+心跳) 2. 模拟FR3频段雷达回波 3. 提取生命体征信号 Args: freq: 载波频率 (Hz), 默认14GHz (FR3中间) tx_power: 发射功率 (dBm) """ def __init__(self, freq=14e9, tx_power=10): self.freq = freq self.wavelength = 3e8 / freq self.tx_power = tx_power self.breathing_rate = 0.25 self.heart_rate = 1.2 self.breathing_amplitude = 6e-3 self.heart_amplitude = 0.3e-3 def model_chest_displacement(self, duration=10, fs=1000): """ 建模胸腔位移(呼吸+心跳叠加) 物理模型: - 呼吸:胸腔大幅度缓慢起伏 - 心跳:胸壁微小快速振动 Returns: displacement: 胸部位移 (m), shape=(N,) """ t = np.arange(0, duration, 1/fs) breathing = self.breathing_amplitude * ( np.sin(2 * np.pi * self.breathing_rate * t) + 0.3 * np.sin(2 * np.pi * 2 * self.breathing_rate * t) ) heartbeat = self.heart_amplitude * ( np.sin(2 * np.pi * self.heart_rate * t) + 0.5 * np.sin(2 * np.pi * 2 * self.heart_rate * t) + 0.2 * np.sin(2 * np.pi * 3 * self.heart_rate * t) ) noise = np.random.normal(0, 0.1e-4, len(t)) displacement = breathing + heartbeat + noise return t, displacement def simulate_radar_echo(self, displacement, target_distance=1.0, snr_db=20): """ 模拟FR3频段雷达回波 物理原理: - 胸腔位移导致相位变化: Δφ = 4π·Δd/λ - FR3波长~2cm, 0.3mm心跳 → Δφ ≈ 0.1 rad (可检测) - sub-6GHz波长~10cm, 0.3mm → Δφ ≈ 0.02 rad (难检测) Args: displacement: 胸部位移 (m) target_distance: 目标距离 snr_db: 信噪比 """ phase_mod = 4 * np.pi * displacement / self.wavelength t = np.arange(len(displacement)) / 1000 carrier = np.exp(1j * (2 * np.pi * self.freq * t + phase_mod)) multipath_delays = [0, 3e-9, 8e-9] multipath_gains = [1.0, 0.5, 0.3] received = np.zeros_like(carrier, dtype=complex) for delay, gain in zip(multipath_delays, multipath_gains): delayed = np.roll(carrier, int(delay * 1000)) received += gain * delayed signal_power = np.mean(np.abs(received)**2) noise_power = signal_power / (10 ** (snr_db / 10)) noise = np.random.normal(0, np.sqrt(noise_power/2), len(received)) + \ 1j * np.random.normal(0, np.sqrt(noise_power/2), len(received)) return received + noise def extract_vital_signs(self, received_signal, fs=1000): """ 从雷达回波提取生命体征 信号处理管道: 1. 相位解调 2. 带通滤波分离呼吸/心跳 3. 频谱分析 """ phase = np.angle(received_signal) phase_unwrapped = np.unwrap(phase) phase_detrended = signal.detrend(phase_unwrapped) breathing_filter = signal.butter(4, [0.1, 0.5], btype='band', fs=fs) breathing_signal = signal.filtfilt(*breathing_filter, phase_detrended) heart_filter = signal.butter(4, [0.8, 2.0], btype='band', fs=fs) heart_signal = signal.filtfilt(*heart_filter, phase_detrended) freqs_b, psd_b = signal.welch(breathing_signal, fs=fs, nperseg=1024) freqs_h, psd_h = signal.welch(heart_signal, fs=fs, nperseg=1024) breathing_freq = freqs_b[np.argmax(psd_b)] heart_freq = freqs_h[np.argmax(psd_h)] return { 'breathing_signal': breathing_signal, 'heart_signal': heart_signal, 'breathing_rate_hz': breathing_freq, 'heart_rate_hz': heart_freq, 'breathing_bpm': breathing_freq * 60, 'heart_bpm': heart_freq * 60 }
def compare_frequency_bands(): """对比FR1/FR3/FR2频段性能""" bands = { 'FR1 (5GHz)': {'freq': 5e9, 'wavelength': 0.06}, 'FR3 (14GHz)': {'freq': 14e9, 'wavelength': 0.0214}, 'FR3 (24GHz)': {'freq': 24e9, 'wavelength': 0.0125}, 'FR2 (60GHz)': {'freq': 60e9, 'wavelength': 0.005}, } print("=" * 75) print("频段对比:心跳微动(0.3mm)的相位变化") print("=" * 75) print(f"{'频段':<15} {'波长(mm)':<12} {'相位变化(rad)':<15} {'可检测性':<10}") print("-" * 75) heart_displacement = 0.3e-3 for name, params in bands.items(): phase_change = 4 * np.pi * heart_displacement / params['wavelength'] detectable = "✅" if phase_change > 0.05 else "⚠️" print(f"{name:<15} {params['wavelength']*1e3:<12.1f} {phase_change:<15.4f} {detectable:<10}") print("\n关键结论:FR3频段(7-24GHz)在心跳检测方面具有最优性价比") print(" - 相位灵敏度远高于FR1") print(" - 多径丰富度优于FR2(mmWave)") print(" - 穿透力优于FR2")
if __name__ == "__main__": simulator = FR3VitalSignsSimulator(freq=14e9) t, displacement = simulator.model_chest_displacement(duration=10) print(f"胸部位移: 范围 [{displacement.min()*1e3:.2f}mm, {displacement.max()*1e3:.2f}mm]") echo = simulator.simulate_radar_echo(displacement, snr_db=20) results = simulator.extract_vital_signs(echo) print(f"\n提取结果:") print(f" 呼吸频率: {results['breathing_bpm']:.1f} bpm (真值: 15.0)") print(f" 心率: {results['heart_bpm']:.1f} bpm (真值: 72.0)") print() compare_frequency_bands()
|