4、激光雷达数据采集:激光雷达驱动安装、话题数据解析、可视化与录制
激光雷达,说白了就是机器人的「眼睛」。没有它,机器人就是个瞎子。我在做移动机器人导航时,踩过最多的坑就是激光雷达数据没采好。你想想看,数据都没采对,后面建图、定位全白搭。
这一章,咱们就手把手搞定激光雷达的驱动安装、话题数据解析、可视化与录制。嗯,都是实打实的干货。
4.1 激光雷达驱动安装
市面上常见的激光雷达,比如思岚的RPLIDAR、镭神的LS系列、Velodyne的VLP-16,驱动安装方式大同小异。我个人习惯用 apt 安装官方维护的驱动包,省心。
以RPLIDAR A1为例,安装命令如下:
sudo apt install ros-noetic-rplidar-ros
如果你用的是镭神N10,那就装这个:
sudo apt install ros-noetic-lslidar-driver
Velodyne的驱动稍微复杂点,但也是标准流程:
sudo apt install ros-noetic-velodyne-driver
sudo apt update。我遇到过好几次因为源没更新,装了个老版本驱动,结果雷达死活不转。
驱动装好后,启动雷达节点。以RPLIDAR为例:
roslaunch rplidar_ros rplidar.launch
这时候你应该能看到雷达开始旋转,终端里刷出一堆数据。如果没反应,检查一下USB权限:
sudo chmod 666 /dev/ttyUSB0
4.2 话题数据解析
雷达启动后,数据会通过ROS话题发布。默认话题名一般是 /scan。咱们用 rostopic 命令看看:
rostopic echo /scan
你会看到一堆数据,别慌。我来拆解一下核心字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| header.stamp | time | 时间戳,记录数据采集时刻 |
| header.frame_id | string | 坐标系名称,通常是 laser_frame |
| angle_min | float32 | 扫描起始角度(弧度) |
| angle_max | float32 | 扫描结束角度(弧度) |
| angle_increment | float32 | 角度分辨率 |
| time_increment | float32 | 每帧时间间隔 |
| scan_time | float32 | 扫描周期 |
| range_min | float32 | 最小测量距离(米) |
| range_max | float32 | 最大测量距离(米) |
| ranges | float32[] | 距离数据数组 |
| intensities | float32[] | 反射强度数组 |
为什么要有 intensities?说白了就是雷达收到的回波强度。我在做室内定位时,就靠这个区分玻璃墙和普通墙壁——玻璃的反射强度明显低很多。
如果你想在代码里解析这些数据,写个简单的订阅器就行:
#!/usr/bin/env python3
import rospy
from sensor_msgs.msg import LaserScan
def scan_callback(msg):
# 获取第一个有效距离
for i, dist in enumerate(msg.ranges):
if dist > msg.range_min and dist < msg.range_max:
rospy.loginfo(f"角度 {msg.angle_min + i * msg.angle_increment:.2f} rad, 距离 {dist:.2f} m")
break
rospy.init_node('scan_parser')
rospy.Subscriber('/scan', LaserScan, scan_callback)
rospy.spin()
inf 或 nan,直接拿来用会出大问题。
4.3 可视化
光看数字没意思,咱们用RViz把数据变成图像。启动RViz:
rviz
在RViz里,添加一个 LaserScan 显示插件。设置话题为 /scan,坐标系选 laser_frame。嗯,这时候你应该能看到一圈点云了。
我个人习惯把点云颜色调成渐变,近处红色、远处蓝色。这样一眼就能看出障碍物距离。设置方法:在 LaserScan 插件的 Color Transformer 里选 Intensity 或 Distance。
Range Display 里的最大最小值。我经常把最大值设成雷达的实际量程,比如RPLIDAR A1就是12米。
还有一种可视化方式是用 plotjuggler,适合看数据趋势:
sudo apt install ros-noetic-plotjuggler
rosrun plotjuggler plotjuggler
在PlotJuggler里订阅 /scan 话题,选择 ranges[0] 到 ranges[360],就能看到一条完整的扫描曲线。这个工具我在调试雷达时经常用,比RViz更直观。
4.4 数据录制
录数据用ROS的 rosbag 工具。命令很简单:
rosbag record /scan -o laser_data
这条命令会录制 /scan 话题,并自动生成一个带时间戳的bag文件,比如 laser_data_2025-01-15-14-30-00.bag。
如果你想录多个话题,比如同时录雷达和里程计:
rosbag record /scan /odom -o multi_sensor
录制完成后,回放数据:
rosbag play laser_data_2025-01-15-14-30-00.bag
回放时,你可以用 -r 参数控制速度。比如 -r 0.5 就是半速播放,方便仔细分析:
rosbag play -r 0.5 laser_data_2025-01-15-14-30-00.bag
查看bag文件信息:
rosbag info laser_data_2025-01-15-14-30-00.bag
你会看到话题列表、消息数量、时长等信息。嗯,这个命令我几乎天天用,排查数据问题全靠它。
4.5 避坑指南
最后,分享几个我踩过的坑:
- USB掉线问题: 雷达长时间运行后,USB口可能会掉线。我建议用
udev规则固定设备名,并加一个心跳检测脚本。 - 数据丢帧: 如果雷达数据频繁丢帧,检查一下CPU负载。我遇到过因为同时跑SLAM和可视化,CPU满载导致雷达数据丢失。
- 时间戳异常: 回放bag时,如果时间戳不对,用
--clock参数:rosbag play --clock laser_data.bag。 - 坐标系混乱: 多雷达场景下,每个雷达的
frame_id必须唯一。我曾经两个雷达都叫laser_frame,结果TF树直接崩了。
好了,这一章的内容就到这里。激光雷达数据采集是ROS机器人开发的基本功,你想想看,后面建图、定位、导航,哪一步离得开它?下一章咱们聊聊IMU数据采集,那个更有意思。