Euro NCAP 2026 无响应驾驶员干预系统(ESF)设计与实现

Euro NCAP 2026 无响应驾驶员干预系统(ESF)设计与实现

无响应驾驶员定义

Euro NCAP 2026 定义无响应驾驶员(Unresponsive Driver)为:

1
2
3
4
5
6
7
8
判定条件(满足任一):
1. 分心警告后 3 秒内视线未回到道路
2. 眼睛持续闭合 ≥6 秒
3. 无头部运动 + 无转向输入 + 无踏板输入

触发条件:
- 速度 ≥50km/h
- 系统检测到驾驶员异常状态

ESF(Emergency Stop Function)系统架构

整体设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌─────────────────────────────────────────────────────────┐
│ ESF 系统架构 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ DMS 检测 │───→│ 状态判断 │───→│ 干预决策 │ │
│ └─────────┘ └─────────┘ └─────────────────┘ │
│ │ │ │ │
│ ↓ ↓ ↓ │
│ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ 眼动状态 │ │ ADAS 状态 │ │ 执行机构 │ │
│ │ 头部姿态 │ │ 车辆状态 │ │ 转向/制动/灯光 │ │
│ │ 手部位置 │ │ 道路环境 │ │ HMI 警告 │ │
│ └─────────┘ └─────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘

干预级别

级别 触发条件 系统响应
Level 1 检测到分心 视觉警告
Level 2 分心持续 视觉 + 听觉警告
Level 3 无响应确认 FCW/AEB 灵敏度提高
Level 4 持续无响应 LKA/LDW 调整
Level 5 严重无响应 ESF 启动(靠边停车)

核心算法实现

无响应检测器

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
import numpy as np
from typing import Dict, Optional
from dataclasses import dataclass
from enum import Enum
import time

class UnresponsiveState(Enum):
"""无响应状态枚举"""
NORMAL = "normal" # 正常
DISTRACTED = "distracted" # 分心
WARNED = "warned" # 已警告
UNRESPONSIVE = "unresponsive" # 无响应
CRITICAL = "critical" # 严重无响应


@dataclass
class DriverState:
"""驾驶员状态"""
timestamp: float
eyes_closed: bool
eyes_closed_duration: float
gaze_on_road: bool
head_movement_detected: bool
hand_on_wheel: bool


@dataclass
class VehicleState:
"""车辆状态"""
timestamp: float
speed: float
steering_angle: float
throttle: float
brake: float
lane_position: float


class UnresponsiveDriverDetector:
"""
无响应驾驶员检测器

Euro NCAP 2026 合规实现
"""

def __init__(self):
# 检测参数
self.gaze_return_timeout = 3.0 # 分心警告后视线返回超时
self.eyes_closed_threshold = 6.0 # 眼睛闭合阈值
self.no_movement_threshold = 10.0 # 无动作阈值

# 状态跟踪
self.current_state = UnresponsiveState.NORMAL
self.state_start_time: Optional[float] = None
self.warning_issued_time: Optional[float] = None

# 历史数据
self.driver_state_history: list = []
self.vehicle_state_history: list = []

def update(self,
driver_state: DriverState,
vehicle_state: VehicleState) -> Dict:
"""
更新检测状态

Args:
driver_state: 驾驶员状态
vehicle_state: 车辆状态

Returns:
result: 检测结果
"""
current_time = driver_state.timestamp

# 检查速度条件
if vehicle_state.speed < 50: # km/h
return self._normal_result("Speed below threshold")

# 添加到历史
self.driver_state_history.append(driver_state)
self.vehicle_state_history.append(vehicle_state)

# 维护历史长度
max_history = 300 # 10秒 @ 30Hz
if len(self.driver_state_history) > max_history:
self.driver_state_history.pop(0)
self.vehicle_state_history.pop(0)

# 检测逻辑
result = self._detect(current_time, driver_state, vehicle_state)

return result

def _detect(self,
current_time: float,
driver_state: DriverState,
vehicle_state: VehicleState) -> Dict:
"""执行检测"""

# 条件 1:眼睛持续闭合 ≥6 秒
if driver_state.eyes_closed and driver_state.eyes_closed_duration >= self.eyes_closed_threshold:
return self._transition_state(
UnresponsiveState.CRITICAL,
current_time,
"Eyes closed for >= 6 seconds"
)

# 条件 2:分心警告后 3 秒视线未返回
if self.current_state == UnresponsiveState.WARNED:
if self.warning_issued_time is not None:
time_since_warning = current_time - self.warning_issued_time

if time_since_warning >= self.gaze_return_timeout:
if not driver_state.gaze_on_road:
return self._transition_state(
UnresponsiveState.UNRESPONSIVE,
current_time,
"Gaze not returned after warning"
)

# 条件 3:无动作检测
no_movement = self._check_no_movement(driver_state, vehicle_state)
if no_movement['detected'] and no_movement['duration'] >= self.no_movement_threshold:
return self._transition_state(
UnresponsiveState.UNRESPONSIVE,
current_time,
"No movement detected"
)

# 状态更新
if driver_state.gaze_on_road and not driver_state.eyes_closed:
return self._transition_state(
UnresponsiveState.NORMAL,
current_time,
"Driver responsive"
)
elif not driver_state.gaze_on_road:
if self.current_state == UnresponsiveState.NORMAL:
return self._transition_state(
UnresponsiveState.DISTRACTED,
current_time,
"Driver distracted"
)

return self._current_result()

def _check_no_movement(self,
driver_state: DriverState,
vehicle_state: VehicleState) -> Dict:
"""检测无动作"""
# 检查历史数据中的动作
recent_driver = self.driver_state_history[-100:] # 最近 3.3 秒

head_movement = any(s.head_movement_detected for s in recent_driver)
hand_on_wheel = any(s.hand_on_wheel for s in recent_driver)

# 检查车辆输入
recent_vehicle = self.vehicle_state_history[-100:]

steering_change = any(
abs(v.steering_angle - recent_vehicle[0].steering_angle) > 5
for v in recent_vehicle
)

throttle_input = any(v.throttle > 0.1 for v in recent_vehicle)
brake_input = any(v.brake > 0.1 for v in recent_vehicle)

# 无动作判定
no_movement = not (head_movement or hand_on_wheel or
steering_change or throttle_input or brake_input)

return {
'detected': no_movement,
'duration': len(recent_driver) / 30.0 if no_movement else 0.0
}

def _transition_state(self,
new_state: UnresponsiveState,
timestamp: float,
reason: str) -> Dict:
"""状态转换"""
old_state = self.current_state
self.current_state = new_state

if new_state == UnresponsiveState.WARNED:
self.warning_issued_time = timestamp

return {
'state': new_state.value,
'state_changed': old_state != new_state,
'previous_state': old_state.value,
'timestamp': timestamp,
'reason': reason,
'esf_required': new_state == UnresponsiveState.CRITICAL
}

def _current_result(self) -> Dict:
"""返回当前状态"""
return {
'state': self.current_state.value,
'state_changed': False,
'esf_required': False
}

def _normal_result(self, reason: str) -> Dict:
"""返回正常状态"""
return {
'state': UnresponsiveState.NORMAL.value,
'state_changed': False,
'reason': reason,
'esf_required': False
}

ESF 执行控制器

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
class ESFController:
"""
紧急停止功能(ESF)控制器

执行最小风险策略(MRM)
"""

def __init__(self):
# ESF 状态
self.esf_active = False
self.esf_start_time: Optional[float] = None

# 干预参数
self.deceleration_rate = 3.0 # m/s²
self.target_stop_duration = 30.0 # 秒

# HMI 控制
self.hmi_controller = HMIController()

# ADAS 接口
self.adas_interface = ADASInterface()

def execute_esf(self,
vehicle_state: VehicleState,
road_context: Dict) -> Dict:
"""
执行紧急停止功能

Args:
vehicle_state: 当前车辆状态
road_context: 道路环境信息

Returns:
action: 执行的动作
"""
if not self.esf_active:
self.esf_active = True
self.esf_start_time = vehicle_state.timestamp

# 1. 激活危险警示灯
self.hmi_controller.activate_hazard_lights()

# 2. 发出语音警告
self.hmi_controller.play_warning("Emergency stop initiated")

# 3. 减速策略
current_speed = vehicle_state.speed / 3.6 # 转换为 m/s

# 检查是否可以靠边停车
if road_context.get('right_lane_available', False):
# 向右变道 + 减速
action = {
'type': 'lane_change_and_stop',
'target_lane': 'right',
'deceleration': self.deceleration_rate,
'steering_angle': self._calculate_lane_change_steering(road_context)
}
else:
# 仅减速停车
action = {
'type': 'stop_in_lane',
'deceleration': self.deceleration_rate,
'target_speed': 0.0
}

# 4. 调整 ADAS 参数
self.adas_interface.set_fcw_sensitivity('maximum')
self.adas_interface.set_aeb_enabled(True)
self.adas_interface.set_lka_enabled(True)

# 5. 发送 eCall(如果配置)
if self._should_trigger_ecall(vehicle_state):
self._trigger_ecall()

return action

def _calculate_lane_change_steering(self, road_context: Dict) -> float:
"""计算变道转向角度"""
# 简化实现
return 3.0 # 度

def _should_trigger_ecall(self, vehicle_state: VehicleState) -> bool:
"""判断是否触发 eCall"""
# 如果车辆已停止且驾驶员仍无响应
return vehicle_state.speed < 5 and self.esf_active

def _trigger_ecall(self):
"""触发紧急呼叫"""
# 实现 eCall 触发逻辑
pass

def cancel_esf(self):
"""取消 ESF"""
self.esf_active = False
self.esf_start_time = None

self.hmi_controller.deactivate_hazard_lights()
self.adas_interface.reset_sensitivity()


class HMIController:
"""HMI 控制器"""

def __init__(self):
self.hazard_lights_active = False
self.current_warning = None

def activate_hazard_lights(self):
"""激活危险警示灯"""
self.hazard_lights_active = True
# 实际调用车辆 CAN 接口

def deactivate_hazard_lights(self):
"""关闭危险警示灯"""
self.hazard_lights_active = False

def play_warning(self, message: str):
"""播放语音警告"""
self.current_warning = message
# 实际调用音频播放接口


class ADASInterface:
"""ADAS 接口"""

def __init__(self):
self.fcw_sensitivity = 'normal'
self.aeb_enabled = True
self.lka_enabled = True

def set_fcw_sensitivity(self, level: str):
"""设置 FCW 灵敏度"""
self.fcw_sensitivity = level

def set_aeb_enabled(self, enabled: bool):
"""设置 AEB 启用状态"""
self.aeb_enabled = enabled

def set_lka_enabled(self, enabled: bool):
"""设置 LKA 启用状态"""
self.lka_enabled = enabled

def reset_sensitivity(self):
"""重置灵敏度"""
self.fcw_sensitivity = 'normal'

完整系统集成

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
class UnresponsiveDriverInterventionSystem:
"""
无响应驾驶员干预系统

集成 DMS 检测和 ESF 执行
"""

def __init__(self):
self.detector = UnresponsiveDriverDetector()
self.esf_controller = ESFController()

# 干预策略
self.intervention_strategy = InterventionStrategy()

def process(self,
driver_state: DriverState,
vehicle_state: VehicleState,
road_context: Dict) -> Dict:
"""
处理单帧数据

Args:
driver_state: 驾驶员状态
vehicle_state: 车辆状态
road_context: 道路环境

Returns:
intervention: 干预动作
"""
# 1. 检测无响应状态
detection_result = self.detector.update(driver_state, vehicle_state)

# 2. 根据状态选择干预策略
if detection_result['state'] == 'critical':
# 启动 ESF
action = self.esf_controller.execute_esf(vehicle_state, road_context)
elif detection_result['state'] == 'unresponsive':
# 准备干预
action = self.intervention_strategy.prepare_intervention(vehicle_state)
elif detection_result['state'] == 'warned':
# 发出警告
action = self.intervention_strategy.issue_warning()
else:
# 正常状态
action = {'type': 'none'}

return {
'detection': detection_result,
'intervention': action
}


class InterventionStrategy:
"""干预策略"""

def __init__(self):
self.warning_level = 0

def prepare_intervention(self, vehicle_state: VehicleState) -> Dict:
"""准备干预"""
return {
'type': 'prepare',
'actions': ['increase_fcw_sensitivity', 'enable_aeb', 'monitor_lane']
}

def issue_warning(self) -> Dict:
"""发出警告"""
self.warning_level += 1

return {
'type': 'warning',
'level': self.warning_level,
'modalities': ['visual', 'auditory', 'haptic']
}

Euro NCAP 2026 测试场景

场景 测试内容 通过条件
UD-01 眼睛闭合 6 秒 ESF 启动,车辆减速停车
UD-02 分心警告后视线未返回 状态升级为 Unresponsive
UD-03 无动作 10 秒 检测并发出警告
UD-04 ESF 执行中驾驶员恢复 ESF 取消,控制权交还
UD-05 低速场景(<50km/h) ESF 不启动

IMS 开发启示

1. 系统集成要点

1
2
3
4
5
DMS 输出 → 无响应检测 → ADAS 接口 → 车辆控制
↓ ↓ ↓ ↓
眼动状态 状态判断 FCW/AEB 转向/制动
头部姿态 时间判断 LKA/LDW 灯光/HMI
手部检测 阈值判断 eCall 语音警告

2. 安全设计原则

原则 实现方式
冗余检测 多模态融合(眼动 + 头部 + 车辆输入)
分级响应 渐进式干预(警告 → 准备 → 执行)
可恢复性 驾驶员响应后立即取消干预
日志记录 全程记录用于事后分析

3. CAN 信号需求

信号 来源 用途
车速 ESC 激活条件判断
转向角 SAS 动作检测
油门踏板 ECM 动作检测
刹车踏板 ESC 动作检测
车道位置 LKA 停车位置判断

参考来源:


Euro NCAP 2026 无响应驾驶员干预系统(ESF)设计与实现
https://dapalm.com/2026/06/13/2026-06-13-Euro-NCAP-2026-Unresponsive-Driver-ESF/
作者
Mars
发布于
2026年6月13日
许可协议