第1章:传感器数据接入——让自动驾驶的“眼睛”和“耳朵”真正工作起来

大家好,我是你们的老朋友。今天咱们正式进入Autoware实战的第一关——传感器数据接入。

说实话,我见过太多新手一上来就急着跑感知算法,结果连点云都看不到,或者图像数据全是雪花。嗯,这其实很正常。传感器接入是整个自动驾驶系统的地基,地基不稳,后面全是白搭。

这一章,我会带着大家把LiDAR、相机、IMU/GNSS这几个核心传感器的驱动配置、数据获取、以及最基础的标定原理,一个一个啃下来。别急,咱们慢慢来。

核心观点:传感器接入不是简单的“插上线就能用”。你需要理解数据格式、时间同步、坐标系转换这三个关键点。我个人的经验是,花70%的时间搞定传感器接入,后面30%的算法调试会顺畅得多。

传感器数据接入 LiDAR驱动与点云 相机驱动与图像 IMU/GNSS数据融合 传感器标定基础 • Velodyne / Ouster / Hesai • ROS2驱动配置 • 点云话题与可视化 • USB / GMSL相机 • 图像话题与压缩 • 时间戳对齐 • 9轴数据解析 • EKF融合原理 • 航向推算 • 内参标定 • 外参标定 • 联合标定工具

1.1 LiDAR驱动配置与点云数据获取

LiDAR,说白了就是自动驾驶的“眼睛”——但它不是看颜色,而是看距离。我个人最常用的就是Velodyne VLP-16和Ouster OS1-64。这两种在Autoware里都有现成的驱动包。

配置LiDAR驱动,其实就三步:

  1. 安装驱动包——用apt或者源码编译都行。我建议用源码,因为有时候apt的版本太旧。
  2. 配置IP和端口——LiDAR一般通过UDP发数据,你得告诉它你的电脑IP是多少。
  3. 启动驱动节点——然后就能在ROS2里看到/points_raw或者/velodyne_points话题了。

举个例子,Velodyne的驱动启动命令长这样:

ros2 launch velodyne_driver velodyne_driver_node.launch.py
    device_ip:=192.168.1.201
    port:=2368
    frame_id:=velodyne

小技巧:启动后记得用rviz2订阅一下点云话题。如果看到的是“一团乱麻”,别慌——大概率是坐标系没设对。我刚开始做的时候,把frame_id写成了base_link,结果点云全飘在天上,折腾了半小时才发现。

点云数据长什么样?说白了就是一个sensor_msgs::msg::PointCloud2的消息,里面包含每个点的x、y、z坐标和强度值。强度值很有用——比如车道线反光强,地面反光弱,可以用来做地面分割。

1.2 相机驱动与图像数据获取

相机这块,我踩过的坑最多。为什么?因为相机种类太多了——USB相机、GMSL相机、工业相机……每种驱动方式都不一样。

在Autoware里,最常用的还是USB相机,比如普通的USB摄像头或者Intel RealSense。驱动用usb_cam包就行:

ros2 run usb_cam usb_cam_node_exe
    --ros-args -p video_device:=/dev/video0
    -p image_width:=1280
    -p image_height:=720
    -p pixel_format:=yuyv

启动后,你会看到/image_raw话题。但注意——原始图像数据量很大,1280x720的彩色图,一帧就将近3MB。如果直接传输,网络带宽很快就满了。

注意:千万别在车里用WiFi传原始图像!我曾经在测试车上用5G WiFi传1080p图像,结果延迟飙到200ms,车辆控制直接崩了。后来改用压缩后的/image_compressed话题,延迟降到30ms以内。

图像数据的时间戳对齐是个大问题。LiDAR和相机的时钟如果不一致,融合出来的结果就是“驴唇不对马嘴”。我建议用硬件触发同步,或者至少用ROS2的time_synchronizer做软同步。

1.3 IMU/GNSS数据融合

IMU和GNSS,一个是“感觉”,一个是“定位”。IMU告诉你“我在加速”,GNSS告诉你“我在哪里”。但单独用都不靠谱——IMU会漂,GNSS会丢星。

所以,得把它们融合起来。Autoware里用的是robot_localization包,里面实现了扩展卡尔曼滤波(EKF)。配置起来其实不复杂:

ros2 run robot_localization ekf_node
    --ros-args -p frequency:=30
    -p sensor_timeout:=0.1
    -p two_d_mode:=false
    -p publish_tf:=true
    -p map_frame:=map
    -p odom_frame:=odom
    -p base_link_frame:=base_link
    -p world_frame:=map

这里有个关键点——two_d_mode参数。如果你只在平地上跑,设成true可以省掉z轴和roll/pitch的计算。但如果你要过坡道或者减速带,必须设成false,否则定位会跳。

经验之谈:IMU的安装位置很重要。我见过有人把IMU贴在车顶,结果车辆转弯时离心力导致数据严重失真。最好把IMU固定在车辆重心附近,而且要用减震垫。

GNSS这块,我推荐用RTK级别的接收机,比如u-blox F9P或者NovAtel。普通GPS精度只有2-5米,在自动驾驶里根本不够用。RTK可以做到厘米级,但需要基站或者网络差分服务。

1.4 传感器标定基础

标定,说白了就是告诉系统“每个传感器在车上的什么位置、什么角度”。没有标定,LiDAR看到的前方障碍物和相机看到的障碍物,在空间上是对不上的。

标定分两种:

  • 内参标定——针对传感器自身。比如相机的焦距、畸变参数。LiDAR的内参一般出厂就标好了,但相机需要自己标。用棋盘格和camera_calibration包就行。
  • 外参标定——传感器之间的相对位置。比如LiDAR和相机之间的旋转平移矩阵。这个最麻烦,但也是最重要的。

Autoware里有个标定工具叫calibration_toolkit,支持LiDAR到相机、LiDAR到IMU的标定。操作流程大致是:

  1. 把车停在空旷场地,放几个标定板(或者用自然特征点)。
  2. 同时录制LiDAR点云和相机图像。
  3. 运行标定算法,自动计算外参矩阵。
  4. 验证——把点云投影到图像上,看看边缘是否对齐。

避坑指南:我曾经在标定时用了太小的标定板,结果算法一直收敛不了。后来换成1.2米x0.9米的大棋盘格,一次就成功了。标定板至少要占图像面积的1/4以上。

标定完成后,你会得到一个.yaml文件,里面记录了所有外参。把这个文件放到Autoware的配置目录下,系统启动时自动加载。

嗯,这一章的内容就到这里。传感器接入这块,说白了就是“让数据流起来”。LiDAR出点云,相机出图像,IMU/GNSS出位姿,然后通过标定把它们对齐到同一个坐标系下。听起来简单,但每一步都有坑。我上面提到的那些经验,都是真金白银换来的教训。

可可精品资料库