第2章:点云数据基础——从激光雷达原始数据到三维空间点

说实话,很多做SLAM的朋友一开始就急着调算法、跑图优化,结果定位漂移了都不知道问题出在哪。我个人的经验是——点云数据的基础没打牢。你连激光雷达吐出来的原始数据长什么样都不清楚,怎么指望它给你精准建图?

这一章,我们就来聊聊激光雷达的原始数据到底是个啥,又是怎么变成我们熟悉的(x, y, z)三维点的。嗯,这里面的坑,我踩过不少。

2.1 激光雷达的原始数据长什么样?

先问个问题:你拆开过激光雷达的数据包吗?我第一次拿到16线雷达的原始数据时,整个人是懵的——一堆十六进制数,完全看不出门道。

其实,不管你是用Velodyne、Hesai还是Ouster,原始数据的基本结构都差不多。以最常见的UDP数据包为例,它通常包含这几部分:

  • 数据包头:标识数据来源、设备型号、时间戳等
  • 激光测距值:每个激光点返回的距离(单位:米或厘米)
  • 反射强度值:目标物体对激光的反射强度(0-255)
  • 角度信息:水平旋转角度和垂直俯仰角度
  • 时间戳:精确到微秒级的采集时间

核心要点:原始数据本质上是一个极坐标系下的测量结果——每个点由(距离, 水平角, 垂直角)三个量描述。我们后续要做的,就是把它们转换到笛卡尔坐标系。

我记得有一次,团队里新来的同学直接拿原始距离值当坐标用,结果点云全飞到了天上去。嗯,这个坑你们别踩。

2.2 从极坐标到笛卡尔坐标:数学转换

说白了,激光雷达的每个点,在极坐标系下就是三个值:

  • r:激光测得的距离
  • θ:水平旋转角(通常0°在正前方,顺时针增加)
  • φ:垂直俯仰角(向上为正,向下为负)

转换到三维空间点(x, y, z)的公式其实很简单:

x = r * cos(φ) * sin(θ)
y = r * cos(φ) * cos(θ)
z = r * sin(φ)

你想想看,这个公式本质上就是把一个球面上的点投影到三个坐标轴上。我在做第一个激光雷达驱动时,就因为搞混了sin和cos的顺序,点云图直接旋转了90度——排查了整整一个下午。

个人技巧:写代码时,建议先打印一个已知位置的点(比如正前方1米处的点),验证转换是否正确。我每次写新驱动都会这么做,能省下大量调试时间。

2.3 多线激光雷达的特殊处理

16线、32线、64线、128线……线数越多,点云越密。但多线雷达有个特点:每条激光线的垂直角度是固定的。

以Velodyne VLP-16为例,它的16条激光线垂直分布在-15°到+15°之间,每条线间隔2°。也就是说,你不需要从数据包里解析每个点的垂直角度——根据激光线编号就能查到对应的垂直角。

激光线编号 垂直角度(°) 典型应用场景
0(最下方) -15 地面检测
4 -7 低矮障碍物
8 1 水平方向主视野
12 9 高处障碍物
15(最上方) 15 树木、建筑顶部

为什么要强调这个?因为很多人在做点云滤波时,会无差别地处理所有线束。我曾经在项目中遇到过这样的情况:地面点云滤波把路沿也给滤掉了,就是因为没区分不同线束的垂直角度范围。

2.4 点云数据的常见存储格式

原始数据转换完成后,我们通常需要把它存成某种标准格式。目前最常用的有三种:

  • PCD(Point Cloud Data):ROS社区最常用,支持ASCII和二进制两种格式,头部信息清晰
  • PLY(Polygon File Format):支持颜色、法向量等附加属性,适合可视化
  • LAS/LAZ:测绘行业标准,支持分类、强度等丰富属性

我个人习惯在调试阶段用PCD的ASCII格式——可以直接用文本编辑器打开查看,方便排查问题。但正式运行时一定要转成二进制,否则文件大小和读写速度会让你崩溃。

避坑指南:我曾经在项目中直接用ROS的pcl_ros保存点云,没注意坐标系单位。雷达输出的是毫米,PCL默认是米,结果点云缩小了1000倍。嗯,从那以后我每次保存都会先检查一下点的坐标范围。

2.5 知识体系总览

为了让你更直观地理解这一章的内容,我画了一张流程图:

点云数据基础:从原始数据到三维空间点 步骤1:原始UDP数据包 距离r + 角度θ,φ + 强度 步骤2:极坐标解析 提取(r, θ, φ)三元组 步骤3:坐标转换 x = r·cosφ·sinθ 多线雷达特殊处理 根据线编号查表获取垂直角 避免逐点解析角度 单线/固态雷达 直接解析每个点的角度 输出:三维空间点云 (x, y, z, intensity)

这张图把整个流程串起来了:从UDP数据包开始,经过极坐标解析、坐标转换,最终得到我们熟悉的(x, y, z)三维点。多线雷达和单线雷达的区别,就在于中间那个垂直角度的获取方式。

2.6 实战中的几个关键检查点

最后,分享几个我在实际项目中总结的检查点。每次处理点云数据前,我都会过一遍:

  1. 检查坐标系方向:雷达的x轴是朝前还是朝左?不同厂家定义不同
  2. 检查单位:距离值是米还是厘米?强度值是0-255还是0-1?
  3. 检查时间戳:是雷达本地时间还是系统时间?有没有时钟同步?
  4. 检查点云范围:用min/max看一眼坐标范围,能快速发现异常

一个小技巧:我习惯在驱动代码里加一个可视化验证模式——把转换后的点云实时显示在Rviz或Open3D里,用肉眼确认每个点都在合理位置。这比任何单元测试都管用。

好了,这一章的内容就到这里。点云数据的基础打牢了,后面做滤波、配准、建图才能心里有底。记住:数据质量决定算法上限,这句话我反复跟团队强调。

可可精品资料库