ARIA HYDROGEN:世界首款 3D UWB 雷达 SoC 完全解析(含信号处理代码)

前言

儿童存在检测(CPD)是 Euro NCAP 2026 强制要求。ARIA SENSING HYDROGEN 是世界首款真 3D UWB 雷达 SoC,专为舱内感知设计。

核心数据:

参数 规格
芯片型号 HYDROGEN v1.1
封装 9×9mm QFN64
功耗 90mA @ 1.8V = 162mW
处理器 双 RISC-V 核心
天线配置 4Tx + 4Rx MIMO
带宽 500MHz - 1.8GHz 可编程
角分辨率 ~5°(数字波束成形)
检测维度 1D / 2D / 3D

一、硬件完整规格

1.1 HYDROGEN SoC 规格表

参数类别 规格 备注
射频参数
工作频段 3-10 GHz UWB 多中心频率支持
可编程带宽 500 MHz - 1.8 GHz 最高分辨率模式
发射通道 4 个 可配置
接收通道 4 个 可配置
处理器
主处理器 双 RISC-V MCU 内置
DSP 能力 支持 时域/频域处理
功耗
工作电流 90 mA @ 1.8V
功耗 162 mW 远低于 mmWave
封装
封装类型 QFN64 9×9mm
工作温度 -40°C ~ +85°C 车规

1.2 与传统方案对比

维度 HYDROGEN UWB 60GHz mmWave 传统 UWB
角分辨率 ~5° ~10-15° N/A(仅测距)
带宽 1.8 GHz 4 GHz < 1 GHz
功耗 162 mW 500-1000 mW 100-200 mW
穿透性 ✅ 强 ⚠️ 中 ✅ 强
3D 检测 ✅ 原生支持 ⚠️ 需多芯片 ❌ 仅 1D/2D
成本

1.3 开发板与评估套件

产品 型号 用途
芯片 HYDROGEN v1.1 SoC 本体
评估板 待确认 开发测试
演示系统 CPD Demo Kit 车载 CPD 方案

二、信号处理算法代码

2.1 呼吸检测信号处理

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
"""
UWB 雷达呼吸检测信号处理
基于 HYDROGEN SoC 输出的原始 ADC 数据

依赖:numpy, scipy
"""

import numpy as np
from scipy import signal
from scipy.fft import fft, fftfreq

class UWBBreathingDetector:
"""UWB 雷达呼吸检测器"""

def __init__(self, fs: float = 20.0):
"""
初始化检测器

Args:
fs: 采样率 (Hz),典型值 10-30 Hz
"""
self.fs = fs
# 呼吸频率范围 (儿童: 12-30 bpm = 0.2-0.5 Hz)
self.breath_band = (0.15, 0.6) # Hz
# 心跳频率范围 (儿童: 80-140 bpm = 1.33-2.33 Hz)
self.heart_band = (1.0, 2.5) # Hz

def process_raw_adc(self, adc_data: np.ndarray) -> np.ndarray:
"""
处理原始 ADC 数据,提取距离-时间矩阵

Args:
adc_data: shape (n_samples, n_range_bins)

Returns:
range_time_matrix: shape (n_slow_time, n_range_bins)
"""
# 慢时间 FFT(多普勒处理)
n_samples, n_range = adc_data.shape

# 沿慢时间轴做 FFT
doppler_matrix = np.abs(fft(adc_data, axis=0))

return doppler_matrix

def extract_vital_signs(self, range_bin_data: np.ndarray,
duration: float = 10.0) -> dict:
"""
从指定距离bin提取生命体征

Args:
range_bin_data: 单个距离bin的时域数据
duration: 分析时长 (秒)

Returns:
dict: breathing_rate, heart_rate, confidence
"""
n = len(range_bin_data)

# 去除直流分量
data_centered = range_bin_data - np.mean(range_bin_data)

# 带通滤波
nyq = self.fs / 2

# 呼吸频段滤波
b_breath, a_breath = signal.butter(
4,
[self.breath_band[0] / nyq, self.breath_band[1] / nyq],
btype='band'
)
breath_signal = signal.filtfilt(b_breath, a_breath, data_centered)

# 心跳频段滤波
b_heart, a_heart = signal.butter(
4,
[self.heart_band[0] / nyq, self.heart_band[1] / nyq],
btype='band'
)
heart_signal = signal.filtfilt(b_heart, a_heart, data_centered)

# 频谱分析
freq = fftfreq(n, 1/self.fs)[:n//2]

breath_spectrum = np.abs(fft(breath_signal))[:n//2]
heart_spectrum = np.abs(fft(heart_signal))[:n//2]

# 找主频
breath_idx = np.argmax(breath_spectrum)
heart_idx = np.argmax(heart_spectrum)

breathing_rate_hz = freq[breath_idx]
heart_rate_hz = freq[heart_idx]

# 转换为 BPM
breathing_bpm = breathing_rate_hz * 60
heart_bpm = heart_rate_hz * 60

# 置信度计算(频谱峰值与平均值比)
breath_confidence = breath_spectrum[breath_idx] / np.mean(breath_spectrum)
heart_confidence = heart_spectrum[heart_idx] / np.mean(heart_spectrum)

return {
'breathing_rate_bpm': breathing_bpm,
'heart_rate_bpm': heart_bpm,
'breathing_confidence': breath_confidence,
'heart_confidence': heart_confidence,
'breath_signal': breath_signal,
'heart_signal': heart_signal
}

def classify_target(self, vital_signs: dict) -> str:
"""
根据生命体征分类目标

Args:
vital_signs: 生命体征检测结果

Returns:
'child', 'adult', 'pet', 'unknown'
"""
breathing = vital_signs['breathing_rate_bpm']

# 儿童呼吸频率: 12-30 bpm (睡眠时可能更低)
# 成人呼吸频率: 12-20 bpm
# 宠物呼吸频率: 15-40 bpm (取决于体型)

if vital_signs['breathing_confidence'] < 2.0:
return 'unknown'

if breathing < 10:
return 'unknown' # 信号质量差
elif 20 <= breathing <= 35:
return 'child' # 儿童特征呼吸频率
elif 12 <= breathing < 20:
return 'adult'
elif breathing > 35:
return 'pet'
else:
return 'unknown'


# 使用示例
if __name__ == "__main__":
detector = UWBBreathingDetector(fs=20.0)

# 模拟数据 (实际从 HYDROGEN ADC 读取)
n_samples = 200 # 10秒 @ 20Hz
n_range_bins = 100
adc_data = np.random.randn(n_samples, n_range_bins) * 0.1

# 添加模拟呼吸信号到距离 bin 50
t = np.arange(n_samples) / 20.0
breathing_signal = 0.5 * np.sin(2 * np.pi * 0.35 * t) # 21 bpm
adc_data[:, 50] += breathing_signal

# 检测生命体征
vital_signs = detector.extract_vital_signs(adc_data[:, 50])

print(f"呼吸频率: {vital_signs['breathing_rate_bpm']:.1f} BPM")
print(f"心跳频率: {vital_signs['heart_rate_bpm']:.1f} BPM")
print(f"目标分类: {detector.classify_target(vital_signs)}")

2.2 数字波束成形代码

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
"""
HYDROGEN 4×4 MIMO 数字波束成形
使用时域延迟求和波束成形
"""

import numpy as np

class DigitalBeamformer:
"""HYDROGEN 数字波束成形器"""

def __init__(self, n_tx: int = 4, n_rx: int = 4,
c: float = 3e8, fc: float = 6e9):
"""
初始化波束成形器

Args:
n_tx: 发射天线数
n_rx: 接收天线数
c: 光速
fc: 中心频率
"""
self.n_tx = n_tx
self.n_rx = n_rx
self.c = c
self.fc = fc
self.wavelength = c / fc

# 天线阵列间距 (假设半波长)
self.d = self.wavelength / 2

def compute_steering_vector(self, theta: float, phi: float) -> np.ndarray:
"""
计算波束指向向量

Args:
theta: 方位角 (弧度)
phi: 仰角 (弧度)

Returns:
steering_vector: shape (n_rx,)
"""
# 假设均匀线阵
k = 2 * np.pi / self.wavelength

steering = np.zeros(self.n_rx, dtype=complex)
for i in range(self.n_rx):
# 天线位置
ant_pos = i * self.d
# 相位延迟
delay = k * ant_pos * np.sin(theta) * np.cos(phi)
steering[i] = np.exp(1j * delay)

return steering

def beamform(self, rx_data: np.ndarray,
theta_scan: np.ndarray) -> np.ndarray:
"""
对接收数据进行波束成形扫描

Args:
rx_data: shape (n_samples, n_rx)
theta_scan: 扫描角度数组 (弧度)

Returns:
beamformed: shape (n_samples, n_angles)
"""
n_samples, n_rx = rx_data.shape
n_angles = len(theta_scan)

beamformed = np.zeros((n_samples, n_angles), dtype=complex)

for i, theta in enumerate(theta_scan):
w = self.compute_steering_vector(theta, 0)
# 归一化权重
w = w / np.sqrt(np.sum(np.abs(w)**2))
# 加权求和
beamformed[:, i] = np.dot(rx_data, w.conj())

return beamformed

def find_target_angle(self, rx_data: np.ndarray,
theta_scan: np.ndarray) -> float:
"""
查找目标角度

Args:
rx_data: 接收数据
theta_scan: 扫描角度

Returns:
target_angle: 目标角度 (弧度)
"""
beamformed = self.beamform(rx_data, theta_scan)

# 计算各角度能量
energy = np.sum(np.abs(beamformed)**2, axis=0)

# 找峰值
peak_idx = np.argmax(energy)

return theta_scan[peak_idx]


# 使用示例
if __name__ == "__main__":
bf = DigitalBeamformer(n_tx=4, n_rx=4, fc=6e9)

# 扫描角度范围: -60° 到 +60°
theta_scan = np.linspace(-np.pi/3, np.pi/3, 61)

# 模拟接收数据 (假设目标在 30°)
n_samples = 100
target_theta = np.pi / 6 # 30°
true_steering = bf.compute_steering_vector(target_theta, 0)

# 生成模拟信号
signal = np.random.randn(n_samples) + 1j * np.random.randn(n_samples)
rx_data = np.outer(signal, true_steering)
rx_data += 0.1 * (np.random.randn(n_samples, 4) +
1j * np.random.randn(n_samples, 4))

# 检测角度
detected_angle = bf.find_target_angle(rx_data, theta_scan)
print(f"真实角度: {np.degrees(target_theta):.1f}°")
print(f"检测角度: {np.degrees(detected_angle):.1f}°")

2.3 CPD 完整检测流程

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
"""
HYDROGEN CPD 完整检测流程
集成呼吸检测 + 波束成形 + 目标分类
"""

import numpy as np
from dataclasses import dataclass
from enum import Enum
from typing import List, Tuple, Optional

class TargetType(Enum):
CHILD = "child"
ADULT = "adult"
PET = "pet"
OBJECT = "object"
UNKNOWN = "unknown"

@dataclass
class DetectedTarget:
"""检测到的目标"""
target_type: TargetType
position: Tuple[float, float, float] # (x, y, z) in meters
breathing_rate: Optional[float] # BPM
confidence: float

class HYDROGEN_CPD:
"""HYDROGEN CPD 检测系统"""

def __init__(self):
self.breathing_detector = UWBBreathingDetector(fs=20.0)
self.beamformer = DigitalBeamformer(n_tx=4, n_rx=4)

# 车舱几何参数
self.cabin_range = (0.3, 2.5) # 检测距离范围 (米)

def scan_cabin(self, adc_data: np.ndarray,
range_bins: np.ndarray) -> List[DetectedTarget]:
"""
扫描车舱,检测所有目标

Args:
adc_data: 原始 ADC 数据 (n_chirps, n_range_bins, n_rx)
range_bins: 距离bin对应的距离 (米)

Returns:
检测到的目标列表
"""
targets = []
n_chirps, n_range, n_rx = adc_data.shape

# 波束成形扫描角度
theta_scan = np.linspace(-np.pi/2, np.pi/2, 91)

# 对每个距离bin进行扫描
for r_idx in range(n_range):
distance = range_bins[r_idx]

# 跳过车舱外的距离
if distance < self.cabin_range[0] or distance > self.cabin_range[1]:
continue

# 获取该距离bin的数据
rx_data = adc_data[:, r_idx, :] # (n_chirps, n_rx)

# 波束成形
beamformed = self.beamformer.beamform(rx_data, theta_scan)

# 找峰值角度
energy = np.sum(np.abs(beamformed)**2, axis=0)
if np.max(energy) < 1e-6:
continue

peak_idx = np.argmax(energy)
target_theta = theta_scan[peak_idx]

# 提取该方向的时域信号
target_signal = beamformed[:, peak_idx]

# 检测生命体征
vital_signs = self.breathing_detector.extract_vital_signs(
target_signal
)

# 分类目标
if vital_signs['breathing_confidence'] > 3.0:
target_type = self.breathing_detector.classify_target(vital_signs)

# 计算 3D 位置
x = distance * np.sin(target_theta)
y = distance * np.cos(target_theta)
z = 0.0 # 单层波束成形,高度未知

target = DetectedTarget(
target_type=TargetType(target_type),
position=(x, y, z),
breathing_rate=vital_signs['breathing_rate_bpm'],
confidence=vital_signs['breathing_confidence']
)
targets.append(target)

return targets

def check_cpd_alert(self, targets: List[DetectedTarget],
vehicle_locked: bool) -> Tuple[bool, str]:
"""
检查是否需要 CPD 警报

Args:
targets: 检测到的目标
vehicle_locked: 车辆是否已锁

Returns:
(需要警报, 警报信息)
"""
if not vehicle_locked:
return False, ""

children = [t for t in targets
if t.target_type == TargetType.CHILD]

if children:
child = children[0]
alert_msg = (
f"检测到儿童遗留在车内!\n"
f"位置: ({child.position[0]:.1f}, {child.position[1]:.1f}) m\n"
f"呼吸频率: {child.breathing_rate:.0f} BPM\n"
f"置信度: {child.confidence:.1f}"
)
return True, alert_msg

return False, ""


# 完整使用示例
if __name__ == "__main__":
cpd = HYDROGEN_CPD()

# 模拟数据 (实际从 HYDROGEN 获取)
n_chirps = 200
n_range = 100
n_rx = 4
adc_data = np.random.randn(n_chirps, n_range, n_rx) * 0.01

# 距离bin映射
range_bins = np.linspace(0, 3, n_range)

# 添加模拟儿童信号 (距离 1m, 角度 30°)
child_range_idx = 33 # ~1m
child_theta = np.pi / 6
t = np.arange(n_chirps) / 20.0

# 儿童呼吸信号 (25 BPM)
breath_signal = np.sin(2 * np.pi * 0.42 * t)

# 添加到 ADC 数据
steering = cpd.beamformer.compute_steering_vector(child_theta, 0)
for i in range(n_rx):
adc_data[:, child_range_idx, i] += 0.1 * breath_signal * steering[i].real

# 执行检测
targets = cpd.scan_cabin(adc_data, range_bins)

print(f"检测到 {len(targets)} 个目标:")
for t in targets:
print(f" - 类型: {t.target_type.value}")
print(f" 位置: {t.position}")
print(f" 呼吸: {t.breathing_rate:.1f} BPM")
print(f" 置信度: {t.confidence:.2f}")

# CPD 警报检查
alert, msg = cpd.check_cpd_alert(targets, vehicle_locked=True)
if alert:
print(f"\n⚠️ CPD 警报:\n{msg}")

三、应用场景详解

3.1 CPD 儿童检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CPD 检测完整流程:

1. 车辆状态检测
└── 检测车辆是否锁车

2. 持续监测模式
├── HYDROGEN 进入低功耗扫描
├── 每隔 5 秒扫描一次
└── 功耗 < 50 mW

3. 目标检测
├── 波束成形扫描车内
├── 检测生命体征信号
└── 分类目标类型

4. 儿童检测确认
├── 呼吸频率特征匹配
├── 多帧确认(避免误报)
└── 置信度评估

5. 多级警报
├── 一级:车内喇叭警告
├── 二级:手机 App 推送
└── 三级:紧急呼叫服务

3.2 与 ALGORIZED AI 平台集成

功能 HYDROGEN 硬件 ALGORIZED 软件
人数统计 波束成形定位 AI 目标跟踪
生命体征 微动信号采集 呼吸/心跳估计
行为识别 时域信号 动作模式分类
目标分类 特征信号 AI 分类器

四、开发集成指南

4.1 硬件接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HYDROGEN 接口框图:

┌─────────────────────────────────────────────────────────┐
│ HYDROGEN SoC (QFN64) │
│ │
│ 数字接口: │
│ ├── SPI (主/从模式) │
│ ├── UART (调试/配置) │
│ └── GPIO (触发/状态) │
│ │
│ 天线接口: │
│ ├── TX1-TX4 (4 发射) │
│ └── RX1-RX4 (4 接收) │
│ │
│ 电源: │
│ ├── VDD_1V8 (核心电源) │
│ └── VDD_IO (IO 电源) │
└─────────────────────────────────────────────────────────┘

4.2 数据输出格式

数据类型 格式 更新率
原始 ADC 16-bit I/Q 可配置
距离-多普勒 FFT 结果 10-30 Hz
生命体征 结构化 JSON 1 Hz
目标列表 结构化 JSON 1 Hz

五、对 IMS 开发的启示

5.1 方案选型建议

需求 推荐方案 理由
基础 CPD HYDROGEN 单芯片 低功耗、低成本
高精度 CPD HYDROGEN + 摄像头融合 视觉确认
多功能舱内 HYDROGEN + DMS 摄像头 完整感知

5.2 算法优化方向

  1. 多帧时域积分:提高微弱信号信噪比
  2. 深度学习分类:提高儿童/宠物区分精度
  3. 多传感器融合:UWB + 摄像头 + 雷达

六、总结

核心优势

维度 HYDROGEN
功耗 162 mW(mmWave 的 1/5)
分辨率 5° 角分辨率 + 高距离分辨率
穿透性 强(穿透毯子/座椅)
成本 低(单芯片方案)

开发建议

  1. 快速验证:使用 CPD Demo Kit 验证场景
  2. 算法开发:基于 ADC 原始数据开发信号处理
  3. 量产集成:与 ALGORIZED 合作 AI 算法

参考来源:

发布日期: 2026-04-11
关键词: UWB雷达, CPD, 儿童检测, ARIA SENSING, HYDROGEN, 信号处理


ARIA HYDROGEN:世界首款 3D UWB 雷达 SoC 完全解析(含信号处理代码)
https://dapalm.com/2026/04/11/2026-04-11-ARIA-HYDROGEN-3D-UWB-Radar-SoC-CPD/
作者
Mars
发布于
2026年4月11日
许可协议