EasyCarla-RL:自动驾驶端到端本地部署训练、测试与carla仿真复现

EasyCarla-RL 项目架构与核心实现梳理

一、项目整体架构

1.1 目录结构

复制代码
EasyCarla-RL/
├── easycarla/                    # 主环境模块(Python包)
│   ├── envs/                     # CARLA环境封装
│   │   ├── __init__.py
│   │   └── carla_env.py          # Carla环境核心实现
│   └── __init__.py
├── example/                      # 高级示例代码
│   ├── agents/                   # RL智能体实现
│   │   ├── __init__.py
│   │   ├── bc_diffusion.py       # Behavior Cloning + Diffusion
│   │   ├── diffusion.py          # 扩散模型核心
│   │   ├── helpers.py            # 辅助工具函数
│   │   ├── model.py              # MLP网络架构
│   │   └── ql_diffusion.py       # Diffusion Q-Learning主类
│   ├── params_dql/               # 预训练模型参数
│   │   ├── actor_200.pth
│   │   └── critic_200.pth
│   ├── utils/                    # 工具模块
│   │   ├── __init__.py
│   │   ├── data_sampler.py       # 数据集采样器
│   │   ├── logger.py             # 日志工具
│   │   ├── pytorch_util.py       # PyTorch工具
│   │   └── utils.py              # 通用工具
│   └── run_dql_in_carla.py       # 在CARLA中运行DQL模型
├── assets/                       # 静态资源(演示GIF)
├── easycarla_demo.py             # 基础演示脚本
├── requirements.txt              # 依赖清单
├── setup.py                      # 包安装配置
└── README.md                     # 项目说明文档

1.2 模块职责说明

模块 职责 核心功能
easycarla.envs CARLA环境封装 Gym兼容接口、传感器管理、奖励计算
example.agents RL算法实现 Diffusion Q-Learning、行为克隆
example.utils 工具函数 数据采样、日志记录、模型保存/加载

二、核心算法实现

2.1 Diffusion Q-Learning 架构

2.1.1 整体架构

Diffusion Q-Learning 是一种离线强化学习算法,将扩散模型与Q学习相结合:

复制代码
┌─────────────────────────────────────────────────────────────┐
│                     Diffusion Q-Learning                    │
├─────────────────────────────────────────────────────────────┤
│  ┌──────────┐    ┌──────────┐    ┌──────────┐              │
│  │  Actor   │←───│  EMA     │←───│  Critic  │              │
│  │(Diffusion)│   │ (Target) │   │(Double Q)│              │
│  └────┬─────┘    └──────────┘    └────┬─────┘              │
│       │                               │                     │
│       ▼                               ▼                     │
│  ┌─────────────────────────────────────────────┐            │
│  │            训练循环 (Training Loop)         │            │
│  │  BC Loss + Q Loss → Actor Update           │            │
│  │  TD Error → Critic Update                  │            │
│  └─────────────────────────────────────────────┘            │
└─────────────────────────────────────────────────────────────┘
2.1.2 核心组件

1. Critic 网络 (ql_diffusion.py:17-46)

采用 Double Q-Learning 架构,包含两个独立的Q网络:

python 复制代码
class Critic(nn.Module):
    def __init__(self, state_dim, action_dim, hidden_dim=256):
        self.q1_model = nn.Sequential(
            nn.Linear(state_dim + action_dim, hidden_dim),
            nn.Mish(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.Mish(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.Mish(),
            nn.Linear(hidden_dim, 1)
        )
        self.q2_model = nn.Sequential(...)  # 结构相同
    
    def q_min(self, state, action):
        q1, q2 = self.forward(state, action)
        return torch.min(q1, q2)  # 取最小Q值避免过估计

2. Diffusion Actor (diffusion.py:19-181)

基于扩散模型的策略网络,支持多种beta schedule:

参数 类型 说明
beta_schedule str 可选:linearcosinevp
n_timesteps int 扩散步数(默认100)
loss_type str 损失类型:l1l2
clip_denoised bool 是否裁剪去噪输出

3. MLP 模型 (model.py:12-48)

时序条件的MLP网络,输入包含:

  • state (307维)
  • action (3维)
  • time_embedding (16维) → 通过正弦位置编码生成

2.2 训练流程

训练循环在 Diffusion_QL.train() 方法中实现:

复制代码
┌──────────────────────────────────────────────────────────────┐
│                    训练迭代流程                              │
├──────────────────────────────────────────────────────────────┤
│  1. 采样数据 → replay_buffer.sample(batch_size)             │
│                         │                                   │
│                         ▼                                   │
│  2. Critic更新 → TD目标计算 → MSE损失优化                    │
│                         │                                   │
│                         ▼                                   │
│  3. Actor更新 → BC Loss + η * Q Loss                        │
│                         │                                   │
│                         ▼                                   │
│  4. 目标网络更新 → EMA更新Actor, Polyak更新Critic            │
└──────────────────────────────────────────────────────────────┘

损失函数设计

python 复制代码
# Actor损失 = 行为克隆损失 + Q学习损失
bc_loss = self.actor.loss(action, state)           # 模仿学习
q_loss = - q_new_action.mean() / q_abs.mean()      # 最大化Q值
actor_loss = bc_loss + self.eta * q_loss           # eta=0.01

三、数据集加载

3.1 数据集格式

项目提供的离线数据集存储为HDF5格式,包含约110万时间步:

复制代码
easycarla_offline_dataset.hdf5
├── observations      → shape: [N, 307]    # 观测向量
├── actions           → shape: [N, 3]      # [throttle, steer, brake]
├── rewards           → shape: [N]         # 标量奖励
├── costs             → shape: [N]         # 安全成本
├── done              → shape: [N]         # 终止标志
├── next_observations → shape: [N, 307]    # 下一时刻观测
└── info              → dict
    ├── is_collision  → shape: [N]
    └── is_off_road   → shape: [N]

3.2 数据采样器 (data_sampler.py)

核心功能

  • 支持多种reward调整策略
  • 批量采样训练数据
  • 自动转换为PyTorch张量
python 复制代码
class Data_Sampler(object):
    def __init__(self, data, device, reward_tune='no'):
        self.state = torch.from_numpy(data['observations']).float()
        self.action = torch.from_numpy(data['actions']).float()
        self.next_state = torch.from_numpy(data['next_observations']).float()
        self.reward = torch.from_numpy(data['rewards']).reshape(-1, 1).float()
        self.not_done = 1. - torch.from_numpy(data['dones']).reshape(-1, 1).float()
    
    def sample(self, batch_size):
        ind = torch.randint(0, self.size, size=(batch_size,))
        return (
            self.state[ind].to(self.device),
            self.action[ind].to(self.device),
            self.next_state[ind].to(self.device),
            self.reward[ind].to(self.device),
            self.not_done[ind].to(self.device)
        )

Reward调整策略

策略 说明 适用场景
no 不调整 默认
normalize 标准化 (mean=0, std=1) 通用
iql_antmaze reward - 1.0 AntMaze环境
iql_locomotion 按轨迹返回归一化 连续控制
cql_antmaze (reward - 0.5) * 4.0 CQL算法

四、数据预处理

4.1 观测向量结构

观测向量为307维,由以下部分拼接而成:

组件 维度 说明
ego_state 9 自车状态(位置、速度、角度等)
lane_info 2 车道宽度 + 横向偏移
lidar 240 LiDAR扫描数据(240个角度bin)
nearby_vehicles 20 最多5辆车 × 4特征
waypoints 36 最多12个路点 × 3特征

4.2 各组件提取逻辑

1. LiDAR特征提取 (carla_env.py:513-547)

python 复制代码
# LiDAR数据转换流程
max_range = 50.0
lidar_features = np.full((240,), max_range)  # 初始化

for detection in self.lidar_data:
    x, y = detection.point.x, detection.point.y
    # 坐标变换:全局→自车局部
    local_x = np.cos(-ego_yaw) * x - np.sin(-ego_yaw) * y
    local_y = np.sin(-ego_yaw) * x + np.cos(-ego_yaw) * y
    
    distance = np.sqrt(local_x**2 + local_y**2)
    angle_deg = (np.degrees(np.arctan2(local_y, local_x)) + 360) % 360
    index = int(angle_deg // 1.5)  # 1.5°分辨率,240个bin
    
    if index < 240:
        lidar_features[index] = min(lidar_features[index], distance)

lidar_features /= max_range  # 归一化到[0, 1]

2. 自车状态提取 (carla_env.py:549-592)

包含9维特征:

  • ego_x, ego_y: 全局坐标
  • ego_yaw: 航向角(弧度)
  • speed: 速度大小
  • angular_velocity.z: 角速度
  • acceleration.x/y: 加速度分量
  • front_vehicle_distance: 前车距离
  • relative_speed: 相对前车速度

3. 周围车辆信息 (carla_env.py:594-633)

最多检测5辆周围车辆,每辆车4个特征:

  • local_x, local_y: 相对自车的局部坐标
  • yaw_diff: 相对航向角
  • speed: 车辆速度

4. 路点信息 (carla_env.py:635-659)

提取前方12个路点,每个路点包含:

  • local_x, local_y: 局部坐标
  • yaw_relative: 相对航向角

5. 车道信息 (carla_env.py:661-683)

  • lane_width: 当前车道宽度
  • lateral_offset: 自车偏离车道中心线的距离

五、模型加载

5.1 模型保存与加载接口

保存模型

python 复制代码
model = Diffusion_QL(state_dim=307, action_dim=3, max_action=1.0, ...)
model.save_model('./params_dql', id=200)  # 保存为 actor_200.pth, critic_200.pth

加载模型

python 复制代码
model = Diffusion_QL(state_dim=307, action_dim=3, max_action=1.0, ...)
model.load_model('./params_dql', id=200)  # 加载指定checkpoint

5.2 推理流程 (run_dql_in_carla.py)

python 复制代码
# 1. 环境初始化
env = gym.make('carla-v0', params=carla_params)

# 2. 模型初始化
model = Diffusion_QL(
    state_dim=307,
    action_dim=3,
    max_action=1.0,
    device=device,
    discount=0.99,
    tau=0.005,
    eta=0.01,
    beta_schedule='vp',
    n_timesteps=5
)

# 3. 加载预训练模型
model.load_model('./params_dql', id=200)

# 4. 推理循环
obs = env.reset()
while not done:
    obs_vec = convert_obs_dict_to_vector(obs)
    action = model.sample_action(obs_vec)
    obs, reward, cost, done, info = env.step(action)

动作采样策略

python 复制代码
def sample_action(self, state):
    # 重复采样50次
    state_rpt = torch.repeat_interleave(state, repeats=50, dim=0)
    with torch.no_grad():
        action = self.actor.sample(state_rpt)
        q_value = self.critic_target.q_min(state_rpt, action).flatten()
        idx = torch.multinomial(F.softmax(q_value, dim=0), 1)  # 按Q值加权采样
    return action[idx].cpu().data.numpy().flatten()

六、CARLA仿真环境

6.1 环境配置参数

python 复制代码
carla_params = {
    'number_of_vehicles': 100,      # 周围车辆数量
    'number_of_walkers': 0,         # 行人数量
    'dt': 0.1,                      # 仿真时间步长(秒)
    'ego_vehicle_filter': 'vehicle.tesla.model3',  # 自车类型
    'surrounding_vehicle_spawned_randomly': True, # 车辆随机生成
    'port': 2000,                   # CARLA服务器端口
    'town': 'Town03',               # 地图场景
    'max_time_episode': 1000,       # 每回合最大步数
    'max_waypoints': 12,            # 路点数量
    'visualize_waypoints': True,    # 可视化路点
    'desired_speed': 8,             # 期望速度(m/s)
    'max_ego_spawn_times': 200,     # 自车生成重试次数
    'view_mode': 'top',             # 视角模式:'top' 或 'follow'
    'traffic': 'off',               # 交通灯控制
    'lidar_max_range': 50.0,        # LiDAR最大感知距离
    'max_nearby_vehicles': 5,       # 最大检测车辆数
}

6.2 传感器配置

LiDAR传感器

  • 通道数:1(水平扫描)
  • 最大距离:50米
  • 旋转频率:10Hz
  • 点云密度:10000点/秒
  • 垂直FOV:0°(仅水平扫描)

碰撞传感器

  • 实时检测碰撞事件
  • 记录碰撞强度
  • 触发回合终止

6.3 奖励函数设计 (carla_env.py:702-738)

奖励函数由多个分量组成:

分量 权重 说明
正向驾驶奖励 +1.0×speed 速度奖励(不超过期望速度)
超速惩罚 -1.0×(speed-desired) 超过期望速度时惩罚
车道偏离惩罚 -1.0×lateral_offset 偏离车道中心惩罚
横向加速度惩罚 -0.5×|a_lat| 平滑驾驶约束
静止惩罚 -1.0 前方无车但静止时惩罚
碰撞惩罚 -100.0 发生碰撞
偏离道路惩罚 -100.0 驶离可行驶区域

6.4 成本函数设计 (carla_env.py:740-768)

用于安全强化学习的约束成本:

分量 权重 说明
碰撞成本 +20.0 发生碰撞
偏离道路成本 +20.0 驶离可行驶区域
超速成本 (speed-desired)/desired 超速比例

6.5 终止条件 (carla_env.py:770-822)

python 复制代码
def _terminal(self):
    # 1. 碰撞检测
    if len(self.collision_hist) > 0:
        return True
    
    # 2. 超过最大步数
    if self.time_step > self.max_time_episode:
        return True
    
    # 3. 驶离可行驶车道
    waypoint = self.world.get_map().get_waypoint(...)
    if waypoint is None:
        return True
    
    # 4. 逆向行驶(航向偏差>90°)
    if abs(yaw_diff) > np.pi / 2:
        return True
    
    # 5. 偏离车道中心过远
    if lateral_offset > lane_width / 2 + 1.0:
        return True
    
    return False

七、关键技术要点

7.1 坐标变换

所有传感器数据需转换为自车局部坐标系:

python 复制代码
# 全局坐标 → 自车局部坐标
local_x = np.cos(-ego_yaw) * global_x - np.sin(-ego_yaw) * global_y
local_y = np.sin(-ego_yaw) * global_x + np.cos(-ego_yaw) * global_y

7.2 同步模式控制

CARLA支持同步和异步两种模式:

  • 同步模式:服务器等待客户端指令后才推进仿真,用于精确控制
  • 异步模式:服务器自主运行,用于环境重置时清理场景
python 复制代码
def _set_synchronous_mode(self, synchronous=True):
    self.settings.synchronous_mode = synchronous
    self.world.apply_settings(self.settings)

7.3 渲染视角

支持两种渲染视角:

模式 说明 适用场景
top 鸟瞰视角(40米高空) 全局观察
follow 第三人称跟随视角 细节观察

八、使用示例

8.1 基础演示

bash 复制代码
python easycarla_demo.py

功能:

  • 随机选择自动驾驶或手动控制
  • 输出每步奖励和成本
  • 展示基本Gym接口

8.2 Diffusion Q-Learning 评估

bash 复制代码
cd example
python run_dql_in_carla.py

功能:

  • 加载预训练的Diffusion Q-Learning模型
  • 在CARLA中运行评估
  • 输出回合总奖励和步数

九、数据集下载

来源 链接
Hugging Face https://huggingface.co/datasets/silverwingsbot/easycarla
百度网盘 链接(提取码: 2049)

数据集规格

  • 大小:约2.76 GB
  • 格式:HDF5
  • 轨迹数:7,000+
  • 时间步数:110万+
  • 专家/随机比例:8:2

十、预训练模型与数据集关系

10.1 预训练模型来源

example/params_dql/actor_200.pthexample/params_dql/critic_200.pth 这两个预训练模型文件确实是通过 easycarla_offline_dataset.hdf5 离线数据集训练得到的

10.2 模型命名规则

文件名中的 200 表示训练迭代次数:

  • actor_200.pth → Actor网络(扩散模型)在第200个训练epoch/迭代保存
  • critic_200.pth → Critic网络(Double Q-Learning)在第200个训练epoch/迭代保存

10.3 训练算法匹配

使用的 Diffusion Q-Learning 算法支持:

  • 行为克隆(Behavior Cloning):从数据集中学习专家行为
  • Q学习:优化价值函数
  • 损失函数bc_loss + η * q_loss(行为克隆损失 + Q损失)

10.4 数据集格式匹配

数据集包含训练所需的完整数据:

数据字段 维度 用途
observations (N, 307) 状态输入
actions (N, 3) 专家动作标签(油门、转向、刹车)
rewards (N,) 奖励信号
next_observations (N, 307) 下一状态(用于TD目标计算)
done (N,) 终止标志

observations(307维向量)状态输入:

数据集包含完整的自车轨迹信息,由以下字段共同构成:

字段 维度 用途
observations (N, 307) 当前时刻观测(自车状态+LiDAR+路点+周围车辆)
actions (N, 3) 专家执行的动作
rewards (N,) 奖励信号
next_observations (N, 307) 下一时刻观测
done (N,) 是否到达轨迹终点
info dict 额外信息(is_collisionis_off_road

数据集规模

  • 轨迹数:7,000+
  • 时间步数:110万+
  • 专家/随机比例:8:2

观测向量中的自车状态 (前9维 ego_state):

索引 状态量 说明
0-1 ego_x, ego_y 自车全局坐标
2 ego_yaw 自车航向角(弧度)
3 speed 自车速度
4 angular_velocity.z 角速度
5-6 acceleration.x/y 加速度分量
7 front_vehicle_distance 前车距离
8 relative_speed 相对前车速度

actions动作空间详细说明(3维向量):

索引 动作类型 取值范围 说明
[0] throttle(油门) 0.0, 1.0 0=无油门,1=全油门
[1] steer(转向) -1.0, 1.0 -1=左转,0=直行,1=右转
[2] brake(刹车) 0.0, 1.0 0=无刹车,1=急刹
python 复制代码
# 动作空间定义(来自 carla_env.py:43-46)
self.action_space = spaces.Box(
    low=np.array([0.0, -1.0, 0.0], dtype=np.float32),  # 最小值
    high=np.array([1.0, 1.0, 1.0], dtype=np.float32)   # 最大值
)

10.5 训练流程

复制代码
┌──────────────────────────────────────────────────────────────┐
│                  训练流程示意图                              │
├──────────────────────────────────────────────────────────────┤
│  easycarla_offline_dataset.hdf5                            │
│          │                                                  │
│          ▼                                                  │
│  ┌──────────────────┐                                       │
│  │  Data_Sampler    │ ← 数据采样器                          │
│  └────────┬─────────┘                                       │
│           │                                                 │
│           ▼                                                 │
│  ┌──────────────────┐                                       │
│  │ Diffusion_QL     │ ← 训练算法                            │
│  │  (BC + Q-Learning)│                                      │
│  └────────┬─────────┘                                       │
│           │                                                 │
│           ▼                                                 │
│  actor_200.pth  critic_200.pth                             │
└──────────────────────────────────────────────────────────────┘

10.6 完整训练流程

10.6.1 训练环境准备
  1. 安装依赖

    bash 复制代码
    pip install -r requirements.txt
    pip install -e .
  2. 下载数据集

    • 从 Hugging Face 或百度网盘下载 easycarla_offline_dataset.hdf5
    • 放置到 example/ 目录下
10.6.2 训练脚本(train_dql.py)

项目提供了完整的训练脚本 example/train_dql.py

python 复制代码
import h5py
import torch
from agents.ql_diffusion import Diffusion_QL
from utils.data_sampler import Data_Sampler

# 加载数据集
with h5py.File('easycarla_offline_dataset.hdf5', 'r') as f:
    data = {
        'observations': f['observations'][:],
        'actions': f['actions'][:],
        'rewards': f['rewards'][:],
        'next_observations': f['next_observations'][:],
        'done': f['done'][:]
    }

# 创建数据采样器
replay_buffer = Data_Sampler(data, device, reward_tune='normalize')

# 初始化模型
model = Diffusion_QL(
    state_dim=307,
    action_dim=3,
    max_action=1.0,
    device=device,
    discount=0.99,
    tau=0.005,
    eta=0.01,
    beta_schedule='vp',
    n_timesteps=5
)

# 训练循环
for epoch in range(200):
    metrics = model.train(replay_buffer, iterations=1000, batch_size=128)
    
    # 保存模型(每50轮或最后一轮)
    if epoch % 50 == 0 or epoch == 199:
        model.save_model('./params_dql', id=epoch+1)
10.6.3 训练命令
bash 复制代码
cd example
python train_dql.py
10.6.4 训练算法详解

Diffusion Q-Learning 结合了行为克隆和Q学习:

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    训练迭代流程                             │
├─────────────────────────────────────────────────────────────┤
│  1. 数据采样 → replay_buffer.sample(batch_size)           │
│                         │                                  │
│                         ▼                                  │
│  2. Critic更新 → TD目标计算 → MSE损失优化                   │
│     target_q = reward + γ * min(Q1', Q2')                  │
│                         │                                  │
│                         ▼                                  │
│  3. Actor更新 → BC Loss + η * Q Loss                       │
│     bc_loss = actor.loss(action, state)                    │
│     q_loss = -Q(s, actor(s)) / |Q|                         │
│     actor_loss = bc_loss + 0.01 * q_loss                   │
│                         │                                  │
│                         ▼                                  │
│  4. 目标网络更新 → EMA更新Actor, Polyak更新Critic          │
└─────────────────────────────────────────────────────────────┘

关键参数说明

参数 说明
discount (γ) 0.99 折扣因子
tau 0.005 Polyak平均系数
eta 0.01 Q学习损失权重
beta_schedule 'vp' 扩散过程beta调度
n_timesteps 5 扩散步数
batch_size 128 批次大小
10.6.5 模型保存

训练完成后,模型将保存到 example/params_dql/ 目录:

复制代码
params_dql/
├── actor_50.pth      # 第50轮保存
├── critic_50.pth
├── actor_100.pth     # 第100轮保存
├── critic_100.pth
├── actor_150.pth     # 第150轮保存
├── critic_150.pth
├── actor_200.pth     # 第200轮保存(最终模型)
└── critic_200.pth
10.6.6 训练时间估计

在单GPU(NVIDIA RTX 3090)上:

  • 每轮迭代(1000次训练步):约2-3分钟
  • 完整200轮训练:约6-10小时

十一、依赖说明

txt 复制代码
carla==0.9.13
gym==0.26.2
numpy==1.24.3
torch==2.0.1
h5py==3.9.0

十二、训练与测试的奖励函数调用分析

12.1 调用关系对比

训练脚本和测试脚本对 _get_reward 的调用方式完全不同:

脚本 是否调用 _get_reward 奖励来源
train_dql.py 从 HDF5 文件读取预计算的奖励
run_dql_in_carla.py 实时调用 CARLA 环境计算

12.2 训练流程

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    训练流程 (train_dql.py)                     │
├─────────────────────────────────────────────────────────────────┤
│  easycarla_offline_dataset.hdf5                                │
│         │                                                      │
│         ▼                                                      │
│  读取 precomputed_rewards ← 采集时已调用 _get_reward()         │
│         │                                                      │
│         ▼                                                      │
│  训练模型 (Diffusion_QL.train())                              │
│         │                                                      │
│         ▼                                                      │
│  保存 actor.pth, critic.pth                                    │
└─────────────────────────────────────────────────────────────────┘

12.3 测试流程

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                   测试流程 (run_dql_in_carla.py)               │
├─────────────────────────────────────────────────────────────────┤
│  加载 actor.pth, critic.pth                                   │
│         │                                                      │
│         ▼                                                      │
│  env.step(action)                                              │
│         │                                                      │
│         ├─► _get_reward() ← 实时计算奖励                      │
│         ├─► _get_cost()                                       │
│         └─► 返回 (obs, reward, cost, done, info)               │
│         │                                                      │
│         ▼                                                      │
│  循环直到 done=True                                            │
└─────────────────────────────────────────────────────────────────┘

12.4 关键区别

训练脚本 train_dql.py

  • 不直接调用 _get_reward
  • easycarla_offline_dataset.hdf5 加载预计算的奖励
  • 这些奖励是在数据采集时由 CARLA 环境的 _get_reward 预先计算并保存的

测试脚本 run_dql_in_carla.py

  • 每一步都调用 env.step(action)
  • 内部会实时调用 _get_reward() 计算当前步骤的奖励

12.5 潜在问题分析

  1. 奖励分布不一致

    • 训练时的奖励来自专家数据采集时的预计算值
    • 测试时的奖励是实时计算的
    • 可能存在分布偏移
  2. 策略差异

    • 数据采集时的专家策略与测试时模型的策略可能不同
    • 导致测试时的状态分布与训练数据不匹配
  3. 性能影响

    • 模型可能在训练数据上表现良好
    • 但在测试环境中泛化性能下降

十三、引用致谢

本项目基于以下开源工作:

  1. CARLA Simulator - 自动驾驶仿真平台
  2. gym-carla - CARLA的Gym接口封装
  3. Diffusion Policies for Offline RL - 扩散模型在离线RL中的应用

十四、数据集说明 (easycarla_offline_dataset.hdf5)

数据集基本信息

属性
文件名 easycarla_offline_dataset.hdf5
样本数量 1,114,451 条
观测维度 307 维
动作维度 3 维 (Throttle, Steer, Brake)

数据集字段

字段名 形状 说明
observations (1114451, 307) 当前观测向量
actions (1114451, 3) 专家动作 (Throttle, Steer, Brake)
rewards (1114451,) 即时奖励
next_observations (1114451, 307) 下一时刻观测
done (1114451,) Episode结束标志
costs (1114451,) 成本值
info Group 信息组

info字段详情

info 是一个 HDF5 Group,包含:

子字段 说明
is_collision 是否发生碰撞
is_off_road 是否偏离道路

observations 观测向量结构 (307维)

维度范围 内容 维度 说明
0-8 ego_state 9 自车状态(速度、位置等)
9-10 lane_info 2 车道信息(车道宽度、横向偏移)
11-250 lidar 240 激光雷达点云数据
251-270 nearby_vehicles 20 周围车辆信息(5辆车×4维)
271-306 waypoints 36 路径点 (12个点×3维: x, y, yaw)
ego_state (9维)
索引 内容 单位
0-2 自车位置 (x, y, z)
3 自车速度 m/s
4-6 自车加速度 (a_x, a_y, a_z) m/s²
7 前方障碍物距离
8 航向角 弧度
lidar (240维)

激光雷达点云数据,按距离和角度编码。

nearby_vehicles (20维)

周围5辆车的信息,每辆车4维:

  • 相对位置 x, y
  • 相对速度 v_x, v_y

数据集使用示例

python 复制代码
import h5py

with h5py.File('easycarla_offline_dataset.hdf5', 'r') as f:
    # 加载观测和动作
    observations = f['observations'][:]  # (1114451, 307)
    actions = f['actions'][:]           # (1114451, 3)
    
    # 解析观测结构
    ego_state = observations[:, 0:9]      # 自车状态
    lane_info = observations[:, 9:11]     # 车道信息
    lidar = observations[:, 11:251]        # 激光雷达
    nearby_vehicles = observations[:, 251:271]  # 周围车辆
    waypoints = observations[:, 271:307]   # 路径点

训练脚本中的使用

train_offline_bc_planning.py / train_offline_dql_planning.py:

python 复制代码
state = torch.FloatTensor(self.data['observations'][idx])  # 完整307维
action = torch.FloatTensor(self.data['actions'][idx])

注意事项

  1. LiDAR和周围车辆数据:虽然数据集中包含这些数据,但部分训练脚本(如BC)并未专门处理这些高维感知数据
  2. 奖励来自预计算:训练时使用的奖励是数据采集时预计算的,与在线计算可能存在差异
  3. 轨迹提取:waypoints只有12个点,训练脚本会外推至20个点(点间距2米)