""" 工具类模块 提供触觉反馈系统所需的实用工具函数 """ import time import math from typing import Dict, Any, List, Optional, Union import threading import json class HapticUtils: """ 触觉工具类 提供触觉反馈系统所需的实用工具函数 """ def __init__(self, plugin): """ 初始化触觉工具类 Args: plugin: 触觉反馈系统插件实例 """ self.plugin = plugin self.enabled = False self.initialized = False # 性能监控 self.performance_metrics = { 'update_times': [], 'effect_processing_times': [], 'device_response_times': [], 'memory_usage': 0 } # 日志配置 self.log_config = { 'enable_logging': True, 'log_level': 'INFO', 'log_file': '/home/hello/EG/plugins/user/haptic_feedback_system/logs/haptic.log', 'max_log_size': 10 * 1024 * 1024, # 10MB 'log_format': '[{timestamp}] {level}: {message}' } # 数据转换配置 self.conversion_config = { 'intensity_curve': 'linear', # linear, exponential, logarithmic 'frequency_mapping': 'linear', 'duration_scaling': 'linear' } # 数学工具 self.math_utils = MathUtils() # 缓存管理 self.cache_manager = CacheManager() # 调试工具 self.debug_tools = DebugTools() # 统计信息 self.stats = { 'functions_called': 0, 'data_processed': 0, 'cache_hits': 0, 'cache_misses': 0 } print("✓ 触觉工具类已创建") def initialize(self) -> bool: """ 初始化触觉工具类 Returns: 是否初始化成功 """ try: # 创建日志目录 import os log_dir = "/home/hello/EG/plugins/user/haptic_feedback_system/logs" os.makedirs(log_dir, exist_ok=True) self.initialized = True print("✓ 触觉工具类初始化完成") return True except Exception as e: print(f"✗ 触觉工具类初始化失败: {e}") import traceback traceback.print_exc() return False def enable(self) -> bool: """ 启用触觉工具类 Returns: 是否启用成功 """ try: if not self.initialized: print("✗ 触觉工具类未初始化") return False self.enabled = True print("✓ 触觉工具类已启用") return True except Exception as e: print(f"✗ 触觉工具类启用失败: {e}") import traceback traceback.print_exc() return False def disable(self): """禁用触觉工具类""" try: self.enabled = False print("✓ 触觉工具类已禁用") except Exception as e: print(f"✗ 触觉工具类禁用失败: {e}") import traceback traceback.print_exc() def finalize(self): """清理触觉工具类资源""" try: self.disable() self.performance_metrics.clear() self.cache_manager.clear() self.initialized = False print("✓ 触觉工具类资源已清理") except Exception as e: print(f"✗ 触觉工具类资源清理失败: {e}") import traceback traceback.print_exc() def update(self, dt: float): """ 更新触觉工具类状态 Args: dt: 时间增量 """ try: if not self.enabled: return # 更新性能指标 self._update_performance_metrics(dt) except Exception as e: print(f"✗ 触觉工具类更新失败: {e}") import traceback traceback.print_exc() def _update_performance_metrics(self, dt: float): """更新性能指标""" try: # 记录更新时间 self.performance_metrics['update_times'].append(dt) # 保持历史记录大小 if len(self.performance_metrics['update_times']) > 1000: self.performance_metrics['update_times'] = self.performance_metrics['update_times'][-1000:] except Exception as e: print(f"✗ 性能指标更新失败: {e}") def log_message(self, message: str, level: str = 'INFO'): """ 记录日志消息 Args: message: 日志消息 level: 日志级别 (DEBUG, INFO, WARNING, ERROR) """ try: if not self.log_config['enable_logging']: return # 检查日志级别 level_priority = {'DEBUG': 0, 'INFO': 1, 'WARNING': 2, 'ERROR': 3} config_level = self.log_config['log_level'] if level_priority.get(level, 1) < level_priority.get(config_level, 1): return # 格式化日志消息 timestamp = time.strftime('%Y-%m-%d %H:%M:%S') formatted_message = self.log_config['log_format'].format( timestamp=timestamp, level=level, message=message ) # 输出到控制台 print(formatted_message) # 写入日志文件 try: with open(self.log_config['log_file'], 'a', encoding='utf-8') as f: f.write(formatted_message + '\n') except Exception as e: pass # 忽略文件写入错误 except Exception as e: pass # 忽略日志记录错误 def measure_performance(self, func: callable, *args, **kwargs) -> tuple: """ 测量函数性能 Args: func: 要测量的函数 *args: 函数参数 **kwargs: 函数关键字参数 Returns: (结果, 执行时间) """ try: start_time = time.perf_counter() result = func(*args, **kwargs) end_time = time.perf_counter() execution_time = end_time - start_time # 记录到性能指标 metric_name = f"{func.__name__}_times" if metric_name not in self.performance_metrics: self.performance_metrics[metric_name] = [] self.performance_metrics[metric_name].append(execution_time) # 保持历史记录大小 if len(self.performance_metrics[metric_name]) > 1000: self.performance_metrics[metric_name] = self.performance_metrics[metric_name][-1000:] self.stats['functions_called'] += 1 return (result, execution_time) except Exception as e: self.log_message(f"性能测量失败: {e}", 'ERROR') raise def convert_intensity(self, intensity: float, curve: str = None) -> float: """ 转换强度值 Args: intensity: 原始强度值 (0.0-1.0) curve: 转换曲线类型 Returns: 转换后的强度值 """ try: curve_type = curve or self.conversion_config['intensity_curve'] intensity = max(0.0, min(1.0, intensity)) if curve_type == 'exponential': # 指数曲线 return math.pow(intensity, 2) elif curve_type == 'logarithmic': # 对数曲线 return math.log(intensity + 1) / math.log(2) else: # 线性曲线 return intensity except Exception as e: self.log_message(f"强度转换失败: {e}", 'ERROR') return intensity def convert_frequency(self, frequency: float, min_freq: float = 1.0, max_freq: float = 100.0, mapping: str = None) -> float: """ 转换频率值 Args: frequency: 原始频率值 min_freq: 最小频率 max_freq: 最大频率 mapping: 映射类型 Returns: 转换后的频率值 """ try: mapping_type = mapping or self.conversion_config['frequency_mapping'] frequency = max(0.0, frequency) if mapping_type == 'logarithmic': # 对数映射 log_min = math.log(max(min_freq, 1.0)) log_max = math.log(max(max_freq, 1.0)) log_freq = math.log(max(frequency, 1.0)) normalized = (log_freq - log_min) / (log_max - log_min) return min_freq + normalized * (max_freq - min_freq) else: # 线性映射 return max(min_freq, min(max_freq, frequency)) except Exception as e: self.log_message(f"频率转换失败: {e}", 'ERROR') return frequency def scale_duration(self, duration: float, scale_factor: float = 1.0, scaling_type: str = None) -> float: """ 缩放持续时间 Args: duration: 原始持续时间 scale_factor: 缩放因子 scaling_type: 缩放类型 Returns: 缩放后的持续时间 """ try: scaling = scaling_type or self.conversion_config['duration_scaling'] duration = max(0.0, duration) scale_factor = max(0.0, scale_factor) if scaling == 'exponential': return duration * math.pow(scale_factor, 2) elif scaling == 'logarithmic': return duration * math.log(scale_factor + 1) else: return duration * scale_factor except Exception as e: self.log_message(f"持续时间缩放失败: {e}", 'ERROR') return duration def interpolate_values(self, start_value: float, end_value: float, progress: float, interpolation_type: str = 'linear') -> float: """ 插值计算 Args: start_value: 起始值 end_value: 结束值 progress: 进度 (0.0-1.0) interpolation_type: 插值类型 Returns: 插值结果 """ try: progress = max(0.0, min(1.0, progress)) if interpolation_type == 'ease_in': progress = math.pow(progress, 2) elif interpolation_type == 'ease_out': progress = 1.0 - math.pow(1.0 - progress, 2) elif interpolation_type == 'ease_in_out': progress = 0.5 * (1 - math.cos(progress * math.pi)) # linear 为默认情况,无需特殊处理 return start_value + (end_value - start_value) * progress except Exception as e: self.log_message(f"插值计算失败: {e}", 'ERROR') return start_value def calculate_distance(self, pos1: tuple, pos2: tuple) -> float: """ 计算两点间距离 Args: pos1: 第一个点 (x, y, z) pos2: 第二个点 (x, y, z) Returns: 距离值 """ try: dx = pos2[0] - pos1[0] dy = pos2[1] - pos1[1] dz = pos2[2] - pos1[2] return math.sqrt(dx*dx + dy*dy + dz*dz) except Exception as e: self.log_message(f"距离计算失败: {e}", 'ERROR') return 0.0 def normalize_vector(self, vector: tuple) -> tuple: """ 归一化向量 Args: vector: 输入向量 (x, y, z) Returns: 归一化后的向量 """ try: magnitude = math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2) if magnitude > 0: return (vector[0]/magnitude, vector[1]/magnitude, vector[2]/magnitude) else: return (0, 0, 0) except Exception as e: self.log_message(f"向量归一化失败: {e}", 'ERROR') return (0, 0, 0) def get_performance_stats(self) -> Dict[str, Any]: """ 获取性能统计信息 Returns: 性能统计字典 """ try: stats = {} for key, times in self.performance_metrics.items(): if times: stats[key] = { 'count': len(times), 'average': sum(times) / len(times), 'min': min(times), 'max': max(times), 'total': sum(times) } return stats except Exception as e: self.log_message(f"性能统计获取失败: {e}", 'ERROR') return {} def get_system_info(self) -> Dict[str, Any]: """ 获取系统信息 Returns: 系统信息字典 """ try: import platform import psutil return { 'platform': platform.system(), 'platform_version': platform.version(), 'processor': platform.processor(), 'cpu_count': psutil.cpu_count(), 'memory_total': psutil.virtual_memory().total, 'memory_available': psutil.virtual_memory().available, 'plugin_version': getattr(self.plugin, 'version', 'unknown') } except Exception as e: self.log_message(f"系统信息获取失败: {e}", 'ERROR') return {} def get_stats(self) -> Dict[str, int]: """ 获取统计信息 Returns: 统计信息字典 """ return self.stats.copy() def reset_stats(self): """重置统计信息""" try: self.stats = { 'functions_called': 0, 'data_processed': 0, 'cache_hits': 0, 'cache_misses': 0 } print("✓ 工具类统计信息已重置") except Exception as e: self.log_message(f"统计信息重置失败: {e}", 'ERROR') def set_log_config(self, config: Dict[str, Any]) -> bool: """ 设置日志配置 Args: config: 日志配置字典 Returns: 是否设置成功 """ try: self.log_config.update(config) self.log_message(f"日志配置已更新: {self.log_config}", 'INFO') return True except Exception as e: self.log_message(f"日志配置设置失败: {e}", 'ERROR') return False def set_conversion_config(self, config: Dict[str, Any]) -> bool: """ 设置转换配置 Args: config: 转换配置字典 Returns: 是否设置成功 """ try: self.conversion_config.update(config) self.log_message(f"转换配置已更新: {self.conversion_config}", 'INFO') return True except Exception as e: self.log_message(f"转换配置设置失败: {e}", 'ERROR') return False def get_cache_manager(self): """ 获取缓存管理器 Returns: 缓存管理器实例 """ return self.cache_manager def get_debug_tools(self): """ 获取调试工具 Returns: 调试工具实例 """ return self.debug_tools class MathUtils: """数学工具类""" @staticmethod def clamp(value: float, min_value: float, max_value: float) -> float: """限制值在指定范围内""" return max(min_value, min(max_value, value)) @staticmethod def lerp(start: float, end: float, t: float) -> float: """线性插值""" return start + (end - start) * t @staticmethod def smoothstep(edge0: float, edge1: float, x: float) -> float: """平滑插值""" t = MathUtils.clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0) return t * t * (3.0 - 2.0 * t) class CacheManager: """缓存管理器""" def __init__(self): self.cache = {} self.access_times = {} self.max_size = 1000 def get(self, key: str) -> Optional[Any]: """获取缓存值""" if key in self.cache: self.access_times[key] = time.time() return self.cache[key] return None def set(self, key: str, value: Any, ttl: float = 300.0): """设置缓存值""" self.cache[key] = value self.access_times[key] = time.time() # 检查缓存大小 if len(self.cache) > self.max_size: self._cleanup() def _cleanup(self): """清理过期缓存""" current_time = time.time() expired_keys = [ key for key, access_time in self.access_times.items() if current_time - access_time > 300.0 ] for key in expired_keys: del self.cache[key] del self.access_times[key] def clear(self): """清空缓存""" self.cache.clear() self.access_times.clear() class DebugTools: """调试工具类""" def __init__(self): self.debug_enabled = False self.debug_data = {} def enable_debug(self): """启用调试模式""" self.debug_enabled = True def disable_debug(self): """禁用调试模式""" self.debug_enabled = False def log_debug_data(self, key: str, data: Any): """记录调试数据""" if self.debug_enabled: self.debug_data[key] = data def get_debug_data(self, key: str = None) -> Union[Dict[str, Any], Any]: """获取调试数据""" if key: return self.debug_data.get(key) return self.debug_data.copy() def clear_debug_data(self): """清空调试数据""" self.debug_data.clear()