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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
| """ Calterah多站UWB感知仿真 单站(monostatic) vs 多站(multistatic)对比
依赖: numpy, matplotlib """
import numpy as np from typing import List, Tuple
class UWBSensingSimulator: """ UWB座舱感知仿真器 对比: 1. 单站: 1个锚点自发自收 2. 多站: 多个锚点同步收发 场景: 座椅上有一个儿童(目标) 锚点: 4个UWB节点(前左、前右、后左、后右) """ def __init__(self): self.cabin_length = 3.0 self.cabin_width = 1.8 self.cabin_height = 1.2 self.anchors = { 'front_left': np.array([0.3, 0.3, 0.8]), 'front_right': np.array([0.3, 1.5, 0.8]), 'rear_left': np.array([2.7, 0.3, 0.8]), 'rear_right': np.array([2.7, 1.5, 0.8]), 'center': np.array([1.5, 0.9, 0.6]), } self.target = np.array([2.0, 0.9, 0.3]) self.bandwidth = 500e6 self.center_freq = 8.5e9 self.wavelength = 3e8 / self.center_freq def simulate_monostatic(self, anchor_name='center'): """ 单站UWB: 一个锚点自发自收 问题: - 只有一个视角,遮挡即失效 - 角度分辨率差 - 多径衰落敏感 """ anchor = self.anchors[anchor_name] distance = np.linalg.norm(self.target - anchor) t_delay = 2 * distance / 3e8 breath_freq = 0.2 heart_freq = 1.25 breath_amp = 0.004 heart_amp = 0.0003 t = np.linspace(0, 5, 1000) chest_motion = (breath_amp * np.sin(2*np.pi*breath_freq*t) + heart_amp * np.sin(2*np.pi*heart_freq*t)) phase = 4 * np.pi * (distance + chest_motion) / self.wavelength return { 'mode': 'monostatic', 'anchor': anchor_name, 'distance': distance, 'phase': phase, 'chest_motion': chest_motion, 'issues': [ '单视角,遮挡即失效', '角度分辨率差', '多径衰落敏感', '近距离目标盲区' ] } def simulate_multistatic(self, anchor_names=None): """ 多站UWB: 多个锚点同步收发 优势: - 空间分集,消除遮挡 - 三角测量提高角度分辨率 - 多径去相关,衰落鲁棒 - 生命体征交叉验证 """ if anchor_names is None: anchor_names = list(self.anchors.keys()) anchors = [self.anchors[name] for name in anchor_names] n_anchors = len(anchors) distances = [] phases = [] t = np.linspace(0, 5, 1000) breath_freq = 0.2 heart_freq = 1.25 breath_amp = 0.004 heart_amp = 0.0003 chest_motion = (breath_amp * np.sin(2*np.pi*breath_freq*t) + heart_amp * np.sin(2*np.pi*heart_freq*t)) for i, tx in enumerate(anchors): for j, rx in enumerate(anchors): if i == j: continue d_tx = np.linalg.norm(self.target - tx) d_rx = np.linalg.norm(self.target - rx) d_total = d_tx + d_rx distances.append({ 'tx': anchor_names[i], 'rx': anchor_names[j], 'distance': d_total }) phase = 2 * np.pi * (d_total + chest_motion) / self.wavelength phases.append(phase) fused_phase = np.mean(phases, axis=0) from scipy.signal import butter, filtfilt b_breath, a_breath = butter(4, [0.1, 0.5], btype='band', fs=200) breath_signal = filtfilt(b_breath, a_breath, fused_phase) b_heart, a_heart = butter(4, [0.8, 2.0], btype='band', fs=200) heart_signal = filtfilt(b_heart, a_heart, fused_phase) return { 'mode': 'multistatic', 'n_anchors': n_anchors, 'n_links': len(distances), 'distances': distances, 'fused_phase': fused_phase, 'breath_signal': breath_signal, 'heart_signal': heart_signal, 'advantages': [ f'{len(distances)}条多站链路交叉验证', '空间分集消除遮挡', '三角测量提高定位精度', '多径去相关提升信噪比', '可分离近距离目标(儿童vs成人)' ] } def compare_detection_accuracy(self): """对比单站vs多站的检测精度""" n_trials = 100 mono_detect = 0 multi_detect = 0 for _ in range(n_trials): obscured = np.random.choice(['none', 'left', 'right', 'front']) if obscured == 'none': mono_detect += 1 if obscured == 'left': visible = ['front_right', 'rear_right'] elif obscured == 'right': visible = ['front_left', 'rear_left'] elif obscured == 'front': visible = ['rear_left', 'rear_right'] else: visible = list(self.anchors.keys()) if len(visible) >= 2: multi_detect += 1 return { 'monostatic_detection_rate': mono_detect / n_trials, 'multistatic_detection_rate': multi_detect / n_trials, 'improvement': (multi_detect - mono_detect) / n_trials }
if __name__ == "__main__": sim = UWBSensingSimulator() print("=" * 60) print("Calterah多站UWB vs 单站UWB 对比仿真") print("=" * 60) print(f"\nUWB锚点位置:") for name, pos in sim.anchors.items(): print(f" {name}: {pos}") print(f" 目标(儿童): {sim.target}") mono = sim.simulate_monostatic('center') print(f"\n--- 单站UWB ---") print(f" 锚点: {mono['anchor']}") print(f" 距离: {mono['distance']:.3f}m") print(f" 问题:") for issue in mono['issues']: print(f" ❌ {issue}") multi = sim.simulate_multistatic() print(f"\n--- 多站UWB ---") print(f" 锚点数: {multi['n_anchors']}") print(f" 多站链路数: {multi['n_links']}") print(f" 优势:") for adv in multi['advantages']: print(f" ✅ {adv}") comp = sim.compare_detection_accuracy() print(f"\n--- 蒙特卡洛检测率对比 (100次) ---") print(f" 单站检测率: {comp['monostatic_detection_rate']:.1%}") print(f" 多站检测率: {comp['multistatic_detection_rate']:.1%}") print(f" 提升幅度: +{comp['improvement']:.1%}")
|