3、激光雷达数据接入:启动激光雷达节点、可视化激光数据(RViz2)、理解LaserScan消息结构

好,咱们今天来聊聊激光雷达的数据接入。说实话,这是整个导航系统里最基础、也最关键的一步。你想想看,机器人要是连周围环境都“看”不清,那后面的路径规划、避障什么的,全都是空中楼阁。

我个人习惯把激光雷达比作机器人的“眼睛”。但这双眼睛跟我们人眼不太一样——它不关心颜色,只关心距离。它发射一束激光,碰到障碍物弹回来,算算时间差,就知道前面有多远了。

3.1 启动激光雷达节点

不同品牌的激光雷达,启动方式略有不同。但万变不离其宗,核心就是发布 LaserScan 消息。我以最常见的思岚(Slamtec)RPLIDAR 系列为例,给你演示一下。

首先,你得确保驱动装好了。如果你用的是 ROS 2 Humble,可以这样安装:

sudo apt install ros-humble-slamtec-lidar-sdk2

装好之后,启动节点就一行命令:

ros2 launch sllidar_ros2 sllidar_launch.py

嗯,这里要注意。启动的时候,终端会刷出一堆日志。你重点看有没有 connected 和 started 这两个词。如果看到 failed to open serial port,那八成是权限问题。我曾经在这上面栽过跟头——折腾了半天,最后发现是忘了把用户加到 dialout 组里。

小技巧: 如果你用的是 USB 转串口的雷达,建议先执行 ls -l /dev/ttyUSB* 看看设备有没有权限。没有的话,运行 sudo chmod 666 /dev/ttyUSB0 临时解决,或者一劳永逸地加用户组。

3.2 可视化激光数据(RViz2)

节点跑起来了,怎么知道它有没有正常工作?最直观的办法就是用 RViz2 看。

启动 RViz2:

ros2 run rviz2 rviz2

打开之后,默认是一片黑。别慌,按下面几步操作:

  1. 在左下角 Displays 面板,点击 Add 按钮。
  2. 选择 By topic 标签页。
  3. 找到 /scan 这个 topic,选中 LaserScan,点 OK。

这时候你应该能看到一圈红色的点云了。如果雷达是 360 度的,那这些点会围成一个完整的圆。如果只有 270 度,你会看到一段圆弧。

我记得第一次在 RViz2 里看到激光数据时,还挺兴奋的。但紧接着就发现问题了——点云在不停地抖动。后来排查发现,是雷达的固定螺丝松了。你看,有时候问题就这么简单。

核心要点: 在 RViz2 中,Fixed Frame 必须设置为 laser_frame 或 base_laser_link,否则你什么都看不到。这是新手最容易踩的坑。

3.3 理解 LaserScan 消息结构

光会看还不够,你得懂它背后的数据结构。说白了,LaserScan 就是一个 ROS 2 的消息类型。你可以用命令行把它打印出来看看:

ros2 topic echo /scan --once

输出大概长这样:

header:
  stamp:
    sec: 1693123456
    nanosec: 123456789
  frame_id: laser_frame
angle_min: -3.14159
angle_max: 3.14159
angle_increment: 0.0174533
time_increment: 0.0001
scan_time: 0.1
range_min: 0.15
range_max: 12.0
ranges: [0.5, 0.6, 0.7, ...]
intensities: [10, 12, 15, ...]

我来给你拆解一下每个字段的含义:

字段 含义 我的经验
header.frame_id 激光雷达的坐标系名称 一定要和 TF 树里的名字对上,否则数据没法用
angle_min / angle_max 扫描的起始和结束角度(弧度) 360度雷达一般是 -π 到 π,270度的是 -2.356 到 2.356
angle_increment 相邻两个激光点之间的角度间隔 角度越小,分辨率越高,但数据量也越大
range_min / range_max 有效测量距离范围 小于 min 或大于 max 的值,通常表示无效数据
ranges 每个角度对应的距离值(米) 这是核心数据,长度 = (angle_max - angle_min) / angle_increment
intensities 每个点的反射强度 可以用来区分不同材质的物体,但很多廉价雷达不提供

你可能会问:为什么 ranges 里有些值是 inf 或 0.0?

嗯,inf 表示没有检测到障碍物(比如射向了天空),0.0 通常表示测量失败。我在做项目时,一般会写个过滤函数,把这些无效值剔除掉,不然导航算法会出问题。

避坑指南: 我曾经遇到过一个问题——雷达数据在 RViz2 里显示正常,但导航就是不走。查了半天,发现是 range_max 设置得太小,导致远处的障碍物被忽略了。所以,一定要根据你雷达的实际参数来设置这个值。

3.4 知识体系总览

说了这么多,我画了一张图帮你梳理一下整个流程。从启动节点,到可视化,再到理解消息结构,其实是一条线:

激光雷达数据接入知识体系 启动激光雷达节点 RViz2 可视化 理解 LaserScan 消息 安装驱动 → 启动 launch 文件 检查串口权限 / 设备连接 Add → By topic → /scan 设置 Fixed Frame 为 laser_frame header / angle_min / angle_max ranges / intensities / range_min/max 最终目标:获取可靠的激光数据,为 Nav2 导航提供输入

这张图把今天的内容串起来了。从左到右,你一步步走通,激光雷达的数据就能为导航所用了。

最后,我想说一句:别怕看原始数据。很多同学喜欢直接用 RViz2 看个大概,但真正遇到问题时,ros2 topic echo 才是你的救命稻草。我调试过不下十种雷达,每次出问题,都是靠打印原始消息找到的线索。

好了,这一节就到这里。去试试你的雷达吧,看看能不能在 RViz2 里看到那圈漂亮的红色点云。

课后小练习: 用 ros2 topic info /scan 查看发布者和订阅者信息,再用 ros2 interface show sensor_msgs/msg/LaserScan 查看完整的消息定义。相信我,这两个命令你会经常用到。