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
| """ 触觉反馈干预系统
根据DMS状态等级,触发不同触觉模式 依赖: pip install numpy RPi.GPIO(树莓派) 或等效接口 """
import numpy as np from typing import Dict, List from dataclasses import dataclass from enum import IntEnum import time
class HapticLevel(IntEnum): NONE = 0 LIGHT_VIBRATION = 1 PULSE_PATTERN = 2 SEATBELT_TENSE = 3 FULL_ALERT = 4 EMERGENCY = 5
@dataclass class DriverState: """DMS输入状态""" perclos: float = 0.0 gaze_off_road_sec: float = 0.0 phone_detected: bool = False responsive: bool = True fatigue_duration_sec: float = 0.0
class HapticInterventionSystem: """ 触觉干预系统 决策逻辑: 1. DMS状态 → 干预等级 2. 干预等级 → 触觉模式 3. 触觉模式 → 执行器控制 """ HAPTIC_PATTERNS = { HapticLevel.LIGHT_VIBRATION: { 'pattern': 'sine', 'frequency': 150, 'amplitude': 0.4, 'duration_ms': 500, 'repeat': 1, 'actuators': ['sw_left', 'sw_right'], }, HapticLevel.PULSE_PATTERN: { 'pattern': 'pulse', 'frequency': 200, 'amplitude': 0.7, 'duration_ms': 200, 'gap_ms': 100, 'repeat': 3, 'actuators': ['sw_left', 'sw_right', 'sw_top', 'sw_bottom'], }, HapticLevel.SEATBELT_TENSE: { 'pattern': 'seatbelt_pre', 'duration_ms': 300, 'force': 50, 'repeat': 1, 'actuators': ['seatbelt_left', 'seatbelt_right'], }, HapticLevel.FULL_ALERT: { 'pattern': 'full', 'frequency': 250, 'amplitude': 1.0, 'duration_ms': 1000, 'gap_ms': 200, 'repeat': 5, 'actuators': ['sw_all', 'seatbelt_all', 'seat_all'], }, HapticLevel.EMERGENCY: { 'pattern': 'emergency', 'frequency': 300, 'amplitude': 1.0, 'duration_ms': 2000, 'gap_ms': 100, 'repeat': 999, 'actuators': ['sw_all', 'seatbelt_all', 'seat_all'], }, } def determine_level(self, driver: DriverState, speed_kmh: float) -> HapticLevel: """根据DMS状态确定干预等级""" if driver.gaze_off_road_sec > 4 or driver.phone_detected: if speed_kmh > 80: return HapticLevel.PULSE_PATTERN return HapticLevel.LIGHT_VIBRATION if driver.perclos > 0.30: if driver.fatigue_duration_sec > 10: return HapticLevel.SEATBELT_TENSE return HapticLevel.PULSE_PATTERN elif driver.perclos > 0.15: return HapticLevel.LIGHT_VIBRATION if not driver.responsive: if driver.fatigue_duration_sec > 30: return HapticLevel.EMERGENCY elif driver.fatigue_duration_sec > 15: return HapticLevel.FULL_ALERT elif driver.fatigue_duration_sec > 5: return HapticLevel.SEATBELT_TENSE return HapticLevel.NONE def generate_waveform(self, level: HapticLevel) -> Dict: """生成执行器控制波形""" if level == HapticLevel.NONE: return {'actuators': [], 'waveform': []} pattern = self.HAPTIC_PATTERNS[level] if pattern['pattern'] == 'sine': t = np.linspace(0, pattern['duration_ms']/1000, int(pattern['duration_ms'])) waveform = pattern['amplitude'] * np.sin(2*np.pi*pattern['frequency']*t) elif pattern['pattern'] == 'pulse': total_duration = pattern['duration_ms'] * pattern['repeat'] + \ pattern.get('gap_ms', 0) * (pattern['repeat']-1) t = np.linspace(0, total_duration/1000, int(total_duration*10)) waveform = np.zeros_like(t) for i in range(pattern['repeat']): start = i * (pattern['duration_ms'] + pattern.get('gap_ms', 0)) end = start + pattern['duration_ms'] mask = (t*1000 >= start) & (t*1000 < end) waveform[mask] = pattern['amplitude'] * \ np.sin(2*np.pi*pattern['frequency']*t[mask]) elif pattern['pattern'] == 'seatbelt_pre': t = np.linspace(0, pattern['duration_ms']/1000, int(pattern['duration_ms'])) waveform = np.minimum(t / 0.05, 1.0) * pattern['force'] else: duration = min(pattern['duration_ms'], 2000) t = np.linspace(0, duration/1000, int(duration*10)) waveform = pattern['amplitude'] * \ np.sin(2*np.pi*pattern['frequency']*t) return { 'actuators': pattern['actuators'], 'waveform': waveform.tolist(), 'duration_ms': len(waveform) / 10, 'pattern': pattern['pattern'], }
if __name__ == "__main__": system = HapticInterventionSystem() states = [ ('正常', DriverState(perclos=0.05, gaze_off_road_sec=1.0)), ('轻度分心', DriverState(gaze_off_road_sec=4.5)), ('手机使用', DriverState(phone_detected=True)), ('中度疲劳', DriverState(perclos=0.28, fatigue_duration_sec=5)), ('重度疲劳', DriverState(perclos=0.45, fatigue_duration_sec=15)), ('无响应', DriverState(responsive=False, fatigue_duration_sec=35)), ] for name, driver in states: level = system.determine_level(driver, speed_kmh=80) wave = system.generate_waveform(level) print(f"{name}: 等级{level.name}, " f"执行器={wave.get('actuators', [])}, " f"时长={wave.get('duration_ms', 0):.0f}ms")
|