第4章:激光雷达标定基础

各位同学,今天我们来聊聊激光雷达标定。说实话,这是整个感知融合系统里最基础、也最容易踩坑的一环。我见过太多团队,算法调得天花乱坠,结果一上路就崩——最后发现,是激光雷达根本没标好。

4.1 激光雷达工作原理

激光雷达,英文叫LiDAR,全称是Light Detection And Ranging。说白了,就是通过发射激光束,测量目标距离。原理其实不复杂:发射一束激光,打到物体上反射回来,接收器记录时间差,乘以光速再除以2,距离就出来了。

但实际工程里,远没这么简单。我遇到过一个问题:为什么同一个目标,不同线束测出来的距离不一样?后来发现,是激光发射器和接收器的对准偏差导致的。嗯,这里要注意,机械式激光雷达里,每个激光器-探测器对都有微小的装配误差。

目前主流的激光雷达分三类:

  • 机械旋转式:通过电机带动激光器旋转,实现360°扫描。代表产品有Velodyne HDL-64、禾赛Pandar系列。优点是视场角大,缺点是机械结构复杂,寿命有限。
  • 固态式:没有旋转部件,通过光学相控阵或微振镜实现扫描。体积小、可靠性高,但视场角受限。
  • 混合固态式:介于两者之间,比如MEMS振镜方案。目前很多量产车都在用。

我个人习惯把激光雷达分成两类来看:测距原理和扫描方式。测距原理决定了精度,扫描方式决定了覆盖范围。标定时,这两者都要考虑。

4.2 点云数据格式

激光雷达输出的原始数据,就是点云。每个点包含三维坐标(x, y, z)和反射强度(intensity)。有些雷达还会输出时间戳、线束ID、回波次数等信息。

常见的点云格式有:

格式 特点 典型应用
PCD Point Cloud Library原生格式,支持ASCII和二进制 算法开发、可视化
PLY 支持顶点和面片,可存储颜色信息 3D建模、渲染
LAS/LAZ 行业标准格式,支持分类、回波等属性 测绘、地理信息系统
BIN 自定义二进制格式,体积小、解析快 自动驾驶实时系统

我建议初学者直接用PCD格式,因为PCL库支持最好。但实际工程中,我们更常用BIN格式——省空间、解析快。我记得有一次,客户要求点云数据必须实时传输,PCD格式一帧要2MB,换成BIN后压缩到500KB,带宽压力瞬间下来了。

来看一个简单的点云数据读取示例:

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
if (pcl::io::loadPCDFile<pcl::PointXYZI>("scan.pcd", *cloud) == -1) {
    PCL_ERROR("Couldn't read file scan.pcd\n");
    return -1;
}

std::cout << "Loaded " << cloud->width * cloud->height << " data points" << std::endl;

这里要注意,PointXYZI结构体包含x、y、z和intensity四个字段。intensity值反映了目标表面的反射特性,对目标识别很有帮助。比如,车道线反射率通常比路面高,通过intensity就能区分。

小技巧:标定时,我习惯在场景中放置高反射率标定板(比如白色亚光板),这样点云中能清晰看到标定板轮廓,方便提取特征点。

4.3 激光雷达坐标系定义

坐标系定义是标定的基础。搞错了坐标系,后面所有工作都是白费。我见过一个团队,标定完发现点云和相机图像对不上,查了两天才发现——激光雷达坐标系定义和算法里用的不一致。

激光雷达坐标系通常遵循右手定则:

  • X轴:指向车辆前方(或雷达安装方向)
  • Y轴:指向车辆左侧(或雷达左侧)
  • Z轴:指向上方

但不同厂商可能有差异。比如Velodyne的坐标系是:X轴指向车辆右侧,Y轴指向前方,Z轴向上。而禾赛的坐标系则遵循ROS标准:X轴向前,Y轴向左,Z轴向上。

为什么会这样?说白了,就是历史遗留问题。早期激光雷达主要用于测绘,坐标系定义偏向地理坐标系。后来自动驾驶兴起,大家才逐渐统一到车辆坐标系。

我建议的做法是:在标定前,先确认雷达的原始坐标系定义。然后统一转换到车辆坐标系下。转换公式很简单:

// 假设原始坐标系为Velodyne定义
// 需要转换到ROS标准坐标系
// 原始: X_right, Y_front, Z_up
// 目标: X_front, Y_left, Z_up

pcl::PointCloud<pcl::PointXYZI>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZI>);
Eigen::Matrix4f transform = Eigen::Matrix4f::Identity();
transform(0,0) = 0;  transform(0,1) = 1;  // X_front = Y_original
transform(1,0) = -1; transform(1,1) = 0;  // Y_left = -X_original
// Z保持不变

pcl::transformPointCloud(*cloud, *transformed_cloud, transform);
避坑指南:我曾经在标定一个16线激光雷达时,发现标定结果总是有5cm左右的偏差。排查了很久,最后发现是雷达的安装角度有0.5°的倾斜。这个角度在近距离影响不大,但到了50米外,偏差就放大到40cm了。所以,标定前一定要用水平仪确认雷达的安装姿态。

4.4 本章知识体系

为了让大家更直观地理解本章内容,我画了一张结构图:

激光雷达标定基础 - 知识体系 工作原理 • 机械旋转式 • 固态式 • 混合固态式 • 测距原理:TOF • 扫描方式 点云数据格式 • PCD格式 • PLY格式 • LAS/LAZ格式 • BIN格式 • 字段:x,y,z,intensity 坐标系定义 • 右手定则 • X轴:前方/右侧 • Y轴:左侧/前方 • Z轴:向上 • 厂商差异 标定目标 统一坐标系 → 精确测量 → 可靠感知 实践:PCL读取点云 + 坐标系转换 图4-1 激光雷达标定基础知识体系

这张图把本章的三个核心内容串起来了。你想想看,工作原理决定了你用什么方式获取数据,数据格式决定了你怎么处理这些数据,坐标系定义决定了你怎么把数据用起来。三者缺一不可。

核心要点:

  • 激光雷达标定的本质,是建立从雷达原始测量到车辆坐标系的精确映射关系
  • 点云数据格式的选择,要在精度、速度和存储之间做权衡
  • 坐标系定义必须统一,否则后续的融合、定位、规划都会出错

好了,这一章就到这里。记住一句话:标定做不好,算法再好也白搭。下一章我们聊聊相机标定,到时候会讲到怎么把相机和激光雷达的数据对齐——嗯,那才是真正有意思的部分。

可可精品资料库