自动驾驶-第一阶段-7 天搭环境 + 跑通端到端闭环 Demo

从零开始,在CARLA仿真器中实现你的第一个自动驾驶系统, 数据采集·模仿学习训练·闭环评测· GPU服务器指南

1.1 什么是 CARLA?

CARLA(Car Learning to Act)是一个开源的自动驾驶仿真器。你可以把它理解为一个“虚拟城市”——里面有道路、建筑、车辆、行人、红绿灯,而你可以用 Python 代码控制一辆车在这个城市里行驶。
CARLA 采用 Client-Server 架构:
Server(服务端): 运行 Unreal Engine 渲染的 3D 世界,负责物理模拟、图形渲染。就像游戏服务器。
Client(客户端): 你写的 Python 脚本,通过 API 连接到 Server,发送指令(创建车辆、获取传感器数据、控制车辆运动)。

类比理解:
想象你在玩《GTA》,游戏本身就是 Server,而你写的 Python 代码就是一个“外挂”——它可以自动操作游戏里的车辆、读取摄像头画面、让车自动开。

1.2 安装步骤(Ubuntu 20.04/22.04 CARLA 0.9.15, 不推荐这个版本,请看下边)

Step 1:下载 CARLA 0.9.15
打开终端,执行以下命令:

# 创建工作目录
mkdir -p ~/carla && cd ~/carla

# 下载 CARLA 0.9.15 预编译包(约 15GB)
wget https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/CARLA_0.9.15.tar.gz

# 解压
tar -xzf CARLA_0.9.15.tar.gz

Step 2:安装 Python 依赖

# 创建 conda 环境
conda create -n carla python=3.8 -y
conda activate carla

# 安装 CARLA Python API
pip install carla==0.9.15

# 安装其他依赖
pip install numpy opencv-python pygame matplotlib

Step 3:启动 CARLA 服务器

cd ~/carla

# 方式 1:有显示器(本地机器)
./CarlaUE4.sh

# 方式 2:无显示器/云服务器(headless + 降低质量省显存)
./CarlaUE4.sh -RenderOffScreen -quality-level=Low
启动后,服务器会监听 localhost:2000 端口,等待客户端连接。

⚠️ 常见问题
如果报错 “Vulkan device not found”,尝试加上 -opengl 参数:./CarlaUE4.sh -RenderOffScreen -opengl。如果显存不足,加上 -quality-level=Low 可以将显存占用从 4GB+ 降到 2GB 左右。

1.3 安装步骤(Ubuntu 20.04/22.04 CARLA 0.9.16 - 推荐版本)

Step 1:下载 CARLA 0.9.16
打开终端,执行以下命令:

# 创建工作目录
mkdir -p ~/carla && cd ~/carla

# 下载 CARLA 0.9.16 预编译包(约 15GB)
wget https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/CARLA_0.9.16.tar.gz

# 解压
tar -xzf CARLA_0.9.16.tar.gz

Step 2:安装 Python 依赖

# 创建 conda 环境, 推荐 3.10 版本
conda create -n carla python=3.10 -y
conda activate carla

# 安装 CARLA Python API
pip install carla==0.9.16

# 安装其他依赖
pip install numpy opencv-python pygame matplotlib

Step 3:启动 CARLA 服务器

cd ~/carla

# 方式 1:有显示器(本地机器)
./CarlaUE4.sh

# 方式 2:无显示器/云服务器(headless + 降低质量省显存)
./CarlaUE4.sh -RenderOffScreen -quality-level=Low
启动后,服务器会监听 localhost:2000 端口,等待客户端连接。

conda 清除环境(出问题的时候执行)

conda deactivate
conda remove --name carla --all
conda clean --all

# 查看环境列表
conda env list

实际启动步骤:

cd /home/lionsking/carla
./CarlaUE4.sh -windowed -ResX=1280 -ResY=720 -quality-level=Epic

pytorch 环境安装

本机环境:

(carla) lionsking@ai-dev:~/carla$ nvidia-smi
Sat Mar 28 09:01:13 2026       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.126.09             Driver Version: 580.126.09     CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 5060 ...    Off |   00000000:01:00.0  On |                  N/A |
| N/A   49C    P4              8W /   70W |     198MiB /   8151MiB |      5%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A            3072      G   /usr/lib/xorg/Xorg                      155MiB |
+-----------------------------------------------------------------------------------------+
(carla) lionsking@ai-dev:~/carla$ python --version
Python 3.10.20

结合你的系统信息:
Linux + Conda (carla 环境)
Python 3.10
NVIDIA 驱动 580,支持 CUDA 13.0
RTX 5060 显卡
我给你唯一正确、一步到位的安装命令:
最终安装命令(直接复制运行)

安装命令:

# 这个版本有问题,再 RTX5060 报错
# pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

# 报错信息,后边执行
# NVIDIA GeForce RTX 5060 Laptop GPU with CUDA capability sm_120 is not compatible

# 如果下载的慢,用清华的镜像源
# pip install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple

# 这个版本支持不了
# pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126

# 卸载旧版的,安装cu130版本, NVIDIA 驱动 580,支持 CUDA 13.0
# pip uninstall torch torchvision torchaudio -y

# 安装支持 RTX 5060 的最新版(必须用这个)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu130

# pip install torch torchvision torchaudio --pre --index-url https://download.pytorch.org/whl/nightly/cu130 --trusted-host download.pytorch.org

# 验证是否修复
(carla) lionsking@ai-dev:~/carla$ python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"
2.11.0+cu126
True
(carla) lionsking@ai-dev:~/carla$ 

安装后查看:

import torch
print(torch.__version__)        # 查看版本
print(torch.cuda.is_available()) # 必须输出 True
print(torch.cuda.device_count()) # 查看 GPU 数量

闭环测试 + 可视化

什么是“开环”和“闭环”?

这是自动驾驶领域最重要的概念之一:
开环测试(Open-loop):用已经录好的数据测试模型。给模型看一张图,比较它的预测和真实值。缺点:模型的预测不会影响下一帧看到什么,所以无法检测“开歪后能不能纠正”这种问题。

闭环测试(Closed-loop):把模型放到 CARLA 中实际开车。模型的预测会真正影响车辆运动,车辆运动又会改变摄像头看到的场景。这形成了一个“反馈回路”,所以叫“闭环”。

为什么闭环测试重要?
一个模型可能在开环测试中表现很好(loss 很低),但在闭环中完全不能用。这就是为什么现在的自动驾驶行业越来越重视闭环评测(如 NAVSIM、Bench2Drive)。特斯拉 FSD 的核心优势之一,就是能用百万辆真实车辆做闭环测试。

闭环测试脚本
创建文件 closed_loop_test.py

import carla
import torch
import cv2
import numpy as np
import time
import random
from torchvision import transforms
from model import DrivingModel

# ===================== 固定尺寸 =====================
IMG_WIDTH, IMG_HEIGHT = 400, 200

# ===================== 视频录制 =====================
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video = cv2.VideoWriter('test_run.mp4', fourcc, 20, (IMG_WIDTH, IMG_HEIGHT))

# ===================== 加载模型 =====================
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
model = DrivingModel().to(DEVICE)
model.load_state_dict(torch.load('driving_model.pth', map_location=DEVICE))
model.eval()

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

# ===================== 连接 CARLA =====================
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()

# 同步模式(必须开)
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05
world.apply_settings(settings)

# 清理旧物体
for actor in world.get_actors().filter('*vehicle*'):
    actor.destroy()
for sensor in world.get_actors().filter('*sensor*'):
    sensor.destroy()

# ===================== 生成车辆 =====================
bp_lib = world.get_blueprint_library()
vehicle_bp = bp_lib.filter('vehicle.tesla.model3')[0]
spawn_point = random.choice(world.get_map().get_spawn_points())
vehicle = world.spawn_actor(vehicle_bp, spawn_point)

# 视角跟随车辆
spectator = world.get_spectator()

# ===================== 摄像头 =====================
camera_bp = bp_lib.find('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', str(IMG_WIDTH))
camera_bp.set_attribute('image_size_y', str(IMG_HEIGHT))
camera_bp.set_attribute('fov', '110')

camera_transform = carla.Transform(
    carla.Location(x=2.5, z=0.7),
    carla.Rotation(pitch=-15)
)
camera = world.spawn_actor(camera_bp, camera_transform, attach_to=vehicle)

latest_image = None

def camera_callback(image):
    global latest_image
    array = np.frombuffer(image.raw_data, dtype=np.uint8)
    array = array.reshape((IMG_HEIGHT, IMG_WIDTH, 4))[:, :, :3]
    latest_image = array

camera.listen(camera_callback)

# ===================== 主驾驶循环 =====================
total_distance = 0
prev_location = vehicle.get_transform().location

print("开始 AI 驾驶...")

for step in range(1500):
    world.tick()

    if latest_image is None:
        continue

    # 视角跟随
    try:
        v_trans = vehicle.get_transform()
        spectator.set_transform(carla.Transform(
            carla.Location(
                x=v_trans.location.x - 8,
                y=v_trans.location.y,
                z=v_trans.location.z + 4
            ),
            carla.Rotation(pitch=-30)
        ))
    except:
        pass

    # 图像预处理
    img_rgb = cv2.cvtColor(latest_image, cv2.COLOR_BGR2RGB)
    img_tensor = transform(img_rgb).unsqueeze(0).to(DEVICE)

    # 推理
    with torch.no_grad():
        pred = model(img_tensor)[0].cpu().numpy()

    # ===================== 修复:转成原生 float =====================
    steer = float(np.clip(pred[0], -1.0, 1.0))
    throttle = float(np.clip(pred[1], 0.2, 0.5))

    # 车辆控制(绝对不报错)
    control = carla.VehicleControl()
    control.steer = steer
    control.throttle = throttle
    control.brake = 0.0
    vehicle.apply_control(control)

    # 计算距离
    now_loc = vehicle.get_transform().location
    total_distance += now_loc.distance(prev_location)
    prev_location = now_loc

    # 显示 + 写视频
    display = latest_image.copy()
    cv2.putText(display, f'Steer: {steer:.2f}', (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    cv2.putText(display, f'Throttle: {throttle:.1f}', (10, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

    video.write(display)
    cv2.imshow("AI Driving", display)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# ===================== 释放资源 =====================
video.release()
cv2.destroyAllWindows()
vehicle.destroy()
camera.destroy()

print(f'行驶距离: {total_distance:.1f} 米')
print("视频已保存:test_run.mp4")

file


相关文章:
无人驾驶-04-在 Ubuntu22.04 RTX5060 安装 Carla 及启动

为者常成,行者常至