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

注意: 有些雷达需要先插USB再上电,有些则相反。我曾经因为顺序搞反,折腾了半小时才发现是供电问题。

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()

重点: 解析时一定要做距离有效性检查。雷达数据里经常出现 infnan,直接拿来用会出大问题。

4.3 可视化

光看数字没意思,咱们用RViz把数据变成图像。启动RViz:

rviz

在RViz里,添加一个 LaserScan 显示插件。设置话题为 /scan,坐标系选 laser_frame。嗯,这时候你应该能看到一圈点云了。

我个人习惯把点云颜色调成渐变,近处红色、远处蓝色。这样一眼就能看出障碍物距离。设置方法:在 LaserScan 插件的 Color Transformer 里选 IntensityDistance

小技巧: 如果点云显示不全,检查一下 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

注意: 录制时别开太多话题。我曾经一次录了20个话题,结果bag文件10分钟就飙到5GB,硬盘直接爆了。

录制完成后,回放数据:

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数据采集,那个更有意思。