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
| class CockpitScanAnalyzer: """ 座舱扫描模式分析 核心思想: - 正常飞行员定期扫描关键仪表 - 疲劳时扫描模式僵化,遗漏重要区域 """ def __init__(self, cockpit_layout): """ Args: cockpit_layout: 座舱仪表布局定义 """ self.layout = cockpit_layout self.key_instruments = { 'airspeed': {'priority': 'HIGH', 'expected_scan_rate': 0.3}, 'altitude': {'priority': 'HIGH', 'expected_scan_rate': 0.3}, 'attitude': {'priority': 'HIGH', 'expected_scan_rate': 0.4}, 'heading': {'priority': 'MEDIUM', 'expected_scan_rate': 0.2}, 'engine': {'priority': 'MEDIUM', 'expected_scan_rate': 0.15}, } def analyze_scan_pattern(self, gaze_data, window_seconds=60): """ 分析扫描模式 Returns: scan_quality: 扫描质量评分 """ fixation_counts = {key: 0 for key in self.key_instruments} for fixation in gaze_data['fixations']: region = self.classify_region(fixation['position']) if region in fixation_counts: fixation_counts[region] += 1 total_fixations = sum(fixation_counts.values()) if total_fixations == 0: return {'quality': 0, 'missed_regions': list(self.key_instruments.keys())} scan_rates = { k: v / total_fixations for k, v in fixation_counts.items() } deviations = {} for inst, expected in self.key_instruments.items(): actual = scan_rates.get(inst, 0) expected_rate = expected['expected_scan_rate'] deviations[inst] = abs(actual - expected_rate) / expected_rate quality = 1.0 - np.mean(list(deviations.values())) missed = [ inst for inst, rate in scan_rates.items() if rate < self.key_instruments[inst]['expected_scan_rate'] * 0.5 ] return { 'quality': quality, 'scan_rates': scan_rates, 'deviations': deviations, 'missed_regions': missed } def classify_region(self, position): """根据注视位置分类仪表区域""" x, y = position if x < 0.33: return 'airspeed' elif x < 0.66: if y < 0.5: return 'attitude' else: return 'heading' else: if y < 0.7: return 'altitude' else: return 'engine'
|