🔦 第3章 激光雷达数据采集

做SLAM这么多年,我始终觉得激光雷达是让人又爱又恨的传感器。爱它精度高、直接测距,恨它娇气——运动快了畸变,遇到玻璃直接“失明”。这一章咱们就聊聊2D/3D激光雷达的配置、点云格式,还有那些年我踩过的坑。

激光雷达数据采集 · 核心脉络 2D/3D 配置 串口 · 网络 · ROS驱动 点云数据格式 sensor_msgs · PCD · bin 采集注意事项 运动畸变 · 反光材质 ⚙️ 波特率 · 帧率 · 坐标系 📦 时间戳 · 强度 · 环号 ⚠️ 去畸变 · 抗反光策略

⚙️ 2D/3D 激光雷达配置

先说说2D雷达。我最早接触的是Sick TIM系列和Hokuyo UST,后来国产的思岚也用了不少。配置其实不复杂,但有几个细节容易翻车。

  • 物理连接:2D雷达多数走串口或USB转串口。记得检查波特率——我遇到过好几次,驱动默认115200,雷达实际是921600,结果啥都收不到。
  • 3D雷达:Velodyne、Ouster、RoboSense这些,基本走UDP网络。你得给雷达配一个静态IP,或者用DHCP。我个人习惯在电脑上单独拉一个网段,避免跟办公室网络冲突。
  • ROS驱动:启动文件里注意 frame_id 要统一。比如2D雷达我一般设 laser,3D设 velodyne 或 os_lidar。不然后面做tf树的时候,你想想看,找半天找不到坐标系。
💡 我的小习惯:每次拿到新雷达,先用官方上位机测一下,确认能出点云再上ROS。这一步能省下大量排查时间。

📁 点云数据格式

ROS里最常见的点云消息是 sensor_msgs/LaserScan(2D)和 sensor_msgs/PointCloud2(3D)。但做数据集时,我更喜欢存成PCD或bin格式。

格式适用场景备注
LaserScan2D雷达原始数据包含角度、距离、强度
PointCloud23D雷达 / 融合点云可携带xyz、intensity、ring等字段
PCD离线处理、深度学习点云库原生格式,支持ascii/二进制
.bin (KITTI格式)大规模数据集纯二进制,读取快,但缺字段名

嗯,这里要注意:如果你用PointCloud2,时间戳一定要填对。我见过不少rosbag里点云的时间戳是0,导致后面去畸变时完全没法做插值。

# 一个典型的PointCloud2消息字段
# 来自Velodyne VLP-16
fields: 
  - name: x
    offset: 0
    datatype: 7  # FLOAT32
  - name: y
    offset: 4
    datatype: 7
  - name: z
    offset: 8
    datatype: 7
  - name: intensity
    offset: 12
    datatype: 7
  - name: ring
    offset: 16
    datatype: 4  # UINT16

⚠️ 采集注意事项

这部分全是实战经验。我直接说重点。

🏃 运动畸变

说白了,就是雷达在扫描过程中,机器人一直在动。比如2D雷达一帧数据是360°扫描,如果车在转弯,这一帧的起点和终点对应的位姿已经不一样了。结果就是点云“扭曲”。

  • 低速移动:0.3m/s以下,畸变通常可忽略。但室内机器人经常跑0.5~1m/s,这时候就得处理了。
  • 去畸变方法:利用IMU或里程计做线性插值。我习惯在采集时同时录IMU,后处理时用 laser_geometry 或自己写插值节点。
  • 硬件技巧:有些3D雷达(如Ouster)支持“精确时间戳”模式,每个点都有时间偏移。用这个数据去畸变效果很好。
⚠️ 我曾经踩过的坑:有一次在室内走廊快速采集,没开去畸变,结果建出来的地图墙角全是圆弧。后来加了IMU去畸变,才恢复成直角。所以,如果你要建结构化地图,运动畸变必须处理。

🪞 反光材质

玻璃、镜面、抛光金属——这些是激光雷达的噩梦。光线直接透过去或者镜面反射,导致要么测不到点,要么测出飞点(outlier)。

  • 现象:玻璃门在点云里直接“消失”,或者出现一大片噪点。
  • 应对策略:
    1. 贴磨砂膜或喷漆(临时采集时可以这样做)。
    2. 多角度扫描,让雷达斜着打玻璃,有时能收到漫反射。
    3. 后期用强度滤波或距离滤波剔除飞点。
📌 我的经验:在商场或办公楼采集时,玻璃墙几乎不可避免。我一般会在采集前用胶带在玻璃上贴几个标记点,或者在后期手动标注“玻璃区域”,建图时直接mask掉。虽然麻烦,但比后期花几天调参数靠谱。

好了,关于激光雷达数据采集的核心内容就这些。配置、格式、畸变、反光——每个点都值得你在实际项目中反复验证。