Vayyar 4D成像雷达:一颗芯片覆盖全车舱的CPD/OMS方案

Vayyar 4D成像雷达:一颗芯片覆盖全车舱的CPD/OMS方案

来源: Vayyar官方 + Euro NCAP CPD协议
发布时间: 2026年4月
核心价值: 一颗芯片替代7个传统传感器,覆盖3排座椅


核心洞察

Vayyar 4D成像雷达优势:

特性 传统方案 Vayyar方案
传感器数量 7个(超声波+压力+摄像头) 1个芯片
覆盖范围 单点检测 3排座椅全覆盖
穿透能力 不能穿透遮挡 穿透毯子/座椅
隐私保护 摄像头有隐私问题 雷达无图像
成本 高(多传感器) 低(单芯片)

Euro NCAP CPD合规:

  • 2023年起CPD纳入评分
  • 2026年强制要求
  • Vayyar已通过AEC-Q100认证、ASIL-B合规

一、技术原理

1.1 4D成像雷达概念

4D = 3D空间 + 速度

维度 测量内容 用途
X轴 水平距离 水平定位
Y轴 垂直高度 高度定位
Z轴 深度距离 距离测量
速度 多普勒速度 运动/呼吸检测

1.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
"""
Vayyar 4D成像雷达技术参数
"""

# 硬件规格
VAYYAR_SPECS = {
'chip_name': '4D Imaging Radar-on-Chip',
'frequency': '60 GHz', # mmWave频段
'transceivers': 48, # 最多48个收发器
'field_of_view': {
'azimuth': 120, # 方位角 120°
'elevation': 60, # 俯仰角 60°
},
'range_resolution': 0.02, # 距离分辨率 2cm
'velocity_resolution': 0.1, # 速度分辨率 0.1m/s
'update_rate': 30, # 更新率 30Hz
'power_consumption': 3.5, # 功耗 3.5W
'interface': ['SPI', 'I2C', 'UART'],
'qualification': ['AEC-Q100', 'ASIL-B'],
}

# 覆盖能力
COVERAGE = {
'rows': 3, # 覆盖3排座椅
'occupants': 8, # 最多检测8人
'footwell': True, # 检测脚部空间
'trunk': False, # 不覆盖后备箱
}

print("=== Vayyar 4D成像雷达规格 ===")
for key, value in VAYYAR_SPECS.items():
print(f"{key}: {value}")

1.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
"""
CPD儿童存在检测原理
基于毫米波雷达生命体征检测
"""

import numpy as np
from scipy import signal
from typing import Tuple, Optional

class CPDDetector:
"""
儿童存在检测器

检测原理:
1. 60GHz毫米波雷达探测微小运动
2. 通过多普勒效应检测呼吸/心跳
3. 区分活体与静止物体
"""

def __init__(self):
# 检测参数
self.breathing_freq_range = (0.2, 0.6) # 呼吸频率 12-36次/分钟
self.heartbeat_freq_range = (1.0, 2.0) # 心跳频率 60-120次/分钟
self.min_motion_amplitude = 0.001 # 最小运动幅度 (m)

# 历史缓冲
self.range_doppler_history = []

def detect_presence(self,
range_doppler_map: np.ndarray,
range_bins: np.ndarray,
velocity_bins: np.ndarray) -> Tuple[bool, dict]:
"""
检测儿童存在

Args:
range_doppler_map: 距离-多普勒图 (D, R)
range_bins: 距离bin (R,)
velocity_bins: 速度bin (D,)

Returns:
(presence_detected, info)
"""
# 1. 检测静态目标(速度≈0)
static_threshold = 0.1 # m/s
static_mask = np.abs(velocity_bins) < static_threshold

# 2. 提取静态目标的距离分布
static_profile = np.sum(range_doppler_map[static_mask], axis=0)

# 3. 检测能量峰值(存在目标)
peaks, properties = signal.find_peaks(static_profile, height=np.mean(static_profile) * 2)

if len(peaks) == 0:
return False, {'status': 'no_target'}

# 4. 对每个峰值检测生命体征
detections = []
for peak in peaks:
distance = range_bins[peak]

# 检测微多普勒(呼吸运动)
micro_doppler = self._extract_micro_doppler(
range_doppler_map, peak, velocity_bins
)

# 分析呼吸频率
breathing_detected, breathing_freq = self._detect_breathing(micro_doppler)

if breathing_detected:
detections.append({
'distance': distance,
'breathing_freq': breathing_freq,
'type': 'living' # 活体
})

# 5. 判断结果
if len(detections) > 0:
return True, {
'status': 'child_detected',
'detections': detections,
'count': len(detections)
}

return False, {'status': 'object_only'}

def _extract_micro_doppler(self,
range_doppler_map: np.ndarray,
range_bin: int,
velocity_bins: np.ndarray) -> np.ndarray:
"""提取微多普勒信号"""
# 提取该距离bin的多普勒分布
doppler_profile = range_doppler_map[:, range_bin]

# 只保留低速度区域(呼吸运动)
micro_doppler_mask = np.abs(velocity_bins) < 0.5 # <0.5 m/s
micro_doppler = doppler_profile[micro_doppler_mask]

return micro_doppler

def _detect_breathing(self, micro_doppler: np.ndarray) -> Tuple[bool, float]:
"""检测呼吸信号"""
# 简化实现:实际需要时频分析
# 检查信号能量是否超过阈值

if len(micro_doppler) == 0:
return False, 0.0

energy = np.sum(micro_doppler ** 2)

# 阈值判断
if energy > 1e-6: # 经验阈值
# 估计呼吸频率(简化)
breathing_freq = 0.3 # 约18次/分钟
return True, breathing_freq

return False, 0.0


# 实际测试
if __name__ == "__main__":
detector = CPDDetector()

# 模拟距离-多普勒图
range_bins = np.linspace(0, 3, 64) # 0-3m
velocity_bins = np.linspace(-2, 2, 32) # -2到2 m/s

# 场景1:空车
rd_map_empty = np.random.randn(32, 64) * 0.01
presence, info = detector.detect_presence(rd_map_empty, range_bins, velocity_bins)
print(f"空车检测: {presence}, 信息: {info}")

# 场景2:有儿童(模拟呼吸运动)
rd_map_child = np.random.randn(32, 64) * 0.01
# 在1.5m处添加静态目标+微多普勒
target_range_bin = 32 # 1.5m
static_velocity_bins = np.where(np.abs(velocity_bins) < 0.1)[0]
rd_map_child[static_velocity_bins, target_range_bin] += 0.5
presence, info = detector.detect_presence(rd_map_child, range_bins, velocity_bins)
print(f"儿童检测: {presence}, 信息: {info}")

二、功能覆盖

2.1 CPD儿童存在检测

Euro NCAP CPD测试场景:

场景 描述 Vayyar能力
场景1 婴儿在安全座椅 ✅ 检测
场景2 儿童被毯子覆盖 ✅ 穿透检测
场景3 儿童在脚部空间 ✅ 全覆盖检测
场景4 儿童在后排地板 ✅ 俯仰角覆盖
场景5 宠物遗留 ✅ 活体检测

2.2 OMS乘员监控

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
"""
OMS乘员监控系统
基于4D成像雷达的多功能检测
"""

from dataclasses import dataclass
from typing import List, Optional
from enum import Enum

class OccupantType(Enum):
"""乘员类型"""
ADULT = "adult"
CHILD = "child"
INFANT = "infant" # 婴儿座椅
PET = "pet"
OBJECT = "object"
EMPTY = "empty"

class SeatPosition(Enum):
"""座椅位置"""
DRIVER = "driver"
FRONT_PASSENGER = "front_passenger"
REAR_LEFT = "rear_left"
REAR_CENTER = "rear_center"
REAR_RIGHT = "rear_right"

@dataclass
class OccupantInfo:
"""乘员信息"""
seat: SeatPosition
type: OccupantType
presence: bool
position_3d: tuple # (x, y, z) in meters
vital_signs: Optional[dict] # {'breathing_rate': ..., 'heartbeat': ...}
seatbelt_status: Optional[bool]

class OMSDetector:
"""
乘员监控系统

功能:
1. 乘员分类(成人/儿童/婴儿座椅)
2. 位置检测
3. 生命体征监测
4. 安全带提醒增强
"""

def __init__(self):
# 分类阈值(基于体积和运动特征)
self.size_thresholds = {
'adult': (0.3, 0.8), # 体素体积 m³
'child': (0.15, 0.3),
'infant': (0.05, 0.15),
'pet': (0.02, 0.1),
}

def monitor_cabin(self,
point_cloud: np.ndarray,
vital_signs: np.ndarray) -> List[OccupantInfo]:
"""
监控全车舱

Args:
point_cloud: 3D点云 (N, 4) [x, y, z, intensity]
vital_signs: 生命体征信号

Returns:
各座椅乘员信息
"""
occupants = []

# 定义座椅区域
seat_regions = self._define_seat_regions()

for seat, region in seat_regions.items():
# 提取该座椅区域的点云
seat_points = self._extract_region_points(point_cloud, region)

if len(seat_points) < 10:
# 无乘员
occupants.append(OccupantInfo(
seat=seat,
type=OccupantType.EMPTY,
presence=False,
position_3d=(0, 0, 0),
vital_signs=None,
seatbelt_status=None
))
continue

# 计算乘员体积
volume = self._calculate_volume(seat_points)

# 分类乘员类型
occupant_type = self._classify_occupant(volume, seat_points)

# 计算位置
position = self._calculate_position(seat_points)

# 检测生命体征
vitals = self._detect_vital_signs(vital_signs, region)

occupants.append(OccupantInfo(
seat=seat,
type=occupant_type,
presence=True,
position_3d=position,
vital_signs=vitals,
seatbelt_status=None # 需要融合安全带传感器
))

return occupants

def _define_seat_regions(self) -> dict:
"""定义座椅3D区域"""
# 简化定义(实际需要精确标定)
return {
SeatPosition.DRIVER: {
'x': (0.5, 1.2),
'y': (0.3, 0.8),
'z': (0.0, 1.0)
},
SeatPosition.FRONT_PASSENGER: {
'x': (0.5, 1.2),
'y': (-0.8, -0.3),
'z': (0.0, 1.0)
},
# ... 后排座椅
}

def _extract_region_points(self,
points: np.ndarray,
region: dict) -> np.ndarray:
"""提取区域内的点"""
mask = (
(points[:, 0] >= region['x'][0]) & (points[:, 0] <= region['x'][1]) &
(points[:, 1] >= region['y'][0]) & (points[:, 1] <= region['y'][1]) &
(points[:, 2] >= region['z'][0]) & (points[:, 2] <= region['z'][1])
)
return points[mask]

def _calculate_volume(self, points: np.ndarray) -> float:
"""计算凸包体积"""
# 简化:计算边界框体积
x_range = points[:, 0].max() - points[:, 0].min()
y_range = points[:, 1].max() - points[:, 1].min()
z_range = points[:, 2].max() - points[:, 2].min()
return x_range * y_range * z_range

def _classify_occupant(self,
volume: float,
points: np.ndarray) -> OccupantType:
"""分类乘员类型"""
for otype, (v_min, v_max) in self.size_thresholds.items():
if v_min <= volume < v_max:
return OccupantType(otype)

return OccupantType.OBJECT

def _calculate_position(self, points: np.ndarray) -> tuple:
"""计算质心位置"""
return tuple(points[:, :3].mean(axis=0))

def _detect_vital_signs(self,
vital_signs: np.ndarray,
region: dict) -> Optional[dict]:
"""检测生命体征"""
# 简化实现
return {
'breathing_rate': 18, # 次/分钟
'heartbeat': 75 # 次/分钟
}


# 实际测试
if __name__ == "__main__":
detector = OMSDetector()

# 模拟点云数据
np.random.seed(42)

# 驾驶员位置有人
driver_points = np.random.randn(500, 4)
driver_points[:, 0] = driver_points[:, 0] * 0.2 + 0.8 # x
driver_points[:, 1] = driver_points[:, 1] * 0.2 + 0.5 # y
driver_points[:, 2] = driver_points[:, 2] * 0.3 + 0.5 # z

# 空点云
empty_points = np.random.randn(10, 4) * 0.01

# 合并
point_cloud = np.vstack([driver_points, empty_points])
vital_signs = np.random.randn(100)

# 监控
occupants = detector.monitor_cabin(point_cloud, vital_signs)

print("=== 乘员监控结果 ===")
for occ in occupants:
print(f"{occ.seat.value}: {occ.type.value}, 存在: {occ.presence}")

2.3 增强安全带提醒

功能对比:

功能 传统SBR Vayyar增强SBR
检测方式 压力传感器 雷达+分类
分类能力 ❌ 仅检测重量 ✅ 区分人/物
儿童座椅 ❌ 误报警 ✅ 正确识别
后排气囊禁用 ❌ 无 ✅ 支持

三、系统架构

3.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
┌────────────────────────────────────────────────────────────┐
│ Vayyar雷达部署架构 │
├────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 车顶控制台 │ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ Vayyar 4D成像雷达芯片 │ │ │
│ │ │ (60GHz, 48收发器, 120°FOV) │ │ │
│ │ └─────────────────────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ 覆盖区域 │ │
│ │ │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │前排 │ │后排 │ │第三排│ │ │
│ │ │座椅 │ │座椅 │ │ 座椅 │ │ │
│ │ └─────┘ └─────┘ └─────┘ │ │
│ │ │ │
│ │ ✅ 全覆盖(包括脚部空间) │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ 控制器/处理单元 │ │
│ │ │ │
│ │ ├── SPI/I2C接口 │ │
│ │ ├── DSP处理单元 │ │
│ │ └── CAN总线输出 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ 输出信号 │ │
│ │ │ │
│ │ ├── CPD报警 → HMI/手机App │ │
│ │ ├── SBR信号 → 仪表盘警告 │ │
│ │ ├── OMS信息 → 气囊控制单元 │ │
│ │ └── 生命体征 → ADAS系统 │ │
│ └─────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────┘

3.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
126
127
128
129
130
131
132
133
134
135
136
"""
Vayyar雷达软件处理流程
"""

import numpy as np
from typing import Tuple, List

class VayyarRadarProcessor:
"""
Vayyar雷达信号处理器

处理流程:
1. 原始数据采集
2. FFT距离-多普勒处理
3. 点云生成
4. 目标检测与跟踪
5. 生命体征提取
6. 应用层输出
"""

def __init__(self, config: dict = None):
self.config = config or {
'num_chirps': 128, # 每帧chirp数
'num_samples': 256, # 每chirp采样点
'sample_rate': 10e6, # 采样率 10MHz
'bandwidth': 4e9, # 带宽 4GHz
'center_freq': 60e9, # 中心频率 60GHz
}

# FFT参数
self.range_fft_size = 256
self.doppler_fft_size = 128

def process_frame(self,
raw_data: np.ndarray) -> Tuple[np.ndarray, List[dict]]:
"""
处理一帧雷达数据

Args:
raw_data: 原始ADC数据 (num_chirps, num_samples)

Returns:
(range_doppler_map, detected_targets)
"""
# 1. 距离FFT
range_fft = np.fft.fft(raw_data, n=self.range_fft_size, axis=1)

# 2. 多普勒FFT
range_doppler = np.fft.fftshift(
np.fft.fft(range_fft, n=self.doppler_fft_size, axis=0),
axes=0
)

# 3. CFAR目标检测
targets = self._cfar_detection(range_doppler)

# 4. 点云生成
point_cloud = self._generate_point_cloud(targets)

return range_doppler, targets

def _cfar_detection(self,
range_doppler: np.ndarray) -> List[dict]:
"""
CFAR恒虚警检测

自适应阈值检测,提取目标点
"""
targets = []

# 简化CFAR实现
threshold = np.mean(np.abs(range_doppler)) * 3

# 找峰值
peaks = np.where(np.abs(range_doppler) > threshold)

for i in range(len(peaks[0])):
doppler_idx = peaks[0][i]
range_idx = peaks[1][i]

# 计算距离和速度
range_m = self._calculate_range(range_idx)
velocity_ms = self._calculate_velocity(doppler_idx)

targets.append({
'range': range_m,
'velocity': velocity_ms,
'amplitude': np.abs(range_doppler[doppler_idx, range_idx]),
'range_idx': range_idx,
'doppler_idx': doppler_idx
})

return targets

def _calculate_range(self, range_idx: int) -> float:
"""计算距离"""
# c / (2 * bandwidth) * bin_index
range_resolution = 3e8 / (2 * self.config['bandwidth'])
return range_idx * range_resolution

def _calculate_velocity(self, doppler_idx: int) -> float:
"""计算速度"""
# 多普勒频率到速度
wavelength = 3e8 / self.config['center_freq']
doppler_resolution = self.config['sample_rate'] / self.doppler_fft_size
velocity = (doppler_idx - self.doppler_fft_size // 2) * doppler_resolution * wavelength / 2
return velocity

def _generate_point_cloud(self, targets: List[dict]) -> np.ndarray:
"""生成3D点云(需要多天线DoA)"""
# 简化:返回2D坐标
points = []
for t in targets:
points.append([t['range'], 0, 0, t['amplitude']])
return np.array(points)


# 实际测试
if __name__ == "__main__":
processor = VayyarRadarProcessor()

# 模拟原始数据
raw_data = np.random.randn(128, 256) * 0.1

# 添加目标(在10m处,速度1m/s)
target_range_bin = 85 # 约10m
target_doppler_bin = 70 # 约1m/s
raw_data[target_doppler_bin, target_range_bin] += 5.0

# 处理
rd_map, targets = processor.process_frame(raw_data)

print(f"距离-多普勒图形状: {rd_map.shape}")
print(f"检测到 {len(targets)} 个目标")
for t in targets[:3]:
print(f" 距离: {t['range']:.2f}m, 速度: {t['velocity']:.2f}m/s")

四、与竞品对比

4.1 技术对比

厂商 频段 收发器数 覆盖范围 认证状态
Vayyar 60GHz 48 3排/8人 AEC-Q100, ASIL-B
TI IWR6843 60GHz 12 2排/5人 AEC-Q100
Infineon BGT60 60GHz 6 1排/2人 AEC-Q100
Volvo EX90 60GHz 3雷达 全舱 定制方案

4.2 成本对比

方案 传感器成本 安装成本 总成本
传统多传感器 $150 $50 $200
Vayyar单芯片 $80 $20 $100
节省 - - -50%

五、IMS开发建议

5.1 集成方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
IMS雷达集成架构

├── 硬件选型
│ ├── Vayyar 60GHz RoC(推荐)
│ ├── TI IWR6843AOP(备选)
│ └── Infineon BGT60(低端方案)

├── 软件开发
│ ├── CPD算法(生命体征检测)
│ ├── OMS算法(乘员分类)
│ └── SBR增强算法

├── 系统集成
│ ├── CAN/LIN通信
│ ├── 与DMS联动
│ └── HMI报警策略

└── 测试验证
├── Euro NCAP CPD测试
├── 极端温度测试
└── 误报率测试

5.2 Euro NCAP CPD测试清单

测试项 要求 Vayyar验证
婴儿座椅检测 检测率≥90% ✅ 95%+
毯子覆盖检测 检测率≥85% ✅ 92%+
脚部空间检测 检测率≥80% ✅ 90%+
宠物检测 检测率≥75% ✅ 85%+
误报率 <5次/天 ✅ <1次/天

六、总结

6.1 核心优势

  1. 一颗芯片替代7个传感器:大幅降低成本和复杂度
  2. 全舱覆盖:3排座椅、脚部空间全覆盖
  3. 穿透检测:穿透毯子、座椅检测儿童
  4. 隐私友好:无图像记录,符合GDPR
  5. 车规认证:AEC-Q100、ASIL-B合规

6.2 应用场景

场景 功能 Euro NCAP关联
CPD 儿童存在检测 2023年起评分
OMS 乘员分类/位置 2026年要求
SBR 安全带提醒增强 评分项
气囊自适应 根据乘员调整 安全加分
防盗 入侵检测 附加功能

参考链接:

  • Vayyar官网:https://vayyar.com/auto/
  • Euro NCAP CPD协议:Euro NCAP Safe Driving Protocol
  • Nissan Brain-to-Vehicle:EEG疲劳检测应用案例

Vayyar 4D成像雷达:一颗芯片覆盖全车舱的CPD/OMS方案
https://dapalm.com/2026/04/24/2026-04-24-vayyar-4d-radar-cpd-oms/
作者
Mars
发布于
2026年4月24日
许可协议