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度就够用。
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图像里分不清远处和近处的物体,但深度相机可以。我在做泊车场景时,深度相机帮了大忙——它能精确测量车尾到墙的距离。
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万点每秒对大多数场景已经足够。
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的精度受噪声影响很大。我建议你在城市峡谷场景里把噪声调大一点——模拟高楼遮挡信号的情况。开阔路段则可以调小。
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 | 全局定位 |
好了,这一章的内容就到这里。传感器配置看起来简单,但真正用好它们需要大量实践。下一章我们会讲如何用这些传感器数据训练自动驾驶模型——到时候你就知道今天学的这些有多重要了。