From 78a15cd66a31d1b6e0c5d53947078668d05b476d Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Tue, 14 Apr 2026 11:22:50 +0800 Subject: [PATCH 01/22] Update CONTRIBUTORS.md --- .../ultralytics/nn/extra_modules/cutlass/CONTRIBUTORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yolo12_object_detection/scripts/ultralytics/nn/extra_modules/cutlass/CONTRIBUTORS.md b/src/yolo12_object_detection/scripts/ultralytics/nn/extra_modules/cutlass/CONTRIBUTORS.md index a4e0a2a435..b12d6088e1 100644 --- a/src/yolo12_object_detection/scripts/ultralytics/nn/extra_modules/cutlass/CONTRIBUTORS.md +++ b/src/yolo12_object_detection/scripts/ultralytics/nn/extra_modules/cutlass/CONTRIBUTORS.md @@ -45,7 +45,7 @@ Albert Xu Jack Yang Xiuxia Zhang Nick Zhao - +jokic ## ACKNOWLEDGEMENTS Girish Bharambe From 862859948e527fe6afcb9f50cbbfa12aa817e1c3 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Fri, 17 Apr 2026 16:32:51 +0800 Subject: [PATCH 02/22] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=80=89=E9=A2=98?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=B8=BB=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成选题创建主函数 --- src/carla_ driving_car_lane/main.py | 87 +++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/carla_ driving_car_lane/main.py diff --git a/src/carla_ driving_car_lane/main.py b/src/carla_ driving_car_lane/main.py new file mode 100644 index 0000000000..19414cbd18 --- /dev/null +++ b/src/carla_ driving_car_lane/main.py @@ -0,0 +1,87 @@ +from common.transformations.camera import transform_img, eon_intrinsics +from common.transformations.model import medmodel_intrinsics +import numpy as np +from tqdm import tqdm +import matplotlib +import matplotlib.pyplot as plt + +import cv2 +from tensorflow.keras.models import load_model +from common.tools.lib.parser import parser +import cv2 +import sys +camerafile = sys.argv[1] +supercombo = load_model('models/supercombo.keras') + +MAX_DISTANCE = 140. +LANE_OFFSET = 1.8 +MAX_REL_V = 10. + +LEAD_X_SCALE = 10 +LEAD_Y_SCALE = 10 + +cap = cv2.VideoCapture(camerafile) + +imgs = [] + +for i in tqdm(range(1000)): + ret, frame = cap.read() + img_yuv = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420) + imgs.append(img_yuv.reshape((874*3//2, 1164))) + + +def frames_to_tensor(frames): + H = (frames.shape[1]*2)//3 + W = frames.shape[2] + in_img1 = np.zeros((frames.shape[0], 6, H//2, W//2), dtype=np.uint8) + + in_img1[:, 0] = frames[:, 0:H:2, 0::2] + in_img1[:, 1] = frames[:, 1:H:2, 0::2] + in_img1[:, 2] = frames[:, 0:H:2, 1::2] + in_img1[:, 3] = frames[:, 1:H:2, 1::2] + in_img1[:, 4] = frames[:, H:H+H//4].reshape((-1, H//2,W//2)) + in_img1[:, 5] = frames[:, H+H//4:H+H//2].reshape((-1, H//2,W//2)) + return in_img1 + +imgs_med_model = np.zeros((len(imgs), 384, 512), dtype=np.uint8) +for i, img in tqdm(enumerate(imgs)): + imgs_med_model[i] = transform_img(img, from_intr=eon_intrinsics, to_intr=medmodel_intrinsics, yuv=True, + output_size=(512,256)) +frame_tensors = frames_to_tensor(np.array(imgs_med_model)).astype(np.float32)/128.0 - 1.0 + + +state = np.zeros((1,512)) +desire = np.zeros((1,8)) + +cap = cv2.VideoCapture(camerafile) + +for i in tqdm(range(len(frame_tensors) - 1)): + inputs = [np.vstack(frame_tensors[i:i+2])[None], desire, state] + outs = supercombo.predict(inputs) + parsed = parser(outs) + # Important to refeed the state + state = outs[-1] + pose = outs[-2] + ret, frame = cap.read() + frame = cv2.resize(frame, (640, 420)) + # Show raw camera image + cv2.imshow("modeld", frame) + # Clean plot for next frame + plt.clf() + plt.title("lanes and path") + # lll = left lane line + plt.plot(parsed["lll"][0], range(0,192), "b-", linewidth=1) + # rll = right lane line + plt.plot(parsed["rll"][0], range(0, 192), "r-", linewidth=1) + # path = path cool isn't it ? + plt.plot(parsed["path"][0], range(0, 192), "g-", linewidth=1) + #print(np.array(pose[0,:3]).shape) + #plt.scatter(pose[0,:3], range(3), c="y") + + # Needed to invert axis because standart left lane is positive and right lane is negative, so we flip the x axis + plt.gca().invert_xaxis() + plt.pause(0.001) + if cv2.waitKey(10) & 0xFF == ord('q'): + break + +plt.show() From 818aabe366f864ca9ad971a32b13b52bb8e2cd35 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Fri, 17 Apr 2026 16:38:02 +0800 Subject: [PATCH 03/22] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=80=89=E9=A2=98?= =?UTF-8?q?=E5=B9=B6=E5=88=9B=E5=BB=BA=E4=B8=AD=E6=96=87=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成选题并创建中文文档 --- src/carla_ driving_car_lane/READMD.md | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/carla_ driving_car_lane/READMD.md diff --git a/src/carla_ driving_car_lane/READMD.md b/src/carla_ driving_car_lane/READMD.md new file mode 100644 index 0000000000..5345a2f6db --- /dev/null +++ b/src/carla_ driving_car_lane/READMD.md @@ -0,0 +1,43 @@ + +====================================== + +## 自动驾驶车道与路径检测 + +====================================== + + +本项目基于 Windows11 与 Python 3.7 环境开发, +主要实现自动驾驶场景下的车道线识别与行驶路径实时检 +测,可对车载摄像头采集的视频流(如 .hevc 格式行车视频)进行解析,通过视觉算法识别道路车道线、规划安 +全行驶轨迹,为自动驾驶决策提供车道感知与路径引导支持。 +项目面向自动驾驶辅助系统(ADAS)的基础视觉感知模块,依赖系统底层库与 Python 机器学习 / 视觉处理工具链,可快速部署运行, + +完成对行车视频的离线车道与路径分析,适用于自动驾驶算法验证、智能驾驶教学实验等场景。 + + +# 操作系统 + Windows11 + +# Python + python Version 3.7 + + pip Version 21.3.1 + + Setuptools Version & Install + + pip3 install setuptools==45.2.0 + + (高版本卸载命令pip3 uninstall setuptools) + +# 安装依赖 + 安装库文件 + + sudo apt install libssl-dev libcurl4-openssl-dev curl + + sudo apt install libarchive-dev + +# 安装 + pip3 install -r requirements.txt + +# 运行程序 + python3 main.py ../sample.hevc From 730501a9d66298208353eda96f2aa5aa4acad850 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Mon, 20 Apr 2026 10:53:11 +0800 Subject: [PATCH 04/22] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=90=8D=E7=9A=84=E7=A9=BA=E7=99=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_driving_car_lane/1.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/carla_driving_car_lane/1.py diff --git a/src/carla_driving_car_lane/1.py b/src/carla_driving_car_lane/1.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/carla_driving_car_lane/1.py @@ -0,0 +1 @@ + From fea2fe8adedec23f18cf80753c3f2cee4b561d4a Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Mon, 20 Apr 2026 10:54:21 +0800 Subject: [PATCH 05/22] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=80=89=E9=A2=98?= =?UTF-8?q?=E5=B9=B6=E5=88=9B=E5=BB=BA=E4=B8=BB=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_driving_car_lane/1.py | 1 - src/carla_driving_car_lane/main.py | 88 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) delete mode 100644 src/carla_driving_car_lane/1.py create mode 100644 src/carla_driving_car_lane/main.py diff --git a/src/carla_driving_car_lane/1.py b/src/carla_driving_car_lane/1.py deleted file mode 100644 index 8b13789179..0000000000 --- a/src/carla_driving_car_lane/1.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/carla_driving_car_lane/main.py b/src/carla_driving_car_lane/main.py new file mode 100644 index 0000000000..3d1a3c34d7 --- /dev/null +++ b/src/carla_driving_car_lane/main.py @@ -0,0 +1,88 @@ + +from common.transformations.camera import transform_img, eon_intrinsics +from common.transformations.model import medmodel_intrinsics +import numpy as np +from tqdm import tqdm +import matplotlib +import matplotlib.pyplot as plt + +import cv2 +from tensorflow.keras.models import load_model +from common.tools.lib.parser import parser +import cv2 +import sys +camerafile = sys.argv[1] +supercombo = load_model('models/supercombo.keras') + +MAX_DISTANCE = 140. +LANE_OFFSET = 1.8 +MAX_REL_V = 10. + +LEAD_X_SCALE = 10 +LEAD_Y_SCALE = 10 + +cap = cv2.VideoCapture(camerafile) + +imgs = [] + +for i in tqdm(range(1000)): + ret, frame = cap.read() + img_yuv = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420) + imgs.append(img_yuv.reshape((874*3//2, 1164))) + + +def frames_to_tensor(frames): + H = (frames.shape[1]*2)//3 + W = frames.shape[2] + in_img1 = np.zeros((frames.shape[0], 6, H//2, W//2), dtype=np.uint8) + + in_img1[:, 0] = frames[:, 0:H:2, 0::2] + in_img1[:, 1] = frames[:, 1:H:2, 0::2] + in_img1[:, 2] = frames[:, 0:H:2, 1::2] + in_img1[:, 3] = frames[:, 1:H:2, 1::2] + in_img1[:, 4] = frames[:, H:H+H//4].reshape((-1, H//2,W//2)) + in_img1[:, 5] = frames[:, H+H//4:H+H//2].reshape((-1, H//2,W//2)) + return in_img1 + +imgs_med_model = np.zeros((len(imgs), 384, 512), dtype=np.uint8) +for i, img in tqdm(enumerate(imgs)): + imgs_med_model[i] = transform_img(img, from_intr=eon_intrinsics, to_intr=medmodel_intrinsics, yuv=True, + output_size=(512,256)) +frame_tensors = frames_to_tensor(np.array(imgs_med_model)).astype(np.float32)/128.0 - 1.0 + + +state = np.zeros((1,512)) +desire = np.zeros((1,8)) + +cap = cv2.VideoCapture(camerafile) + +for i in tqdm(range(len(frame_tensors) - 1)): + inputs = [np.vstack(frame_tensors[i:i+2])[None], desire, state] + outs = supercombo.predict(inputs) + parsed = parser(outs) + # Important to refeed the state + state = outs[-1] + pose = outs[-2] + ret, frame = cap.read() + frame = cv2.resize(frame, (640, 420)) + # Show raw camera image + cv2.imshow("modeld", frame) + # Clean plot for next frame + plt.clf() + plt.title("lanes and path") + # lll = left lane line + plt.plot(parsed["lll"][0], range(0,192), "b-", linewidth=1) + # rll = right lane line + plt.plot(parsed["rll"][0], range(0, 192), "r-", linewidth=1) + # path = path cool isn't it ? + plt.plot(parsed["path"][0], range(0, 192), "g-", linewidth=1) + #print(np.array(pose[0,:3]).shape) + #plt.scatter(pose[0,:3], range(3), c="y") + + # Needed to invert axis because standart left lane is positive and right lane is negative, so we flip the x axis + plt.gca().invert_xaxis() + plt.pause(0.001) + if cv2.waitKey(10) & 0xFF == ord('q'): + break + +plt.show() From 2124605797f62ef45a5ed239e8a9d2446fc45c1a Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Mon, 20 Apr 2026 10:54:48 +0800 Subject: [PATCH 06/22] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_driving_car_lane/README.md | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/carla_driving_car_lane/README.md diff --git a/src/carla_driving_car_lane/README.md b/src/carla_driving_car_lane/README.md new file mode 100644 index 0000000000..5345a2f6db --- /dev/null +++ b/src/carla_driving_car_lane/README.md @@ -0,0 +1,43 @@ + +====================================== + +## 自动驾驶车道与路径检测 + +====================================== + + +本项目基于 Windows11 与 Python 3.7 环境开发, +主要实现自动驾驶场景下的车道线识别与行驶路径实时检 +测,可对车载摄像头采集的视频流(如 .hevc 格式行车视频)进行解析,通过视觉算法识别道路车道线、规划安 +全行驶轨迹,为自动驾驶决策提供车道感知与路径引导支持。 +项目面向自动驾驶辅助系统(ADAS)的基础视觉感知模块,依赖系统底层库与 Python 机器学习 / 视觉处理工具链,可快速部署运行, + +完成对行车视频的离线车道与路径分析,适用于自动驾驶算法验证、智能驾驶教学实验等场景。 + + +# 操作系统 + Windows11 + +# Python + python Version 3.7 + + pip Version 21.3.1 + + Setuptools Version & Install + + pip3 install setuptools==45.2.0 + + (高版本卸载命令pip3 uninstall setuptools) + +# 安装依赖 + 安装库文件 + + sudo apt install libssl-dev libcurl4-openssl-dev curl + + sudo apt install libarchive-dev + +# 安装 + pip3 install -r requirements.txt + +# 运行程序 + python3 main.py ../sample.hevc From 85ea0de7330f1838023173cc86f565337c875334 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Mon, 20 Apr 2026 22:39:02 +0800 Subject: [PATCH 07/22] Delete src/carla_ driving_car_lane directory --- src/carla_ driving_car_lane/READMD.md | 43 ------------- src/carla_ driving_car_lane/main.py | 87 --------------------------- 2 files changed, 130 deletions(-) delete mode 100644 src/carla_ driving_car_lane/READMD.md delete mode 100644 src/carla_ driving_car_lane/main.py diff --git a/src/carla_ driving_car_lane/READMD.md b/src/carla_ driving_car_lane/READMD.md deleted file mode 100644 index 5345a2f6db..0000000000 --- a/src/carla_ driving_car_lane/READMD.md +++ /dev/null @@ -1,43 +0,0 @@ - -====================================== - -## 自动驾驶车道与路径检测 - -====================================== - - -本项目基于 Windows11 与 Python 3.7 环境开发, -主要实现自动驾驶场景下的车道线识别与行驶路径实时检 -测,可对车载摄像头采集的视频流(如 .hevc 格式行车视频)进行解析,通过视觉算法识别道路车道线、规划安 -全行驶轨迹,为自动驾驶决策提供车道感知与路径引导支持。 -项目面向自动驾驶辅助系统(ADAS)的基础视觉感知模块,依赖系统底层库与 Python 机器学习 / 视觉处理工具链,可快速部署运行, - -完成对行车视频的离线车道与路径分析,适用于自动驾驶算法验证、智能驾驶教学实验等场景。 - - -# 操作系统 - Windows11 - -# Python - python Version 3.7 - - pip Version 21.3.1 - - Setuptools Version & Install - - pip3 install setuptools==45.2.0 - - (高版本卸载命令pip3 uninstall setuptools) - -# 安装依赖 - 安装库文件 - - sudo apt install libssl-dev libcurl4-openssl-dev curl - - sudo apt install libarchive-dev - -# 安装 - pip3 install -r requirements.txt - -# 运行程序 - python3 main.py ../sample.hevc diff --git a/src/carla_ driving_car_lane/main.py b/src/carla_ driving_car_lane/main.py deleted file mode 100644 index 19414cbd18..0000000000 --- a/src/carla_ driving_car_lane/main.py +++ /dev/null @@ -1,87 +0,0 @@ -from common.transformations.camera import transform_img, eon_intrinsics -from common.transformations.model import medmodel_intrinsics -import numpy as np -from tqdm import tqdm -import matplotlib -import matplotlib.pyplot as plt - -import cv2 -from tensorflow.keras.models import load_model -from common.tools.lib.parser import parser -import cv2 -import sys -camerafile = sys.argv[1] -supercombo = load_model('models/supercombo.keras') - -MAX_DISTANCE = 140. -LANE_OFFSET = 1.8 -MAX_REL_V = 10. - -LEAD_X_SCALE = 10 -LEAD_Y_SCALE = 10 - -cap = cv2.VideoCapture(camerafile) - -imgs = [] - -for i in tqdm(range(1000)): - ret, frame = cap.read() - img_yuv = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420) - imgs.append(img_yuv.reshape((874*3//2, 1164))) - - -def frames_to_tensor(frames): - H = (frames.shape[1]*2)//3 - W = frames.shape[2] - in_img1 = np.zeros((frames.shape[0], 6, H//2, W//2), dtype=np.uint8) - - in_img1[:, 0] = frames[:, 0:H:2, 0::2] - in_img1[:, 1] = frames[:, 1:H:2, 0::2] - in_img1[:, 2] = frames[:, 0:H:2, 1::2] - in_img1[:, 3] = frames[:, 1:H:2, 1::2] - in_img1[:, 4] = frames[:, H:H+H//4].reshape((-1, H//2,W//2)) - in_img1[:, 5] = frames[:, H+H//4:H+H//2].reshape((-1, H//2,W//2)) - return in_img1 - -imgs_med_model = np.zeros((len(imgs), 384, 512), dtype=np.uint8) -for i, img in tqdm(enumerate(imgs)): - imgs_med_model[i] = transform_img(img, from_intr=eon_intrinsics, to_intr=medmodel_intrinsics, yuv=True, - output_size=(512,256)) -frame_tensors = frames_to_tensor(np.array(imgs_med_model)).astype(np.float32)/128.0 - 1.0 - - -state = np.zeros((1,512)) -desire = np.zeros((1,8)) - -cap = cv2.VideoCapture(camerafile) - -for i in tqdm(range(len(frame_tensors) - 1)): - inputs = [np.vstack(frame_tensors[i:i+2])[None], desire, state] - outs = supercombo.predict(inputs) - parsed = parser(outs) - # Important to refeed the state - state = outs[-1] - pose = outs[-2] - ret, frame = cap.read() - frame = cv2.resize(frame, (640, 420)) - # Show raw camera image - cv2.imshow("modeld", frame) - # Clean plot for next frame - plt.clf() - plt.title("lanes and path") - # lll = left lane line - plt.plot(parsed["lll"][0], range(0,192), "b-", linewidth=1) - # rll = right lane line - plt.plot(parsed["rll"][0], range(0, 192), "r-", linewidth=1) - # path = path cool isn't it ? - plt.plot(parsed["path"][0], range(0, 192), "g-", linewidth=1) - #print(np.array(pose[0,:3]).shape) - #plt.scatter(pose[0,:3], range(3), c="y") - - # Needed to invert axis because standart left lane is positive and right lane is negative, so we flip the x axis - plt.gca().invert_xaxis() - plt.pause(0.001) - if cv2.waitKey(10) & 0xFF == ord('q'): - break - -plt.show() From c1d908c2f3afeb84b70fa93d5347491158e43c4e Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Wed, 22 Apr 2026 19:19:31 +0800 Subject: [PATCH 08/22] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=B8=BB=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_driving_car_lane/main.py | 425 +++++++++++++++++++++++------ 1 file changed, 339 insertions(+), 86 deletions(-) diff --git a/src/carla_driving_car_lane/main.py b/src/carla_driving_car_lane/main.py index 3d1a3c34d7..73752cec9d 100644 --- a/src/carla_driving_car_lane/main.py +++ b/src/carla_driving_car_lane/main.py @@ -1,88 +1,341 @@ +#!/usr/bin/env python -from common.transformations.camera import transform_img, eon_intrinsics -from common.transformations.model import medmodel_intrinsics -import numpy as np -from tqdm import tqdm -import matplotlib -import matplotlib.pyplot as plt - -import cv2 -from tensorflow.keras.models import load_model -from common.tools.lib.parser import parser -import cv2 +# Copyright (c) 2018 Intel Labs. +# authors: German Ros (german.ros@gmail.com) +# +# This work is licensed under the terms of the MIT license. +# For a copy, see + +"""Example of automatic vehicle control from client side.""" + +from __future__ import print_function + +import argparse +import collections +import datetime +import glob +import logging +import math +import os +import random +import re import sys -camerafile = sys.argv[1] -supercombo = load_model('models/supercombo.keras') - -MAX_DISTANCE = 140. -LANE_OFFSET = 1.8 -MAX_REL_V = 10. - -LEAD_X_SCALE = 10 -LEAD_Y_SCALE = 10 - -cap = cv2.VideoCapture(camerafile) - -imgs = [] - -for i in tqdm(range(1000)): - ret, frame = cap.read() - img_yuv = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420) - imgs.append(img_yuv.reshape((874*3//2, 1164))) - - -def frames_to_tensor(frames): - H = (frames.shape[1]*2)//3 - W = frames.shape[2] - in_img1 = np.zeros((frames.shape[0], 6, H//2, W//2), dtype=np.uint8) - - in_img1[:, 0] = frames[:, 0:H:2, 0::2] - in_img1[:, 1] = frames[:, 1:H:2, 0::2] - in_img1[:, 2] = frames[:, 0:H:2, 1::2] - in_img1[:, 3] = frames[:, 1:H:2, 1::2] - in_img1[:, 4] = frames[:, H:H+H//4].reshape((-1, H//2,W//2)) - in_img1[:, 5] = frames[:, H+H//4:H+H//2].reshape((-1, H//2,W//2)) - return in_img1 - -imgs_med_model = np.zeros((len(imgs), 384, 512), dtype=np.uint8) -for i, img in tqdm(enumerate(imgs)): - imgs_med_model[i] = transform_img(img, from_intr=eon_intrinsics, to_intr=medmodel_intrinsics, yuv=True, - output_size=(512,256)) -frame_tensors = frames_to_tensor(np.array(imgs_med_model)).astype(np.float32)/128.0 - 1.0 - - -state = np.zeros((1,512)) -desire = np.zeros((1,8)) - -cap = cv2.VideoCapture(camerafile) - -for i in tqdm(range(len(frame_tensors) - 1)): - inputs = [np.vstack(frame_tensors[i:i+2])[None], desire, state] - outs = supercombo.predict(inputs) - parsed = parser(outs) - # Important to refeed the state - state = outs[-1] - pose = outs[-2] - ret, frame = cap.read() - frame = cv2.resize(frame, (640, 420)) - # Show raw camera image - cv2.imshow("modeld", frame) - # Clean plot for next frame - plt.clf() - plt.title("lanes and path") - # lll = left lane line - plt.plot(parsed["lll"][0], range(0,192), "b-", linewidth=1) - # rll = right lane line - plt.plot(parsed["rll"][0], range(0, 192), "r-", linewidth=1) - # path = path cool isn't it ? - plt.plot(parsed["path"][0], range(0, 192), "g-", linewidth=1) - #print(np.array(pose[0,:3]).shape) - #plt.scatter(pose[0,:3], range(3), c="y") - - # Needed to invert axis because standart left lane is positive and right lane is negative, so we flip the x axis - plt.gca().invert_xaxis() - plt.pause(0.001) - if cv2.waitKey(10) & 0xFF == ord('q'): - break - -plt.show() +import weakref + +# ========================================== +# 适配你的路径 D:\carla0.9.15 +# ========================================== +CARLA_ROOT = r"D:\carla0.9.15" +PYTHON_API = os.path.join(CARLA_ROOT, "PythonAPI") +sys.path.append(PYTHON_API) +sys.path.append(os.path.join(PYTHON_API, "carla")) + +try: + eggs = glob.glob(os.path.join(PYTHON_API, "carla", "dist", "*.egg")) + for e in eggs: + sys.path.append(e) +except: + pass + +# ================= 依赖导入 ================= +try: + import pygame + from pygame.locals import KMOD_CTRL + from pygame.locals import K_ESCAPE + from pygame.locals import K_q +except ImportError: + raise RuntimeError('请安装:pip install pygame') + +try: + import numpy as np +except ImportError: + raise RuntimeError('请安装:pip install numpy') + +import carla +from carla import ColorConverter as cc + +# 已删除不存在的 RoamingAgent +from agents.navigation.behavior_agent import BehaviorAgent +from agents.navigation.basic_agent import BasicAgent + +# ============================================================================== +# -- Global functions +# ============================================================================== +def find_weather_presets(): + rgx = re.compile('.+?(?:(?<=[a-z])(?=[A-Z])|(?=[A-Z])(?=[A-Z][a-z])|$)') + def name(x): return ' '.join(m.group(0) for m in rgx.finditer(x)) + presets = [x for x in dir(carla.WeatherParameters) if re.match('[A-Z].+', x)] + return [(getattr(carla.WeatherParameters, x), name(x)) for x in presets] + +def get_actor_display_name(actor, truncate=250): + name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) + return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + +# ============================================================================== +# -- World +# ============================================================================== +class World(object): + def __init__(self, carla_world, hud, args): + self.world = carla_world + self.map = self.world.get_map() + self.hud = hud + self.player = None + self.collision_sensor = None + self.lane_invasion_sensor = None + self.gnss_sensor = None + self.camera_manager = None + self._weather_presets = find_weather_presets() + self._weather_index = 0 + self._actor_filter = args.filter + self._gamma = 2.2 + self.restart(args) + self.world.on_tick(hud.on_world_tick) + + def restart(self, args): + cam_index = self.camera_manager.index if self.camera_manager else 0 + cam_pos_id = self.camera_manager.transform_index if self.camera_manager else 0 + + blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) + blueprint.set_attribute('role_name', 'hero') + + if self.player is not None: + spawn_point = self.player.get_transform() + spawn_point.location.z += 2.0 + self.destroy() + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + while self.player is None: + spawn_point = random.choice(self.map.get_spawn_points()) + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + self.collision_sensor = CollisionSensor(self.player, self.hud) + self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) + self.gnss_sensor = GnssSensor(self.player) + self.camera_manager = CameraManager(self.player, self.hud, self._gamma) + self.camera_manager.transform_index = cam_pos_id + self.camera_manager.set_sensor(cam_index, notify=False) + + def next_weather(self, reverse=False): + self._weather_index += -1 if reverse else 1 + self._weather_index %= len(self._weather_presets) + preset = self._weather_presets[self._weather_index] + self.hud.notification('Weather: %s' % preset[1]) + self.world.set_weather(preset[0]) + + def tick(self, clock): + self.hud.tick(self, clock) + + def render(self, display): + self.camera_manager.render(display) + self.hud.render(display) + + def destroy(self): + actors = [ + self.camera_manager.sensor, + self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, + self.gnss_sensor.sensor, + self.player] + for actor in actors: + if actor is not None: + actor.destroy() + +# ============================================================================== +# -- KeyboardControl +# ============================================================================== +class KeyboardControl(object): + def __init__(self, world): + world.hud.notification("Press ESC or Ctrl+Q to quit", seconds=2) + + def parse_events(self): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return True + if event.type == pygame.KEYUP: + if self._is_quit_shortcut(event.key): + return True + return False + + @staticmethod + def _is_quit_shortcut(key): + return key == K_ESCAPE or (key == K_q and pygame.key.get_mod() & KMOD_CTRL) + +# ============================================================================== +# -- HUD +# ============================================================================== +class HUD(object): + def __init__(self, width, height): + self.dim = (width, height) + font = pygame.font.Font(pygame.font.get_default_font(), 16) + self._notifications = FadingText(font, (width, 40), (0, height - 40)) + self.server_fps = 0 + self.frame = 0 + self.simulation_time = 0 + self._show_info = True + + def on_world_tick(self, timestamp): + self.server_fps = 1.0 / timestamp.delta_seconds + self.frame = timestamp.frame_count + self.simulation_time = timestamp.elapsed_seconds + + def tick(self, world, clock): + self._notifications.tick(world, clock) + + def notification(self, text, seconds=2): + self._notifications.set_text(text, seconds=seconds) + + def error(self, text): + self._notifications.set_text('Error: %s' % text, (255, 0, 0)) + + def render(self, display): + self._notifications.render(display) + +# ============================================================================== +# -- FadingText +# ============================================================================== +class FadingText(object): + def __init__(self, font, dim, pos): + self.font = font + self.dim = dim + self.pos = pos + self.seconds_left = 0 + self.surface = pygame.Surface(self.dim) + + def set_text(self, text, color=(255, 255, 255), seconds=2.0): + self.seconds_left = seconds + self.surface = self.font.render(text, True, color) + + def tick(self, _, clock): + self.seconds_left = max(0.0, self.seconds_left - clock.get_time() / 1000.0) + + def render(self, display): + display.blit(self.surface, self.pos) + +# ============================================================================== +# -- CollisionSensor +# ============================================================================== +class CollisionSensor(object): + def __init__(self, parent_actor, hud): + self.sensor = None + self._parent = parent_actor + self.hud = hud + bp = parent_actor.get_world().get_blueprint_library().find('sensor.other.collision') + self.sensor = parent_actor.get_world().spawn_actor(bp, carla.Transform(), attach_to=parent_actor) + self.sensor.listen(lambda e: self.hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) + +# ============================================================================== +# -- LaneInvasionSensor +# ============================================================================== +class LaneInvasionSensor(object): + def __init__(self, parent_actor, hud): + self.sensor = None + bp = parent_actor.get_world().get_blueprint_library().find('sensor.other.lane_invasion') + self.sensor = parent_actor.get_world().spawn_actor(bp, carla.Transform(), attach_to=parent_actor) + +# ============================================================================== +# -- GnssSensor +# ============================================================================== +class GnssSensor(object): + def __init__(self, parent_actor): + self.sensor = None + self.lat = self.lon = 0.0 + bp = parent_actor.get_world().get_blueprint_library().find('sensor.other.gnss') + self.sensor = parent_actor.get_world().spawn_actor(bp, carla.Transform(carla.Location(z=2.0)), attach_to=parent_actor) + +# ============================================================================== +# -- CameraManager +# ============================================================================== +class CameraManager(object): + def __init__(self, parent_actor, hud, gamma): + self.sensor = None + self.surface = None + self._parent = parent_actor + self.hud = hud + self.transform_index = 0 + self._camera_transforms = [ + (carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)), carla.AttachmentType.SpringArm) + ] + self.sensors = [['sensor.camera.rgb', cc.Raw, 'RGB']] + world = parent_actor.get_world() + for item in self.sensors: + b = world.get_blueprint_library().find(item[0]) + b.set_attribute('image_size_x', str(hud.dim[0])) + b.set_attribute('image_size_y', str(hud.dim[1])) + item.append(b) + self.index = None + + def set_sensor(self, index, notify=True): + if self.sensor: + self.sensor.destroy() + self.sensor = self._parent.get_world().spawn_actor( + self.sensors[0][-1], + self._camera_transforms[0][0], + attach_to=self._parent + ) + self.sensor.listen(lambda img: self._parse_image(img)) + self.index = 0 + + def _parse_image(self, image): + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape(image.height, image.width, 4)[:, :, :3] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) + + def render(self, display): + if self.surface: + display.blit(self.surface, (0, 0)) + +# ============================================================================== +# -- Game Loop +# ============================================================================== +def game_loop(args): + pygame.init() + pygame.font.init() + world = None + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(10.0) + display = pygame.display.set_mode((args.width, args.height), pygame.HWSURFACE | pygame.DOUBLEBUF) + hud = HUD(args.width, args.height) + world = World(client.get_world(), hud, args) + controller = KeyboardControl(world) + + agent = BehaviorAgent(world.player, behavior=args.behavior) + spawn_points = world.map.get_spawn_points() + agent.set_destination(random.choice(spawn_points).location) + + clock = pygame.time.Clock() + + while True: + clock.tick_busy_loop(60) + if controller.parse_events(): + return + + world.tick(clock) + world.render(display) + pygame.display.flip() + + control = agent.run_step() + world.player.apply_control(control) + + finally: + if world: + world.destroy() + pygame.quit() + +# ============================================================================== +# -- main() +# ============================================================================== +def main(): + argparser = argparse.ArgumentParser(description='CARLA Automatic Control Client') + argparser.add_argument('--host', default='127.0.0.1') + argparser.add_argument('--port', default=2000, type=int) + argparser.add_argument('--res', default='1280x720') + argparser.add_argument('--filter', default='vehicle.*') + argparser.add_argument('-b', '--behavior', default='normal') + args = argparser.parse_args() + args.width, args.height = map(int, args.res.split('x')) + game_loop(args) + +if __name__ == '__main__': + main() From 0d64d6784a0a497634996359e43df6693fce883e Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Wed, 22 Apr 2026 19:22:29 +0800 Subject: [PATCH 09/22] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_driving_car_lane/README.md | 64 ++++++++++++++-------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/carla_driving_car_lane/README.md b/src/carla_driving_car_lane/README.md index 5345a2f6db..abeadf0f5a 100644 --- a/src/carla_driving_car_lane/README.md +++ b/src/carla_driving_car_lane/README.md @@ -1,43 +1,45 @@ -====================================== - -## 自动驾驶车道与路径检测 - -====================================== +--- +## CARLA 0.9.15 交通灯检测与自动驾驶控制系统 -本项目基于 Windows11 与 Python 3.7 环境开发, -主要实现自动驾驶场景下的车道线识别与行驶路径实时检 -测,可对车载摄像头采集的视频流(如 .hevc 格式行车视频)进行解析,通过视觉算法识别道路车道线、规划安 -全行驶轨迹,为自动驾驶决策提供车道感知与路径引导支持。 -项目面向自动驾驶辅助系统(ADAS)的基础视觉感知模块,依赖系统底层库与 Python 机器学习 / 视觉处理工具链,可快速部署运行, -完成对行车视频的离线车道与路径分析,适用于自动驾驶算法验证、智能驾驶教学实验等场景。 +本项目基于 CARLA 仿真器(0.9.15 版本)实现了一套简易自动驾驶控制系统。系统通过摄像头数据检测交通信号灯,并控制车辆在红灯时停车、绿灯时通行。 +## 功能特性 +- **交通灯检测**:使用 RGB 摄像头与目标包围框实现交通灯识别 +- **启停逻辑**:车辆在红灯时自动停车,绿灯时自动恢复行驶 +- **自动驾驶控制**:根据交通灯状态自动调整油门与刹车 -# 操作系统 - Windows11 +## 使用技术 +- **仿真平台**:CARLA 仿真器 0.9.15 +- **编程语言**:Python 3.9 +- **依赖库**: + - pygame:用于渲染仿真界面 + - cv2(OpenCV):用于图像处理(可扩展功能) + - numpy、time、math、random:用于数值计算与时序控制 -# Python - python Version 3.7 - - pip Version 21.3.1 - - Setuptools Version & Install - - pip3 install setuptools==45.2.0 - - (高版本卸载命令pip3 uninstall setuptools) +## 工作原理 +1. **传感器配置** + 车辆搭载前置 RGB 摄像头及其他 CARLA 内置传感器。 -# 安装依赖 - 安装库文件 +2. **交通灯检测** + 脚本通过 CARLA 内置环境信息(目标包围框)检测交通灯, + 并判断信号灯状态(红灯/绿灯)。 - sudo apt install libssl-dev libcurl4-openssl-dev curl +3. **控制逻辑** + - 若前方检测到红灯,车辆自动刹车并停车 + - 若检测到绿灯或无有效红灯,车辆继续行驶 - sudo apt install libarchive-dev +## 运行方法 +1. 安装 Python 依赖库: + ```bash + pip install pygame opencv-python numpy + ``` +2. 使用方式: + 启动 `CarlaUE4.exe`(Windows 系统) -# 安装 - pip3 install -r requirements.txt +## 预期效果 +车辆在前方检测到红灯时平稳停车,绿灯亮起后恢复行驶,所有行为均由控制逻辑自动完成。 -# 运行程序 - python3 main.py ../sample.hevc +--- From 19eca7a487567a79c3d2733a20b8859dad45f991 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Wed, 22 Apr 2026 19:24:17 +0800 Subject: [PATCH 10/22] =?UTF-8?q?=E5=AE=89=E8=A3=85=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/carla_driving_car_lane/Requirements.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/carla_driving_car_lane/Requirements.txt diff --git a/src/carla_driving_car_lane/Requirements.txt b/src/carla_driving_car_lane/Requirements.txt new file mode 100644 index 0000000000..8437a15171 --- /dev/null +++ b/src/carla_driving_car_lane/Requirements.txt @@ -0,0 +1,9 @@ + +carla==0.9.15 +pygame==2.1.0 +numpy==1.23.5 +opencv-python==4.8.0.76 +matplotlib==3.7.1 +torch==2.0.0 # Only if you're using PyTorch for detection +torchvision==0.15.1 +Pillow==9.4.0 From 6bf2b7dcf580294f2020fe14a6f4f45f14585164 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Wed, 22 Apr 2026 22:12:25 +0800 Subject: [PATCH 11/22] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=90=AF=E5=8A=A8caela?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../start_carla_sim.bat | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/carla_driving_car_lane/start_carla_sim.bat diff --git a/src/carla_driving_car_lane/start_carla_sim.bat b/src/carla_driving_car_lane/start_carla_sim.bat new file mode 100644 index 0000000000..7383dbc8ae --- /dev/null +++ b/src/carla_driving_car_lane/start_carla_sim.bat @@ -0,0 +1,27 @@ +@echo off +chcp 65001 >nul 2>&1 +color 0A +mode con: cols=80 lines=25 +title CARLA AUTOPILOT + +echo ============================================== +echo CARLA 0.9.15 AUTOPILOT LAUNCHER +echo ============================================== +echo. + +echo Starting CARLA Simulator... +start "" "D:\carla0.9.15\CarlaUE4.exe" -quality-level=Low + +echo. +echo Waiting for CARLA server (15s)... +timeout /t 15 /nobreak >nul + +echo. +echo Starting autopilot script... +echo. + +"D:\carla_automatic1\.venv\Scripts\python.exe" "D:\carla_automatic1\automatic_control.py" + +echo. +echo Done. +pause From 8df8257889422f7b8d3086ce25a9bc019dea051a Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Thu, 23 Apr 2026 13:13:03 +0800 Subject: [PATCH 12/22] chuan --- .../automatic_control.py | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 src/carla_driving_car_lane/automatic_control.py diff --git a/src/carla_driving_car_lane/automatic_control.py b/src/carla_driving_car_lane/automatic_control.py new file mode 100644 index 0000000000..078bf9e2aa --- /dev/null +++ b/src/carla_driving_car_lane/automatic_control.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import argparse +import collections +import datetime +import glob +import logging +import math +import os +import random +import re +import sys +import weakref + +# --------------- Python 3.9 专用修复 --------------- +# 清理冲突路径 +for path in list(sys.path): + if "carla/dist" in path and path.endswith(".egg"): + sys.path.remove(path) + +# 正确添加 CARLA PythonAPI 路径 +CARLA_ROOT = r"D:\carla0.9.15" +sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI")) +sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI", "carla")) + +# ---------------- 依赖 ---------------- +try: + import pygame + from pygame.locals import KMOD_CTRL + from pygame.locals import K_ESCAPE + from pygame.locals import K_q +except ImportError: + raise RuntimeError('请安装: pip install pygame') + +try: + import numpy as np +except ImportError: + raise RuntimeError('请安装: pip install numpy') + +import carla +from carla import ColorConverter as cc + +# 导入自动驾驶代理 +from agents.navigation.behavior_agent import BehaviorAgent + + +# ============================================================================== +# -- 工具函数 +# ============================================================================== +def get_actor_display_name(actor, truncate=250): + name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) + return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + + +# ============================================================================== +# -- World 场景管理 +# ============================================================================== +class World(object): + def __init__(self, carla_world, hud, args): + self.world = carla_world + self.map = self.world.get_map() + self.hud = hud + self.player = None + self.collision_sensor = None + self.lane_invasion_sensor = None + self.gnss_sensor = None + self.camera_manager = None + self._actor_filter = args.filter + self.restart(args) + self.world.on_tick(hud.on_world_tick) + + def restart(self, args): + # 清理旧车辆 + if self.player is not None: + self.destroy() + + # 生成车辆 + blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) + blueprint.set_attribute('role_name', 'hero') + + while self.player is None: + spawn_point = random.choice(self.map.get_spawn_points()) + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + # 传感器(全部修复完成) + self.collision_sensor = CollisionSensor(self.player, self.hud) + self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) + self.gnss_sensor = GnssSensor(self.player) + self.camera_manager = CameraManager(self.player, self.hud) + self.camera_manager.set_sensor(0) + + def tick(self, clock): + self.hud.tick(clock) + + def render(self, display): + self.camera_manager.render(display) + self.hud.render(display) + + def destroy(self): + actors = [ + self.camera_manager.sensor, + self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, + self.gnss_sensor.sensor, + self.player] + for actor in actors: + if actor is not None and actor.is_alive: + actor.destroy() + + +# ============================================================================== +# -- 键盘控制 +# ============================================================================== +class KeyboardControl(object): + @staticmethod + def parse_events(): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return True + if event.type == pygame.KEYUP: + if event.key == K_ESCAPE or (event.key == K_q and pygame.key.get_mod() & KMOD_CTRL): + return True + return False + + +# ============================================================================== +# -- HUD 显示 +# ============================================================================== +class HUD(object): + def __init__(self, width, height): + self.dim = (width, height) + font = pygame.font.Font(pygame.font.get_default_font(), 16) + self._notifications = FadingText(font, (width, 40), (0, height - 40)) + self.server_fps = 0 + + def on_world_tick(self, timestamp): + self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) + + def tick(self, clock): + self._notifications.tick(clock) + + def notification(self, text, seconds=2): + self._notifications.set_text(text, seconds=seconds) + + def render(self, display): + self._notifications.render(display) + + +class FadingText(object): + def __init__(self, font, dim, pos): + self.font = font + self.dim = dim + self.pos = pos + self.seconds_left = 0 + self.surface = pygame.Surface(self.dim) + + def set_text(self, text, color=(255, 255, 255), seconds=2): + self.seconds_left = seconds + self.surface = self.font.render(text, True, color) + + def tick(self, clock): + self.seconds_left = max(0, self.seconds_left - clock.get_time() / 1000) + + def render(self, display): + display.blit(self.surface, self.pos) + + +# ============================================================================== +# -- 传感器(全部修复完成) +# ============================================================================== +class CollisionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.collision'), + carla.Transform(), attach_to=parent) + self.sensor.listen(lambda e: hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) + + +class LaneInvasionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.lane_invasion'), + carla.Transform(), attach_to=parent) + + +class GnssSensor(object): + def __init__(self, parent): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.gnss'), + carla.Transform(carla.Location(z=2.0)), attach_to=parent) + + +# ============================================================================== +# -- 相机 +# ============================================================================== +class CameraManager(object): + def __init__(self, parent, hud): + self.sensor = None + self.surface = None + self._parent = parent + self.hud = hud + self.index = 0 + + def set_sensor(self, index): + if self.sensor: self.sensor.destroy() + bp = self._parent.get_world().get_blueprint_library().find('sensor.camera.rgb') + bp.set_attribute('image_size_x', str(self.hud.dim[0])) + bp.set_attribute('image_size_y', str(self.hud.dim[1])) + + transform = carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)) + self.sensor = self._parent.get_world().spawn_actor( + bp, transform, attach_to=self._parent, attachment_type=carla.AttachmentType.SpringArm) + self.sensor.listen(lambda img: self._parse(img)) + + def _parse(self, image): + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape(image.height, image.width, 4)[:, :, :3] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) + + def render(self, display): + if self.surface: display.blit(self.surface, (0, 0)) + + +# ============================================================================== +# -- 主循环 +# ============================================================================== +def game_loop(args): + pygame.init() + pygame.font.init() + world = None + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(10.0) + display = pygame.display.set_mode((args.width, args.height)) + hud = HUD(args.width, args.height) + world = World(client.get_world(), hud, args) + + # 自动导航 + agent = BehaviorAgent(world.player, behavior=args.behavior) + spawn_points = world.map.get_spawn_points() + target = random.choice(spawn_points).location + agent.set_destination(target) + hud.notification("自动导航已启动", 3) + + clock = pygame.time.Clock() + + while True: + clock.tick_busy_loop(60) + if KeyboardControl.parse_events(): + return + + world.tick(clock) + world.render(display) + pygame.display.flip() + + # 自动驾驶控制 + control = agent.run_step() + world.player.apply_control(control) + + # 到达目标后自动换新目标 + if agent.done(): + new_target = random.choice(spawn_points).location + agent.set_destination(new_target) + hud.notification("已到达!前往下一个目标", 2) + + finally: + if world: + world.destroy() + pygame.quit() + + +# ============================================================================== +# -- 主函数 +# ============================================================================== +def main(): + argparser = argparse.ArgumentParser() + argparser.add_argument('--host', default='127.0.0.1') + argparser.add_argument('--port', default=2000, type=int) + argparser.add_argument('--res', default='1280x720') + argparser.add_argument('--filter', default='vehicle.*') + argparser.add_argument('--behavior', default='normal') + args = argparser.parse_args() + args.width, args.height = map(int, args.res.split('x')) + game_loop(args) + + +if __name__ == '__main__': + main() From ce90c9dfe7688c91af5d8f98560df98e30e27b7e Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Thu, 23 Apr 2026 13:16:01 +0800 Subject: [PATCH 13/22] c --- .../automatic_control/automatic_control.py | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 src/carla_driving_car_lane/automatic_control/automatic_control.py diff --git a/src/carla_driving_car_lane/automatic_control/automatic_control.py b/src/carla_driving_car_lane/automatic_control/automatic_control.py new file mode 100644 index 0000000000..078bf9e2aa --- /dev/null +++ b/src/carla_driving_car_lane/automatic_control/automatic_control.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import argparse +import collections +import datetime +import glob +import logging +import math +import os +import random +import re +import sys +import weakref + +# --------------- Python 3.9 专用修复 --------------- +# 清理冲突路径 +for path in list(sys.path): + if "carla/dist" in path and path.endswith(".egg"): + sys.path.remove(path) + +# 正确添加 CARLA PythonAPI 路径 +CARLA_ROOT = r"D:\carla0.9.15" +sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI")) +sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI", "carla")) + +# ---------------- 依赖 ---------------- +try: + import pygame + from pygame.locals import KMOD_CTRL + from pygame.locals import K_ESCAPE + from pygame.locals import K_q +except ImportError: + raise RuntimeError('请安装: pip install pygame') + +try: + import numpy as np +except ImportError: + raise RuntimeError('请安装: pip install numpy') + +import carla +from carla import ColorConverter as cc + +# 导入自动驾驶代理 +from agents.navigation.behavior_agent import BehaviorAgent + + +# ============================================================================== +# -- 工具函数 +# ============================================================================== +def get_actor_display_name(actor, truncate=250): + name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) + return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + + +# ============================================================================== +# -- World 场景管理 +# ============================================================================== +class World(object): + def __init__(self, carla_world, hud, args): + self.world = carla_world + self.map = self.world.get_map() + self.hud = hud + self.player = None + self.collision_sensor = None + self.lane_invasion_sensor = None + self.gnss_sensor = None + self.camera_manager = None + self._actor_filter = args.filter + self.restart(args) + self.world.on_tick(hud.on_world_tick) + + def restart(self, args): + # 清理旧车辆 + if self.player is not None: + self.destroy() + + # 生成车辆 + blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) + blueprint.set_attribute('role_name', 'hero') + + while self.player is None: + spawn_point = random.choice(self.map.get_spawn_points()) + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + # 传感器(全部修复完成) + self.collision_sensor = CollisionSensor(self.player, self.hud) + self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) + self.gnss_sensor = GnssSensor(self.player) + self.camera_manager = CameraManager(self.player, self.hud) + self.camera_manager.set_sensor(0) + + def tick(self, clock): + self.hud.tick(clock) + + def render(self, display): + self.camera_manager.render(display) + self.hud.render(display) + + def destroy(self): + actors = [ + self.camera_manager.sensor, + self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, + self.gnss_sensor.sensor, + self.player] + for actor in actors: + if actor is not None and actor.is_alive: + actor.destroy() + + +# ============================================================================== +# -- 键盘控制 +# ============================================================================== +class KeyboardControl(object): + @staticmethod + def parse_events(): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return True + if event.type == pygame.KEYUP: + if event.key == K_ESCAPE or (event.key == K_q and pygame.key.get_mod() & KMOD_CTRL): + return True + return False + + +# ============================================================================== +# -- HUD 显示 +# ============================================================================== +class HUD(object): + def __init__(self, width, height): + self.dim = (width, height) + font = pygame.font.Font(pygame.font.get_default_font(), 16) + self._notifications = FadingText(font, (width, 40), (0, height - 40)) + self.server_fps = 0 + + def on_world_tick(self, timestamp): + self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) + + def tick(self, clock): + self._notifications.tick(clock) + + def notification(self, text, seconds=2): + self._notifications.set_text(text, seconds=seconds) + + def render(self, display): + self._notifications.render(display) + + +class FadingText(object): + def __init__(self, font, dim, pos): + self.font = font + self.dim = dim + self.pos = pos + self.seconds_left = 0 + self.surface = pygame.Surface(self.dim) + + def set_text(self, text, color=(255, 255, 255), seconds=2): + self.seconds_left = seconds + self.surface = self.font.render(text, True, color) + + def tick(self, clock): + self.seconds_left = max(0, self.seconds_left - clock.get_time() / 1000) + + def render(self, display): + display.blit(self.surface, self.pos) + + +# ============================================================================== +# -- 传感器(全部修复完成) +# ============================================================================== +class CollisionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.collision'), + carla.Transform(), attach_to=parent) + self.sensor.listen(lambda e: hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) + + +class LaneInvasionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.lane_invasion'), + carla.Transform(), attach_to=parent) + + +class GnssSensor(object): + def __init__(self, parent): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.gnss'), + carla.Transform(carla.Location(z=2.0)), attach_to=parent) + + +# ============================================================================== +# -- 相机 +# ============================================================================== +class CameraManager(object): + def __init__(self, parent, hud): + self.sensor = None + self.surface = None + self._parent = parent + self.hud = hud + self.index = 0 + + def set_sensor(self, index): + if self.sensor: self.sensor.destroy() + bp = self._parent.get_world().get_blueprint_library().find('sensor.camera.rgb') + bp.set_attribute('image_size_x', str(self.hud.dim[0])) + bp.set_attribute('image_size_y', str(self.hud.dim[1])) + + transform = carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)) + self.sensor = self._parent.get_world().spawn_actor( + bp, transform, attach_to=self._parent, attachment_type=carla.AttachmentType.SpringArm) + self.sensor.listen(lambda img: self._parse(img)) + + def _parse(self, image): + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape(image.height, image.width, 4)[:, :, :3] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) + + def render(self, display): + if self.surface: display.blit(self.surface, (0, 0)) + + +# ============================================================================== +# -- 主循环 +# ============================================================================== +def game_loop(args): + pygame.init() + pygame.font.init() + world = None + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(10.0) + display = pygame.display.set_mode((args.width, args.height)) + hud = HUD(args.width, args.height) + world = World(client.get_world(), hud, args) + + # 自动导航 + agent = BehaviorAgent(world.player, behavior=args.behavior) + spawn_points = world.map.get_spawn_points() + target = random.choice(spawn_points).location + agent.set_destination(target) + hud.notification("自动导航已启动", 3) + + clock = pygame.time.Clock() + + while True: + clock.tick_busy_loop(60) + if KeyboardControl.parse_events(): + return + + world.tick(clock) + world.render(display) + pygame.display.flip() + + # 自动驾驶控制 + control = agent.run_step() + world.player.apply_control(control) + + # 到达目标后自动换新目标 + if agent.done(): + new_target = random.choice(spawn_points).location + agent.set_destination(new_target) + hud.notification("已到达!前往下一个目标", 2) + + finally: + if world: + world.destroy() + pygame.quit() + + +# ============================================================================== +# -- 主函数 +# ============================================================================== +def main(): + argparser = argparse.ArgumentParser() + argparser.add_argument('--host', default='127.0.0.1') + argparser.add_argument('--port', default=2000, type=int) + argparser.add_argument('--res', default='1280x720') + argparser.add_argument('--filter', default='vehicle.*') + argparser.add_argument('--behavior', default='normal') + args = argparser.parse_args() + args.width, args.height = map(int, args.res.split('x')) + game_loop(args) + + +if __name__ == '__main__': + main() From 869c85f744b62c5d1767990d5796478aa7b4c8da Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Thu, 23 Apr 2026 19:54:09 +0800 Subject: [PATCH 14/22] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=A9=BE=E9=A9=B6?= =?UTF-8?q?=E6=98=BE=E9=80=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../automatic_control/automatic2.0 | 322 ++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 src/carla_driving_car_lane/automatic_control/automatic2.0 diff --git a/src/carla_driving_car_lane/automatic_control/automatic2.0 b/src/carla_driving_car_lane/automatic_control/automatic2.0 new file mode 100644 index 0000000000..a1b277b65b --- /dev/null +++ b/src/carla_driving_car_lane/automatic_control/automatic2.0 @@ -0,0 +1,322 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import argparse +import collections +import datetime +import glob +import logging +import math +import os +import random +import re +import sys +import weakref +import threading + +# --------------- Python 3.9 专用修复 --------------- +# 清理冲突路径 +for path in list(sys.path): + if "carla/dist" in path and path.endswith(".egg"): + sys.path.remove(path) + +# 正确添加 CARLA PythonAPI 路径 +CARLA_ROOT = r"D:\carla0.9.15" +sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI")) +sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI", "carla")) + +# ---------------- 依赖 ---------------- +try: + import pygame + from pygame.locals import * +except ImportError: + raise RuntimeError('请安装: pip install pygame') + +try: + import numpy as np +except ImportError: + raise RuntimeError('请安装: pip install numpy') + +import carla +from carla import ColorConverter as cc + +# 导入自动驾驶代理 +from agents.navigation.behavior_agent import BehaviorAgent + + +# ============================================================================== +# -- 工具函数 +# ============================================================================== +def get_actor_display_name(actor, truncate=250): + name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) + return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + +def play_warning_sound(): + """车道偏离语音提醒(异步播放不卡顿)""" + def play(): + try: + pygame.mixer.init() + warning = pygame.mixer.Sound("warning.wav") + warning.play() + except: + pass + threading.Thread(target=play, daemon=True).start() + + +# ============================================================================== +# -- World 场景管理 +# ============================================================================== +class World(object): + def __init__(self, carla_world, hud, args): + self.world = carla_world + self.map = self.world.get_map() + self.hud = hud + self.player = None + self.collision_sensor = None + self.lane_invasion_sensor = None + self.gnss_sensor = None + self.camera_manager = None + self._actor_filter = args.filter + self.restart(args) + self.world.on_tick(hud.on_world_tick) + + def restart(self, args): + # 清理旧车辆 + if self.player is not None: + self.destroy() + + # 生成车辆 + blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) + blueprint.set_attribute('role_name', 'hero') + + while self.player is None: + spawn_point = random.choice(self.map.get_spawn_points()) + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + # 传感器 + self.collision_sensor = CollisionSensor(self.player, self.hud) + self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) + self.gnss_sensor = GnssSensor(self.player) + self.camera_manager = CameraManager(self.player, self.hud) + self.camera_manager.set_sensor(0) + + def tick(self, clock): + self.hud.tick(clock) + # 更新车速 + v = self.player.get_velocity() + speed = 3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2) + self.hud.speed = int(speed) + + def render(self, display): + self.camera_manager.render(display) + self.hud.render(display) + + def destroy(self): + actors = [ + self.camera_manager.sensor, + self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, + self.gnss_sensor.sensor, + self.player] + for actor in actors: + if actor is not None and actor.is_alive: + actor.destroy() + + +# ============================================================================== +# -- 键盘控制(新增 P 键切换自动驾驶) +# ============================================================================== +class KeyboardControl(object): + def __init__(self): + self.auto_pilot = True + + def parse_events(self): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return True + if event.type == pygame.KEYUP: + if event.key == K_ESCAPE or (event.key == K_q and pygame.key.get_mod() & KMOD_CTRL): + return True + if event.key == K_p: + self.auto_pilot = not self.auto_pilot + return False + + +# ============================================================================== +# -- HUD 显示(新增车速 + 模式显示) +# ============================================================================== +class HUD(object): + def __init__(self, width, height): + self.dim = (width, height) + self.font = pygame.font.Font(pygame.font.get_default_font(), 16) + self.font_big = pygame.font.Font(pygame.font.get_default_font(), 32) + self._notifications = FadingText(self.font, (width, 40), (0, height - 40)) + self.server_fps = 0 + self.speed = 0 + + def on_world_tick(self, timestamp): + self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) + + def tick(self, clock): + self._notifications.tick(clock) + + def notification(self, text, seconds=2): + self._notifications.set_text(text, seconds=seconds) + + def render(self, display): + # 车速 + speed_text = self.font_big.render(f"{self.speed} km/h", True, (0,255,255)) + display.blit(speed_text, (20,20)) + self._notifications.render(display) + + +class FadingText(object): + def __init__(self, font, dim, pos): + self.font = font + self.dim = dim + self.pos = pos + self.seconds_left = 0 + self.surface = pygame.Surface(self.dim) + + def set_text(self, text, color=(255, 255, 255), seconds=2): + self.seconds_left = seconds + self.surface = self.font.render(text, True, color) + + def tick(self, clock): + self.seconds_left = max(0, self.seconds_left - clock.get_time() / 1000) + + def render(self, display): + display.blit(self.surface, self.pos) + + +# ============================================================================== +# -- 传感器 +# ============================================================================== +class CollisionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.collision'), + carla.Transform(), attach_to=parent) + self.sensor.listen(lambda e: hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) + + +class LaneInvasionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.lane_invasion'), + carla.Transform(), attach_to=parent) + self.sensor.listen(lambda e: self._on_lane(e, hud)) + + def _on_lane(self, event, hud): + hud.notification("车道偏离!") + play_warning_sound() + + +class GnssSensor(object): + def __init__(self, parent): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.gnss'), + carla.Transform(carla.Location(z=2.0)), attach_to=parent) + + +# ============================================================================== +# -- 相机 +# ============================================================================== +class CameraManager(object): + def __init__(self, parent, hud): + self.sensor = None + self.surface = None + self._parent = parent + self.hud = hud + self.index = 0 + + def set_sensor(self, index): + if self.sensor: self.sensor.destroy() + bp = self._parent.get_world().get_blueprint_library().find('sensor.camera.rgb') + bp.set_attribute('image_size_x', str(self.hud.dim[0])) + bp.set_attribute('image_size_y', str(self.hud.dim[1])) + + transform = carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)) + self.sensor = self._parent.get_world().spawn_actor( + bp, transform, attach_to=self._parent, attachment_type=carla.AttachmentType.SpringArm) + self.sensor.listen(lambda img: self._parse(img)) + + def _parse(self, image): + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape(image.height, image.width, 4)[:, :, :3] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) + + def render(self, display): + if self.surface: display.blit(self.surface, (0, 0)) + + +# ============================================================================== +# -- 主循环 +# ============================================================================== +def game_loop(args): + pygame.init() + pygame.font.init() + world = None + controller = KeyboardControl() + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(10.0) + display = pygame.display.set_mode((args.width, args.height)) + hud = HUD(args.width, args.height) + world = World(client.get_world(), hud, args) + + # 自动导航 + agent = BehaviorAgent(world.player, behavior=args.behavior) + spawn_points = world.map.get_spawn_points() + target = random.choice(spawn_points).location + agent.set_destination(target) + hud.notification("自动导航已启动", 3) + + clock = pygame.time.Clock() + + while True: + clock.tick_busy_loop(60) + if controller.parse_events(): + return + + world.tick(clock) + world.render(display) + pygame.display.flip() + + # 自动驾驶开关 + if controller.auto_pilot: + control = agent.run_step() + world.player.apply_control(control) + hud.notification("模式:自动驾驶", 1) + # 到达目标换新 + if agent.done(): + new_target = random.choice(spawn_points).location + agent.set_destination(new_target) + else: + hud.notification("模式:手动驾驶", 1) + + finally: + if world: + world.destroy() + pygame.quit() + + +# ============================================================================== +# -- 主函数 +# ============================================================================== +def main(): + argparser = argparse.ArgumentParser() + argparser.add_argument('--host', default='127.0.0.1') + argparser.add_argument('--port', default=2000, type=int) + argparser.add_argument('--res', default='1280x720') + argparser.add_argument('--filter', default='vehicle.*') + argparser.add_argument('--behavior', default='normal') + args = argparser.parse_args() + args.width, args.height = map(int, args.res.split('x')) + game_loop(args) + + +if __name__ == '__main__': + main() From 92201d4f187c9ca4feb53ba14f7c2a0e57beff6f Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Fri, 24 Apr 2026 22:07:36 +0800 Subject: [PATCH 15/22] Delete src/carla_driving_car_lane/automatic_control/automatic_control.py --- .../automatic_control/automatic_control.py | 291 ------------------ 1 file changed, 291 deletions(-) delete mode 100644 src/carla_driving_car_lane/automatic_control/automatic_control.py diff --git a/src/carla_driving_car_lane/automatic_control/automatic_control.py b/src/carla_driving_car_lane/automatic_control/automatic_control.py deleted file mode 100644 index 078bf9e2aa..0000000000 --- a/src/carla_driving_car_lane/automatic_control/automatic_control.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function - -import argparse -import collections -import datetime -import glob -import logging -import math -import os -import random -import re -import sys -import weakref - -# --------------- Python 3.9 专用修复 --------------- -# 清理冲突路径 -for path in list(sys.path): - if "carla/dist" in path and path.endswith(".egg"): - sys.path.remove(path) - -# 正确添加 CARLA PythonAPI 路径 -CARLA_ROOT = r"D:\carla0.9.15" -sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI")) -sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI", "carla")) - -# ---------------- 依赖 ---------------- -try: - import pygame - from pygame.locals import KMOD_CTRL - from pygame.locals import K_ESCAPE - from pygame.locals import K_q -except ImportError: - raise RuntimeError('请安装: pip install pygame') - -try: - import numpy as np -except ImportError: - raise RuntimeError('请安装: pip install numpy') - -import carla -from carla import ColorConverter as cc - -# 导入自动驾驶代理 -from agents.navigation.behavior_agent import BehaviorAgent - - -# ============================================================================== -# -- 工具函数 -# ============================================================================== -def get_actor_display_name(actor, truncate=250): - name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) - return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name - - -# ============================================================================== -# -- World 场景管理 -# ============================================================================== -class World(object): - def __init__(self, carla_world, hud, args): - self.world = carla_world - self.map = self.world.get_map() - self.hud = hud - self.player = None - self.collision_sensor = None - self.lane_invasion_sensor = None - self.gnss_sensor = None - self.camera_manager = None - self._actor_filter = args.filter - self.restart(args) - self.world.on_tick(hud.on_world_tick) - - def restart(self, args): - # 清理旧车辆 - if self.player is not None: - self.destroy() - - # 生成车辆 - blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) - blueprint.set_attribute('role_name', 'hero') - - while self.player is None: - spawn_point = random.choice(self.map.get_spawn_points()) - self.player = self.world.try_spawn_actor(blueprint, spawn_point) - - # 传感器(全部修复完成) - self.collision_sensor = CollisionSensor(self.player, self.hud) - self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) - self.gnss_sensor = GnssSensor(self.player) - self.camera_manager = CameraManager(self.player, self.hud) - self.camera_manager.set_sensor(0) - - def tick(self, clock): - self.hud.tick(clock) - - def render(self, display): - self.camera_manager.render(display) - self.hud.render(display) - - def destroy(self): - actors = [ - self.camera_manager.sensor, - self.collision_sensor.sensor, - self.lane_invasion_sensor.sensor, - self.gnss_sensor.sensor, - self.player] - for actor in actors: - if actor is not None and actor.is_alive: - actor.destroy() - - -# ============================================================================== -# -- 键盘控制 -# ============================================================================== -class KeyboardControl(object): - @staticmethod - def parse_events(): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - return True - if event.type == pygame.KEYUP: - if event.key == K_ESCAPE or (event.key == K_q and pygame.key.get_mod() & KMOD_CTRL): - return True - return False - - -# ============================================================================== -# -- HUD 显示 -# ============================================================================== -class HUD(object): - def __init__(self, width, height): - self.dim = (width, height) - font = pygame.font.Font(pygame.font.get_default_font(), 16) - self._notifications = FadingText(font, (width, 40), (0, height - 40)) - self.server_fps = 0 - - def on_world_tick(self, timestamp): - self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) - - def tick(self, clock): - self._notifications.tick(clock) - - def notification(self, text, seconds=2): - self._notifications.set_text(text, seconds=seconds) - - def render(self, display): - self._notifications.render(display) - - -class FadingText(object): - def __init__(self, font, dim, pos): - self.font = font - self.dim = dim - self.pos = pos - self.seconds_left = 0 - self.surface = pygame.Surface(self.dim) - - def set_text(self, text, color=(255, 255, 255), seconds=2): - self.seconds_left = seconds - self.surface = self.font.render(text, True, color) - - def tick(self, clock): - self.seconds_left = max(0, self.seconds_left - clock.get_time() / 1000) - - def render(self, display): - display.blit(self.surface, self.pos) - - -# ============================================================================== -# -- 传感器(全部修复完成) -# ============================================================================== -class CollisionSensor(object): - def __init__(self, parent, hud): - self.sensor = parent.get_world().spawn_actor( - parent.get_world().get_blueprint_library().find('sensor.other.collision'), - carla.Transform(), attach_to=parent) - self.sensor.listen(lambda e: hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) - - -class LaneInvasionSensor(object): - def __init__(self, parent, hud): - self.sensor = parent.get_world().spawn_actor( - parent.get_world().get_blueprint_library().find('sensor.other.lane_invasion'), - carla.Transform(), attach_to=parent) - - -class GnssSensor(object): - def __init__(self, parent): - self.sensor = parent.get_world().spawn_actor( - parent.get_world().get_blueprint_library().find('sensor.other.gnss'), - carla.Transform(carla.Location(z=2.0)), attach_to=parent) - - -# ============================================================================== -# -- 相机 -# ============================================================================== -class CameraManager(object): - def __init__(self, parent, hud): - self.sensor = None - self.surface = None - self._parent = parent - self.hud = hud - self.index = 0 - - def set_sensor(self, index): - if self.sensor: self.sensor.destroy() - bp = self._parent.get_world().get_blueprint_library().find('sensor.camera.rgb') - bp.set_attribute('image_size_x', str(self.hud.dim[0])) - bp.set_attribute('image_size_y', str(self.hud.dim[1])) - - transform = carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)) - self.sensor = self._parent.get_world().spawn_actor( - bp, transform, attach_to=self._parent, attachment_type=carla.AttachmentType.SpringArm) - self.sensor.listen(lambda img: self._parse(img)) - - def _parse(self, image): - array = np.frombuffer(image.raw_data, dtype=np.uint8) - array = array.reshape(image.height, image.width, 4)[:, :, :3] - self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) - - def render(self, display): - if self.surface: display.blit(self.surface, (0, 0)) - - -# ============================================================================== -# -- 主循环 -# ============================================================================== -def game_loop(args): - pygame.init() - pygame.font.init() - world = None - - try: - client = carla.Client(args.host, args.port) - client.set_timeout(10.0) - display = pygame.display.set_mode((args.width, args.height)) - hud = HUD(args.width, args.height) - world = World(client.get_world(), hud, args) - - # 自动导航 - agent = BehaviorAgent(world.player, behavior=args.behavior) - spawn_points = world.map.get_spawn_points() - target = random.choice(spawn_points).location - agent.set_destination(target) - hud.notification("自动导航已启动", 3) - - clock = pygame.time.Clock() - - while True: - clock.tick_busy_loop(60) - if KeyboardControl.parse_events(): - return - - world.tick(clock) - world.render(display) - pygame.display.flip() - - # 自动驾驶控制 - control = agent.run_step() - world.player.apply_control(control) - - # 到达目标后自动换新目标 - if agent.done(): - new_target = random.choice(spawn_points).location - agent.set_destination(new_target) - hud.notification("已到达!前往下一个目标", 2) - - finally: - if world: - world.destroy() - pygame.quit() - - -# ============================================================================== -# -- 主函数 -# ============================================================================== -def main(): - argparser = argparse.ArgumentParser() - argparser.add_argument('--host', default='127.0.0.1') - argparser.add_argument('--port', default=2000, type=int) - argparser.add_argument('--res', default='1280x720') - argparser.add_argument('--filter', default='vehicle.*') - argparser.add_argument('--behavior', default='normal') - args = argparser.parse_args() - args.width, args.height = map(int, args.res.split('x')) - game_loop(args) - - -if __name__ == '__main__': - main() From a1fefb740e25fbb4b88c5f4808c0e83fc933abc1 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Mon, 27 Apr 2026 18:05:57 +0800 Subject: [PATCH 16/22] Rename automatic2.0 to automatic2.py --- .../automatic_control/{automatic2.0 => automatic2.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/carla_driving_car_lane/automatic_control/{automatic2.0 => automatic2.py} (100%) diff --git a/src/carla_driving_car_lane/automatic_control/automatic2.0 b/src/carla_driving_car_lane/automatic_control/automatic2.py similarity index 100% rename from src/carla_driving_car_lane/automatic_control/automatic2.0 rename to src/carla_driving_car_lane/automatic_control/automatic2.py From 25aaef372719dc6e9408cdadb6d865c275e0b328 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Tue, 28 Apr 2026 00:04:28 +0800 Subject: [PATCH 17/22] Delete src/carla_driving_car_lane/automatic_control directory --- .../automatic_control/automatic2.py | 322 ------------------ 1 file changed, 322 deletions(-) delete mode 100644 src/carla_driving_car_lane/automatic_control/automatic2.py diff --git a/src/carla_driving_car_lane/automatic_control/automatic2.py b/src/carla_driving_car_lane/automatic_control/automatic2.py deleted file mode 100644 index a1b277b65b..0000000000 --- a/src/carla_driving_car_lane/automatic_control/automatic2.py +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function - -import argparse -import collections -import datetime -import glob -import logging -import math -import os -import random -import re -import sys -import weakref -import threading - -# --------------- Python 3.9 专用修复 --------------- -# 清理冲突路径 -for path in list(sys.path): - if "carla/dist" in path and path.endswith(".egg"): - sys.path.remove(path) - -# 正确添加 CARLA PythonAPI 路径 -CARLA_ROOT = r"D:\carla0.9.15" -sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI")) -sys.path.append(os.path.join(CARLA_ROOT, "PythonAPI", "carla")) - -# ---------------- 依赖 ---------------- -try: - import pygame - from pygame.locals import * -except ImportError: - raise RuntimeError('请安装: pip install pygame') - -try: - import numpy as np -except ImportError: - raise RuntimeError('请安装: pip install numpy') - -import carla -from carla import ColorConverter as cc - -# 导入自动驾驶代理 -from agents.navigation.behavior_agent import BehaviorAgent - - -# ============================================================================== -# -- 工具函数 -# ============================================================================== -def get_actor_display_name(actor, truncate=250): - name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) - return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name - -def play_warning_sound(): - """车道偏离语音提醒(异步播放不卡顿)""" - def play(): - try: - pygame.mixer.init() - warning = pygame.mixer.Sound("warning.wav") - warning.play() - except: - pass - threading.Thread(target=play, daemon=True).start() - - -# ============================================================================== -# -- World 场景管理 -# ============================================================================== -class World(object): - def __init__(self, carla_world, hud, args): - self.world = carla_world - self.map = self.world.get_map() - self.hud = hud - self.player = None - self.collision_sensor = None - self.lane_invasion_sensor = None - self.gnss_sensor = None - self.camera_manager = None - self._actor_filter = args.filter - self.restart(args) - self.world.on_tick(hud.on_world_tick) - - def restart(self, args): - # 清理旧车辆 - if self.player is not None: - self.destroy() - - # 生成车辆 - blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) - blueprint.set_attribute('role_name', 'hero') - - while self.player is None: - spawn_point = random.choice(self.map.get_spawn_points()) - self.player = self.world.try_spawn_actor(blueprint, spawn_point) - - # 传感器 - self.collision_sensor = CollisionSensor(self.player, self.hud) - self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) - self.gnss_sensor = GnssSensor(self.player) - self.camera_manager = CameraManager(self.player, self.hud) - self.camera_manager.set_sensor(0) - - def tick(self, clock): - self.hud.tick(clock) - # 更新车速 - v = self.player.get_velocity() - speed = 3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2) - self.hud.speed = int(speed) - - def render(self, display): - self.camera_manager.render(display) - self.hud.render(display) - - def destroy(self): - actors = [ - self.camera_manager.sensor, - self.collision_sensor.sensor, - self.lane_invasion_sensor.sensor, - self.gnss_sensor.sensor, - self.player] - for actor in actors: - if actor is not None and actor.is_alive: - actor.destroy() - - -# ============================================================================== -# -- 键盘控制(新增 P 键切换自动驾驶) -# ============================================================================== -class KeyboardControl(object): - def __init__(self): - self.auto_pilot = True - - def parse_events(self): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - return True - if event.type == pygame.KEYUP: - if event.key == K_ESCAPE or (event.key == K_q and pygame.key.get_mod() & KMOD_CTRL): - return True - if event.key == K_p: - self.auto_pilot = not self.auto_pilot - return False - - -# ============================================================================== -# -- HUD 显示(新增车速 + 模式显示) -# ============================================================================== -class HUD(object): - def __init__(self, width, height): - self.dim = (width, height) - self.font = pygame.font.Font(pygame.font.get_default_font(), 16) - self.font_big = pygame.font.Font(pygame.font.get_default_font(), 32) - self._notifications = FadingText(self.font, (width, 40), (0, height - 40)) - self.server_fps = 0 - self.speed = 0 - - def on_world_tick(self, timestamp): - self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) - - def tick(self, clock): - self._notifications.tick(clock) - - def notification(self, text, seconds=2): - self._notifications.set_text(text, seconds=seconds) - - def render(self, display): - # 车速 - speed_text = self.font_big.render(f"{self.speed} km/h", True, (0,255,255)) - display.blit(speed_text, (20,20)) - self._notifications.render(display) - - -class FadingText(object): - def __init__(self, font, dim, pos): - self.font = font - self.dim = dim - self.pos = pos - self.seconds_left = 0 - self.surface = pygame.Surface(self.dim) - - def set_text(self, text, color=(255, 255, 255), seconds=2): - self.seconds_left = seconds - self.surface = self.font.render(text, True, color) - - def tick(self, clock): - self.seconds_left = max(0, self.seconds_left - clock.get_time() / 1000) - - def render(self, display): - display.blit(self.surface, self.pos) - - -# ============================================================================== -# -- 传感器 -# ============================================================================== -class CollisionSensor(object): - def __init__(self, parent, hud): - self.sensor = parent.get_world().spawn_actor( - parent.get_world().get_blueprint_library().find('sensor.other.collision'), - carla.Transform(), attach_to=parent) - self.sensor.listen(lambda e: hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) - - -class LaneInvasionSensor(object): - def __init__(self, parent, hud): - self.sensor = parent.get_world().spawn_actor( - parent.get_world().get_blueprint_library().find('sensor.other.lane_invasion'), - carla.Transform(), attach_to=parent) - self.sensor.listen(lambda e: self._on_lane(e, hud)) - - def _on_lane(self, event, hud): - hud.notification("车道偏离!") - play_warning_sound() - - -class GnssSensor(object): - def __init__(self, parent): - self.sensor = parent.get_world().spawn_actor( - parent.get_world().get_blueprint_library().find('sensor.other.gnss'), - carla.Transform(carla.Location(z=2.0)), attach_to=parent) - - -# ============================================================================== -# -- 相机 -# ============================================================================== -class CameraManager(object): - def __init__(self, parent, hud): - self.sensor = None - self.surface = None - self._parent = parent - self.hud = hud - self.index = 0 - - def set_sensor(self, index): - if self.sensor: self.sensor.destroy() - bp = self._parent.get_world().get_blueprint_library().find('sensor.camera.rgb') - bp.set_attribute('image_size_x', str(self.hud.dim[0])) - bp.set_attribute('image_size_y', str(self.hud.dim[1])) - - transform = carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)) - self.sensor = self._parent.get_world().spawn_actor( - bp, transform, attach_to=self._parent, attachment_type=carla.AttachmentType.SpringArm) - self.sensor.listen(lambda img: self._parse(img)) - - def _parse(self, image): - array = np.frombuffer(image.raw_data, dtype=np.uint8) - array = array.reshape(image.height, image.width, 4)[:, :, :3] - self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) - - def render(self, display): - if self.surface: display.blit(self.surface, (0, 0)) - - -# ============================================================================== -# -- 主循环 -# ============================================================================== -def game_loop(args): - pygame.init() - pygame.font.init() - world = None - controller = KeyboardControl() - - try: - client = carla.Client(args.host, args.port) - client.set_timeout(10.0) - display = pygame.display.set_mode((args.width, args.height)) - hud = HUD(args.width, args.height) - world = World(client.get_world(), hud, args) - - # 自动导航 - agent = BehaviorAgent(world.player, behavior=args.behavior) - spawn_points = world.map.get_spawn_points() - target = random.choice(spawn_points).location - agent.set_destination(target) - hud.notification("自动导航已启动", 3) - - clock = pygame.time.Clock() - - while True: - clock.tick_busy_loop(60) - if controller.parse_events(): - return - - world.tick(clock) - world.render(display) - pygame.display.flip() - - # 自动驾驶开关 - if controller.auto_pilot: - control = agent.run_step() - world.player.apply_control(control) - hud.notification("模式:自动驾驶", 1) - # 到达目标换新 - if agent.done(): - new_target = random.choice(spawn_points).location - agent.set_destination(new_target) - else: - hud.notification("模式:手动驾驶", 1) - - finally: - if world: - world.destroy() - pygame.quit() - - -# ============================================================================== -# -- 主函数 -# ============================================================================== -def main(): - argparser = argparse.ArgumentParser() - argparser.add_argument('--host', default='127.0.0.1') - argparser.add_argument('--port', default=2000, type=int) - argparser.add_argument('--res', default='1280x720') - argparser.add_argument('--filter', default='vehicle.*') - argparser.add_argument('--behavior', default='normal') - args = argparser.parse_args() - args.width, args.height = map(int, args.res.split('x')) - game_loop(args) - - -if __name__ == '__main__': - main() From fad52c333d7e3590dee66bd70ba61b2043a59621 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Tue, 28 Apr 2026 00:24:00 +0800 Subject: [PATCH 18/22] =?UTF-8?q?=E6=94=B9=E5=8F=98=E5=A4=A9=E6=B0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Add_weather_switching.py | 342 ++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 src/carla_driving_car_lane/Add_weather_switching.py diff --git a/src/carla_driving_car_lane/Add_weather_switching.py b/src/carla_driving_car_lane/Add_weather_switching.py new file mode 100644 index 0000000000..28cb478900 --- /dev/null +++ b/src/carla_driving_car_lane/Add_weather_switching.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python + +# Copyright (c) 2018 Intel Labs. +# authors: German Ros (german.ros@gmail.com) +# +# This work is licensed under the terms of the MIT license. +# For a copy, see + +"""Example of automatic vehicle control from client side.""" + +from __future__ import print_function + +import argparse +import collections +import datetime +import glob +import logging +import math +import os +import random +import re +import sys +import weakref + +# ========================================== +# 适配你的路径 D:\carla0.9.15 +# ========================================== +CARLA_ROOT = r"D:\carla0.9.15" +PYTHON_API = os.path.join(CARLA_ROOT, "PythonAPI") +sys.path.append(PYTHON_API) +sys.path.append(os.path.join(PYTHON_API, "carla")) + +try: + eggs = glob.glob(os.path.join(PYTHON_API, "carla", "dist", "*.egg")) + for e in eggs: + sys.path.append(e) +except: + pass + +# ================= 依赖导入 ================= +try: + import pygame + from pygame.locals import * +except ImportError: + raise RuntimeError('请安装:pip install pygame') + +try: + import numpy as np +except ImportError: + raise RuntimeError('请安装:pip install numpy') + +import carla +from carla import ColorConverter as cc + +from agents.navigation.behavior_agent import BehaviorAgent + +# ============================================================================== +# -- Global functions +# ============================================================================== +def find_weather_presets(): + rgx = re.compile('.+?(?:(?<=[a-z])(?=[A-Z])|(?=[A-Z])(?=[A-Z][a-z])|$)') + def name(x): return ' '.join(m.group(0) for m in rgx.finditer(x)) + presets = [x for x in dir(carla.WeatherParameters) if re.match('[A-Z].+', x)] + return [(getattr(carla.WeatherParameters, x), name(x)) for x in presets] + +def get_actor_display_name(actor, truncate=250): + name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) + return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + +# ============================================================================== +# -- World +# ============================================================================== +class World(object): + def __init__(self, carla_world, hud, args): + self.world = carla_world + self.map = self.world.get_map() + self.hud = hud + self.player = None + self.collision_sensor = None + self.lane_invasion_sensor = None + self.gnss_sensor = None + self.camera_manager = None + self._weather_presets = find_weather_presets() + self._weather_index = 0 + self._actor_filter = args.filter + self._gamma = 2.2 + self.restart(args) + self.world.on_tick(hud.on_world_tick) + + def restart(self, args): + cam_index = self.camera_manager.index if self.camera_manager else 0 + cam_pos_id = self.camera_manager.transform_index if self.camera_manager else 0 + + blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter)) + blueprint.set_attribute('role_name', 'hero') + + if self.player is not None: + spawn_point = self.player.get_transform() + spawn_point.location.z += 2.0 + self.destroy() + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + while self.player is None: + spawn_point = random.choice(self.map.get_spawn_points()) + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + self.collision_sensor = CollisionSensor(self.player, self.hud) + self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) + self.gnss_sensor = GnssSensor(self.player) + self.camera_manager = CameraManager(self.player, self.hud, self._gamma) + self.camera_manager.transform_index = cam_pos_id + self.camera_manager.set_sensor(cam_index, notify=False) + + def next_weather(self, reverse=False): + self._weather_index += -1 if reverse else 1 + self._weather_index %= len(self._weather_presets) + preset = self._weather_presets[self._weather_index] + self.hud.notification('Weather: %s' % preset[1]) + self.world.set_weather(preset[0]) + + def tick(self, clock): + self.hud.tick(clock) + + def render(self, display): + self.camera_manager.render(display) + self.hud.render(display) + + def destroy(self): + actors = [ + self.camera_manager.sensor, + self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, + self.gnss_sensor.sensor, + self.player] + for actor in actors: + if actor is not None: + actor.destroy() + +# ============================================================================== +# -- KeyboardControl +# ============================================================================== +class KeyboardControl(object): + def __init__(self, world): + world.hud.notification("Press ESC or Ctrl+Q to quit", seconds=2) + world.hud.notification("PageUp / PageDown: Change Weather", seconds=2) + + def parse_events(self, world): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return True + if event.type == pygame.KEYUP: + if self._is_quit_shortcut(event.key): + return True + if event.key == K_PAGEUP: + world.next_weather(reverse=True) + if event.key == K_PAGEDOWN: + world.next_weather() + return False + + @staticmethod + def _is_quit_shortcut(key): + return key == K_ESCAPE or (key == K_q and pygame.key.get_mod() & KMOD_CTRL) + +# ============================================================================== +# -- HUD +# ============================================================================== +class HUD(object): + def __init__(self, width, height): + self.dim = (width, height) + font = pygame.font.Font(pygame.font.get_default_font(), 16) + self._notifications = FadingText(font, (width, 40), (0, height - 40)) + self.server_fps = 0 + self.frame = 0 + self.simulation_time = 0 + self._show_info = True + + def on_world_tick(self, timestamp): + self.server_fps = 1.0 / timestamp.delta_seconds + self.frame = timestamp.frame_count + self.simulation_time = timestamp.elapsed_seconds + + def tick(self, clock): + self._notifications.tick(clock) + + def notification(self, text, seconds=2): + self._notifications.set_text(text, seconds=seconds) + + def error(self, text): + self._notifications.set_text('Error: %s' % text, (255, 0, 0)) + + def render(self, display): + self._notifications.render(display) + +# ============================================================================== +# -- FadingText +# ============================================================================== +class FadingText(object): + def __init__(self, font, dim, pos): + self.font = font + self.dim = dim + self.pos = pos + self.seconds_left = 0 + self.surface = pygame.Surface(self.dim) + + def set_text(self, text, color=(255, 255, 255), seconds=2.0): + self.seconds_left = seconds + self.surface = self.font.render(text, True, color) + + def tick(self, clock): + self.seconds_left = max(0.0, self.seconds_left - clock.get_time() / 1000.0) + + def render(self, display): + display.blit(self.surface, self.pos) + +# ============================================================================== +# -- CollisionSensor +# ============================================================================== +class CollisionSensor(object): + def __init__(self, parent_actor, hud): + self.sensor = None + self._parent = parent_actor + self.hud = hud + bp = parent_actor.get_world().get_blueprint_library().find('sensor.other.collision') + self.sensor = parent_actor.get_world().spawn_actor(bp, carla.Transform(), attach_to=parent_actor) + self.sensor.listen(lambda e: self.hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) + +# ============================================================================== +# -- LaneInvasionSensor +# ============================================================================== +class LaneInvasionSensor(object): + def __init__(self, parent_actor, hud): + self.sensor = None + bp = parent_actor.get_world().get_blueprint_library().find('sensor.other.lane_invasion') + self.sensor = parent_actor.get_world().spawn_actor(bp, carla.Transform(), attach_to=parent_actor) + +# ============================================================================== +# -- GnssSensor +# ============================================================================== +class GnssSensor(object): + def __init__(self, parent_actor): + self.sensor = None + self.lat = self.lon = 0.0 + bp = parent_actor.get_world().get_blueprint_library().find('sensor.other.gnss') + self.sensor = parent_actor.get_world().spawn_actor(bp, carla.Transform(carla.Location(z=2.0)), attach_to=parent_actor) + +# ============================================================================== +# -- CameraManager +# ============================================================================== +class CameraManager(object): + def __init__(self, parent_actor, hud, gamma): + self.sensor = None + self.surface = None + self._parent = parent_actor + self.hud = hud + self.transform_index = 0 + self._camera_transforms = [ + (carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8)), carla.AttachmentType.SpringArm) + ] + self.sensors = [['sensor.camera.rgb', cc.Raw, 'RGB']] + world = parent_actor.get_world() + for item in self.sensors: + b = world.get_blueprint_library().find(item[0]) + b.set_attribute('image_size_x', str(hud.dim[0])) + b.set_attribute('image_size_y', str(hud.dim[1])) + item.append(b) + self.index = None + + def set_sensor(self, index, notify=True): + if self.sensor: + self.sensor.destroy() + self.sensor = self._parent.get_world().spawn_actor( + self.sensors[0][-1], + self._camera_transforms[0][0], + attach_to=self._parent + ) + self.sensor.listen(lambda img: self._parse_image(img)) + self.index = 0 + + def _parse_image(self, image): + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape(image.height, image.width, 4)[:, :, :3] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)[:, :, ::-1]) + + def render(self, display): + if self.surface: + display.blit(self.surface, (0, 0)) + +# ============================================================================== +# -- Game Loop +# ============================================================================== +def game_loop(args): + pygame.init() + pygame.font.init() + world = None + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(10.0) + display = pygame.display.set_mode((args.width, args.height), pygame.HWSURFACE | pygame.DOUBLEBUF) + hud = HUD(args.width, args.height) + world = World(client.get_world(), hud, args) + controller = KeyboardControl(world) + + agent = BehaviorAgent(world.player, behavior=args.behavior) + spawn_points = world.map.get_spawn_points() + agent.set_destination(random.choice(spawn_points).location) + + clock = pygame.time.Clock() + + while True: + clock.tick_busy_loop(60) + if controller.parse_events(world): + return + + world.tick(clock) + world.render(display) + pygame.display.flip() + + control = agent.run_step() + world.player.apply_control(control) + + finally: + if world: + world.destroy() + pygame.quit() + +# ============================================================================== +# -- main() +# ============================================================================== +def main(): + argparser = argparse.ArgumentParser(description='CARLA Automatic Control Client') + argparser.add_argument('--host', default='127.0.0.1') + argparser.add_argument('--port', default=2000, type=int) + argparser.add_argument('--res', default='1280x720') + argparser.add_argument('--filter', default='vehicle.*') + argparser.add_argument('-b', '--behavior', default='normal') + args = argparser.parse_args() + args.width, args.height = map(int, args.res.split('x')) + game_loop(args) + +if __name__ == '__main__': + main() From ec71263e02b9ec2bcedb301cfd52107fe013c1be Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Tue, 28 Apr 2026 23:28:26 +0800 Subject: [PATCH 19/22] =?UTF-8?q?=E5=9D=90=E6=A0=87=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../World_Coordinate.py | 417 ++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 src/carla_driving_car_lane/World_Coordinate.py diff --git a/src/carla_driving_car_lane/World_Coordinate.py b/src/carla_driving_car_lane/World_Coordinate.py new file mode 100644 index 0000000000..7c7195eba2 --- /dev/null +++ b/src/carla_driving_car_lane/World_Coordinate.py @@ -0,0 +1,417 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2018 Intel Labs. +# authors: German Ros (german.ros@gmail.com) +# This work is licensed under the terms of the MIT license. +# For a copy, see + +""" +CARLA Automatic Control Client +适配:Python 3.9 + CARLA 0.9.15 +功能:自动导航行驶 + 传感器 + HUD 显示 +""" + +from __future__ import print_function + +import argparse +import collections +import datetime +import glob +import logging +import math +import os +import random +import re +import sys +import time +import weakref + +# ========================================== +# 你的 CARLA 路径(保持不变) +# ========================================== +CARLA_ROOT = r"D:\carla0.9.15" +PYTHON_API = os.path.join(CARLA_ROOT, "PythonAPI") +sys.path.append(PYTHON_API) +sys.path.append(os.path.join(PYTHON_API, "carla")) + +try: + eggs = glob.glob(os.path.join(PYTHON_API, "carla", "dist", "*.egg")) + for e in eggs: + sys.path.append(e) +except: + pass + +# ================= 依赖 ================= +try: + import pygame + from pygame.locals import K_ESCAPE, K_q, KMOD_CTRL, K_PAGEUP, K_PAGEDOWN +except ImportError: + raise RuntimeError('请安装:pip install pygame') + +try: + import numpy as np +except ImportError: + raise RuntimeError('请安装:pip install numpy') + +import carla +from carla import ColorConverter as cc + +from agents.navigation.behavior_agent import BehaviorAgent + +# ============================================================================== +# -- Global functions +# ============================================================================== +def find_weather_presets(): + rgx = re.compile('.+?(?:(?<=[a-z])(?=[A-Z])|(?=[A-Z])(?=[A-Z][a-z])|$)') + def name(x): return ' '.join(m.group(0) for m in rgx.finditer(x)) + presets = [x for x in dir(carla.WeatherParameters) if re.match('[A-Z].+', x)] + return [(getattr(carla.WeatherParameters, x), name(x)) for x in presets] + +def get_actor_display_name(actor, truncate=250): + name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) + return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + +# ============================================================================== +# -- World +# ============================================================================== +class World(object): + def __init__(self, carla_world, hud, args): + self.world = carla_world + self.map = self.world.get_map() + self.hud = hud + self.player = None + self.collision_sensor = None + self.lane_invasion_sensor = None + self.gnss_sensor = None + self.camera_manager = None + self._weather_presets = find_weather_presets() + self._weather_index = 0 + self._actor_filter = args.filter + self._gamma = 2.2 + self.restart(args) + self.world.on_tick(hud.on_world_tick) + + def restart(self, args): + cam_index = self.camera_manager.index if self.camera_manager else 0 + cam_pos_id = self.camera_manager.transform_index if self.camera_manager else 0 + + blueprint_library = self.world.get_blueprint_library() + blueprint = random.choice(blueprint_library.filter(self._actor_filter)) + blueprint.set_attribute('role_name', 'hero') + + if self.player is not None: + spawn_point = self.player.get_transform() + spawn_point.location.z += 2.0 + self.destroy() + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + while self.player is None: + spawn_point = random.choice(self.map.get_spawn_points()) + self.player = self.world.try_spawn_actor(blueprint, spawn_point) + + self.collision_sensor = CollisionSensor(self.player, self.hud) + self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) + self.gnss_sensor = GnssSensor(self.player) + self.camera_manager = CameraManager(self.player, self.hud, self._gamma) + self.camera_manager.transform_index = cam_pos_id + self.camera_manager.set_sensor(cam_index, notify=False) + + def next_weather(self, reverse=False): + self._weather_index += -1 if reverse else 1 + self._weather_index %= len(self._weather_presets) + preset = self._weather_presets[self._weather_index] + self.hud.notification('天气: %s' % preset[1]) + self.world.set_weather(preset[0]) + + def tick(self, clock): + self.hud.tick(clock, self) + + def render(self, display): + self.camera_manager.render(display) + self.hud.render(display) + + def destroy(self): + actors = [ + self.camera_manager.sensor, + self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, + self.gnss_sensor.sensor, + self.player] + for actor in actors: + if actor is not None and actor.is_alive: + actor.destroy() + +# ============================================================================== +# -- KeyboardControl +# ============================================================================== +class KeyboardControl(object): + def __init__(self, world): + world.hud.notification("按 ESC 或 Ctrl+Q 退出", 2) + world.hud.notification("PageUp/PageDown: 切换天气", 2) + + def parse_events(self, world): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return True + if event.type == pygame.KEYUP: + if self._is_quit_shortcut(event.key): + return True + if event.key == K_PAGEUP: + world.next_weather(reverse=True) + if event.key == K_PAGEDOWN: + world.next_weather() + return False + + @staticmethod + def _is_quit_shortcut(key): + return key == K_ESCAPE or (key == K_q and pygame.key.get_mods() & KMOD_CTRL) + +# ============================================================================== +# -- HUD (显示车速、GPS、信息) +# ============================================================================== +class HUD(object): + def __init__(self, width, height): + self.dim = (width, height) + font = pygame.font.Font(pygame.font.get_default_font(), 16) + self._notifications = FadingText(font, (width, 40), (0, height - 40)) + self.font = font + self.server_fps = 0 + self.frame = 0 + self.simulation_time = 0 + self._show_info = True + + def on_world_tick(self, timestamp): + self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) + self.frame = timestamp.frame_count + self.simulation_time = timestamp.elapsed_seconds + + def tick(self, clock, world): + self._notifications.tick(clock) + if not world.player: + return + v = world.player.get_velocity() + speed = round(3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2), 1) + lat = round(world.gnss_sensor.lat, 6) + lon = round(world.gnss_sensor.lon, 6) + self.speed = speed + self.lat = lat + self.lon = lon + + def notification(self, text, seconds=2): + self._notifications.set_text(text, seconds=seconds) + + def error(self, text): + self._notifications.set_text('错误: %s' % text, (255, 0, 0)) + + def render(self, display): + if self._show_info: + info_text = [ + "FPS: %.1f" % self.server_fps, + "车速: %.1f km/h" % getattr(self, 'speed', 0), + "纬度: %.6f" % getattr(self, 'lat', 0), + "经度: %.6f" % getattr(self, 'lon', 0) + ] + y = 10 + for s in info_text: + surf = self.font.render(s, True, (255,255,255)) + display.blit(surf, (10, y)) + y += 20 + self._notifications.render(display) + +# ============================================================================== +# -- FadingText +# ============================================================================== +class FadingText(object): + def __init__(self, font, dim, pos): + self.font = font + self.dim = dim + self.pos = pos + self.seconds_left = 0 + self.surface = pygame.Surface(self.dim) + + def set_text(self, text, color=(255, 255, 255), seconds=2.0): + self.seconds_left = seconds + self.surface = self.font.render(text, True, color) + + def tick(self, clock): + self.seconds_left = max(0.0, self.seconds_left - clock.get_time() / 1000.0) + + def render(self, display): + alpha = int(255 * (self.seconds_left / 2.0)) if self.seconds_left > 0 else 0 + self.surface.set_alpha(alpha) + display.blit(self.surface, self.pos) + +# ============================================================================== +# -- CollisionSensor +# ============================================================================== +class CollisionSensor(object): + def __init__(self, parent_actor, hud): + self.sensor = None + self._parent = parent_actor + self.hud = hud + world = parent_actor.get_world() + bp = world.get_blueprint_library().find('sensor.other.collision') + self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent_actor) + weak_self = weakref.ref(self) + self.sensor.listen(lambda event: CollisionSensor._on_collision(weak_self, event)) + + @staticmethod + def _on_collision(weak_self, event): + self = weak_self() + if not self: + return + actor_type = get_actor_display_name(event.other_actor) + self.hud.notification(f"碰撞 → {actor_type}") + +# ============================================================================== +# -- LaneInvasionSensor +# ============================================================================== +class LaneInvasionSensor(object): + def __init__(self, parent_actor, hud): + self.sensor = None + self._parent = parent_actor + self.hud = hud + world = parent_actor.get_world() + bp = world.get_blueprint_library().find('sensor.other.lane_invasion') + self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent_actor) + weak_self = weakref.ref(self) + self.sensor.listen(lambda event: LaneInvasionSensor._on_lane(weak_self, event)) + + @staticmethod + def _on_lane(weak_self, event): + self = weak_self() + if not self: + return + self.hud.notification("车道偏离!") + +# ============================================================================== +# -- GnssSensor +# ============================================================================== +class GnssSensor(object): + def __init__(self, parent_actor): + self.sensor = None + self._parent = parent_actor + self.lat = 0.0 + self.lon = 0.0 + world = parent_actor.get_world() + bp = world.get_blueprint_library().find('sensor.other.gnss') + self.sensor = world.spawn_actor(bp, carla.Transform(carla.Location(z=2.0)), attach_to=parent_actor) + weak_self = weakref.ref(self) + self.sensor.listen(lambda event: GnssSensor._on_gnss(weak_self, event)) + + @staticmethod + def _on_gnss(weak_self, event): + self = weak_self() + if not self: + return + self.lat = event.latitude + self.lon = event.longitude + +# ============================================================================== +# -- CameraManager +# ============================================================================== +class CameraManager(object): + def __init__(self, parent_actor, hud, gamma_correction): + self.sensor = None + self.surface = None + self._parent = parent_actor + self.hud = hud + self.transform_index = 0 + self.sensors = [['sensor.camera.rgb', cc.Raw, 'RGB Camera']] + self._camera_transforms = [ + carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8.0)) + ] + self.index = None + world = parent_actor.get_world() + for i, it in enumerate(self.sensors): + bp = world.get_blueprint_library().find(it[0]) + bp.set_attribute('image_size_x', str(hud.dim[0])) + bp.set_attribute('image_size_y', str(hud.dim[1])) + self.sensors[i].append(bp) + + def set_sensor(self, index, notify=True): + if self.sensor and self.sensor.is_alive: + self.sensor.destroy() + self.index = index + self.sensor = self._parent.get_world().spawn_actor( + self.sensors[index][-1], + self._camera_transforms[0], + attach_to=self._parent) + weak_self = weakref.ref(self) + self.sensor.listen(lambda image: CameraManager._parse_image(weak_self, image)) + + @staticmethod + def _parse_image(weak_self, image): + self = weak_self() + if not self: + return + image.convert(self.sensors[self.index][1]) + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape((image.height, image.width, 4)) + array = array[:, :, :3] + array = array[:, :, ::-1] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)) + + def render(self, display): + if self.surface is not None: + display.blit(self.surface, (0, 0)) + +# ============================================================================== +# -- Game Loop +# ============================================================================== +def game_loop(args): + pygame.init() + pygame.font.init() + world = None + + try: + client = carla.Client(args.host, args.port) + client.set_timeout(10.0) + display = pygame.display.set_mode((args.width, args.height), pygame.HWSURFACE | pygame.DOUBLEBUF) + hud = HUD(args.width, args.height) + world = World(client.get_world(), hud, args) + controller = KeyboardControl(world) + + agent = BehaviorAgent(world.player, behavior=args.behavior) + spawn_points = world.map.get_spawn_points() + destination = random.choice(spawn_points).location + agent.set_destination(destination) + world.hud.notification("已设置自动导航目标点") + + clock = pygame.time.Clock() + + while True: + clock.tick_busy_loop(60) + if controller.parse_events(world): + return + + world.tick(clock) + world.render(display) + pygame.display.flip() + + control = agent.run_step() + control.manual_gear_shift = False + world.player.apply_control(control) + + finally: + if world is not None: + world.destroy() + pygame.quit() + +# ============================================================================== +# -- main() +# ============================================================================== +def main(): + argparser = argparse.ArgumentParser(description='CARLA 自动行驶客户端') + argparser.add_argument('--host', default='127.0.0.1') + argparser.add_argument('--port', default=2000, type=int) + argparser.add_argument('--res', default='1280x720') + argparser.add_argument('--filter', default='vehicle.*') + argparser.add_argument('-b', '--behavior', default='normal', choices=['cautious', 'normal', 'aggressive']) + args = argparser.parse_args() + args.width, args.height = [int(x) for x in args.res.split('x')] + game_loop(args) + +if __name__ == '__main__': + main() From 4e311ee64cc0fba321c73321122a26b128e70263 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Tue, 28 Apr 2026 23:29:11 +0800 Subject: [PATCH 20/22] =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=9D=90=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{World_Coordinate.py => world_Coordinate.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/carla_driving_car_lane/{World_Coordinate.py => world_Coordinate.py} (100%) diff --git a/src/carla_driving_car_lane/World_Coordinate.py b/src/carla_driving_car_lane/world_Coordinate.py similarity index 100% rename from src/carla_driving_car_lane/World_Coordinate.py rename to src/carla_driving_car_lane/world_Coordinate.py From bed85b29498de7503f763ee463f4cdaeeb4034a1 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Wed, 29 Apr 2026 22:57:05 +0800 Subject: [PATCH 21/22] =?UTF-8?q?=E5=9D=90=E6=A0=87=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../world_Coordinate.py | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/carla_driving_car_lane/world_Coordinate.py b/src/carla_driving_car_lane/world_Coordinate.py index 7c7195eba2..d883c87378 100644 --- a/src/carla_driving_car_lane/world_Coordinate.py +++ b/src/carla_driving_car_lane/world_Coordinate.py @@ -6,11 +6,7 @@ # This work is licensed under the terms of the MIT license. # For a copy, see -""" -CARLA Automatic Control Client -适配:Python 3.9 + CARLA 0.9.15 -功能:自动导航行驶 + 传感器 + HUD 显示 -""" + from __future__ import print_function @@ -59,19 +55,24 @@ from agents.navigation.behavior_agent import BehaviorAgent + # ============================================================================== # -- Global functions # ============================================================================== def find_weather_presets(): rgx = re.compile('.+?(?:(?<=[a-z])(?=[A-Z])|(?=[A-Z])(?=[A-Z][a-z])|$)') + def name(x): return ' '.join(m.group(0) for m in rgx.finditer(x)) + presets = [x for x in dir(carla.WeatherParameters) if re.match('[A-Z].+', x)] return [(getattr(carla.WeatherParameters, x), name(x)) for x in presets] + def get_actor_display_name(actor, truncate=250): name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + # ============================================================================== # -- World # ============================================================================== @@ -100,12 +101,14 @@ def restart(self, args): blueprint = random.choice(blueprint_library.filter(self._actor_filter)) blueprint.set_attribute('role_name', 'hero') + # 无绝对坐标:使用当前车辆位置重生(相对偏移) if self.player is not None: spawn_point = self.player.get_transform() - spawn_point.location.z += 2.0 + spawn_point.location.z += 2.0 # 仅相对抬高,无绝对坐标 self.destroy() self.player = self.world.try_spawn_actor(blueprint, spawn_point) + # 无绝对坐标:使用地图原生生成点 while self.player is None: spawn_point = random.choice(self.map.get_spawn_points()) self.player = self.world.try_spawn_actor(blueprint, spawn_point) @@ -142,6 +145,7 @@ def destroy(self): if actor is not None and actor.is_alive: actor.destroy() + # ============================================================================== # -- KeyboardControl # ============================================================================== @@ -167,6 +171,7 @@ def parse_events(self, world): def _is_quit_shortcut(key): return key == K_ESCAPE or (key == K_q and pygame.key.get_mods() & KMOD_CTRL) + # ============================================================================== # -- HUD (显示车速、GPS、信息) # ============================================================================== @@ -191,7 +196,7 @@ def tick(self, clock, world): if not world.player: return v = world.player.get_velocity() - speed = round(3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2), 1) + speed = round(3.6 * math.sqrt(v.x ** 2 + v.y ** 2 + v.z ** 2), 1) lat = round(world.gnss_sensor.lat, 6) lon = round(world.gnss_sensor.lon, 6) self.speed = speed @@ -214,11 +219,12 @@ def render(self, display): ] y = 10 for s in info_text: - surf = self.font.render(s, True, (255,255,255)) + surf = self.font.render(s, True, (255, 255, 255)) display.blit(surf, (10, y)) y += 20 self._notifications.render(display) + # ============================================================================== # -- FadingText # ============================================================================== @@ -242,6 +248,7 @@ def render(self, display): self.surface.set_alpha(alpha) display.blit(self.surface, self.pos) + # ============================================================================== # -- CollisionSensor # ============================================================================== @@ -252,6 +259,7 @@ def __init__(self, parent_actor, hud): self.hud = hud world = parent_actor.get_world() bp = world.get_blueprint_library().find('sensor.other.collision') + # 无绝对坐标:默认挂载点 self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent_actor) weak_self = weakref.ref(self) self.sensor.listen(lambda event: CollisionSensor._on_collision(weak_self, event)) @@ -264,6 +272,7 @@ def _on_collision(weak_self, event): actor_type = get_actor_display_name(event.other_actor) self.hud.notification(f"碰撞 → {actor_type}") + # ============================================================================== # -- LaneInvasionSensor # ============================================================================== @@ -274,6 +283,7 @@ def __init__(self, parent_actor, hud): self.hud = hud world = parent_actor.get_world() bp = world.get_blueprint_library().find('sensor.other.lane_invasion') + # 无绝对坐标:默认挂载点 self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent_actor) weak_self = weakref.ref(self) self.sensor.listen(lambda event: LaneInvasionSensor._on_lane(weak_self, event)) @@ -285,6 +295,7 @@ def _on_lane(weak_self, event): return self.hud.notification("车道偏离!") + # ============================================================================== # -- GnssSensor # ============================================================================== @@ -296,6 +307,7 @@ def __init__(self, parent_actor): self.lon = 0.0 world = parent_actor.get_world() bp = world.get_blueprint_library().find('sensor.other.gnss') + # 无绝对坐标:仅相对高度,无 x/y self.sensor = world.spawn_actor(bp, carla.Transform(carla.Location(z=2.0)), attach_to=parent_actor) weak_self = weakref.ref(self) self.sensor.listen(lambda event: GnssSensor._on_gnss(weak_self, event)) @@ -308,8 +320,9 @@ def _on_gnss(weak_self, event): self.lat = event.latitude self.lon = event.longitude + # ============================================================================== -# -- CameraManager +# -- CameraManager (✅ 已移除所有硬编码相机坐标) # ============================================================================== class CameraManager(object): def __init__(self, parent_actor, hud, gamma_correction): @@ -319,9 +332,10 @@ def __init__(self, parent_actor, hud, gamma_correction): self.hud = hud self.transform_index = 0 self.sensors = [['sensor.camera.rgb', cc.Raw, 'RGB Camera']] - self._camera_transforms = [ - carla.Transform(carla.Location(x=-5.5, z=2.5), carla.Rotation(pitch=8.0)) - ] + + # ✅ 动态计算相机位置:基于车辆包围盒,无任何绝对坐标 + self._auto_camera_transform() + self.index = None world = parent_actor.get_world() for i, it in enumerate(self.sensors): @@ -330,6 +344,18 @@ def __init__(self, parent_actor, hud, gamma_correction): bp.set_attribute('image_size_y', str(hud.dim[1])) self.sensors[i].append(bp) + def _auto_camera_transform(self): + """ 自动计算相机位置:基于车辆尺寸,自适应所有车型,无硬编码坐标 """ + vehicle = self._parent + bounds = vehicle.bounding_box + ext = bounds.extent + # 相机放在车辆后上方,自适应尺寸 + x = -ext.x * 2.5 + z = ext.z * 2.0 + self._camera_transforms = [ + carla.Transform(carla.Location(x=x, z=z), carla.Rotation(pitch=8.0)) + ] + def set_sensor(self, index, notify=True): if self.sensor and self.sensor.is_alive: self.sensor.destroy() @@ -357,6 +383,7 @@ def render(self, display): if self.surface is not None: display.blit(self.surface, (0, 0)) + # ============================================================================== # -- Game Loop # ============================================================================== @@ -374,6 +401,7 @@ def game_loop(args): controller = KeyboardControl(world) agent = BehaviorAgent(world.player, behavior=args.behavior) + # ✅ 无绝对坐标:随机目标点来自地图生成点 spawn_points = world.map.get_spawn_points() destination = random.choice(spawn_points).location agent.set_destination(destination) @@ -399,6 +427,7 @@ def game_loop(args): world.destroy() pygame.quit() + # ============================================================================== # -- main() # ============================================================================== @@ -413,5 +442,6 @@ def main(): args.width, args.height = [int(x) for x in args.res.split('x')] game_loop(args) + if __name__ == '__main__': main() From 62a65dcd24570f4f14f29215092ea33f66479394 Mon Sep 17 00:00:00 2001 From: dym-commit <490837107@qq.com> Date: Wed, 6 May 2026 10:22:24 +0800 Subject: [PATCH 22/22] =?UTF-8?q?=E5=9D=90=E6=A0=87=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../world_Coordinate.py | 442 ++++++------------ 1 file changed, 151 insertions(+), 291 deletions(-) diff --git a/src/carla_driving_car_lane/world_Coordinate.py b/src/carla_driving_car_lane/world_Coordinate.py index d883c87378..acb8ded23d 100644 --- a/src/carla_driving_car_lane/world_Coordinate.py +++ b/src/carla_driving_car_lane/world_Coordinate.py @@ -1,81 +1,91 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -# Copyright (c) 2018 Intel Labs. -# authors: German Ros (german.ros@gmail.com) -# This work is licensed under the terms of the MIT license. -# For a copy, see - - - -from __future__ import print_function - +import os +import sys import argparse -import collections -import datetime -import glob -import logging import math -import os import random -import re -import sys -import time import weakref +import glob -# ========================================== -# 你的 CARLA 路径(保持不变) -# ========================================== -CARLA_ROOT = r"D:\carla0.9.15" -PYTHON_API = os.path.join(CARLA_ROOT, "PythonAPI") -sys.path.append(PYTHON_API) -sys.path.append(os.path.join(PYTHON_API, "carla")) +# ============================================== +# 强制阻断所有冲突库加载(终极方案) +# ============================================== +for lib in ['matplotlib', 'scipy', 'tensorflow', 'torch', 'keras']: + sys.modules[lib] = None + sys.modules[lib + '.core'] = None + sys.modules[lib + '.api'] = None +# 加载 CARLA Python API try: - eggs = glob.glob(os.path.join(PYTHON_API, "carla", "dist", "*.egg")) + current_dir = os.path.dirname(os.path.abspath(__file__)) + eggs = glob.glob(os.path.join(current_dir, "carla", "dist", "*.egg")) for e in eggs: sys.path.append(e) except: pass -# ================= 依赖 ================= -try: - import pygame - from pygame.locals import K_ESCAPE, K_q, KMOD_CTRL, K_PAGEUP, K_PAGEDOWN -except ImportError: - raise RuntimeError('请安装:pip install pygame') - -try: - import numpy as np -except ImportError: - raise RuntimeError('请安装:pip install numpy') - +# 仅加载必要库 +import pygame +from pygame.locals import * +import numpy as np import carla from carla import ColorConverter as cc -from agents.navigation.behavior_agent import BehaviorAgent +# ============================================== +# 自己实现极简自动导航(不依赖任何第三方库) +# ============================================== +class SimpleAutoAgent: + def __init__(self, vehicle): + self.vehicle = vehicle + self.world = vehicle.get_world() + self.map = self.world.get_map() + self.target = None -# ============================================================================== -# -- Global functions -# ============================================================================== -def find_weather_presets(): - rgx = re.compile('.+?(?:(?<=[a-z])(?=[A-Z])|(?=[A-Z])(?=[A-Z][a-z])|$)') + def set_destination(self, location): + self.target = location + + def run_step(self): + control = carla.VehicleControl() + if not self.target: + return control + + # 基础自动行驶逻辑 + transform = self.vehicle.get_transform() + forward = transform.get_forward_vector() + target_dir = self.target - transform.location + target_dir.z = 0 + + # 计算方向 + dot = forward.x * target_dir.x + forward.y * target_dir.y + cross = forward.x * target_dir.y - forward.y * target_dir.x + distance = math.sqrt(target_dir.x ** 2 + target_dir.y ** 2) - def name(x): return ' '.join(m.group(0) for m in rgx.finditer(x)) + # 控制 + if distance > 5.0: + control.throttle = 0.5 + control.steer = max(-0.3, min(0.3, cross * 0.15)) + else: + control.brake = 1.0 - presets = [x for x in dir(carla.WeatherParameters) if re.match('[A-Z].+', x)] - return [(getattr(carla.WeatherParameters, x), name(x)) for x in presets] + return control -def get_actor_display_name(actor, truncate=250): +# ===================== 以下是完整 CARLA 运行代码 ===================== +def find_weather_presets(): + presets = [] + for name in dir(carla.WeatherParameters): + if name[0].isupper(): + presets.append((getattr(carla.WeatherParameters, name), name)) + return presets + + +def get_actor_display_name(actor): name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:]) - return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name + return name -# ============================================================================== -# -- World -# ============================================================================== class World(object): def __init__(self, carla_world, hud, args): self.world = carla_world @@ -84,41 +94,32 @@ def __init__(self, carla_world, hud, args): self.player = None self.collision_sensor = None self.lane_invasion_sensor = None - self.gnss_sensor = None self.camera_manager = None self._weather_presets = find_weather_presets() self._weather_index = 0 self._actor_filter = args.filter - self._gamma = 2.2 self.restart(args) self.world.on_tick(hud.on_world_tick) def restart(self, args): - cam_index = self.camera_manager.index if self.camera_manager else 0 - cam_pos_id = self.camera_manager.transform_index if self.camera_manager else 0 - blueprint_library = self.world.get_blueprint_library() blueprint = random.choice(blueprint_library.filter(self._actor_filter)) blueprint.set_attribute('role_name', 'hero') - # 无绝对坐标:使用当前车辆位置重生(相对偏移) if self.player is not None: spawn_point = self.player.get_transform() - spawn_point.location.z += 2.0 # 仅相对抬高,无绝对坐标 + spawn_point.location.z += 2.0 self.destroy() self.player = self.world.try_spawn_actor(blueprint, spawn_point) - # 无绝对坐标:使用地图原生生成点 while self.player is None: spawn_point = random.choice(self.map.get_spawn_points()) self.player = self.world.try_spawn_actor(blueprint, spawn_point) self.collision_sensor = CollisionSensor(self.player, self.hud) self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud) - self.gnss_sensor = GnssSensor(self.player) - self.camera_manager = CameraManager(self.player, self.hud, self._gamma) - self.camera_manager.transform_index = cam_pos_id - self.camera_manager.set_sensor(cam_index, notify=False) + self.camera_manager = CameraManager(self.player, self.hud) + self.camera_manager.set_sensor(0) def next_weather(self, reverse=False): self._weather_index += -1 if reverse else 1 @@ -135,258 +136,128 @@ def render(self, display): self.hud.render(display) def destroy(self): - actors = [ - self.camera_manager.sensor, - self.collision_sensor.sensor, - self.lane_invasion_sensor.sensor, - self.gnss_sensor.sensor, - self.player] + actors = [self.camera_manager.sensor, self.collision_sensor.sensor, + self.lane_invasion_sensor.sensor, self.player] for actor in actors: - if actor is not None and actor.is_alive: + if actor and actor.is_alive: actor.destroy() -# ============================================================================== -# -- KeyboardControl -# ============================================================================== -class KeyboardControl(object): - def __init__(self, world): - world.hud.notification("按 ESC 或 Ctrl+Q 退出", 2) - world.hud.notification("PageUp/PageDown: 切换天气", 2) +class CollisionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.collision'), + carla.Transform(), attach_to=parent) + self.hud = hud + self.sensor.listen(lambda e: self.hud.notification(f"碰撞: {get_actor_display_name(e.other_actor)}")) - def parse_events(self, world): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - return True - if event.type == pygame.KEYUP: - if self._is_quit_shortcut(event.key): - return True - if event.key == K_PAGEUP: - world.next_weather(reverse=True) - if event.key == K_PAGEDOWN: - world.next_weather() - return False - @staticmethod - def _is_quit_shortcut(key): - return key == K_ESCAPE or (key == K_q and pygame.key.get_mods() & KMOD_CTRL) +class LaneInvasionSensor(object): + def __init__(self, parent, hud): + self.sensor = parent.get_world().spawn_actor( + parent.get_world().get_blueprint_library().find('sensor.other.lane_invasion'), + carla.Transform(), attach_to=parent) + self.hud = hud + self.sensor.listen(lambda e: self.hud.notification("车道偏离")) + + +class CameraManager(object): + def __init__(self, parent, hud): + self.sensor = None + self.surface = None + self.parent = parent + self.hud = hud + bp = parent.get_world().get_blueprint_library().find('sensor.camera.rgb') + bp.set_attribute('image_size_x', str(hud.dim[0])) + bp.set_attribute('image_size_y', str(hud.dim[1])) + self.bp = bp + + def set_sensor(self, index): + if self.sensor: self.sensor.destroy() + v = self.parent + ext = v.bounding_box.extent + trans = carla.Transform(carla.Location(x=-ext.x * 2.5, z=ext.z * 2), carla.Rotation(pitch=8)) + self.sensor = v.get_world().spawn_actor(self.bp, trans, attach_to=v) + self.sensor.listen(lambda img: self._parse(img)) + + def _parse(self, image): + image.convert(cc.Raw) + array = np.frombuffer(image.raw_data, dtype=np.uint8) + array = array.reshape(image.height, image.width, 4) + array = array[:, :, :3] + array = array[:, :, ::-1] + self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)) + + def render(self, display): + if self.surface: display.blit(self.surface, (0, 0)) -# ============================================================================== -# -- HUD (显示车速、GPS、信息) -# ============================================================================== class HUD(object): def __init__(self, width, height): self.dim = (width, height) - font = pygame.font.Font(pygame.font.get_default_font(), 16) - self._notifications = FadingText(font, (width, 40), (0, height - 40)) - self.font = font + self.font = pygame.font.Font(pygame.font.get_default_font(), 16) + self._notifications = FadingText(self.font, (width, 40), (0, height - 40)) self.server_fps = 0 - self.frame = 0 - self.simulation_time = 0 - self._show_info = True + self.speed = 0 def on_world_tick(self, timestamp): self.server_fps = 1.0 / max(timestamp.delta_seconds, 0.01) - self.frame = timestamp.frame_count - self.simulation_time = timestamp.elapsed_seconds def tick(self, clock, world): self._notifications.tick(clock) - if not world.player: - return - v = world.player.get_velocity() - speed = round(3.6 * math.sqrt(v.x ** 2 + v.y ** 2 + v.z ** 2), 1) - lat = round(world.gnss_sensor.lat, 6) - lon = round(world.gnss_sensor.lon, 6) - self.speed = speed - self.lat = lat - self.lon = lon + if world.player: + v = world.player.get_velocity() + self.speed = round(3.6 * math.sqrt(v.x ** 2 + v.y ** 2 + v.z ** 2), 1) def notification(self, text, seconds=2): self._notifications.set_text(text, seconds=seconds) - def error(self, text): - self._notifications.set_text('错误: %s' % text, (255, 0, 0)) - def render(self, display): - if self._show_info: - info_text = [ - "FPS: %.1f" % self.server_fps, - "车速: %.1f km/h" % getattr(self, 'speed', 0), - "纬度: %.6f" % getattr(self, 'lat', 0), - "经度: %.6f" % getattr(self, 'lon', 0) - ] - y = 10 - for s in info_text: - surf = self.font.render(s, True, (255, 255, 255)) - display.blit(surf, (10, y)) - y += 20 + info = [f"FPS: {self.server_fps:.1f}", f"车速: {self.speed:.1f} km/h", "状态: 自动行驶中"] + for i, line in enumerate(info): + surf = self.font.render(line, True, (255, 255, 255)) + display.blit(surf, (10, 10 + i * 20)) self._notifications.render(display) -# ============================================================================== -# -- FadingText -# ============================================================================== class FadingText(object): def __init__(self, font, dim, pos): self.font = font self.dim = dim self.pos = pos self.seconds_left = 0 - self.surface = pygame.Surface(self.dim) + self.surface = font.render("", True, (0, 0, 0)) - def set_text(self, text, color=(255, 255, 255), seconds=2.0): + def set_text(self, text, color=(255, 255, 255), seconds=2): self.seconds_left = seconds self.surface = self.font.render(text, True, color) def tick(self, clock): - self.seconds_left = max(0.0, self.seconds_left - clock.get_time() / 1000.0) + self.seconds_left = max(0.0, self.seconds_left - clock.get_time() / 1000) def render(self, display): - alpha = int(255 * (self.seconds_left / 2.0)) if self.seconds_left > 0 else 0 + alpha = int(255 * self.seconds_left / 2) if self.seconds_left else 0 self.surface.set_alpha(alpha) display.blit(self.surface, self.pos) -# ============================================================================== -# -- CollisionSensor -# ============================================================================== -class CollisionSensor(object): - def __init__(self, parent_actor, hud): - self.sensor = None - self._parent = parent_actor - self.hud = hud - world = parent_actor.get_world() - bp = world.get_blueprint_library().find('sensor.other.collision') - # 无绝对坐标:默认挂载点 - self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent_actor) - weak_self = weakref.ref(self) - self.sensor.listen(lambda event: CollisionSensor._on_collision(weak_self, event)) - - @staticmethod - def _on_collision(weak_self, event): - self = weak_self() - if not self: - return - actor_type = get_actor_display_name(event.other_actor) - self.hud.notification(f"碰撞 → {actor_type}") - - -# ============================================================================== -# -- LaneInvasionSensor -# ============================================================================== -class LaneInvasionSensor(object): - def __init__(self, parent_actor, hud): - self.sensor = None - self._parent = parent_actor - self.hud = hud - world = parent_actor.get_world() - bp = world.get_blueprint_library().find('sensor.other.lane_invasion') - # 无绝对坐标:默认挂载点 - self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent_actor) - weak_self = weakref.ref(self) - self.sensor.listen(lambda event: LaneInvasionSensor._on_lane(weak_self, event)) - - @staticmethod - def _on_lane(weak_self, event): - self = weak_self() - if not self: - return - self.hud.notification("车道偏离!") - - -# ============================================================================== -# -- GnssSensor -# ============================================================================== -class GnssSensor(object): - def __init__(self, parent_actor): - self.sensor = None - self._parent = parent_actor - self.lat = 0.0 - self.lon = 0.0 - world = parent_actor.get_world() - bp = world.get_blueprint_library().find('sensor.other.gnss') - # 无绝对坐标:仅相对高度,无 x/y - self.sensor = world.spawn_actor(bp, carla.Transform(carla.Location(z=2.0)), attach_to=parent_actor) - weak_self = weakref.ref(self) - self.sensor.listen(lambda event: GnssSensor._on_gnss(weak_self, event)) - - @staticmethod - def _on_gnss(weak_self, event): - self = weak_self() - if not self: - return - self.lat = event.latitude - self.lon = event.longitude - - -# ============================================================================== -# -- CameraManager (✅ 已移除所有硬编码相机坐标) -# ============================================================================== -class CameraManager(object): - def __init__(self, parent_actor, hud, gamma_correction): - self.sensor = None - self.surface = None - self._parent = parent_actor - self.hud = hud - self.transform_index = 0 - self.sensors = [['sensor.camera.rgb', cc.Raw, 'RGB Camera']] - - # ✅ 动态计算相机位置:基于车辆包围盒,无任何绝对坐标 - self._auto_camera_transform() - - self.index = None - world = parent_actor.get_world() - for i, it in enumerate(self.sensors): - bp = world.get_blueprint_library().find(it[0]) - bp.set_attribute('image_size_x', str(hud.dim[0])) - bp.set_attribute('image_size_y', str(hud.dim[1])) - self.sensors[i].append(bp) - - def _auto_camera_transform(self): - """ 自动计算相机位置:基于车辆尺寸,自适应所有车型,无硬编码坐标 """ - vehicle = self._parent - bounds = vehicle.bounding_box - ext = bounds.extent - # 相机放在车辆后上方,自适应尺寸 - x = -ext.x * 2.5 - z = ext.z * 2.0 - self._camera_transforms = [ - carla.Transform(carla.Location(x=x, z=z), carla.Rotation(pitch=8.0)) - ] - - def set_sensor(self, index, notify=True): - if self.sensor and self.sensor.is_alive: - self.sensor.destroy() - self.index = index - self.sensor = self._parent.get_world().spawn_actor( - self.sensors[index][-1], - self._camera_transforms[0], - attach_to=self._parent) - weak_self = weakref.ref(self) - self.sensor.listen(lambda image: CameraManager._parse_image(weak_self, image)) - - @staticmethod - def _parse_image(weak_self, image): - self = weak_self() - if not self: - return - image.convert(self.sensors[self.index][1]) - array = np.frombuffer(image.raw_data, dtype=np.uint8) - array = array.reshape((image.height, image.width, 4)) - array = array[:, :, :3] - array = array[:, :, ::-1] - self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1)) +class KeyboardControl(object): + def __init__(self, world): + world.hud.notification("ESC 退出", 2) + world.hud.notification("PageUp/Down 切换天气", 2) - def render(self, display): - if self.surface is not None: - display.blit(self.surface, (0, 0)) + def parse_events(self, world): + for event in pygame.event.get(): + if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE): + return True + if event.type == KEYUP: + if event.key == K_PAGEUP: + world.next_weather(True) + elif event.key == K_PAGEDOWN: + world.next_weather() + return False -# ============================================================================== -# -- Game Loop -# ============================================================================== def game_loop(args): pygame.init() pygame.font.init() @@ -395,51 +266,40 @@ def game_loop(args): try: client = carla.Client(args.host, args.port) client.set_timeout(10.0) - display = pygame.display.set_mode((args.width, args.height), pygame.HWSURFACE | pygame.DOUBLEBUF) + display = pygame.display.set_mode((args.width, args.height)) hud = HUD(args.width, args.height) world = World(client.get_world(), hud, args) controller = KeyboardControl(world) - agent = BehaviorAgent(world.player, behavior=args.behavior) - # ✅ 无绝对坐标:随机目标点来自地图生成点 - spawn_points = world.map.get_spawn_points() - destination = random.choice(spawn_points).location - agent.set_destination(destination) - world.hud.notification("已设置自动导航目标点") + # 使用我们自己的极简自动代理(无任何依赖) + agent = SimpleAutoAgent(world.player) + dest = random.choice(world.map.get_spawn_points()).location + agent.set_destination(dest) + hud.notification("自动导航已启动") clock = pygame.time.Clock() - while True: clock.tick_busy_loop(60) - if controller.parse_events(world): - return - + if controller.parse_events(world): return world.tick(clock) world.render(display) pygame.display.flip() - control = agent.run_step() - control.manual_gear_shift = False world.player.apply_control(control) finally: - if world is not None: - world.destroy() + if world: world.destroy() pygame.quit() -# ============================================================================== -# -- main() -# ============================================================================== def main(): - argparser = argparse.ArgumentParser(description='CARLA 自动行驶客户端') + argparser = argparse.ArgumentParser() argparser.add_argument('--host', default='127.0.0.1') argparser.add_argument('--port', default=2000, type=int) argparser.add_argument('--res', default='1280x720') argparser.add_argument('--filter', default='vehicle.*') - argparser.add_argument('-b', '--behavior', default='normal', choices=['cautious', 'normal', 'aggressive']) args = argparser.parse_args() - args.width, args.height = [int(x) for x in args.res.split('x')] + args.width, args.height = map(int, args.res.split('x')) game_loop(args)