Euro NCAP 2026 DMS新规详解:25分评分体系与合规要点

Euro NCAP 2026 DMS新规详解:25分评分体系与合规要点

来源: Euro NCAP 2026 Assessment Protocol / Smart Eye 官方解读
发布时间: 2026年4月
核心变化: DMS首次成为25分独立评分项,新增酒驾检测要求


核心洞察

Euro NCAP 2026 DMS重大变化:

项目 2025年前 2026年后
分值 辅助评分 25分独立项
检测内容 疲劳+分心 疲劳+分心+酒驾
检测方式 间接传感器可接受 必须直测(眼动追踪)
触发速度 无明确要求 ≥50km/h
误报率 无硬性指标 影响星级评定

对OEM的影响:

  • 基础DMS无法获得五星评级
  • 方向盘传感器方案不再合规
  • 必须部署眼动追踪摄像头

一、评分体系详解

1.1 25分构成

检测类型 分值 检测要求
分心检测 8分 短暂分心、长时间分心、手机使用
疲劳检测 8分 KSS≥7,≥50km/h,实时检测
酒驾检测 5分 行程开始10分钟内,≥50km/h
系统可用性 4分 默认开启、不可关闭、始终激活
合计 25分

1.2 分心检测(8分)

检测场景:

场景编号 场景描述 触发条件 时限要求
D-01 视线短暂偏离 ≤3秒 不触发警告
D-02 视线长时间偏离 ≥3秒 ≤3秒警告
D-03 视线极端偏离 ≥4秒 立即警告
D-04 手机使用(腿部) 手持手机 ≤3秒警告
D-05 手机使用(耳边) 打电话姿势 立即警告
D-06 手机打字 低头打字 ≤3秒警告

关键技术要求:

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
"""
Euro NCAP 2026 分心检测逻辑
Protocol Section 4.2
"""

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

class GazeZone(Enum):
"""视线区域定义"""
FORWARD = "forward" # 前方道路
LEFT_MIRROR = "left" # 左后视镜
RIGHT_MIRROR = "right" # 右后视镜
REAR_MIRROR = "rear" # 车内后视镜
INSTRUMENT = "instrument" # 仪表盘
CENTER_CONSOLE = "console" # 中控
DOWN = "down" # 下方(腿部)
UNKNOWN = "unknown" # 未识别

@dataclass
class DistractionEvent:
"""分心事件"""
zone: GazeZone
duration: float # 秒
phone_detected: bool
hand_position: Optional[str] # 'lap', 'ear', 'texting', None

class DistractionDetector:
"""
Euro NCAP 2026 分心检测器

检测规则:
1. 视线偏离道路≥3秒触发警告
2. 手机使用检测(视觉+行为)
3. 前置4秒道路注视条件
"""

def __init__(self):
self.forward_gaze_time = 0.0
self.distraction_start = None
self.last_zone = GazeZone.FORWARD

# Euro NCAP阈值
self.WARNING_THRESHOLD = 3.0 # 秒
self.CRITICAL_THRESHOLD = 4.0 # 秒
self.FORWARD_REQUIREMENT = 4.0 # 秒

def update(self,
gaze_zone: GazeZone,
phone_detected: bool = False,
hand_position: Optional[str] = None,
dt: float = 0.033) -> Tuple[bool, Optional[str]]:
"""
更新检测状态

Args:
gaze_zone: 当前视线区域
phone_detected: 是否检测到手机
hand_position: 手部位置
dt: 时间步长(秒)

Returns:
(warning_triggered, warning_type)
"""
warning = False
warning_type = None

# 更新前方注视时间
if gaze_zone == GazeZone.FORWARD:
self.forward_gaze_time += dt
self.distraction_start = None
self.last_zone = GazeZone.FORWARD
else:
# 检查是否满足前置条件(4秒道路注视)
if self.forward_gaze_time >= self.FORWARD_REQUIREMENT:
# 开始计时分心
if self.distraction_start is None:
self.distraction_start = 0.0
else:
self.distraction_start += dt

# 检查是否触发警告
if self.distraction_start >= self.CRITICAL_THRESHOLD:
warning = True
warning_type = "CRITICAL_DISTRACTION"
elif self.distraction_start >= self.WARNING_THRESHOLD:
warning = True
warning_type = "PROLONGED_DISTRACTION"

self.last_zone = gaze_zone

# 手机使用检测(优先级更高)
if phone_detected:
if hand_position == 'ear':
# 打电话姿势:立即警告
warning = True
warning_type = "PHONE_CALL"
elif hand_position in ['lap', 'texting']:
# 手机使用:3秒警告
if self.distraction_start is None:
self.distraction_start = 0.0
else:
self.distraction_start += dt
if self.distraction_start >= self.WARNING_THRESHOLD:
warning = True
warning_type = "PHONE_USE"

return warning, warning_type

def get_gaze_duration(self) -> float:
"""获取当前分心持续时间"""
return self.distraction_start if self.distraction_start else 0.0


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

# 模拟场景1:正常驾驶
print("=== 场景1:正常驾驶 ===")
for i in range(120): # 4秒
warning, wtype = detector.update(GazeZone.FORWARD, dt=0.033)
print(f"前方注视时间: {detector.forward_gaze_time:.1f}秒")

# 模拟场景2:短暂看中控
print("\n=== 场景2:短暂看中控(2秒) ===")
for i in range(60): # 2秒
warning, wtype = detector.update(GazeZone.CENTER_CONSOLE, dt=0.033)
if warning:
print(f"警告触发: {wtype}")
print(f"分心持续时间: {detector.get_gaze_duration():.1f}秒")

# 模拟场景3:长时间分心
print("\n=== 场景3:长时间分心(4秒) ===")
detector.forward_gaze_time = 5.0 # 假设已满足前置条件
for i in range(130): # 4.3秒
warning, wtype = detector.update(GazeZone.CENTER_CONSOLE, dt=0.033)
if warning and i == 90: # 3秒
print(f"一级警告: {wtype}")
elif warning and i == 120: # 4秒
print(f"二级警告: {wtype}")
print(f"分心持续时间: {detector.get_gaze_duration():.1f}秒")

# 模拟场景4:手机使用
print("\n=== 场景4:手机打电话 ===")
detector.forward_gaze_time = 5.0
warning, wtype = detector.update(GazeZone.UNKNOWN,
phone_detected=True,
hand_position='ear',
dt=0.033)
print(f"立即警告: {warning}, 类型: {wtype}")

1.3 疲劳检测(8分)

检测标准:

指标 Euro NCAP要求 实现方式
疲劳等级 KSS ≥ 7 PERCLOS、眼睑开度、眨眼频率
检测速度 ≥ 50 km/h 车速信号触发
检测时间 实时连续 滑动窗口
警告分级 一级/二级 根据严重程度

KSS量表对应:

KSS 状态 Euro NCAP要求
1-3 极度清醒 不检测
4-6 轻度疲劳 不检测
7-8 中度疲劳 触发检测
9 严重疲劳 二级警告

实现代码:

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
"""
Euro NCAP 2026 疲劳检测实现
基于PERCLOS和眼动特征
"""

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

class FatigueLevel(Enum):
"""疲劳等级"""
AWAKE = "awake" # 清醒 (KSS 1-3)
SLIGHT = "slight" # 轻度疲劳 (KSS 4-6)
MODERATE = "moderate" # 中度疲劳 (KSS 7-8) → 一级警告
SEVERE = "severe" # 严重疲劳 (KSS 9) → 二级警告

@dataclass
class EyeMetrics:
"""眼部指标"""
perclos: float # 闭眼百分比 (0-100)
blink_rate: float # 眨眼频率 (次/分钟)
avg_closure_duration: float # 平均闭眼时长 (ms)
eye_openness: float # 眼睑开度 (0-1)
gaze_entropy: float # 眼动熵

class FatigueDetector:
"""
Euro NCAP 2026 疲劳检测器

检测标准:
- KSS ≥ 7 触发警告
- 速度 ≥ 50 km/h
- 连续实时监测
"""

def __init__(self):
# Euro NCAP阈值
self.SPEED_THRESHOLD = 50.0 # km/h
self.PERCLOS_WARNING = 30.0 # %
self.PERCLOS_CRITICAL = 50.0 # %
self.BLINK_RATE_NORMAL = 15.0 # 次/分钟
self.CLOSURE_DURATION_WARNING = 500 # ms

# 历史缓冲
self.eye_history: List[float] = []
self.blink_timestamps: List[float] = []

# 窗口配置
self.window_size = 60 # 60秒窗口

def update(self,
eye_openness: float,
vehicle_speed: float,
timestamp: float) -> Tuple[FatigueLevel, Optional[str]]:
"""
更新疲劳检测状态

Args:
eye_openness: 眼睑开度 (0=闭眼, 1=睁眼)
vehicle_speed: 车速 (km/h)
timestamp: 时间戳 (秒)

Returns:
(fatigue_level, warning_type)
"""
# 速度检查
if vehicle_speed < self.SPEED_THRESHOLD:
return FatigueLevel.AWAKE, None

# 更新历史
self.eye_history.append(eye_openness)
self.blink_timestamps.append(timestamp)

# 保持窗口大小
if len(self.eye_history) > self.window_size * 30: # 30fps
self.eye_history = self.eye_history[-int(self.window_size * 30):]

# 计算PERCLOS
perclos = self._calculate_perclos()

# 计算眨眼频率
blink_rate = self._calculate_blink_rate()

# 检测闭眼事件
closure_duration = self._detect_closure_event(eye_openness)

# 判断疲劳等级
fatigue_level, warning = self._classify_fatigue(
perclos, blink_rate, closure_duration
)

return fatigue_level, warning

def _calculate_perclos(self) -> float:
"""
计算PERCLOS值

PERCLOS = 闭眼时间占比 × 100
闭眼定义:眼睑开度 < 0.2
"""
if len(self.eye_history) == 0:
return 0.0

closed_count = sum(1 for e in self.eye_history if e < 0.2)
perclos = closed_count / len(self.eye_history) * 100

return perclos

def _calculate_blink_rate(self) -> float:
"""计算眨眼频率(次/分钟)"""
if len(self.blink_timestamps) < 2:
return 0.0

# 检测眨眼事件(眼睑开度从>0.5变为<0.2再变为>0.5)
# 简化实现:统计时间跨度
duration = self.blink_timestamps[-1] - self.blink_timestamps[0]

if duration < 10: # 至少10秒数据
return 0.0

# 估计眨眼次数(基于PERCLOS)
perclos = self._calculate_perclos()
estimated_blinks = perclos * duration / 60 * 3 # 假设每次眨眼200ms

blink_rate = estimated_blinks / duration * 60

return blink_rate

def _detect_closure_event(self, eye_openness: float) -> float:
"""
检测闭眼事件持续时间

Returns:
闭眼持续时间 (ms),如果当前睁眼则返回0
"""
if eye_openness > 0.2:
return 0.0

# 检测连续闭眼时长
closed_frames = 0
for i in range(len(self.eye_history) - 1, -1, -1):
if self.eye_history[i] < 0.2:
closed_frames += 1
else:
break

# 转换为毫秒 (30fps)
duration_ms = closed_frames * 1000 / 30

return duration_ms

def _classify_fatigue(self,
perclos: float,
blink_rate: float,
closure_duration: float) -> Tuple[FatigueLevel, Optional[str]]:
"""
疲劳等级分类

Args:
perclos: PERCLOS值
blink_rate: 眨眼频率
closure_duration: 当前闭眼持续时间

Returns:
(疲劳等级, 警告类型)
"""
# 微睡眠检测(闭眼>1.5秒)
if closure_duration > 1500:
return FatigueLevel.SEVERE, "MICROSLEEP"

# PERCLOS判断
if perclos >= self.PERCLOS_CRITICAL:
return FatigueLevel.SEVERE, "SEVERE_FATIGUE"

if perclos >= self.PERCLOS_WARNING:
return FatigueLevel.MODERATE, "MODERATE_FATIGUE"

# 眨眼频率异常
if blink_rate > 30 or blink_rate < 5:
if perclos > 15:
return FatigueLevel.MODERATE, "ABNORMAL_BLINK"

return FatigueLevel.AWAKE, None


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

print("=== 场景1:正常驾驶 ===")
for i in range(180): # 6秒
eye = 0.8 + np.random.randn() * 0.1 # 正常开度
level, warning = detector.update(eye, 60.0, i * 0.033)
if warning:
print(f"警告: {warning}")
print(f"PERCLOS: {detector._calculate_perclos():.1f}%")

print("\n=== 场景2:疲劳驾驶 ===")
detector = FatigueDetector() # 重置
for i in range(300): # 10秒
# 模拟疲劳:频繁闭眼
if np.random.rand() < 0.4: # 40%时间闭眼
eye = 0.1
else:
eye = 0.7
level, warning = detector.update(eye, 60.0, i * 0.033)
if warning:
print(f"[{i*0.033:.1f}s] 警告: {warning}, 等级: {level.value}")

print(f"最终PERCLOS: {detector._calculate_perclos():.1f}%")

1.4 酒驾检测(5分,新增)

检测要求:

项目 要求 说明
启动时间 行程开始10分钟内 从点火开始计时
检测速度 ≥ 50 km/h 低速不检测
检测方式 行为分析 对比历史驾驶模式
区分能力 区分疲劳vs酒驾 不同干预策略

行为特征对比:

特征 疲劳 酒驾
眼睑开度 下降 正常或波动
眨眼频率 增加或减少 异常模式
视线稳定性 下降 高度不稳定
头部姿态 下垂 摇晃
反应时间 延长 延长+错误增多
微睡眠 可能出现 不出现

实现框架:

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
"""
Euro NCAP 2026 酒驾检测框架
基于行为分析与历史对比
"""

import numpy as np
from enum import Enum
from dataclasses import dataclass
from typing import Optional, Dict, List
from collections import deque

class ImpairmentType(Enum):
"""损伤类型"""
NONE = "none"
FATIGUE = "fatigue"
ALCOHOL = "alcohol"
UNKNOWN = "unknown"

@dataclass
class BehavioralFeatures:
"""行为特征"""
gaze_stability: float # 视线稳定性 (0-1)
head_stability: float # 头部稳定性 (0-1)
blink_regularity: float # 眨眼规律性 (0-1)
reaction_score: float # 反应评分 (0-1)
lane_keeping_score: float # 车道保持评分 (0-1)
steering_jerkiness: float # 方向盘抖动 (0-1)

class ImpairmentDetector:
"""
Euro NCAP 2026 损伤检测器

功能:
1. 区分疲劳与酒驾
2. 基于历史驾驶模式对比
3. 多特征融合判断
"""

def __init__(self):
# Euro NCAP要求
self.DETECTION_WINDOW = 600 # 10分钟 = 600秒
self.SPEED_THRESHOLD = 50.0

# 历史驾驶模式(需要个性化建模)
self.baseline_features: Optional[Dict[str, float]] = None

# 特征缓冲
self.feature_history: deque = deque(maxlen=300) # 10秒@30fps

# 时间戳
self.trip_start_time: Optional[float] = None

def start_trip(self, timestamp: float):
"""开始新行程"""
self.trip_start_time = timestamp
self.feature_history.clear()

def update(self,
features: BehavioralFeatures,
vehicle_speed: float,
timestamp: float) -> Tuple[ImpairmentType, Optional[str]]:
"""
更新损伤检测状态

Args:
features: 行为特征
vehicle_speed: 车速
timestamp: 时间戳

Returns:
(损伤类型, 警告类型)
"""
# 速度检查
if vehicle_speed < self.SPEED_THRESHOLD:
return ImpairmentType.NONE, None

# 时间检查(10分钟内)
if self.trip_start_time is None:
self.start_trip(timestamp)

elapsed = timestamp - self.trip_start_time
if elapsed > self.DETECTION_WINDOW:
return ImpairmentType.NONE, None # 超时停止检测

# 记录特征
self.feature_history.append(features)

# 需要足够数据
if len(self.feature_history) < 90: # 至少3秒
return ImpairmentType.NONE, None

# 提取统计特征
stats = self._compute_statistics()

# 与基线对比
deviation = self._compute_deviation(stats)

# 分类损伤类型
impairment_type, warning = self._classify_impairment(stats, deviation)

return impairment_type, warning

def _compute_statistics(self) -> Dict[str, float]:
"""计算统计特征"""
features = list(self.feature_history)

return {
'gaze_stability_mean': np.mean([f.gaze_stability for f in features]),
'gaze_stability_std': np.std([f.gaze_stability for f in features]),
'head_stability_mean': np.mean([f.head_stability for f in features]),
'head_stability_std': np.std([f.head_stability for f in features]),
'blink_regularity': np.mean([f.blink_regularity for f in features]),
'reaction_score': np.mean([f.reaction_score for f in features]),
'steering_jerkiness': np.mean([f.steering_jerkiness for f in features]),
}

def _compute_deviation(self, stats: Dict[str, float]) -> Dict[str, float]:
"""计算与基线的偏差"""
if self.baseline_features is None:
# 使用默认基线
self.baseline_features = {
'gaze_stability': 0.85,
'head_stability': 0.90,
'blink_regularity': 0.80,
'reaction_score': 0.85,
'steering_jerkiness': 0.20,
}

deviation = {}
for key in stats:
if key in self.baseline_features:
deviation[key] = abs(stats[key] - self.baseline_features[key])
else:
# 从key中提取基础名称
base_key = key.replace('_mean', '').replace('_std', '')
if base_key in self.baseline_features:
deviation[key] = abs(stats[key] - self.baseline_features[base_key])

return deviation

def _classify_impairment(self,
stats: Dict[str, float],
deviation: Dict[str, float]) -> Tuple[ImpairmentType, Optional[str]]:
"""
分类损伤类型

疲劳特征:
- 视线稳定性下降但波动小
- 头部稳定性下降
- 眨眼规律性下降

酒驾特征:
- 视线稳定性高度波动(std大)
- 头部稳定性波动大
- 反应评分下降明显
- 方向盘抖动增加
"""
# 提取关键特征
gaze_std = stats.get('gaze_stability_std', 0)
head_std = stats.get('head_stability_std', 0)
steering_jerkiness = stats.get('steering_jerkiness', 0)
blink_reg = stats.get('blink_regularity', 0)

# 酒驾判断:高度波动
if gaze_std > 0.3 and head_std > 0.2:
if steering_jerkiness > 0.5:
return ImpairmentType.ALCOHOL, "ALCOHOL_IMPAIRMENT"

# 疲劳判断:稳定性下降但波动小
if blink_reg < 0.5 and gaze_std < 0.2:
return ImpairmentType.FATIGUE, "FATIGUE_DETECTED"

# 混合或未知
if deviation.get('reaction_score', 0) > 0.3:
return ImpairmentType.UNKNOWN, "IMPAIRMENT_DETECTED"

return ImpairmentType.NONE, None


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

print("=== 场景1:正常驾驶 ===")
detector.start_trip(0.0)
for i in range(100):
features = BehavioralFeatures(
gaze_stability=0.85 + np.random.randn() * 0.05,
head_stability=0.90 + np.random.randn() * 0.03,
blink_regularity=0.80,
reaction_score=0.85,
lane_keeping_score=0.90,
steering_jerkiness=0.15 + np.random.randn() * 0.05,
)
imp_type, warning = detector.update(features, 60.0, i * 0.033)
if warning:
print(f"警告: {warning}")
print(f"结果: {imp_type.value}")

print("\n=== 场景2:酒驾模拟 ===")
detector = ImpairmentDetector()
detector.start_trip(0.0)
for i in range(100):
# 酒驾:高度波动
features = BehavioralFeatures(
gaze_stability=0.5 + np.random.randn() * 0.35, # 高波动
head_stability=0.6 + np.random.randn() * 0.25, # 高波动
blink_regularity=0.7,
reaction_score=0.5,
lane_keeping_score=0.6,
steering_jerkiness=0.6 + np.random.randn() * 0.1,
)
imp_type, warning = detector.update(features, 60.0, i * 0.033)
if warning:
print(f"[{i*0.033:.1f}s] 检测到: {imp_type.value}, 警告: {warning}")

print(f"最终结果: {imp_type.value}")

二、系统要求

2.1 硬件要求

组件 要求 说明
摄像头 红外摄像头 全天候工作
分辨率 ≥ 640×480 满足眼动追踪
帧率 ≥ 25 fps 实时检测
视场角 ≥ 50° 覆盖驾驶员面部
处理器 支持AI推理 NPU/GPU加速

2.2 系统配置要求

配置项 Euro NCAP要求 说明
默认状态 行程开始时自动开启 不可默认关闭
关闭操作 需要多步操作 不能单键关闭
ADAS联动 使用辅助驾驶时仍激活 不得禁用
灵敏度调整 用户不可调整 保证一致性

2.3 警告策略

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
"""
Euro NCAP 2026 警告分级策略
"""

from enum import Enum
from dataclasses import dataclass

class WarningLevel(Enum):
"""警告等级"""
NONE = 0
LEVEL_1 = 1 # 一级警告(轻度)
LEVEL_2 = 2 # 二级警告(严重)
EMERGENCY = 3 # 紧急停车

@dataclass
class WarningAction:
"""警告动作"""
visual: bool # 视觉警告
audible: bool # 听觉警告
haptic: bool # 触觉警告
duration: float # 持续时间(秒)
escalation: WarningLevel # 升级等级

class WarningStrategy:
"""
Euro NCAP 2026 警告策略

分级原则:
1. 一级警告:轻中度问题
2. 二级警告:严重问题
3. 紧急停车:无响应驾驶员
"""

def __init__(self):
# 警告配置
self.warning_configs = {
# 分心警告
'PROLONGED_DISTRACTION': WarningAction(
visual=True, audible=False, haptic=False,
duration=3.0, escalation=WarningLevel.LEVEL_2
),
'CRITICAL_DISTRACTION': WarningAction(
visual=True, audible=True, haptic=False,
duration=5.0, escalation=WarningLevel.LEVEL_2
),
'PHONE_USE': WarningAction(
visual=True, audible=True, haptic=True,
duration=3.0, escalation=WarningLevel.LEVEL_2
),
'PHONE_CALL': WarningAction(
visual=True, audible=True, haptic=True,
duration=5.0, escalation=WarningLevel.EMERGENCY
),

# 疲劳警告
'MODERATE_FATIGUE': WarningAction(
visual=True, audible=True, haptic=False,
duration=5.0, escalation=WarningLevel.LEVEL_2
),
'SEVERE_FATIGUE': WarningAction(
visual=True, audible=True, haptic=True,
duration=10.0, escalation=WarningLevel.EMERGENCY
),
'MICROSLEEP': WarningAction(
visual=True, audible=True, haptic=True,
duration=0, escalation=WarningLevel.EMERGENCY
),

# 损伤警告
'ALCOHOL_IMPAIRMENT': WarningAction(
visual=True, audible=True, haptic=True,
duration=10.0, escalation=WarningLevel.EMERGENCY
),
'FATIGUE_DETECTED': WarningAction(
visual=True, audible=True, haptic=False,
duration=5.0, escalation=WarningLevel.LEVEL_2
),

# 紧急停车
'EMERGENCY_STOP': WarningAction(
visual=True, audible=True, haptic=True,
duration=0, escalation=WarningLevel.EMERGENCY
),
}

def get_warning_action(self, warning_type: str) -> WarningAction:
"""获取警告动作配置"""
return self.warning_configs.get(warning_type,
WarningAction(False, False, False, 0, WarningLevel.NONE))

def escalate_warning(self,
current_level: WarningLevel,
persistent_time: float) -> WarningLevel:
"""
警告升级逻辑

Args:
current_level: 当前警告等级
persistent_time: 问题持续时间

Returns:
升级后的警告等级
"""
if current_level == WarningLevel.NONE:
return WarningLevel.LEVEL_1

# 一级警告持续15秒升级为二级
if current_level == WarningLevel.LEVEL_1 and persistent_time > 15:
return WarningLevel.LEVEL_2

# 二级警告持续30秒升级为紧急
if current_level == WarningLevel.LEVEL_2 and persistent_time > 30:
return WarningLevel.EMERGENCY

return current_level


# 实际测试
if __name__ == "__main__":
strategy = WarningStrategy()

print("=== 各场景警告配置 ===")
for warning_type in ['PROLONGED_DISTRACTION', 'PHONE_USE',
'MODERATE_FATIGUE', 'MICROSLEEP', 'ALCOHOL_IMPAIRMENT']:
action = strategy.get_warning_action(warning_type)
print(f"\n{warning_type}:")
print(f" 视觉: {action.visual}, 听觉: {action.audible}, 触觉: {action.haptic}")
print(f" 持续时间: {action.duration}s, 升级等级: {action.escalation.value}")

三、合规检查清单

3.1 硬件合规

检查项 要求 验证方法
[ ] 红外摄像头 940nm红外 硬件规格确认
[ ] 分辨率 ≥ 640×480 实际测试
[ ] 帧率 ≥ 25 fps 实际测试
[ ] 视场角 覆盖驾驶员面部 光学测试
[ ] 夜间性能 红外补光 暗室测试

3.2 软件合规

检查项 要求 验证方法
[ ] 默认开启 行程启动时自动激活 功能测试
[ ] 不可单键关闭 需要多步操作 功能测试
[ ] ADAS联动 辅助驾驶时保持激活 集成测试
[ ] 灵敏度锁定 用户不可调整 功能测试
[ ] 警告记录 存储事件日志 数据验证

3.3 测试场景合规

Euro NCAP测试场景清单:

编号 场景 检测时限 通过标准
D-01 视线短暂偏离(≤3s) 不触发 不误报
D-02 视线长时间偏离(3-4s) ≤3s 发出警告
D-03 视线极端偏离(≥4s) ≤3s 发出警告
D-04 手机使用(腿部) ≤3s 发出警告
D-05 手机使用(耳边) ≤3s 发出警告
F-01 PERCLOS≥30% 实时 发出警告
F-02 微睡眠(>1.5s) ≤3s 发出警告
I-01 酒驾行为模式 ≤10min 发出警告

四、IMS开发建议

4.1 技术路线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Euro NCAP 2026 DMS技术路线

├── 硬件选型
│ ├── 红外摄像头:OV2311/OV9282
│ ├── 红外补光:940nm LED
│ └── 处理器:QCS8255/SNPE

├── 算法开发
│ ├── 眼动追踪:瞳孔检测+视线估计
│ ├── 疲劳检测:PERCLOS+眨眼特征
│ ├── 分心检测:视线区域+手机检测
│ └── 酒驾检测:行为分析+历史对比

├── 系统集成
│ ├── 默认开启机制
│ ├── 多级警告策略
│ ├── ADAS联动接口
│ └── 事件记录存储

└── 测试验证
├── 台架测试
├── 实车测试
└── Euro NCAP官方测试

4.2 优先级排序

功能 优先级 工作量 Euro NCAP分值
视线追踪 P0 8分(分心检测基础)
PERCLOS计算 P0 8分(疲劳检测核心)
手机检测 P1 4分
酒驾检测 P1 5分
警告策略 P0 4分

五、总结

5.1 核心要点

  1. 25分独立评分:DMS成为星级评定的关键项
  2. 必须直测:间接传感器方案不再合规
  3. 新增酒驾检测:首次纳入评估范围
  4. 警告分级:多级警告+紧急停车
  5. 系统可用性:默认开启、不可关闭

5.2 时间节点

时间 里程碑
2025年1月 Euro NCAP发布2026协议
2025年Q2 OEM提交技术文档
2026年1月 正式实施新评分体系
2027年 全面强制实施

参考文档:

  • Euro NCAP 2026 Assessment Protocol
  • Euro NCAP Safe Driving Protocol v0.9
  • Smart Eye: Driver Monitoring 2.0

Euro NCAP 2026 DMS新规详解:25分评分体系与合规要点
https://dapalm.com/2026/04/24/2026-04-24-euro-ncap-2026-dms-25-points/
作者
Mars
发布于
2026年4月24日
许可协议