🔦 第3章 激光雷达数据采集
做SLAM这么多年,我始终觉得激光雷达是让人又爱又恨的传感器。爱它精度高、直接测距,恨它娇气——运动快了畸变,遇到玻璃直接“失明”。这一章咱们就聊聊2D/3D激光雷达的配置、点云格式,还有那些年我踩过的坑。
⚙️ 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格式。
| 格式 | 适用场景 | 备注 |
|---|---|---|
| LaserScan | 2D雷达原始数据 | 包含角度、距离、强度 |
| PointCloud2 | 3D雷达 / 融合点云 | 可携带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)。
- 现象:玻璃门在点云里直接“消失”,或者出现一大片噪点。
- 应对策略:
- 贴磨砂膜或喷漆(临时采集时可以这样做)。
- 多角度扫描,让雷达斜着打玻璃,有时能收到漫反射。
- 后期用强度滤波或距离滤波剔除飞点。
📌 我的经验:在商场或办公楼采集时,玻璃墙几乎不可避免。我一般会在采集前用胶带在玻璃上贴几个标记点,或者在后期手动标注“玻璃区域”,建图时直接mask掉。虽然麻烦,但比后期花几天调参数靠谱。
好了,关于激光雷达数据采集的核心内容就这些。配置、格式、畸变、反光——每个点都值得你在实际项目中反复验证。