From 47f6b86563479699b02a0a4b73cbdfa045c56964 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 22 Sep 2025 10:56:00 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E6=97=A0=E4=BA=BA=E8=BD=A6=E7=9A=84?= =?UTF-8?q?=E6=B7=B1=E5=BA=A6=E8=AF=AD=E4=B9=89=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_autonomous_driving/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/carla_autonomous_driving/README.md diff --git a/src/carla_autonomous_driving/README.md b/src/carla_autonomous_driving/README.md new file mode 100644 index 0000000000..e69de29bb2 From ce4d0cce30573d19645ed544f19a4e4d46d7ea34 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 24 Nov 2025 09:35:47 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=84=9F=E7=9F=A5?= =?UTF-8?q?=E6=A8=A1=E5=9D=97README=E5=B9=B6=E6=B7=BB=E5=8A=A0=E4=BC=A0?= =?UTF-8?q?=E6=84=9F=E5=99=A8=E7=8E=AF=E5=A2=83=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 100 ++++ .../basic_environment_with_sensors.py | 441 ++++++++++++++++++ 2 files changed, 541 insertions(+) create mode 100644 src/carla_autonomous_driving_perception/README.md create mode 100644 src/carla_autonomous_driving_perception/basic_environment_with_sensors.py diff --git a/src/carla_autonomous_driving_perception/README.md b/src/carla_autonomous_driving_perception/README.md new file mode 100644 index 0000000000..aa6feafbaa --- /dev/null +++ b/src/carla_autonomous_driving_perception/README.md @@ -0,0 +1,100 @@ +# 自动驾驶系统(基于 CARLA 与深度学习) + +## 项目概述 +本项目构建了基于 CARLA 仿真平台的自动驾驶系统,通过深度学习技术提升车辆感知能力,集成多模态传感器实现全面环境认知,提供模块化、可扩展的代码库支持自动驾驶算法研发。借助 CARLA 的高保真仿真能力,模拟真实世界驾驶场景与挑战,为自动驾驶技术的学习、研究与开发提供可靠环境。 + +## 环境准备 + +### 依赖库安装 +```bash +# 建议使用Python 3.7及以上版本(推荐虚拟环境) +pip install carla +pip install numpy opencv-python keras tensorflow pygame matplotlib +``` + +#### 依赖说明: +- carla:自动驾驶高保真仿真平台核心库 +- python 3.7+:项目开发与运行的 Python 版本 +- opencv-python:图像数据处理与可视化 +- keras:深度学习语义分割模型构建 +- tensorflow:深度学习模型训练与优化 +- pygame:手动控制车辆功能支持 +- numpy:数值计算基础支持 +- matplotlib:数据可视化工具 + +### 开发环境配置 +1. 下载并安装[CARLA 官方发行版](https://github.com/carla-simulator/carla/releases)(推荐最新稳定版本) +2. 安装[VSCode](https://code.visualstudio.com/)并配置 Python 3.7+ 解释器 +3. 推荐插件:Python、Pylance、Code Runner(提升开发效率) + +## 项目结构 + +| 文件名 | 功能描述 | +|--------------------|--------------------------------------------------------------| +| `main.py` | 核心程序入口,负责 CARLA 客户端连接、世界初始化与主循环控制 | +| `perception.py` | 感知模块,基于深度学习实现语义分割与环境要素识别 | +| `sensor_manager.py`| 传感器管理模块,处理 RGBA 摄像头、LiDAR 等多模态数据采集与同步 | +| `model_trainer.py` | 模型训练工具,提供语义分割 CNN 模型的训练、验证与优化流程 | +| `utils.py` | 通用工具函数库,包含数据转换、可视化与性能评估等辅助功能 | +| `config.yaml` | 配置文件,存储仿真参数(传感器类型、模型参数、仿真帧率等) | +| `README.md` | 项目说明文档 | + +## 核心功能 + +### 1. 高保真仿真环境 +- 基于 CARLA 构建多样化驾驶场景,支持天气(晴、雨、雾)、时间(昼、夜)等环境动态调整 +- 模拟多车辆与交通参与者,还原复杂交通流场景 +- 支持 CARLA 服务器自动连接、断开重连与仿真状态实时监控 + +### 2. 多模态感知系统 +- 集成 RGBA 摄像头(色彩纹理信息)、LiDAR(深度距离信息)等多类传感器 +- 基于深度学习实现实时语义分割,精准识别道路、车辆、行人、交通标志等核心要素 +- 优化传感器数据与车辆状态的时间戳同步,提升感知准确性 + +### 3. 深度学习语义分割 +- 针对自动驾驶场景优化的 CNN 网络架构,兼顾分割精度与实时性 +- 提供完整训练流程:数据加载、模型训练、损失计算与权重优化 +- 支持交并比(IoU)等核心指标评估,量化模型性能 + +### 4. 数据收集与可视化 +- 支持批量采集传感器数据(图像、点云)与对应标注,用于模型训练 +- 实时展示车辆动态、传感器原始数据与语义分割结果,便于直观分析系统性能 + +## 使用方法 + +### 启动 CARLA 服务器: +```bash +# 在CARLA安装目录下执行 +./CarlaUE4.sh # Linux/Mac +CarlaUE4.exe # Windows +``` + +### 运行自动驾驶系统: +```bash +python main.py --mode auto # 自动模式(启用感知与决策) +python main.py --mode manual # 手动模式(Pygame键盘控制) +``` + +### 数据采集与模型训练: +```bash +# 采集传感器数据(存储至./dataset目录) +python sensor_manager.py --record --output ./dataset + +# 训练语义分割模型 +python model_trainer.py --data ./dataset --epochs 50 +``` + +## 参数调整指南 + +| 参数 | 调整范围 | 效果说明 | +|--------------------|-------------------|----------------------------------| +| `camera_resolution` | 1280x720~1920x1080 | 提高分辨率增强细节(增加计算量) | +| `lidar_points_per_second` | 50000~200000 | 提高值提升点云密度(增加内存占用)| +| `model_batch_size` | 8~32 | 增大批次加速训练(需更多显存) | +| `simulation_fps` | 10~60 | 提高帧率增强实时性(对硬件要求更高)| + +## 参考资料 +- [CARLA 官方文档](https://carla.readthedocs.io/) +- [Keras 深度学习模型构建指南](https://keras.io/guides/) +- [TensorFlow 模型优化文档](https://www.tensorflow.org/guide/keras/optimizers) +- [语义分割算法综述](https://arxiv.org/abs/1704.06857) \ No newline at end of file diff --git a/src/carla_autonomous_driving_perception/basic_environment_with_sensors.py b/src/carla_autonomous_driving_perception/basic_environment_with_sensors.py new file mode 100644 index 0000000000..9e84fb2435 --- /dev/null +++ b/src/carla_autonomous_driving_perception/basic_environment_with_sensors.py @@ -0,0 +1,441 @@ +import carla +import argparse +import random +import time +import numpy as np +import pygame + + +class CustomTimer: + def __init__(self): + try: + self.timer = time.perf_counter + except AttributeError: + self.timer = time.time + + def time(self): + return self.timer() + + +class DisplayManager: + def __init__(self, grid_size, window_size): + pygame.init() + pygame.font.init() + self.display = pygame.display.set_mode( + window_size, pygame.HWSURFACE | pygame.DOUBLEBUF + ) + + self.grid_size = grid_size + self.window_size = window_size + self.sensor_list = [] + + def get_window_size(self): + return [int(self.window_size[0]), int(self.window_size[1])] + + def get_display_size(self): + return [ + int(self.window_size[0] / self.grid_size[1]), + int(self.window_size[1] / self.grid_size[0]), + ] + + def get_display_offset(self, gridPos): + dis_size = self.get_display_size() + return [int(gridPos[1] * dis_size[0]), int(gridPos[0] * dis_size[1])] + + def add_sensor(self, sensor): + self.sensor_list.append(sensor) + + def get_sensor_list(self): + return self.sensor_list + + def render(self): + if not self.render_enabled(): + return + + for s in self.sensor_list: + s.render() + + pygame.display.flip() + + def destroy(self): + for s in self.sensor_list: + s.destroy() + + def render_enabled(self): + return self.display != None + + +class SensorManager: + def __init__( + self, + world, + display_man, + sensor_type, + transform, + attached, + sensor_options, + display_pos, + ): + self.surface = None + self.world = world + self.display_man = display_man + self.display_pos = display_pos + self.sensor = self.init_sensor(sensor_type, transform, attached, sensor_options) + self.sensor_options = sensor_options + self.timer = CustomTimer() + + self.time_processing = 0.0 + self.tics_processing = 0 + + self.display_man.add_sensor(self) + + def init_sensor(self, sensor_type, transform, attached, sensor_options): + if sensor_type == "RGBCamera": + camera_bp = self.world.get_blueprint_library().find("sensor.camera.rgb") + disp_size = self.display_man.get_display_size() + scalar = 1 + disp_size = [256, 256] * scalar + camera_bp.set_attribute("image_size_x", str(disp_size[0])) + camera_bp.set_attribute("image_size_y", str(disp_size[1])) + for key in sensor_options: + camera_bp.set_attribute(key, sensor_options[key]) + + camera = self.world.spawn_actor(camera_bp, transform, attach_to=attached) + camera.listen(self.save_rgb_image) + + return camera + + elif sensor_type == "LiDAR": + lidar_bp = self.world.get_blueprint_library().find("sensor.lidar.ray_cast") + lidar_bp.set_attribute("range", "100") + lidar_bp.set_attribute( + "dropoff_general_rate", + lidar_bp.get_attribute("dropoff_general_rate").recommended_values[0], + ) + lidar_bp.set_attribute( + "dropoff_intensity_limit", + lidar_bp.get_attribute("dropoff_intensity_limit").recommended_values[0], + ) + lidar_bp.set_attribute( + "dropoff_zero_intensity", + lidar_bp.get_attribute("dropoff_zero_intensity").recommended_values[0], + ) + + for key in sensor_options: + lidar_bp.set_attribute(key, sensor_options[key]) + + lidar = self.world.spawn_actor(lidar_bp, transform, attach_to=attached) + + lidar.listen(self.save_lidar_image) + + return lidar + + elif sensor_type == "SemanticLiDAR": + lidar_bp = self.world.get_blueprint_library().find( + "sensor.lidar.ray_cast_semantic" + ) + lidar_bp.set_attribute("range", "100") + + for key in sensor_options: + lidar_bp.set_attribute(key, sensor_options[key]) + + lidar = self.world.spawn_actor(lidar_bp, transform, attach_to=attached) + + lidar.listen(self.save_semanticlidar_image) + + return lidar + + elif sensor_type == "Radar": + radar_bp = self.world.get_blueprint_library().find("sensor.other.radar") + for key in sensor_options: + radar_bp.set_attribute(key, sensor_options[key]) + + radar = self.world.spawn_actor(radar_bp, transform, attach_to=attached) + radar.listen(self.save_radar_image) + + return radar + + else: + return None + + def get_sensor(self): + return self.sensor + + def save_rgb_image(self, image): + t_start = self.timer.time() + + image.convert(carla.ColorConverter.Raw) + array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8")) + array = np.reshape(array, (image.height, image.width, 4)) + array = array[:, :, :3] + array = array[:, :, ::-1] + + if self.display_man.render_enabled(): + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)) + + t_end = self.timer.time() + self.time_processing += t_end - t_start + self.tics_processing += 1 + + def save_lidar_image(self, image): + t_start = self.timer.time() + + disp_size = self.display_man.get_display_size() + lidar_range = 2.0 * float(self.sensor_options["range"]) + + points = np.frombuffer(image.raw_data, dtype=np.dtype("f4")) + points = np.reshape(points, (int(points.shape[0] / 4), 4)) + lidar_data = np.array(points[:, :2]) + lidar_data *= min(disp_size) / lidar_range + lidar_data += (0.5 * disp_size[0], 0.5 * disp_size[1]) + lidar_data = np.fabs(lidar_data) # pylint: disable=E1111 + lidar_data = lidar_data.astype(np.int32) + lidar_data = np.reshape(lidar_data, (-1, 2)) + lidar_img_size = (disp_size[0], disp_size[1], 3) + lidar_img = np.zeros((lidar_img_size), dtype=np.uint8) + + lidar_img[tuple(lidar_data.T)] = (255, 255, 255) + + if self.display_man.render_enabled(): + self.surface = pygame.surfarray.make_surface(lidar_img) + + t_end = self.timer.time() + self.time_processing += t_end - t_start + self.tics_processing += 1 + + def save_semanticlidar_image(self, image): + t_start = self.timer.time() + + disp_size = self.display_man.get_display_size() + lidar_range = 2.0 * float(self.sensor_options["range"]) + + points = np.frombuffer(image.raw_data, dtype=np.dtype("f4")) + points = np.reshape(points, (int(points.shape[0] / 6), 6)) + lidar_data = np.array(points[:, :2]) + lidar_data *= min(disp_size) / lidar_range + lidar_data += (0.5 * disp_size[0], 0.5 * disp_size[1]) + lidar_data = np.fabs(lidar_data) # pylint: disable=E1111 + lidar_data = lidar_data.astype(np.int32) + lidar_data = np.reshape(lidar_data, (-1, 2)) + lidar_img_size = (disp_size[0], disp_size[1], 3) + lidar_img = np.zeros((lidar_img_size), dtype=np.uint8) + + lidar_img[tuple(lidar_data.T)] = (255, 255, 255) + + if self.display_man.render_enabled(): + self.surface = pygame.surfarray.make_surface(lidar_img) + + t_end = self.timer.time() + self.time_processing += t_end - t_start + self.tics_processing += 1 + + def save_radar_image(self, radar_data): + t_start = self.timer.time() + points = np.frombuffer(radar_data.raw_data, dtype=np.dtype("f4")) + points = np.reshape(points, (len(radar_data), 4)) + + t_end = self.timer.time() + self.time_processing += t_end - t_start + self.tics_processing += 1 + + def render(self): + if self.surface is not None: + offset = self.display_man.get_display_offset(self.display_pos) + self.display_man.display.blit(self.surface, offset) + + def destroy(self): + self.sensor.destroy() + + +def run_simulation(args, client): + display_manager = None + vehicle = None + vehicle_list = [] + timer = CustomTimer() + + try: + + # Getting the world and + world = client.get_world() + original_settings = world.get_settings() + + if args.sync: + traffic_manager = client.get_trafficmanager(8000) + settings = world.get_settings() + traffic_manager.set_synchronous_mode(True) + settings.synchronous_mode = True + settings.fixed_delta_seconds = 0.05 + world.apply_settings(settings) + + # Changing the weather to clear noon + weather = carla.WeatherParameters( + cloudiness=0.0, + precipitation=22.0, + wetness=1.5, + fog_density=0.0, + wind_intensity=0.0, + sun_altitude_angle=10.0, + sun_azimuth_angle=34.0, + ) + world.set_weather(weather) + + # Instantiating the vehicle to which we attached the sensors + # Using a Tesla Model 3 as our client AV to be controlled + vehicle_bp = world.get_blueprint_library().filter("*model3*")[0] + vehicle = world.spawn_actor( + vehicle_bp, random.choice(world.get_map().get_spawn_points()) + ) + vehicle_list.append(vehicle) + + vehicle.set_autopilot(False) + + # Display Manager organize all the sensors an its display in a window + display_manager = DisplayManager( + grid_size=[2, 3], window_size=[args.width, args.height] + ) + + SensorManager( + world, + display_manager, + "RGBCamera", + carla.Transform(carla.Location(x=0, z=2.4), carla.Rotation(yaw=-90)), + vehicle, + {}, + display_pos=[0, 0], + ) + SensorManager( + world, + display_manager, + "RGBCamera", + carla.Transform(carla.Location(x=0, z=2.4), carla.Rotation(yaw=+00)), + vehicle, + {}, + display_pos=[0, 1], + ) + SensorManager( + world, + display_manager, + "RGBCamera", + carla.Transform(carla.Location(x=0, z=2.4), carla.Rotation(yaw=+90)), + vehicle, + {}, + display_pos=[0, 2], + ) + SensorManager( + world, + display_manager, + "RGBCamera", + carla.Transform(carla.Location(x=0, z=2.4), carla.Rotation(yaw=180)), + vehicle, + {}, + display_pos=[1, 1], + ) + + SensorManager( + world, + display_manager, + "LiDAR", + carla.Transform(carla.Location(x=0, z=2.4)), + vehicle, + { + "channels": "64", + "range": "100", + "points_per_second": "250000", + "rotation_frequency": "20", + }, + display_pos=[1, 0], + ) + SensorManager( + world, + display_manager, + "SemanticLiDAR", + carla.Transform(carla.Location(x=0, z=2.4)), + vehicle, + { + "channels": "64", + "range": "100", + "points_per_second": "100000", + "rotation_frequency": "20", + }, + display_pos=[1, 2], + ) + + # Simulation loop + call_exit = False + time_init_sim = timer.time() + while True: + # Carla Tick + if args.sync: + world.tick() + else: + world.wait_for_tick() + + # Render received data + display_manager.render() + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + call_exit = True + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE or event.key == pygame.K_q: + call_exit = True + break + + if call_exit: + break + + finally: + if display_manager: + display_manager.destroy() + + client.apply_batch([carla.command.DestroyActor(x) for x in vehicle_list]) + + world.apply_settings(original_settings) + + +def main(): + argparser = argparse.ArgumentParser(description="Grid of sensors on the our Car") + argparser.add_argument( + "--host", + metavar="H", + default="127.0.0.1", + help="IP of the host server (default: 127.0.0.1)", + ) + argparser.add_argument( + "-p", + "--port", + metavar="P", + default=2000, + type=int, + help="TCP port to listen to (default: 2000)", + ) + argparser.add_argument( + "--sync", action="store_true", help="Synchronous mode execution" + ) + argparser.add_argument( + "--async", dest="sync", action="store_false", help="Asynchronous mode execution" + ) + argparser.set_defaults(sync=True) + argparser.add_argument( + "--res", + metavar="WIDTHxHEIGHT", + default="1280x720", + help="window resolution (default: 1280x720)", + ) + + args = argparser.parse_args() + + args.width, args.height = [int(x) for x in args.res.split("x")] + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(5.0) + + run_simulation(args, client) + + except KeyboardInterrupt: + print("\nKeyboard Interrupt or Cancelled by user") + + +if __name__ == "__main__": + main() From 2269e13eb8619ff05d8524ada0e9a303f078bbfc Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 1 Dec 2025 10:26:23 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E5=8A=A0=E8=BD=BDTown05=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=EF=BC=8C=E5=AE=9A=E4=BD=8DModel3=E5=B9=B6=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E8=87=B3=E5=90=8E=E4=B8=8A=E6=96=B9=E8=BF=BD=E5=B0=BE?= =?UTF-8?q?=E8=A7=86=E8=A7=92=EF=BC=8C=E8=8E=B7=E5=8F=96=E5=85=A8=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E5=90=88=E6=B3=95=E7=94=9F=E6=88=90=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carlaCNN.ipynb | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 src/carla_autonomous_driving_perception/carlaCNN.ipynb diff --git a/src/carla_autonomous_driving_perception/carlaCNN.ipynb b/src/carla_autonomous_driving_perception/carlaCNN.ipynb new file mode 100644 index 0000000000..9170e30855 --- /dev/null +++ b/src/carla_autonomous_driving_perception/carlaCNN.ipynb @@ -0,0 +1,340 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "824d0b8e", + "metadata": {}, + "source": [ + "## Advanced Autonomous Vehicle(AV) Self Driving System\n", + "#### Technolgies/Softwares/Non-Standard libraries used: \n", + " - CARLA (Open Source AV Simulator)\n", + " - Keras (To implement Deep Learning Models)\n", + " - Tensorflow (To train the model weights)\n", + " - Pygame (To enable the model to imitate human-like input to the simulator)\n", + " - OpenCV (To fetch and display/manipulate the data collected from virtual senors, videlicet, RGB Camera, LiDAR, Collision Detector)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "230ac814", + "metadata": { + "ExecuteTime": { + "end_time": "2023-10-22T18:16:39.365234400Z", + "start_time": "2023-10-22T18:16:38.309235100Z" + } + }, + "outputs": [], + "source": [ + "# Importing standard libraries\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "import pandas as pd\n", + "import random\n", + "import time\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "918b653a", + "metadata": { + "ExecuteTime": { + "end_time": "2023-10-22T18:16:45.025256100Z", + "start_time": "2023-10-22T18:16:40.364122800Z" + } + }, + "outputs": [], + "source": [ + "# Importing Machine Learning & Deep Learning Libraries\n", + "# Installed tensorflow directML instead in order to have AMD GPU support in Windows 10 for model training\n", + "import tensorflow as tf" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "34763218da257835", + "metadata": { + "ExecuteTime": { + "end_time": "2023-10-22T18:16:47.300784800Z", + "start_time": "2023-10-22T18:16:47.246787200Z" + }, + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'),\n", + " PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Avoid OOM errors by setting GPU Memory Consumption Growth and making sure that the dedicated gpus are recognizable to tensorflow\n", + "gpus = tf.config.experimental.list_physical_devices('GPU')\n", + "for gpu in gpus:\n", + " tf.config.experimental.set_memory_growth(gpu, True)\n", + "gpus" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f4c1ccdff9bbe9b7", + "metadata": { + "ExecuteTime": { + "end_time": "2023-10-22T18:16:55.780242500Z", + "start_time": "2023-10-22T18:16:50.525349600Z" + }, + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + ":219: RuntimeWarning: Your system is avx2 capable but pygame was not built with support for it. The performance of some of your blits could be adversely affected. Consider enabling compile time detection with environment variables like PYGAME_DETECT_AVX2=1 if you are compiling without cross compilation.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pygame 2.5.2 (SDL 2.28.4, Python 3.8.18)\n", + "Hello from the pygame community. https://www.pygame.org/contribute.html\n" + ] + } + ], + "source": [ + "import carla\n", + "import pygame\n", + "\n", + "client = carla.Client('localhost', 2000)\n", + "client.set_timeout(5.0)\n", + "world = client.load_world(\n", + " 'Town05'\n", + ")\n", + "\n", + "bp_lib = world.get_blueprint_library()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "33d70bcdcef2f77c", + "metadata": { + "ExecuteTime": { + "end_time": "2023-10-22T18:18:22.991767600Z", + "start_time": "2023-10-22T18:18:22.718766400Z" + }, + "collapsed": false + }, + "outputs": [], + "source": [ + "world.wait_for_tick()\n", + "actor_list = world.get_actors().filter(\n", + " '*model3*'\n", + ")\n", + "vehicle_list = []\n", + "for vehicle in actor_list:\n", + " vehicle_list.append(vehicle)\n", + "\n", + "vehicle = vehicle_list[0]\n", + "\n", + "def set_spectator(world):\n", + " spectator = world.get_spectator()\n", + " transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=-8, z=3)), vehicle.get_transform().rotation)\n", + " spectator.set_transform(transform)\n", + "\n", + "set_spectator(world)\n", + "spawn_points = world.get_map().get_spawn_points()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "198b908e88040cae", + "metadata": { + "ExecuteTime": { + "end_time": "2023-10-22T18:18:26.423763800Z", + "start_time": "2023-10-22T18:18:22.996767100Z" + }, + "collapsed": false + }, + "outputs": [], + "source": [ + "# NPC Traffic.\n", + "for i in range(200):\n", + " vehicle_bp = random.choice(bp_lib.filter('vehicle'))\n", + " npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points))\n", + "\n", + "#Set traffic in motion\n", + "for v in world.get_actors().filter('*vehicle*'):\n", + " v.set_autopilot(True)\n", + "\n", + "# Making sure that the non-deep-learning model is built into the simulator is turned off\n", + "vehicle.set_autopilot(False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b0ca26014cafa02f", + "metadata": { + "ExecuteTime": { + "start_time": "2023-10-22T08:31:03.247650800Z" + }, + "collapsed": false + }, + "outputs": [], + "source": [ + "# Real-Time RGBA sensor/camera footage\n", + "import queue\n", + "import cv2\n", + "from collections import deque\n", + "camera_bp = bp_lib.find('sensor.camera.rgb')\n", + "camera_init_trans = carla.Transform(carla.Location(x =-2,z=10))\n", + "\n", + "camera_bp.set_attribute('image_size_x', '1024')\n", + "camera_bp.set_attribute('image_size_y', '720')\n", + "\n", + "camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle)\n", + "\n", + "image_queue = queue.Queue()\n", + "camera.listen(image_queue.put)\n", + "\n", + "while True:\n", + " # Retrieve and reshape the image\n", + " world.tick()\n", + " image = image_queue.get()\n", + "\n", + " img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))\n", + " cv2.imshow('ImageWindowName',img)\n", + " plt.imshow(img)\n", + " if cv2.waitKey(1) == ord('q'):\n", + " break\n", + "cv2.destroyAllWindows()" + ] + }, + { + "cell_type": "markdown", + "id": "52fb9b67e83d2d2d", + "metadata": { + "collapsed": false + }, + "source": [ + "# Semantic Segmentation of lanes using a RGBA Camera\n", + "- Making using of a CNN Algorithm to semantically segment the camera footage post pre-processing" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "f5e9f45339af4a22", + "metadata": { + "ExecuteTime": { + "start_time": "2023-10-22T08:22:29.754890600Z" + }, + "collapsed": false + }, + "outputs": [], + "source": [ + "img_dir = os.path.join('archive', 'train_label', 'Town04_Clear_Noon_09_09_2020_14_57_22_frame_0_label.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "30612b265948431d", + "metadata": { + "ExecuteTime": { + "start_time": "2023-10-22T05:23:12.340619Z" + }, + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import cv2\n", + "img = cv2.imread(img_dir)\n", + "plt.imshow(100*cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" + ] + }, + { + "cell_type": "markdown", + "id": "853e6cb3613330ca", + "metadata": { + "collapsed": false + }, + "source": [] + }, + { + "cell_type": "markdown", + "id": "571de39195b88f9c", + "metadata": { + "collapsed": false + }, + "source": [ + "### Training of the data set continued in model_build.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16f831a75521d178", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a22888c7d2f69b188c1896f039b1261b57ea8b17 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 1 Dec 2025 11:03:30 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E5=8A=A0=E8=BD=BDTown05=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=EF=BC=8C=E5=AE=9A=E4=BD=8DModel3=E5=B9=B6=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E8=87=B3=E5=90=8E=E4=B8=8A=E6=96=B9=E8=BF=BD=E5=B0=BE?= =?UTF-8?q?=E8=A7=86=E8=A7=92=EF=BC=8C=E8=8E=B7=E5=8F=96=E5=85=A8=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E5=90=88=E6=B3=95=E7=94=9F=E6=88=90=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carlaCNN.py | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/carla_autonomous_driving_perception/carlaCNN.py diff --git a/src/carla_autonomous_driving_perception/carlaCNN.py b/src/carla_autonomous_driving_perception/carlaCNN.py new file mode 100644 index 0000000000..1d4c0acce7 --- /dev/null +++ b/src/carla_autonomous_driving_perception/carlaCNN.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python +# coding: utf-8 + +# ## Advanced Autonomous Vehicle(AV) Self Driving System +# #### Technolgies/Softwares/Non-Standard libraries used: +# - CARLA (Open Source AV Simulator) +# - Keras (To implement Deep Learning Models) +# - Tensorflow (To train the model weights) +# - Pygame (To enable the model to imitate human-like input to the simulator) +# - OpenCV (To fetch and display/manipulate the data collected from virtual senors, videlicet, RGB Camera, LiDAR, Collision Detector) + +# In[1]: + + +# Importing standard libraries +import numpy as np +from matplotlib import pyplot as plt +import pandas as pd +import random +import time +import os + + +# In[2]: + + +# Importing Machine Learning & Deep Learning Libraries +# Installed tensorflow directML instead in order to have AMD GPU support in Windows 10 for model training +import tensorflow as tf + + +# In[3]: + + +# Avoid OOM errors by setting GPU Memory Consumption Growth and making sure that the dedicated gpus are recognizable to tensorflow +gpus = tf.config.experimental.list_physical_devices('GPU') +for gpu in gpus: + tf.config.experimental.set_memory_growth(gpu, True) +gpus + + +# In[4]: + + +import carla +import pygame + +client = carla.Client('localhost', 2000) +client.set_timeout(5.0) +world = client.load_world( + 'Town05' +) + +bp_lib = world.get_blueprint_library() + + +# In[5]: + + +world.wait_for_tick() +actor_list = world.get_actors().filter( + '*model3*' +) +vehicle_list = [] +for vehicle in actor_list: + vehicle_list.append(vehicle) + +vehicle = vehicle_list[0] + +def set_spectator(world): + spectator = world.get_spectator() + transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=-8, z=3)), vehicle.get_transform().rotation) + spectator.set_transform(transform) + +set_spectator(world) +spawn_points = world.get_map().get_spawn_points() + + +# In[6]: + + +# NPC Traffic. +for i in range(200): + vehicle_bp = random.choice(bp_lib.filter('vehicle')) + npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points)) + +#Set traffic in motion +for v in world.get_actors().filter('*vehicle*'): + v.set_autopilot(True) + +# Making sure that the non-deep-learning model is built into the simulator is turned off +vehicle.set_autopilot(False) + + +# In[ ]: + + +# Real-Time RGBA sensor/camera footage +import queue +import cv2 +from collections import deque +camera_bp = bp_lib.find('sensor.camera.rgb') +camera_init_trans = carla.Transform(carla.Location(x =-2,z=10)) + +camera_bp.set_attribute('image_size_x', '1024') +camera_bp.set_attribute('image_size_y', '720') + +camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle) + +image_queue = queue.Queue() +camera.listen(image_queue.put) + +while True: + # Retrieve and reshape the image + world.tick() + image = image_queue.get() + + img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4)) + cv2.imshow('ImageWindowName',img) + plt.imshow(img) + if cv2.waitKey(1) == ord('q'): + break +cv2.destroyAllWindows() + + +# # Semantic Segmentation of lanes using a RGBA Camera +# - Making using of a CNN Algorithm to semantically segment the camera footage post pre-processing + +# In[19]: + + +img_dir = os.path.join('archive', 'train_label', 'Town04_Clear_Noon_09_09_2020_14_57_22_frame_0_label.png') + + +# In[7]: + + +import cv2 +img = cv2.imread(img_dir) +plt.imshow(100*cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) + + +# + +# ### Training of the data set continued in model_build.ipynb + +# In[ ]: + + + + From 706008ac55c5f938028c86bb20649375b23c332b Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 1 Dec 2025 11:22:29 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E4=BB=93=E5=BA=93=E4=B8=AD=E7=9A=84carlaCNN.ipynb=E6=96=87?= =?UTF-8?q?=E4=BB=B6=EF=BC=88=E6=9C=AC=E5=9C=B0=E5=B7=B2=E5=88=A0=E9=99=A4?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=AD=A5=E8=87=B3=E8=BF=9C=E7=A8=8B=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carlaCNN.ipynb | 340 ------------------ 1 file changed, 340 deletions(-) delete mode 100644 src/carla_autonomous_driving_perception/carlaCNN.ipynb diff --git a/src/carla_autonomous_driving_perception/carlaCNN.ipynb b/src/carla_autonomous_driving_perception/carlaCNN.ipynb deleted file mode 100644 index 9170e30855..0000000000 --- a/src/carla_autonomous_driving_perception/carlaCNN.ipynb +++ /dev/null @@ -1,340 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "824d0b8e", - "metadata": {}, - "source": [ - "## Advanced Autonomous Vehicle(AV) Self Driving System\n", - "#### Technolgies/Softwares/Non-Standard libraries used: \n", - " - CARLA (Open Source AV Simulator)\n", - " - Keras (To implement Deep Learning Models)\n", - " - Tensorflow (To train the model weights)\n", - " - Pygame (To enable the model to imitate human-like input to the simulator)\n", - " - OpenCV (To fetch and display/manipulate the data collected from virtual senors, videlicet, RGB Camera, LiDAR, Collision Detector)" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "230ac814", - "metadata": { - "ExecuteTime": { - "end_time": "2023-10-22T18:16:39.365234400Z", - "start_time": "2023-10-22T18:16:38.309235100Z" - } - }, - "outputs": [], - "source": [ - "# Importing standard libraries\n", - "import numpy as np\n", - "from matplotlib import pyplot as plt\n", - "import pandas as pd\n", - "import random\n", - "import time\n", - "import os" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "918b653a", - "metadata": { - "ExecuteTime": { - "end_time": "2023-10-22T18:16:45.025256100Z", - "start_time": "2023-10-22T18:16:40.364122800Z" - } - }, - "outputs": [], - "source": [ - "# Importing Machine Learning & Deep Learning Libraries\n", - "# Installed tensorflow directML instead in order to have AMD GPU support in Windows 10 for model training\n", - "import tensorflow as tf" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "34763218da257835", - "metadata": { - "ExecuteTime": { - "end_time": "2023-10-22T18:16:47.300784800Z", - "start_time": "2023-10-22T18:16:47.246787200Z" - }, - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'),\n", - " PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Avoid OOM errors by setting GPU Memory Consumption Growth and making sure that the dedicated gpus are recognizable to tensorflow\n", - "gpus = tf.config.experimental.list_physical_devices('GPU')\n", - "for gpu in gpus:\n", - " tf.config.experimental.set_memory_growth(gpu, True)\n", - "gpus" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "f4c1ccdff9bbe9b7", - "metadata": { - "ExecuteTime": { - "end_time": "2023-10-22T18:16:55.780242500Z", - "start_time": "2023-10-22T18:16:50.525349600Z" - }, - "collapsed": false - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - ":219: RuntimeWarning: Your system is avx2 capable but pygame was not built with support for it. The performance of some of your blits could be adversely affected. Consider enabling compile time detection with environment variables like PYGAME_DETECT_AVX2=1 if you are compiling without cross compilation.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "pygame 2.5.2 (SDL 2.28.4, Python 3.8.18)\n", - "Hello from the pygame community. https://www.pygame.org/contribute.html\n" - ] - } - ], - "source": [ - "import carla\n", - "import pygame\n", - "\n", - "client = carla.Client('localhost', 2000)\n", - "client.set_timeout(5.0)\n", - "world = client.load_world(\n", - " 'Town05'\n", - ")\n", - "\n", - "bp_lib = world.get_blueprint_library()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "33d70bcdcef2f77c", - "metadata": { - "ExecuteTime": { - "end_time": "2023-10-22T18:18:22.991767600Z", - "start_time": "2023-10-22T18:18:22.718766400Z" - }, - "collapsed": false - }, - "outputs": [], - "source": [ - "world.wait_for_tick()\n", - "actor_list = world.get_actors().filter(\n", - " '*model3*'\n", - ")\n", - "vehicle_list = []\n", - "for vehicle in actor_list:\n", - " vehicle_list.append(vehicle)\n", - "\n", - "vehicle = vehicle_list[0]\n", - "\n", - "def set_spectator(world):\n", - " spectator = world.get_spectator()\n", - " transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=-8, z=3)), vehicle.get_transform().rotation)\n", - " spectator.set_transform(transform)\n", - "\n", - "set_spectator(world)\n", - "spawn_points = world.get_map().get_spawn_points()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "198b908e88040cae", - "metadata": { - "ExecuteTime": { - "end_time": "2023-10-22T18:18:26.423763800Z", - "start_time": "2023-10-22T18:18:22.996767100Z" - }, - "collapsed": false - }, - "outputs": [], - "source": [ - "# NPC Traffic.\n", - "for i in range(200):\n", - " vehicle_bp = random.choice(bp_lib.filter('vehicle'))\n", - " npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points))\n", - "\n", - "#Set traffic in motion\n", - "for v in world.get_actors().filter('*vehicle*'):\n", - " v.set_autopilot(True)\n", - "\n", - "# Making sure that the non-deep-learning model is built into the simulator is turned off\n", - "vehicle.set_autopilot(False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b0ca26014cafa02f", - "metadata": { - "ExecuteTime": { - "start_time": "2023-10-22T08:31:03.247650800Z" - }, - "collapsed": false - }, - "outputs": [], - "source": [ - "# Real-Time RGBA sensor/camera footage\n", - "import queue\n", - "import cv2\n", - "from collections import deque\n", - "camera_bp = bp_lib.find('sensor.camera.rgb')\n", - "camera_init_trans = carla.Transform(carla.Location(x =-2,z=10))\n", - "\n", - "camera_bp.set_attribute('image_size_x', '1024')\n", - "camera_bp.set_attribute('image_size_y', '720')\n", - "\n", - "camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle)\n", - "\n", - "image_queue = queue.Queue()\n", - "camera.listen(image_queue.put)\n", - "\n", - "while True:\n", - " # Retrieve and reshape the image\n", - " world.tick()\n", - " image = image_queue.get()\n", - "\n", - " img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))\n", - " cv2.imshow('ImageWindowName',img)\n", - " plt.imshow(img)\n", - " if cv2.waitKey(1) == ord('q'):\n", - " break\n", - "cv2.destroyAllWindows()" - ] - }, - { - "cell_type": "markdown", - "id": "52fb9b67e83d2d2d", - "metadata": { - "collapsed": false - }, - "source": [ - "# Semantic Segmentation of lanes using a RGBA Camera\n", - "- Making using of a CNN Algorithm to semantically segment the camera footage post pre-processing" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "f5e9f45339af4a22", - "metadata": { - "ExecuteTime": { - "start_time": "2023-10-22T08:22:29.754890600Z" - }, - "collapsed": false - }, - "outputs": [], - "source": [ - "img_dir = os.path.join('archive', 'train_label', 'Town04_Clear_Noon_09_09_2020_14_57_22_frame_0_label.png')" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "30612b265948431d", - "metadata": { - "ExecuteTime": { - "start_time": "2023-10-22T05:23:12.340619Z" - }, - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import cv2\n", - "img = cv2.imread(img_dir)\n", - "plt.imshow(100*cv2.cvtColor(img, cv2.COLOR_BGR2RGB))" - ] - }, - { - "cell_type": "markdown", - "id": "853e6cb3613330ca", - "metadata": { - "collapsed": false - }, - "source": [] - }, - { - "cell_type": "markdown", - "id": "571de39195b88f9c", - "metadata": { - "collapsed": false - }, - "source": [ - "### Training of the data set continued in model_build.ipynb" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16f831a75521d178", - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 7b4e7fe3b563111f81d42afc1225ea696b627114 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Tue, 2 Dec 2025 19:28:16 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E4=BB=93=E5=BA=93=E4=B8=AD=E7=9A=84carlaCNN.py=E6=96=87?= =?UTF-8?q?=E4=BB=B6=EF=BC=88=E6=9C=AC=E5=9C=B0=E5=B7=B2=E5=88=A0=E9=99=A4?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=AD=A5=E8=87=B3=E8=BF=9C=E7=A8=8B=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carlaCNN.py | 151 ------------------ 1 file changed, 151 deletions(-) delete mode 100644 src/carla_autonomous_driving_perception/carlaCNN.py diff --git a/src/carla_autonomous_driving_perception/carlaCNN.py b/src/carla_autonomous_driving_perception/carlaCNN.py deleted file mode 100644 index 1d4c0acce7..0000000000 --- a/src/carla_autonomous_driving_perception/carlaCNN.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 - -# ## Advanced Autonomous Vehicle(AV) Self Driving System -# #### Technolgies/Softwares/Non-Standard libraries used: -# - CARLA (Open Source AV Simulator) -# - Keras (To implement Deep Learning Models) -# - Tensorflow (To train the model weights) -# - Pygame (To enable the model to imitate human-like input to the simulator) -# - OpenCV (To fetch and display/manipulate the data collected from virtual senors, videlicet, RGB Camera, LiDAR, Collision Detector) - -# In[1]: - - -# Importing standard libraries -import numpy as np -from matplotlib import pyplot as plt -import pandas as pd -import random -import time -import os - - -# In[2]: - - -# Importing Machine Learning & Deep Learning Libraries -# Installed tensorflow directML instead in order to have AMD GPU support in Windows 10 for model training -import tensorflow as tf - - -# In[3]: - - -# Avoid OOM errors by setting GPU Memory Consumption Growth and making sure that the dedicated gpus are recognizable to tensorflow -gpus = tf.config.experimental.list_physical_devices('GPU') -for gpu in gpus: - tf.config.experimental.set_memory_growth(gpu, True) -gpus - - -# In[4]: - - -import carla -import pygame - -client = carla.Client('localhost', 2000) -client.set_timeout(5.0) -world = client.load_world( - 'Town05' -) - -bp_lib = world.get_blueprint_library() - - -# In[5]: - - -world.wait_for_tick() -actor_list = world.get_actors().filter( - '*model3*' -) -vehicle_list = [] -for vehicle in actor_list: - vehicle_list.append(vehicle) - -vehicle = vehicle_list[0] - -def set_spectator(world): - spectator = world.get_spectator() - transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=-8, z=3)), vehicle.get_transform().rotation) - spectator.set_transform(transform) - -set_spectator(world) -spawn_points = world.get_map().get_spawn_points() - - -# In[6]: - - -# NPC Traffic. -for i in range(200): - vehicle_bp = random.choice(bp_lib.filter('vehicle')) - npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points)) - -#Set traffic in motion -for v in world.get_actors().filter('*vehicle*'): - v.set_autopilot(True) - -# Making sure that the non-deep-learning model is built into the simulator is turned off -vehicle.set_autopilot(False) - - -# In[ ]: - - -# Real-Time RGBA sensor/camera footage -import queue -import cv2 -from collections import deque -camera_bp = bp_lib.find('sensor.camera.rgb') -camera_init_trans = carla.Transform(carla.Location(x =-2,z=10)) - -camera_bp.set_attribute('image_size_x', '1024') -camera_bp.set_attribute('image_size_y', '720') - -camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle) - -image_queue = queue.Queue() -camera.listen(image_queue.put) - -while True: - # Retrieve and reshape the image - world.tick() - image = image_queue.get() - - img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4)) - cv2.imshow('ImageWindowName',img) - plt.imshow(img) - if cv2.waitKey(1) == ord('q'): - break -cv2.destroyAllWindows() - - -# # Semantic Segmentation of lanes using a RGBA Camera -# - Making using of a CNN Algorithm to semantically segment the camera footage post pre-processing - -# In[19]: - - -img_dir = os.path.join('archive', 'train_label', 'Town04_Clear_Noon_09_09_2020_14_57_22_frame_0_label.png') - - -# In[7]: - - -import cv2 -img = cv2.imread(img_dir) -plt.imshow(100*cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) - - -# - -# ### Training of the data set continued in model_build.ipynb - -# In[ ]: - - - - From 712565b20fe91210589da18c5d74df98f16ca35b Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 8 Dec 2025 10:33:33 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecarla=5Fmodel3=5Fspawn?= =?UTF-8?q?=5Fwith=5Fspectator.py=EF=BC=9A=E5=8A=A0=E8=BD=BDTown05?= =?UTF-8?q?=E7=94=9F=E6=88=90Model3=E5=B9=B6=E8=AE=BE=E7=BD=AE=E8=BF=BD?= =?UTF-8?q?=E5=B0=BE=E8=A7=86=E8=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carla_model3_spawn_with_spectator.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py diff --git a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py new file mode 100644 index 0000000000..3715ef837f --- /dev/null +++ b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py @@ -0,0 +1,31 @@ +import carla +import pygame +import time +import random # 新增:用于随机选生成点 + +client = carla.Client('localhost', 2000) +client.set_timeout(5.0) +world = client.load_world('Town05') +bp_lib = world.get_blueprint_library() + +# 新增:主动生成 Tesla Model3 车辆(解决空列表问题) +model3_bp = bp_lib.find('vehicle.tesla.model3') # 筛选 Model3 蓝图 +spawn_points = world.get_map().get_spawn_points() # 先获取生成点 +vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) # 生成 Model3 + +world.wait_for_tick() +# 后续筛选逻辑可保留(兼容多辆车场景) +actor_list = world.get_actors().filter('*model3*') +vehicle_list = [] +for vehicle in actor_list: + vehicle_list.append(vehicle) +vehicle = vehicle_list[0] + +def set_spectator(world): + spectator = world.get_spectator() + transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=-8, z=3)), vehicle.get_transform().rotation) + spectator.set_transform(transform) + +set_spectator(world) +# 最终获取生成点(供后续使用) +spawn_points = world.get_map().get_spawn_points() \ No newline at end of file From a4d76642953386a9f896bf9c463c18ec358282e1 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Mon, 8 Dec 2025 11:32:03 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E4=B8=BAcarla=5Fmodel3=5Fspawn=5Fwith=5F?= =?UTF-8?q?spectator.py=E6=96=B0=E5=A2=9ENPC=E4=BA=A4=E9=80=9A=E6=B5=81?= =?UTF-8?q?=EF=BC=9A=E7=94=9F=E6=88=90200=E8=BE=86NPC=E5=B9=B6=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E8=87=AA=E5=8A=A8=E9=A9=BE=E9=A9=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carla_model3_spawn_with_spectator.py | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py index 3715ef837f..5d761d3b37 100644 --- a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py +++ b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py @@ -1,31 +1,73 @@ import carla import pygame import time -import random # 新增:用于随机选生成点 +import random # 用于随机选生成点/随机选NPC车辆蓝图 +# 1. 连接CARLA服务器并加载地图 client = carla.Client('localhost', 2000) client.set_timeout(5.0) world = client.load_world('Town05') bp_lib = world.get_blueprint_library() -# 新增:主动生成 Tesla Model3 车辆(解决空列表问题) -model3_bp = bp_lib.find('vehicle.tesla.model3') # 筛选 Model3 蓝图 -spawn_points = world.get_map().get_spawn_points() # 先获取生成点 -vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) # 生成 Model3 - +# 2. 生成主角车辆(Tesla Model3) +model3_bp = bp_lib.find('vehicle.tesla.model3') # 筛选Model3蓝图 +spawn_points = world.get_map().get_spawn_points() # 获取地图合法生成点 +vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) # 生成Model3 world.wait_for_tick() -# 后续筛选逻辑可保留(兼容多辆车场景) + +# 3. 生成200辆NPC车辆(交通流) +print("开始生成NPC交通车辆...") +for i in range(200): + # 随机选择车辆蓝图(过滤所有vehicle类型) + vehicle_bp = random.choice(bp_lib.filter('vehicle')) + # 尝试生成NPC车辆(try_spawn_actor避免生成点冲突导致报错) + npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points)) + # 避免循环过快导致CARLA处理不及时 + time.sleep(0.01) +print(f"NPC车辆生成完成,当前地图车辆总数:{len(world.get_actors().filter('*vehicle*'))}") + +# 4. 启动所有NPC车辆的自动驾驶(交通流动) +print("启动所有NPC车辆自动驾驶...") +for v in world.get_actors().filter('*vehicle*'): + v.set_autopilot(True) + +# 5. 关闭主角Model3车辆的自动驾驶(确保手动控制/后续自定义逻辑) +vehicle.set_autopilot(False) +print("已关闭主角Model3车辆的自动驾驶") + +# 6. 筛选所有Model3车辆(兼容多辆车场景) actor_list = world.get_actors().filter('*model3*') vehicle_list = [] for vehicle in actor_list: vehicle_list.append(vehicle) vehicle = vehicle_list[0] +# 7. 设置观众视角(后上方追尾视角) def set_spectator(world): spectator = world.get_spectator() - transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=-8, z=3)), vehicle.get_transform().rotation) + # 视角位置:主角车后方8米、上方3米,跟随车辆朝向 + transform = carla.Transform( + vehicle.get_transform().transform(carla.Location(x=-8, z=3)), + vehicle.get_transform().rotation + ) spectator.set_transform(transform) set_spectator(world) -# 最终获取生成点(供后续使用) -spawn_points = world.get_map().get_spawn_points() \ No newline at end of file +print("视角已切换至主角Model3车辆后上方追尾视角") + +# 8. 最终获取生成点(供后续扩展使用) +spawn_points = world.get_map().get_spawn_points() +print(f"地图Town05合法生成点总数:{len(spawn_points)}") + +# 保持运行,便于查看效果 +print("\n程序运行中,按Ctrl+C退出...") +try: + while True: + time.sleep(1) +except KeyboardInterrupt: + print("\n程序退出,清理资源...") + # 可选:销毁生成的车辆(避免CARLA残留 Actors) + for v in world.get_actors().filter('*vehicle*'): + if v.is_alive: + v.destroy() + print("资源清理完成") \ No newline at end of file From d9513147ddea6ce27522e3dc584ac2b87c4298d0 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Wed, 10 Dec 2025 21:02:34 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E4=B8=BB=E8=A7=92=E8=BD=A6=E6=B2=BF?= =?UTF-8?q?=E8=BD=A6=E9=81=93=E7=A8=B3=E5=AE=9A=E8=87=AA=E5=8A=A8=E9=A9=BE?= =?UTF-8?q?=E9=A9=B6+=E8=A7=86=E8=A7=92=E5=B9=B3=E6=BB=91=E8=B7=9F?= =?UTF-8?q?=E9=9A=8F=EF=BC=8CNPC=E4=BA=A4=E9=80=9A=E6=B5=81=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=A9=BE=E9=A9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carla_model3_spawn_with_spectator.py | 127 ++++++++++++------ 1 file changed, 83 insertions(+), 44 deletions(-) diff --git a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py index 5d761d3b37..07d927f715 100644 --- a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py +++ b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py @@ -1,73 +1,112 @@ import carla import pygame import time -import random # 用于随机选生成点/随机选NPC车辆蓝图 +import random -# 1. 连接CARLA服务器并加载地图 +# 自定义线性插值函数(兼容Python 3.7+,解决视角抖动核心) +def lerp(a, b, t): + """线性插值:从a到b平滑过渡,t∈[0,1](0=取a,1=取b,越小越平滑)""" + return a + t * (b - a) + +# 1. 连接CARLA服务器并启用同步模式(稳定数据获取,减少抖动) client = carla.Client('localhost', 2000) -client.set_timeout(5.0) +client.set_timeout(10.0) # 延长超时时间,适配多NPC生成 world = client.load_world('Town05') +# 启用同步模式,保证帧率稳定、数据无滞后 +settings = world.get_settings() +settings.synchronous_mode = True +settings.fixed_delta_seconds = 1/30 # 固定30帧/秒 +world.apply_settings(settings) + bp_lib = world.get_blueprint_library() # 2. 生成主角车辆(Tesla Model3) -model3_bp = bp_lib.find('vehicle.tesla.model3') # 筛选Model3蓝图 -spawn_points = world.get_map().get_spawn_points() # 获取地图合法生成点 -vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) # 生成Model3 -world.wait_for_tick() +model3_bp = bp_lib.find('vehicle.tesla.model3') +spawn_points = world.get_map().get_spawn_points() +vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) +world.tick() # 同步帧,获取最新车辆数据 -# 3. 生成200辆NPC车辆(交通流) -print("开始生成NPC交通车辆...") -for i in range(200): - # 随机选择车辆蓝图(过滤所有vehicle类型) +# 3. 生成500辆NPC车辆(分批生成,避免CARLA卡顿/崩溃) +npc_count = 500 # 新增:NPC数量从200增至500 +print(f"开始生成{npc_count}辆NPC交通车辆...") +for i in range(npc_count): vehicle_bp = random.choice(bp_lib.filter('vehicle')) - # 尝试生成NPC车辆(try_spawn_actor避免生成点冲突导致报错) npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points)) - # 避免循环过快导致CARLA处理不及时 - time.sleep(0.01) -print(f"NPC车辆生成完成,当前地图车辆总数:{len(world.get_actors().filter('*vehicle*'))}") + # 每生成100辆同步一次,减轻CARLA压力 + if i % 100 == 0: + world.tick() + time.sleep(0.05) + else: + time.sleep(0.01) +# 统计实际生成的车辆数(生成点冲突可能略少) +actual_npc_count = len(world.get_actors().filter('*vehicle*')) - 1 # 减主角车 +print(f"NPC车辆生成完成,实际生成:{actual_npc_count}辆(含主角车共{len(world.get_actors().filter('*vehicle*'))}辆)") -# 4. 启动所有NPC车辆的自动驾驶(交通流动) -print("启动所有NPC车辆自动驾驶...") +# 4. 启动所有NPC+主角车自动驾驶 +print("启动所有NPC车辆+主角Model3自动驾驶...") for v in world.get_actors().filter('*vehicle*'): v.set_autopilot(True) +print("主角Model3车辆已启用自动驾驶,将与NPC同步行驶") -# 5. 关闭主角Model3车辆的自动驾驶(确保手动控制/后续自定义逻辑) -vehicle.set_autopilot(False) -print("已关闭主角Model3车辆的自动驾驶") - -# 6. 筛选所有Model3车辆(兼容多辆车场景) +# 5. 筛选主角Model3车辆 actor_list = world.get_actors().filter('*model3*') -vehicle_list = [] -for vehicle in actor_list: - vehicle_list.append(vehicle) -vehicle = vehicle_list[0] +vehicle = actor_list[0] if actor_list else None +if not vehicle: + raise Exception("主角Model3车辆生成失败!") -# 7. 设置观众视角(后上方追尾视角) -def set_spectator(world): +# 6. 平滑视角函数(核心解决抖动:插值过渡+实时跟随) +def set_spectator_smooth(world, vehicle, last_transform=None): + """ + 平滑更新主角车后上方视角,避免抖动 + :param last_transform: 上一帧视角,用于插值过渡 + :return: 当前帧视角(供下一帧插值) + """ spectator = world.get_spectator() - # 视角位置:主角车后方8米、上方3米,跟随车辆朝向 - transform = carla.Transform( - vehicle.get_transform().transform(carla.Location(x=-8, z=3)), - vehicle.get_transform().rotation + # 目标视角:主角车后方8米、上方3米,轻微偏移避免遮挡 + vehicle_tf = vehicle.get_transform() + target_tf = carla.Transform( + vehicle_tf.transform(carla.Location(x=-8, z=3, y=0.5)), + vehicle_tf.rotation ) - spectator.set_transform(transform) - -set_spectator(world) -print("视角已切换至主角Model3车辆后上方追尾视角") + # 首次调用直接设置视角 + if last_transform is None: + spectator.set_transform(target_tf) + return target_tf + # 插值平滑过渡(t=0.1,越小视角越稳,0.05~0.2为宜) + smooth_loc = carla.Location( + x=lerp(last_transform.location.x, target_tf.location.x, 0.1), + y=lerp(last_transform.location.y, target_tf.location.y, 0.1), + z=lerp(last_transform.location.z, target_tf.location.z, 0.1) + ) + smooth_rot = carla.Rotation( + pitch=lerp(last_transform.rotation.pitch, target_tf.rotation.pitch, 0.1), + yaw=lerp(last_transform.rotation.yaw, target_tf.rotation.yaw, 0.1), + roll=lerp(last_transform.rotation.roll, target_tf.rotation.roll, 0.1) + ) + smooth_tf = carla.Transform(smooth_loc, smooth_rot) + spectator.set_transform(smooth_tf) + return smooth_tf -# 8. 最终获取生成点(供后续扩展使用) -spawn_points = world.get_map().get_spawn_points() -print(f"地图Town05合法生成点总数:{len(spawn_points)}") +# 初始化视角 +last_spectator_tf = set_spectator_smooth(world, vehicle) +print("视角已切换至主角Model3车辆后上方(平滑跟随,无抖动)") -# 保持运行,便于查看效果 -print("\n程序运行中,按Ctrl+C退出...") +# 7. 主循环:稳定帧率+平滑视角 +print("\n程序运行中,主角车与500辆NPC同步行驶,按Ctrl+C退出...") +clock = pygame.time.Clock() # 精准控制帧率 try: while True: - time.sleep(1) + world.tick() # 同步CARLA帧,数据无滞后 + # 平滑更新视角 + last_spectator_tf = set_spectator_smooth(world, vehicle, last_spectator_tf) + clock.tick(30) # 严格30帧/秒,避免帧率波动导致抖动 except KeyboardInterrupt: print("\n程序退出,清理资源...") - # 可选:销毁生成的车辆(避免CARLA残留 Actors) + # 恢复CARLA默认设置(避免影响后续使用) + settings.synchronous_mode = False + world.apply_settings(settings) + # 销毁所有生成的车辆 for v in world.get_actors().filter('*vehicle*'): if v.is_alive: v.destroy() - print("资源清理完成") \ No newline at end of file + print("资源清理完成,CARLA设置已恢复!") \ No newline at end of file From fc332a2bd4a2c93945b30d262628e1f4a9ae7ea0 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Fri, 12 Dec 2025 14:34:08 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E6=A0=B8=E5=BF=83=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=9F=BA=E4=BA=8ECARLA=E5=BC=BA=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E8=A7=A3=E5=86=B3=E9=95=9C=E5=A4=B4=E6=8A=96?= =?UTF-8?q?=E5=8A=A8=EF=BC=8C=E7=BB=91=E5=AE=9A=E8=A7=86=E8=A7=92=E4=B8=8E?= =?UTF-8?q?=E8=BD=A6=E8=BE=86=E7=8A=B6=E6=80=81=E5=88=B0=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E5=B8=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carla_model3_spawn_with_spectator.py | 166 +++++++++++------- 1 file changed, 103 insertions(+), 63 deletions(-) diff --git a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py index 07d927f715..5b20fcb0c3 100644 --- a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py +++ b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py @@ -2,111 +2,151 @@ import pygame import time import random +from threading import Lock -# 自定义线性插值函数(兼容Python 3.7+,解决视角抖动核心) +# 自定义线性插值函数(适配同步帧) def lerp(a, b, t): - """线性插值:从a到b平滑过渡,t∈[0,1](0=取a,1=取b,越小越平滑)""" + """线性插值:t值根据同步帧率调整(30帧下0.15更稳定)""" return a + t * (b - a) -# 1. 连接CARLA服务器并启用同步模式(稳定数据获取,减少抖动) +# 1. 连接CARLA服务器并配置强同步模式 client = carla.Client('localhost', 2000) -client.set_timeout(10.0) # 延长超时时间,适配多NPC生成 +client.set_timeout(15.0) world = client.load_world('Town05') -# 启用同步模式,保证帧率稳定、数据无滞后 + +# 启用严格同步模式(关键:固定帧间隔,禁用异步更新) settings = world.get_settings() -settings.synchronous_mode = True -settings.fixed_delta_seconds = 1/30 # 固定30帧/秒 +settings.synchronous_mode = True # 客户端控制帧推进 +settings.fixed_delta_seconds = 1/30 # 30帧/秒(与后续tick频率一致) +settings.no_rendering_mode = False # 启用渲染 world.apply_settings(settings) +# 2. 初始化同步锁与帧数据缓存(确保线程安全) +frame_lock = Lock() +latest_snapshot = None # 存储当前帧的Actor快照(含车辆状态) + +# 绑定帧同步回调:每帧更新车辆状态快照 +def on_world_tick(snapshot): + global latest_snapshot + with frame_lock: + latest_snapshot = snapshot # 缓存当前帧的所有Actor状态 +world.on_tick(on_world_tick) + bp_lib = world.get_blueprint_library() +spawn_points = world.get_map().get_spawn_points() -# 2. 生成主角车辆(Tesla Model3) +# 3. 生成主角车辆(Tesla Model3) model3_bp = bp_lib.find('vehicle.tesla.model3') -spawn_points = world.get_map().get_spawn_points() -vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) -world.tick() # 同步帧,获取最新车辆数据 +# 确保生成点有效(避免初始位置异常导致抖动) +vehicle = None +for _ in range(5): + try: + vehicle = world.spawn_actor(model3_bp, random.choice(spawn_points)) + print(f"主角车辆生成成功(ID: {vehicle.id})") + break + except: + time.sleep(0.5) +if not vehicle: + raise Exception("主角车辆生成失败,请重启CARLA服务器") -# 3. 生成500辆NPC车辆(分批生成,避免CARLA卡顿/崩溃) -npc_count = 500 # 新增:NPC数量从200增至500 -print(f"开始生成{npc_count}辆NPC交通车辆...") +# 4. 生成NPC车辆(减少至100辆,确保同步性能) +npc_count = 100 # 500辆会导致同步延迟,100辆是性能与效果的平衡 +print(f"开始生成{npc_count}辆NPC车辆...") for i in range(npc_count): vehicle_bp = random.choice(bp_lib.filter('vehicle')) - npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points)) - # 每生成100辆同步一次,减轻CARLA压力 - if i % 100 == 0: + if 'tesla' in vehicle_bp.id: # 避免与主角车混淆 + continue + # 尝试生成(避开主角车位置) + spawn_point = random.choice(spawn_points) + if spawn_point.location.distance(vehicle.get_location()) < 20: + continue + world.try_spawn_actor(vehicle_bp, spawn_point) + # 每生成20辆同步一次,确保服务器不卡顿 + if i % 20 == 0: world.tick() - time.sleep(0.05) - else: - time.sleep(0.01) -# 统计实际生成的车辆数(生成点冲突可能略少) -actual_npc_count = len(world.get_actors().filter('*vehicle*')) - 1 # 减主角车 -print(f"NPC车辆生成完成,实际生成:{actual_npc_count}辆(含主角车共{len(world.get_actors().filter('*vehicle*'))}辆)") + time.sleep(0.1) -# 4. 启动所有NPC+主角车自动驾驶 -print("启动所有NPC车辆+主角Model3自动驾驶...") -for v in world.get_actors().filter('*vehicle*'): - v.set_autopilot(True) -print("主角Model3车辆已启用自动驾驶,将与NPC同步行驶") +# 统计实际生成数量 +all_vehicles = world.get_actors().filter('*vehicle*') +actual_npc_count = len(all_vehicles) - 1 +print(f"NPC生成完成 | 实际数量: {actual_npc_count}辆(总车辆: {len(all_vehicles)})") -# 5. 筛选主角Model3车辆 -actor_list = world.get_actors().filter('*model3*') -vehicle = actor_list[0] if actor_list else None -if not vehicle: - raise Exception("主角Model3车辆生成失败!") +# 5. 启动所有车辆自动驾驶(绑定交通管理器同步端口) +tm = client.get_trafficmanager(8000) +tm.set_synchronous_mode(True) # 交通管理器也启用同步模式 +for v in all_vehicles: + v.set_autopilot(True, tm.get_port()) # 所有车辆通过TM控制,确保行为同步 -# 6. 平滑视角函数(核心解决抖动:插值过渡+实时跟随) -def set_spectator_smooth(world, vehicle, last_transform=None): +# 6. 平滑视角函数(基于当前帧快照数据) +def set_spectator_smooth(last_transform=None): """ - 平滑更新主角车后上方视角,避免抖动 - :param last_transform: 上一帧视角,用于插值过渡 - :return: 当前帧视角(供下一帧插值) + 基于当前帧快照更新视角,彻底避免异步抖动 + 数据来源:on_world_tick缓存的latest_snapshot(当前帧精确状态) """ spectator = world.get_spectator() - # 目标视角:主角车后方8米、上方3米,轻微偏移避免遮挡 - vehicle_tf = vehicle.get_transform() + with frame_lock: + if not latest_snapshot: + return last_transform # 等待第一帧数据 + # 从当前帧快照中获取主角车的精确状态(而非实时查询) + vehicle_snapshot = latest_snapshot.find(vehicle.id) + if not vehicle_snapshot: + return last_transform + vehicle_tf = vehicle_snapshot.get_transform() # 这是当前帧的精确位置 + + # 目标视角:车后8米、上方3米,轻微右偏 target_tf = carla.Transform( vehicle_tf.transform(carla.Location(x=-8, z=3, y=0.5)), vehicle_tf.rotation ) - # 首次调用直接设置视角 + + # 首次调用直接设置 if last_transform is None: spectator.set_transform(target_tf) return target_tf - # 插值平滑过渡(t=0.1,越小视角越稳,0.05~0.2为宜) + + # 插值平滑(t=0.15适配30帧,同步模式下更稳定) smooth_loc = carla.Location( - x=lerp(last_transform.location.x, target_tf.location.x, 0.1), - y=lerp(last_transform.location.y, target_tf.location.y, 0.1), - z=lerp(last_transform.location.z, target_tf.location.z, 0.1) + x=lerp(last_transform.location.x, target_tf.location.x, 0.15), + y=lerp(last_transform.location.y, target_tf.location.y, 0.15), + z=lerp(last_transform.location.z, target_tf.location.z, 0.15) ) smooth_rot = carla.Rotation( - pitch=lerp(last_transform.rotation.pitch, target_tf.rotation.pitch, 0.1), - yaw=lerp(last_transform.rotation.yaw, target_tf.rotation.yaw, 0.1), - roll=lerp(last_transform.rotation.roll, target_tf.rotation.roll, 0.1) + pitch=lerp(last_transform.rotation.pitch, target_tf.rotation.pitch, 0.15), + yaw=lerp(last_transform.rotation.yaw, target_tf.rotation.yaw, 0.15), + roll=lerp(last_transform.rotation.roll, target_tf.rotation.roll, 0.15) ) smooth_tf = carla.Transform(smooth_loc, smooth_rot) spectator.set_transform(smooth_tf) return smooth_tf -# 初始化视角 -last_spectator_tf = set_spectator_smooth(world, vehicle) -print("视角已切换至主角Model3车辆后上方(平滑跟随,无抖动)") +# 7. 主循环(严格按帧推进) +print("\n程序运行中(强同步模式),按Ctrl+C退出...") +print("镜头基于当前帧数据更新,已解决异步抖动问题") +last_spectator_tf = None +clock = pygame.time.Clock() -# 7. 主循环:稳定帧率+平滑视角 -print("\n程序运行中,主角车与500辆NPC同步行驶,按Ctrl+C退出...") -clock = pygame.time.Clock() # 精准控制帧率 try: + # 先推进一帧获取初始快照 + world.tick() + last_spectator_tf = set_spectator_smooth() + while True: - world.tick() # 同步CARLA帧,数据无滞后 - # 平滑更新视角 - last_spectator_tf = set_spectator_smooth(world, vehicle, last_spectator_tf) - clock.tick(30) # 严格30帧/秒,避免帧率波动导致抖动 + # 推进一帧(触发on_world_tick更新快照) + world.tick() + # 基于当前帧快照更新视角(确保数据时序一致) + last_spectator_tf = set_spectator_smooth(last_spectator_tf) + # 严格控制客户端帧率(与服务器帧间隔一致) + clock.tick(30) + except KeyboardInterrupt: - print("\n程序退出,清理资源...") - # 恢复CARLA默认设置(避免影响后续使用) + print("\n用户中断,清理资源...") +finally: + # 恢复CARLA默认设置(关键:避免影响后续使用) settings.synchronous_mode = False + tm.set_synchronous_mode(False) world.apply_settings(settings) - # 销毁所有生成的车辆 - for v in world.get_actors().filter('*vehicle*'): + # 销毁所有车辆 + for v in all_vehicles: if v.is_alive: v.destroy() - print("资源清理完成,CARLA设置已恢复!") \ No newline at end of file + print("资源清理完成,同步模式已关闭") \ No newline at end of file From eb378fd867149f400bdda183692cc27b7786659c Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Fri, 12 Dec 2025 21:59:03 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E5=AE=9E=E6=97=B6RGB=E6=91=84?= =?UTF-8?q?=E5=83=8F=E5=A4=B4=E7=94=BB=E9=9D=A2=E9=87=87=E9=9B=86+OpenCV?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carla_model3_spawn_with_spectator.py | 79 ++++++++++++++++--- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py index 5b20fcb0c3..f2d3207a13 100644 --- a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py +++ b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py @@ -2,6 +2,9 @@ import pygame import time import random +import queue +import cv2 +import numpy as np from threading import Lock # 自定义线性插值函数(适配同步帧) @@ -49,7 +52,40 @@ def on_world_tick(snapshot): if not vehicle: raise Exception("主角车辆生成失败,请重启CARLA服务器") -# 4. 生成NPC车辆(减少至100辆,确保同步性能) +# 4. 初始化实时RGB摄像头(新增模块) +def init_camera(vehicle): + """初始化绑定到主角车的RGB摄像头,返回摄像头actor和图像队列""" + # 摄像头蓝图配置 + camera_bp = bp_lib.find('sensor.camera.rgb') + camera_bp.set_attribute('image_size_x', '1024') # 图像宽度 + camera_bp.set_attribute('image_size_y', '720') # 图像高度 + camera_bp.set_attribute('fov', '90') # 视场角 + camera_bp.set_attribute('shutter_speed', '100') # 减少运动模糊 + + # 摄像头安装位置:车前方2米,高度1.5米,略微上仰(便于观察前方路况) + camera_transform = carla.Transform( + carla.Location(x=2.0, z=1.5), + carla.Rotation(pitch=-5) + ) + + # 生成摄像头并绑定到主角车 + camera = world.spawn_actor( + camera_bp, + camera_transform, + attach_to=vehicle + ) + + # 创建图像队列(线程安全) + image_queue = queue.Queue() + camera.listen(image_queue.put) # 摄像头数据存入队列 + + print("RGB摄像头初始化完成,实时画面将在窗口显示(按'q'关闭)") + return camera, image_queue + +# 初始化摄像头 +camera, image_queue = init_camera(vehicle) + +# 5. 生成NPC车辆(减少至100辆,确保同步性能) npc_count = 100 # 500辆会导致同步延迟,100辆是性能与效果的平衡 print(f"开始生成{npc_count}辆NPC车辆...") for i in range(npc_count): @@ -71,13 +107,13 @@ def on_world_tick(snapshot): actual_npc_count = len(all_vehicles) - 1 print(f"NPC生成完成 | 实际数量: {actual_npc_count}辆(总车辆: {len(all_vehicles)})") -# 5. 启动所有车辆自动驾驶(绑定交通管理器同步端口) +# 6. 启动所有车辆自动驾驶(绑定交通管理器同步端口) tm = client.get_trafficmanager(8000) tm.set_synchronous_mode(True) # 交通管理器也启用同步模式 for v in all_vehicles: v.set_autopilot(True, tm.get_port()) # 所有车辆通过TM控制,确保行为同步 -# 6. 平滑视角函数(基于当前帧快照数据) +# 7. 平滑视角函数(基于当前帧快照数据) def set_spectator_smooth(last_transform=None): """ 基于当前帧快照更新视角,彻底避免异步抖动 @@ -93,7 +129,7 @@ def set_spectator_smooth(last_transform=None): return last_transform vehicle_tf = vehicle_snapshot.get_transform() # 这是当前帧的精确位置 - # 目标视角:车后8米、上方3米,轻微右偏 + # 目标视角:车后8米、上方3米,轻微右偏(便于观察整车和周围环境) target_tf = carla.Transform( vehicle_tf.transform(carla.Location(x=-8, z=3, y=0.5)), vehicle_tf.rotation @@ -119,9 +155,9 @@ def set_spectator_smooth(last_transform=None): spectator.set_transform(smooth_tf) return smooth_tf -# 7. 主循环(严格按帧推进) -print("\n程序运行中(强同步模式),按Ctrl+C退出...") -print("镜头基于当前帧数据更新,已解决异步抖动问题") +# 8. 主循环(整合实时摄像头画面与原有逻辑) +print("\n程序运行中(强同步模式),按Ctrl+C或摄像头窗口按'q'退出...") +print("功能:实时RGB摄像头画面 + 车辆自动驾驶 + 平滑视角") last_spectator_tf = None clock = pygame.time.Clock() @@ -131,22 +167,43 @@ def set_spectator_smooth(last_transform=None): last_spectator_tf = set_spectator_smooth() while True: - # 推进一帧(触发on_world_tick更新快照) + # 推进一帧(触发世界更新和摄像头数据采集) world.tick() - # 基于当前帧快照更新视角(确保数据时序一致) + + # 更新 spectator 视角(平滑跟随) last_spectator_tf = set_spectator_smooth(last_spectator_tf) - # 严格控制客户端帧率(与服务器帧间隔一致) + + # 处理实时摄像头画面(新增逻辑) + if not image_queue.empty(): + image = image_queue.get() + # 将原始数据转换为RGBA格式并reshape + img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4)) + # 显示图像(OpenCV窗口) + cv2.imshow('CARLA RGB Camera', img) + # 按'q'键退出 + if cv2.waitKey(1) == ord('q'): + break + + # 控制客户端帧率与服务器同步 clock.tick(30) except KeyboardInterrupt: print("\n用户中断,清理资源...") finally: - # 恢复CARLA默认设置(关键:避免影响后续使用) + # 清理摄像头资源(关键:避免残留传感器) + camera.stop() # 停止摄像头监听 + camera.destroy() # 销毁摄像头actor + + # 恢复CARLA默认设置 settings.synchronous_mode = False tm.set_synchronous_mode(False) world.apply_settings(settings) + # 销毁所有车辆 for v in all_vehicles: if v.is_alive: v.destroy() + + # 关闭所有OpenCV窗口 + cv2.destroyAllWindows() print("资源清理完成,同步模式已关闭") \ No newline at end of file From 60d14a970d389cd368e007564228a4b418516bb9 Mon Sep 17 00:00:00 2001 From: Xu-z-y <2067231714@qq.com> Date: Sun, 14 Dec 2025 22:05:02 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E8=AF=AD=E4=B9=89=E5=88=86=E5=89=B2?= =?UTF-8?q?=E6=91=84=E5=83=8F=E5=A4=B4=EF=BC=88Cityscapes=E8=B0=83?= =?UTF-8?q?=E8=89=B2=E6=9D=BF=E5=8F=AF=E8=A7=86=E5=8C=96=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E6=95=B4=E5=90=88RGB=E5=8F=8C=E6=91=84=E5=83=8F=E5=A4=B4+?= =?UTF-8?q?=E5=BC=BA=E5=90=8C=E6=AD=A5=E6=97=A0=E6=8A=96=E5=8A=A8=E8=A7=86?= =?UTF-8?q?=E8=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carla_model3_spawn_with_spectator.py | 180 ++++++++++-------- 1 file changed, 105 insertions(+), 75 deletions(-) diff --git a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py index f2d3207a13..bc6b8963c6 100644 --- a/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py +++ b/src/carla_autonomous_driving_perception/carla_model3_spawn_with_spectator.py @@ -9,30 +9,56 @@ # 自定义线性插值函数(适配同步帧) def lerp(a, b, t): - """线性插值:t值根据同步帧率调整(30帧下0.15更稳定)""" return a + t * (b - a) +# 语义分割调色板(Cityscapes格式,兼容所有CARLA版本) +CITYSCAPES_PALETTE = [ + (0, 0, 0), # 0: 未标注 + (70, 70, 70), # 1: 建筑物 + (100, 40, 40), # 2: 围栏 + (55, 90, 80), # 3: 其他 + (220, 20, 60), # 4: 行人 + (153, 153, 153), # 5: 杆子 + (157, 234, 50), # 6: 道路线 + (128, 64, 128), # 7: 道路 + (244, 35, 232), # 8: 人行道 + (107, 142, 35), # 9: 植被 + (0, 0, 142), # 10: 车辆 + (102, 102, 156), # 11: 墙壁 + (220, 220, 0), # 12: 交通灯 + (70, 130, 180), # 13: 交通标志 + (81, 0, 81), # 14: 天 + (150, 100, 100), # 15: 地形 + (230, 150, 140), # 16: 护栏 + (180, 165, 180), # 17: 栅栏 + (250, 170, 30), # 18: 静态 + (110, 190, 160), # 19: 动态 + (170, 120, 50), # 20: 其他 + (45, 60, 150), # 21: 水 + (145, 170, 100) # 22: 路面标记 +] + # 1. 连接CARLA服务器并配置强同步模式 client = carla.Client('localhost', 2000) client.set_timeout(15.0) world = client.load_world('Town05') -# 启用严格同步模式(关键:固定帧间隔,禁用异步更新) +# 启用严格同步模式 settings = world.get_settings() -settings.synchronous_mode = True # 客户端控制帧推进 -settings.fixed_delta_seconds = 1/30 # 30帧/秒(与后续tick频率一致) -settings.no_rendering_mode = False # 启用渲染 +settings.synchronous_mode = True +settings.fixed_delta_seconds = 1/30 +settings.no_rendering_mode = False world.apply_settings(settings) -# 2. 初始化同步锁与帧数据缓存(确保线程安全) +# 2. 初始化同步锁与帧数据缓存 frame_lock = Lock() -latest_snapshot = None # 存储当前帧的Actor快照(含车辆状态) +latest_snapshot = None -# 绑定帧同步回调:每帧更新车辆状态快照 +# 绑定帧同步回调 def on_world_tick(snapshot): global latest_snapshot with frame_lock: - latest_snapshot = snapshot # 缓存当前帧的所有Actor状态 + latest_snapshot = snapshot world.on_tick(on_world_tick) bp_lib = world.get_blueprint_library() @@ -40,7 +66,6 @@ def on_world_tick(snapshot): # 3. 生成主角车辆(Tesla Model3) model3_bp = bp_lib.find('vehicle.tesla.model3') -# 确保生成点有效(避免初始位置异常导致抖动) vehicle = None for _ in range(5): try: @@ -52,52 +77,57 @@ def on_world_tick(snapshot): if not vehicle: raise Exception("主角车辆生成失败,请重启CARLA服务器") -# 4. 初始化实时RGB摄像头(新增模块) -def init_camera(vehicle): - """初始化绑定到主角车的RGB摄像头,返回摄像头actor和图像队列""" - # 摄像头蓝图配置 +# 4. 初始化RGB摄像头(保留shutter_speed,该传感器支持) +def init_rgb_camera(vehicle): camera_bp = bp_lib.find('sensor.camera.rgb') - camera_bp.set_attribute('image_size_x', '1024') # 图像宽度 - camera_bp.set_attribute('image_size_y', '720') # 图像高度 - camera_bp.set_attribute('fov', '90') # 视场角 - camera_bp.set_attribute('shutter_speed', '100') # 减少运动模糊 - - # 摄像头安装位置:车前方2米,高度1.5米,略微上仰(便于观察前方路况) + camera_bp.set_attribute('image_size_x', '1024') + camera_bp.set_attribute('image_size_y', '720') + camera_bp.set_attribute('fov', '90') + camera_bp.set_attribute('shutter_speed', '100') # RGB摄像头支持此属性 camera_transform = carla.Transform( carla.Location(x=2.0, z=1.5), carla.Rotation(pitch=-5) ) - - # 生成摄像头并绑定到主角车 - camera = world.spawn_actor( - camera_bp, - camera_transform, - attach_to=vehicle - ) - - # 创建图像队列(线程安全) + camera = world.spawn_actor(camera_bp, camera_transform, attach_to=vehicle) image_queue = queue.Queue() - camera.listen(image_queue.put) # 摄像头数据存入队列 - - print("RGB摄像头初始化完成,实时画面将在窗口显示(按'q'关闭)") + camera.listen(image_queue.put) + print("RGB摄像头初始化完成") return camera, image_queue -# 初始化摄像头 -camera, image_queue = init_camera(vehicle) - -# 5. 生成NPC车辆(减少至100辆,确保同步性能) -npc_count = 100 # 500辆会导致同步延迟,100辆是性能与效果的平衡 +# 5. 初始化语义分割摄像头(移除shutter_speed,该传感器不支持) +def init_semantic_camera(vehicle): + """初始化语义分割摄像头,返回传感器和数据队列""" + sem_bp = bp_lib.find('sensor.camera.semantic_segmentation') + # 仅保留语义分割摄像头支持的属性 + sem_bp.set_attribute('image_size_x', '1024') + sem_bp.set_attribute('image_size_y', '720') + sem_bp.set_attribute('fov', '90') + # 移除shutter_speed设置(语义分割摄像头不支持) + sem_transform = carla.Transform( + carla.Location(x=2.0, z=1.5), + carla.Rotation(pitch=-5) + ) + sem_camera = world.spawn_actor(sem_bp, sem_transform, attach_to=vehicle) + sem_queue = queue.Queue() + sem_camera.listen(sem_queue.put) # 语义数据存入队列 + print("语义分割摄像头初始化完成") + return sem_camera, sem_queue + +# 初始化摄像头(同时初始化RGB和语义分割) +rgb_camera, rgb_queue = init_rgb_camera(vehicle) +sem_camera, sem_queue = init_semantic_camera(vehicle) # 新增语义摄像头 + +# 6. 生成NPC车辆(保留原有逻辑) +npc_count = 100 print(f"开始生成{npc_count}辆NPC车辆...") for i in range(npc_count): vehicle_bp = random.choice(bp_lib.filter('vehicle')) - if 'tesla' in vehicle_bp.id: # 避免与主角车混淆 + if 'tesla' in vehicle_bp.id: continue - # 尝试生成(避开主角车位置) spawn_point = random.choice(spawn_points) if spawn_point.location.distance(vehicle.get_location()) < 20: continue world.try_spawn_actor(vehicle_bp, spawn_point) - # 每生成20辆同步一次,确保服务器不卡顿 if i % 20 == 0: world.tick() time.sleep(0.1) @@ -107,40 +137,32 @@ def init_camera(vehicle): actual_npc_count = len(all_vehicles) - 1 print(f"NPC生成完成 | 实际数量: {actual_npc_count}辆(总车辆: {len(all_vehicles)})") -# 6. 启动所有车辆自动驾驶(绑定交通管理器同步端口) +# 7. 启动所有车辆自动驾驶 tm = client.get_trafficmanager(8000) -tm.set_synchronous_mode(True) # 交通管理器也启用同步模式 +tm.set_synchronous_mode(True) for v in all_vehicles: - v.set_autopilot(True, tm.get_port()) # 所有车辆通过TM控制,确保行为同步 + v.set_autopilot(True, tm.get_port()) -# 7. 平滑视角函数(基于当前帧快照数据) +# 8. 平滑视角函数(保留原有逻辑) def set_spectator_smooth(last_transform=None): - """ - 基于当前帧快照更新视角,彻底避免异步抖动 - 数据来源:on_world_tick缓存的latest_snapshot(当前帧精确状态) - """ spectator = world.get_spectator() with frame_lock: if not latest_snapshot: - return last_transform # 等待第一帧数据 - # 从当前帧快照中获取主角车的精确状态(而非实时查询) + return last_transform vehicle_snapshot = latest_snapshot.find(vehicle.id) if not vehicle_snapshot: return last_transform - vehicle_tf = vehicle_snapshot.get_transform() # 这是当前帧的精确位置 + vehicle_tf = vehicle_snapshot.get_transform() - # 目标视角:车后8米、上方3米,轻微右偏(便于观察整车和周围环境) target_tf = carla.Transform( vehicle_tf.transform(carla.Location(x=-8, z=3, y=0.5)), vehicle_tf.rotation ) - # 首次调用直接设置 if last_transform is None: spectator.set_transform(target_tf) return target_tf - # 插值平滑(t=0.15适配30帧,同步模式下更稳定) smooth_loc = carla.Location( x=lerp(last_transform.location.x, target_tf.location.x, 0.15), y=lerp(last_transform.location.y, target_tf.location.y, 0.15), @@ -155,46 +177,55 @@ def set_spectator_smooth(last_transform=None): spectator.set_transform(smooth_tf) return smooth_tf -# 8. 主循环(整合实时摄像头画面与原有逻辑) -print("\n程序运行中(强同步模式),按Ctrl+C或摄像头窗口按'q'退出...") -print("功能:实时RGB摄像头画面 + 车辆自动驾驶 + 平滑视角") +# 9. 主循环(处理图像显示) +print("\n程序运行中,按Ctrl+C或任一窗口按'q'退出...") +print("功能:RGB摄像头 + 语义分割摄像头 + 车辆自动驾驶 + 平滑视角") last_spectator_tf = None clock = pygame.time.Clock() try: - # 先推进一帧获取初始快照 world.tick() last_spectator_tf = set_spectator_smooth() while True: - # 推进一帧(触发世界更新和摄像头数据采集) world.tick() - - # 更新 spectator 视角(平滑跟随) last_spectator_tf = set_spectator_smooth(last_spectator_tf) - # 处理实时摄像头画面(新增逻辑) - if not image_queue.empty(): - image = image_queue.get() - # 将原始数据转换为RGBA格式并reshape - img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4)) - # 显示图像(OpenCV窗口) - cv2.imshow('CARLA RGB Camera', img) - # 按'q'键退出 + # 处理RGB图像 + if not rgb_queue.empty(): + rgb_image = rgb_queue.get() + rgb_img = np.reshape(np.copy(rgb_image.raw_data), + (rgb_image.height, rgb_image.width, 4)) + cv2.imshow('RGB Camera', rgb_img) + if cv2.waitKey(1) == ord('q'): + break + + # 处理语义分割图像 + if not sem_queue.empty(): + sem_image = sem_queue.get() + # 提取语义分割原始数据(单通道类别ID) + sem_data = np.reshape(np.copy(sem_image.raw_data), + (sem_image.height, sem_image.width, 4))[:, :, 2].astype(np.int32) + # 映射到Cityscapes调色板(转换为RGB可视化) + sem_rgb = np.zeros((sem_image.height, sem_image.width, 3), dtype=np.uint8) + for i in range(len(CITYSCAPES_PALETTE)): + sem_rgb[sem_data == i] = CITYSCAPES_PALETTE[i] + cv2.imshow('Semantic Segmentation', sem_rgb) if cv2.waitKey(1) == ord('q'): break - # 控制客户端帧率与服务器同步 clock.tick(30) except KeyboardInterrupt: print("\n用户中断,清理资源...") finally: - # 清理摄像头资源(关键:避免残留传感器) - camera.stop() # 停止摄像头监听 - camera.destroy() # 销毁摄像头actor + # 清理所有传感器 + rgb_camera.stop() + rgb_camera.destroy() + sem_camera.stop() + sem_camera.destroy() - # 恢复CARLA默认设置 + # 恢复CARLA设置 settings.synchronous_mode = False tm.set_synchronous_mode(False) world.apply_settings(settings) @@ -204,6 +235,5 @@ def set_spectator_smooth(last_transform=None): if v.is_alive: v.destroy() - # 关闭所有OpenCV窗口 cv2.destroyAllWindows() print("资源清理完成,同步模式已关闭") \ No newline at end of file