4. CARLA传感器详解:RGB相机、深度相机、LIDAR、雷达、IMU、GNSS的配置与数据获取

各位同学,欢迎来到第四章。这一章我们聊聊CARLA里的传感器——说白了,就是给自动驾驶车装上“眼睛”和“耳朵”。

我个人习惯把传感器比作人的感官系统。RGB相机是眼睛,LIDAR是触觉,IMU是平衡感。少了哪一个,车都开不踏实。我在项目里见过不少新手,上来就怼一堆传感器,结果数据乱成一锅粥。嗯,咱们今天一个一个捋清楚。

4.1 RGB相机:最像人眼的传感器

RGB相机是仿真里最常用的传感器。它输出的是三通道彩色图像,跟手机拍的照片差不多。但要注意,仿真里的相机参数是可以随便调的——焦距、光圈、分辨率,全在代码里。

配置一个RGB相机其实很简单:

# 创建一个RGB相机
camera_bp = blueprint_library.find('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', '800')
camera_bp.set_attribute('image_size_y', '600')
camera_bp.set_attribute('fov', '90')

# 挂载到车辆上
camera = world.spawn_actor(camera_bp, transform, attach_to=vehicle)

这里有个坑——fov(视场角)别设太大。我曾经设到120度,结果图像边缘畸变得厉害,算法直接崩了。一般90度就够用。

小技巧: 如果你做目标检测,建议分辨率设高一点(比如1280x720)。但要是只做车道线识别,800x600完全够,还能省计算资源。

4.2 深度相机:给图像加个距离标签

深度相机跟RGB相机长得一模一样,但输出的不是彩色图,而是每个像素到物体的距离。说白了,就是一张灰度图——越近越亮,越远越暗。

# 深度相机配置
depth_bp = blueprint_library.find('sensor.camera.depth')
depth_bp.set_attribute('image_size_x', '800')
depth_bp.set_attribute('image_size_y', '600')

# 数据回调处理
def process_depth(image):
    # 将深度数据归一化到0-255
    depth_data = image.raw_data
    # 这里可以转成numpy数组做后续处理
    pass

为什么需要深度相机?你想想看,RGB图像里分不清远处和近处的物体,但深度相机可以。我在做泊车场景时,深度相机帮了大忙——它能精确测量车尾到墙的距离。

注意: 深度相机的有效范围有限。CARLA默认是1000米,但实际超过50米精度就开始下降。别指望它看太远。

4.3 LIDAR:点云数据的灵魂

LIDAR是自动驾驶的标配。它发射激光束,测量反射回来的时间,从而生成三维点云。CARLA里模拟的LIDAR效果相当真实——我甚至用它训练过真实场景的模型。

# 配置一个64线LIDAR
lidar_bp = blueprint_library.find('sensor.lidar.ray_cast')
lidar_bp.set_attribute('channels', '64')
lidar_bp.set_attribute('range', '100')
lidar_bp.set_attribute('points_per_second', '1000000')
lidar_bp.set_attribute('rotation_frequency', '20')

lidar = world.spawn_actor(lidar_bp, transform, attach_to=vehicle)

参数里最关键的三个:

  • channels:线数。16线、32线、64线,线越多越密,但计算量也大。
  • range:探测距离。100米够用,200米更好。
  • points_per_second:每秒点数。这个值决定了点云密度。

我曾经犯过一个错——把points_per_second设得太高,结果仿真跑起来卡成PPT。后来发现,100万点每秒对大多数场景已经足够。

核心经验: LIDAR的点云数据需要做预处理。别直接扔给算法,先做一下降采样和滤波,能省不少事。

4.4 雷达:雨雾天的救星

雷达跟LIDAR不一样。它用无线电波,穿透力强,不怕雨雾。CARLA里的雷达传感器模拟的是毫米波雷达,输出的是检测到的物体列表——每个物体有距离、速度、角度等信息。

# 雷达配置
radar_bp = blueprint_library.find('sensor.other.radar')
radar_bp.set_attribute('horizontal_fov', '30')
radar_bp.set_attribute('vertical_fov', '10')
radar_bp.set_attribute('range', '100')

def process_radar(data):
    for detection in data:
        # detection包含:距离、速度、方位角、仰角
        print(f"距离: {detection.depth}, 速度: {detection.velocity}")

雷达的视场角一般比较窄——水平30度,垂直10度。所以它适合做前向探测,不适合环视。我在做高速公路场景时,雷达用来检测前方车辆的速度变化,效果比LIDAR好。

4.5 IMU:车身的“平衡感”

IMU(惯性测量单元)测量加速度和角速度。说白了,就是知道车在怎么动——加速、减速、转弯、颠簸。

# IMU配置
imu_bp = blueprint_library.find('sensor.other.imu')
imu_bp.set_attribute('noise_accel_stddev_x', '0.01')
imu_bp.set_attribute('noise_accel_stddev_y', '0.01')
imu_bp.set_attribute('noise_gyro_stddev', '0.001')

imu = world.spawn_actor(imu_bp, transform, attach_to=vehicle)

IMU的数据通常跟GNSS配合使用。GNSS提供绝对位置,IMU提供相对运动。两者融合,才能得到稳定的定位。嗯,这里有个细节——IMU有噪声参数,别设成0,否则太理想化,跟真实数据对不上。

4.6 GNSS:全球定位系统

GNSS就是咱们常说的GPS(全球定位系统)。它输出经纬度和海拔高度。CARLA里的GNSS模拟得挺真实——会加一些随机噪声,模拟真实环境下的定位误差。

# GNSS配置
gnss_bp = blueprint_library.find('sensor.other.gnss')
gnss_bp.set_attribute('noise_alt_stddev', '0.001')
gnss_bp.set_attribute('noise_lat_stddev', '0.001')
gnss_bp.set_attribute('noise_lon_stddev', '0.001')
gnss_bp.set_attribute('noise_alt_bias', '0.0')

gnss = world.spawn_actor(gnss_bp, transform, attach_to=vehicle)

GNSS的精度受噪声影响很大。我建议你在城市峡谷场景里把噪声调大一点——模拟高楼遮挡信号的情况。开阔路段则可以调小。

避坑指南: 我曾经把GNSS的噪声设成0,结果定位精度高得离谱,算法在真实场景里直接翻车。记住,仿真里加噪声,是为了让模型更鲁棒。

4.7 多传感器同步与数据融合

单个传感器好配,难的是让它们协同工作。CARLA提供了传感器管理器,可以统一控制所有传感器的启停和数据采集。

# 传感器管理器示例
sensor_list = []

# 添加所有传感器到列表
sensor_list.append(camera)
sensor_list.append(lidar)
sensor_list.append(radar)

# 统一监听数据
for sensor in sensor_list:
    sensor.listen(lambda data: process_data(sensor, data))

多传感器同步的关键是时间戳。每个传感器数据都带有时间戳,你需要在回调函数里对齐它们。我一般用队列来缓存数据,等所有传感器都到了再一起处理。

传感器 数据类型 典型频率 主要用途
RGB相机 图像 30 Hz 目标检测、车道线识别
深度相机 深度图 30 Hz 距离测量、避障
LIDAR 点云 10-20 Hz 三维感知、建图
雷达 目标列表 20 Hz 速度检测、远距离探测
IMU 加速度/角速度 100 Hz 姿态估计、运动补偿
GNSS 经纬度 10 Hz 全局定位

好了,这一章的内容就到这里。传感器配置看起来简单,但真正用好它们需要大量实践。下一章我们会讲如何用这些传感器数据训练自动驾驶模型——到时候你就知道今天学的这些有多重要了。