diff --git a/src/tracking_car/config.yaml b/src/tracking_car/config.yaml index dd4d989c9d..2e1dae5a58 100644 --- a/src/tracking_car/config.yaml +++ b/src/tracking_car/config.yaml @@ -4,12 +4,11 @@ port: 2000 timeout: 20.0 # ======================== 传感器配置 ======================== -# 增大分辨率和视野,提升远距离检测能力 -img_width: 1280 # ↑ 从640提升到1280,让远处车辆更清晰 -img_height: 960 # ↑ 从480提升到960 -fov: 110 # ↑ 从90提升到110,扩大视野范围 +img_width: 1280 +img_height: 960 +fov: 110 sensor_tick: 0.05 -use_lidar: true # 保持LiDAR开启,用于距离验证 +use_lidar: true # ======================== LiDAR配置 ======================== lidar_channels: 32 @@ -17,14 +16,11 @@ lidar_range: 100.0 lidar_points_per_second: 500000 # ======================== 检测模型配置 ======================== -# 关键优化:降低阈值,增大输入尺寸 -yolo_model: "yolov8n.pt" # 可选:换成 yolov8m.pt 效果更好 -conf_thres: 0.25 # ↓ 从0.5降低到0.25,检测更多远处目标 -iou_thres: 0.3 # 保持 -device: "cuda" if torch.cuda.is_available() else "cpu" -yolo_imgsz_max: 640 # ↑ 从320提升到640,提升小目标检测能力 -yolo_iou: 0.45 -yolo_quantize: false +yolo_model: "yolov8n.pt" +conf_thres: 0.25 +iou_thres: 0.3 +device: "cpu" +yolo_imgsz_max: 640 # ======================== 跟踪算法配置 ======================== max_age: 5 @@ -39,63 +35,25 @@ display_fps: 30 # ======================== 轨迹历史配置 ======================== track_history_len: 20 -track_line_width: 2 -track_alpha: 0.6 # ======================== 行为分析配置 ======================== -# 针对远距离检测调整参数 -stop_speed_thresh: 0.8 # ↓ 降低停车速度阈值 +stop_speed_thresh: 0.8 stop_frames_thresh: 5 overtake_speed_ratio: 1.5 -overtake_dist_thresh: 60.0 # ↑ 增大超车距离阈值 +overtake_dist_thresh: 60.0 lane_change_thresh: 0.4 brake_accel_thresh: 2.0 turn_angle_thresh: 15.0 -danger_dist_thresh: 15.0 # ↑ 增大危险距离阈值,适应更远检测 +danger_dist_thresh: 15.0 predict_frames: 10 # ======================== 天气与NPC配置 ======================== -default_weather: "clear" # 使用清晰天气,有利于远距离检测 +default_weather: "clear" num_npcs: 20 -# ======================== 性能优化配置 ======================== -auto_adjust_detection: true # 自动调整检测参数 -smooth_alpha: 0.2 -fps_window_size: 15 - -# ======================== 传感器融合配置 ======================== -fuse_lidar_vision: true # 启用传感器融合 - -# ======================== 数据记录配置 ======================== -record_data: true -record_dir: "track_records" -record_format: "csv" -record_fps: 10 -save_screenshots: false - -# ======================== 3D可视化配置 ======================== -use_3d_visualization: true -pcd_view_size: 800 - -# ======================== 检测框样式配置 ======================== -det_box_color: [255, 0, 0] # 蓝色框 -det_box_thickness: 2 -det_label_bg_color: [0, 0, 0] # 黑色背景 -det_label_text_color: [255, 255, 255] # 白色文字 -det_label_font_scale: 0.5 -det_label_padding: 5 - # ======================== 视角控制配置 ======================== view: - default_mode: "satellite" # 默认视角模式 - satellite_height: 50.0 # 卫星视角高度 - behind_distance: 10.0 # 后方视角距离 - first_person_height: 1.6 # 第一人称视角高度 - -# ======================== 新增:远距离检测专用配置 ======================== -far_detection: - enabled: true # 启用远距离检测模式 - min_confidence: 0.2 # 远距离目标最低置信度 - min_pixel_size: 15 # 最小检测像素尺寸(宽或高) - scale_factor: 1.5 # 图像缩放因子用于小目标检测 - enable_multi_scale: true # 启用多尺度检测 \ No newline at end of file + default_mode: "satellite" + satellite_height: 50.0 + behind_distance: 10.0 + first_person_height: 1.6 diff --git a/src/tracking_car/main.py b/src/tracking_car/main.py index 46de81d9b4..88cfab5497 100644 --- a/src/tracking_car/main.py +++ b/src/tracking_car/main.py @@ -31,7 +31,6 @@ print(" - tracker.py") sys.exit(1) - # ======================== Configuration Management ======================== def load_config(config_path=None): @@ -115,7 +114,6 @@ def load_config(config_path=None): return default_config - def setup_carla_client(config): """ Setup CARLA client @@ -157,7 +155,6 @@ def setup_carla_client(config): logger.error(f"[ERROR] Failed to connect to CARLA server: {e}") return None, None - def set_weather(world, weather_name): """ Set weather @@ -182,7 +179,6 @@ def set_weather(world, weather_name): else: logger.warning(f"Unknown weather: {weather_name}, using clear weather") - # ======================== Visualization (Enhanced: Independent stats window) ======================== class Visualizer: @@ -1117,7 +1113,6 @@ def destroy(self): cv2.destroyAllWindows() logger.info("[OK] All visualization windows closed") - # ======================== Main Program ======================== class CarlaTrackingSystem: @@ -1534,33 +1529,35 @@ def _handle_keyboard_input(self, key): logger.info(f"[VIEW] 切换到 {mode_name}") def _control_frame_rate(self, current_fps): - """Control frame rate""" + """自适应帧率控制(简单版)""" import time - target_fps = self.config.get('display_fps', 30) + import psutil + + # 获取当前系统负载 + cpu_usage = psutil.cpu_percent() + + # 根据CPU使用率动态调整目标FPS + if cpu_usage > 85: # 非常高负载 + target_fps = max(10, self.config.get('display_fps', 30) * 0.5) + elif cpu_usage > 70: # 高负载 + target_fps = max(15, self.config.get('display_fps', 30) * 0.7) + elif cpu_usage < 40: # 低负载,可以尝试更高FPS + target_fps = min(60, self.config.get('display_fps', 30) * 1.5) + elif cpu_usage < 60: # 中等负载 + target_fps = min(45, self.config.get('display_fps', 30) * 1.2) + else: # 正常负载 + target_fps = self.config.get('display_fps', 30) + if target_fps <= 0: return - + target_interval = 1.0 / target_fps - - # If frame rate is too high, sleep appropriately - if current_fps > target_fps * 1.2: # Allow 20% fluctuation + + # 如果帧率过高,适当休眠 + if current_fps > target_fps * 1.2: # 允许20%波动 sleep_time = max(0, target_interval - (1.0 / current_fps)) time.sleep(sleep_time) - def _save_screenshot(self): - """Save screenshot""" - try: - import time - timestamp = time.strftime("%Y%m%d_%H%M%S") - filename = f"screenshot_{timestamp}_{self.frame_count:06d}.png" - - # Get currently displayed image - screenshot = self.sensor_manager.get_camera_image() - if utils.valid_img(screenshot): - utils.save_image(screenshot, filename) - logger.info(f"[SCREENSHOT] Screenshot saved: {filename}") - except Exception as e: - logger.warning(f"Screenshot save failed: {e}") def _print_status(self, stats_data): """Print system status""" @@ -1613,7 +1610,6 @@ def cleanup(self): logger.info("[OK] Resource cleanup complete") - # ======================== Main Function ======================== def main(): @@ -1692,7 +1688,6 @@ def main(): logger.info("[END] Program ended") logger.info("=" * 50) - if __name__ == "__main__": # 检查配置 try: diff --git a/src/tracking_car/requirements.txt b/src/tracking_car/requirements.txt index 7765ee6a8d..27cc8e8623 100644 --- a/src/tracking_car/requirements.txt +++ b/src/tracking_car/requirements.txt @@ -1,16 +1,17 @@ # 核心依赖 +# 可选依赖 + carla>=0.9.14 -opencv-python>=4.8.0 +loguru>=0.7.0 +matplotlib>=3.7.0 +numba>=0.57.0 numpy>=1.24.0 -torch>=2.0.0 -ultralytics>=8.0.0 open3d>=0.17.0 +opencv-python>=4.8.0 +pandas>=2.0.0 psutil>=5.9.0 -scipy>=1.10.0 -scikit-learn>=1.2.0 -numba>=0.57.0 -loguru>=0.7.0 pyyaml>=6.0.0 -# 可选依赖 -matplotlib>=3.7.0 -pandas>=2.0.0 \ No newline at end of file +scikit-learn>=1.2.0 +scipy>=1.10.0 +torch>=2.0.0 +ultralytics>=8.0.0 diff --git a/src/tracking_car/sensors.py b/src/tracking_car/sensors.py index bf084f5c01..e4ba38fda4 100644 --- a/src/tracking_car/sensors.py +++ b/src/tracking_car/sensors.py @@ -3,6 +3,7 @@ 包含:相机、LiDAR传感器封装和管理 """ +import random # 添加随机模块支持 import carla import cv2 import numpy as np @@ -23,7 +24,6 @@ import open3d as o3d from sklearn.cluster import DBSCAN - class CameraManager: """相机管理器""" @@ -147,7 +147,6 @@ def destroy(self): logger.warning(f"销毁相机失败: {e}") self.camera = None - class LiDARManager: """LiDAR管理器""" @@ -368,8 +367,6 @@ def destroy(self): logger.warning(f"销毁LiDAR失败: {e}") self.lidar = None -# ======================== 视角管理器 ======================== - class SpectatorManager: """CARLA视角管理器 - 提供卫星视角跟随""" @@ -681,9 +678,6 @@ def destroy(self): logger.info("✅ 所有传感器已销毁") - -# ======================== 工具函数 ======================== - def create_ego_vehicle(world, config, spawn_points=None): """ 创建自车 @@ -797,7 +791,6 @@ def create_ego_vehicle(world, config, spawn_points=None): traceback.print_exc() return None - def spawn_npc_vehicles(world, config, count=None): """ 生成NPC车辆 @@ -848,7 +841,6 @@ def spawn_npc_vehicles(world, config, count=None): continue # 随机选择车辆蓝图 - import random vehicle_bp = random.choice(vehicle_bps) # 尝试生成 @@ -874,7 +866,6 @@ def spawn_npc_vehicles(world, config, count=None): logger.error(f"生成NPC车辆失败: {e}") return 0 - def clear_all_actors(world, exclude_ids=None): """ 清理所有演员(车辆和传感器) @@ -927,9 +918,6 @@ def clear_all_actors(world, exclude_ids=None): except Exception as e: logger.warning(f"清理演员时出错: {e}") - -# ======================== 测试函数 ======================== - def test_sensor_manager(): """测试传感器管理器""" print("=" * 50) @@ -953,6 +941,5 @@ def test_sensor_manager(): return True - if __name__ == "__main__": test_sensor_manager() \ No newline at end of file diff --git a/src/tracking_car/utils.py b/src/tracking_car/utils.py index b227fab51f..0ddf17f2a4 100644 --- a/src/tracking_car/utils.py +++ b/src/tracking_car/utils.py @@ -12,20 +12,13 @@ from datetime import datetime # 配置loguru logger +# 配置日志 try: from loguru import logger - # 移除默认配置,避免冲突 - logger.remove() - # 添加控制台输出 - logger.add(sys.stdout, format="{time:HH:mm:ss} | {level: <8} | {message}", level="INFO") except ImportError: - # 创建简单的logger回退 - class SimpleLogger: - def debug(self, msg): print(f"DEBUG: {msg}") - def info(self, msg): print(f"INFO: {msg}") - def warning(self, msg): print(f"WARNING: {msg}") - def error(self, msg): print(f"ERROR: {msg}") - logger = SimpleLogger() + import logging + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + logger = logging.getLogger(__name__) # 尝试导入yaml,如果失败提供友好的错误信息 try: @@ -35,8 +28,6 @@ def error(self, msg): print(f"ERROR: {msg}") YAML_AVAILABLE = False logger.warning("PyYAML未安装,配置文件功能将受限") -# ======================== 图像处理工具 ======================== - def valid_img(img): """ 检查图像是否有效 @@ -49,7 +40,6 @@ def valid_img(img): """ return img is not None and len(img.shape) == 3 and img.shape[2] == 3 and img.size > 0 - def clip_box(bbox, img_shape): """ 裁剪边界框到图像范围内 @@ -69,7 +59,6 @@ def clip_box(bbox, img_shape): max(bbox[1] + 1, min(bbox[3], h - 1)) ], dtype=np.float32) - def make_div(x, d=32): """ 将数值调整为d的倍数(用于YOLO输入尺寸) @@ -83,7 +72,6 @@ def make_div(x, d=32): """ return (x + d - 1) // d * d - def resize_with_padding(image, target_size, color=(114, 114, 114)): """ 保持长宽比的resize,用指定颜色填充 @@ -120,9 +108,6 @@ def resize_with_padding(image, target_size, color=(114, 114, 114)): return padded, scale, (dx, dy) - -# ======================== 几何计算工具 ======================== - @njit def iou_numpy(box1, box2): """ @@ -147,7 +132,6 @@ def iou_numpy(box1, box2): return ia / ua if ua > 0 else 0.0 - def iou(box1, box2): """ 计算两个边界框的IoU(兼容list和numpy数组) @@ -164,7 +148,6 @@ def iou(box1, box2): box2_np = np.array(box2, dtype=np.float32) return iou_numpy(box1_np, box2_np) - @njit def iou_batch(boxes1, boxes2): """ @@ -187,7 +170,6 @@ def iou_batch(boxes1, boxes2): return iou_matrix - def bbox_center(bbox): """ 计算边界框中心点 @@ -200,7 +182,6 @@ def bbox_center(bbox): """ return ((bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2) - def bbox_area(bbox): """ 计算边界框面积 @@ -213,7 +194,6 @@ def bbox_area(bbox): """ return max(0, bbox[2] - bbox[0]) * max(0, bbox[3] - bbox[1]) - def bbox_aspect_ratio(bbox): """ 计算边界框宽高比 @@ -228,9 +208,6 @@ def bbox_aspect_ratio(bbox): height = max(0.1, bbox[3] - bbox[1]) return width / height - -# ======================== 性能监控工具 ======================== - class FPSCounter: """ FPS计数器 @@ -277,7 +254,6 @@ def reset(self): self.fps_history = [] self.avg_fps = 0.0 - class PerformanceMonitor: """ 性能监控器 @@ -338,9 +314,6 @@ def print_stats(self): logger.info(f"平均检测时间: {stats['avg_detection_time']:.1f}ms") logger.info(f"平均跟踪时间: {stats['avg_tracking_time']:.1f}ms") - -# ======================== 文件操作工具 ======================== - def create_output_dir(base_dir="outputs"): """ 创建输出目录 @@ -362,7 +335,6 @@ def create_output_dir(base_dir="outputs"): logger.info(f"创建输出目录: {output_dir}") return output_dir - def save_image(image, path, create_dir=True): """ 保存图像 @@ -391,7 +363,6 @@ def save_image(image, path, create_dir=True): logger.error(f"保存图像失败 {path}: {e}") return False - def load_yaml_config(path): """ 加载YAML配置文件 @@ -418,7 +389,6 @@ def load_yaml_config(path): logger.error(f"加载配置文件失败 {path}: {e}") return {} - def save_yaml_config(config, path): """ 保存配置到YAML文件 @@ -439,9 +409,6 @@ def save_yaml_config(config, path): except Exception as e: logger.error(f"保存配置失败 {path}: {e}") - -# ======================== 可视化工具 ======================== - def draw_bbox(image, bbox, color=(255, 0, 0), thickness=2, label=None): """ 在图像上绘制单个边界框 @@ -486,7 +453,6 @@ def draw_bbox(image, bbox, color=(255, 0, 0), thickness=2, label=None): return image - def draw_trajectory(image, points, color=(0, 255, 0), thickness=2, max_points=20): """ 在图像上绘制轨迹 @@ -519,7 +485,6 @@ def draw_trajectory(image, points, color=(0, 255, 0), thickness=2, max_points=20 return image - def draw_info_panel(image, info_dict, position="top_left"): """ 在图像上绘制信息面板 @@ -568,9 +533,6 @@ def draw_info_panel(image, info_dict, position="top_left"): return image - -# ======================== 测试函数 ======================== - def run_self_tests(): """运行自测试""" print("=" * 50) @@ -715,7 +677,6 @@ def run_self_tests(): return tests_failed == 0 - if __name__ == "__main__": # 运行自测试 success = run_self_tests()