3、激光雷达驱动接入:LaserScan消息格式、启动文件编写、Rviz2可视化验证
好,咱们今天来聊聊激光雷达的驱动接入。说实话,激光雷达这玩意儿,是我个人觉得机器人感知里最“实在”的传感器之一。它不像摄像头那样需要复杂的视觉算法,数据直观,处理起来也相对直接。但直接归直接,接入过程中还是有不少坑的。我刚开始做项目那会儿,就因为在启动文件里少配了一个参数,雷达数据死活出不来,折腾了一下午。嗯,咱们今天就把这事儿彻底捋清楚。
3.1 LaserScan消息格式:你得看懂雷达在说什么
激光雷达发出来的数据,在ROS2里被封装成sensor_msgs/msg/LaserScan这个消息。说白了,它就是告诉你:在某个角度上,我测到了多远的距离。
咱们来看看这个消息长什么样。我习惯用ros2 interface show命令直接看定义:
# 激光雷达单线扫描数据
std_msgs/Header header # 时间戳和坐标系ID
float32 angle_min # 扫描起始角度 (弧度)
float32 angle_max # 扫描结束角度 (弧度)
float32 angle_increment # 角度分辨率 (弧度)
float32 time_increment # 每帧测量时间间隔 (秒)
float32 scan_time # 扫描周期 (秒)
float32 range_min # 最小有效距离 (米)
float32 range_max # 最大有效距离 (米)
float32[] ranges # 距离数据数组 (米)
float32[] intensities # 强度数据数组 (可选)
这里有几个关键点,我重点说一下:
- header.frame_id:这个特别重要。它告诉Rviz2,这些数据是在哪个坐标系下测量的。我见过有人忘了设这个,结果雷达数据在Rviz2里显示成一条直线,完全对不上位置。你想想看,坐标系都错了,数据怎么可能对?
- angle_min和angle_max:这两个定义了雷达的扫描范围。比如常见的RPLIDAR A1,扫描范围是0到2π,也就是360度全覆盖。但有些工业雷达可能只扫270度,这个要注意。
- angle_increment:角度分辨率。比如360度扫描,如果一圈有720个点,那这个值就是0.5度(约0.0087弧度)。分辨率越高,点云越密,但计算量也越大。
- ranges数组:这是核心数据。数组长度 = (angle_max - angle_min) / angle_increment。每个元素代表对应角度上的距离值。如果某个角度没测到东西,值会是
inf或者NaN。
ros2 topic echo /scan直接看原始数据。如果ranges数组全是inf,那八成是雷达没转起来,或者物理连接有问题。
3.2 启动文件编写:把雷达“叫醒”
好,消息格式看懂了,接下来就是写启动文件,让雷达真正跑起来。我个人习惯用Python格式的启动文件,因为它更灵活,调试起来也方便。
这里我以思岚科技的RPLIDAR A1为例,写一个典型的启动文件:
# rplidar_launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='rplidar_ros',
executable='rplidar_composition',
name='rplidar_node',
output='screen',
parameters=[{
'serial_port': '/dev/ttyUSB0', # 串口设备
'serial_baudrate': 115200, # 波特率
'frame_id': 'laser_frame', # 坐标系ID
'angle_compensate': True, # 角度补偿
'scan_mode': 'Standard', # 扫描模式
}]
)
])
这里有几个参数,我特别想强调一下:
- serial_port:这个得根据你实际设备来。Linux下一般是
/dev/ttyUSB0或/dev/ttyACM0。我曾经遇到过一个问题,插上雷达后系统没识别到设备,后来发现是权限问题,需要用sudo chmod 666 /dev/ttyUSB0给权限。 - frame_id:这个必须和后续的TF树对应上。我一般统一叫
laser_frame,然后在TF发布里把base_link到laser_frame的变换发布出来。 - scan_mode:有些雷达支持多种扫描模式,比如标准模式、性能模式、节能模式。标准模式最稳定,我建议调试阶段先用这个。
ls /dev/tty*查看设备列表,用lsof /dev/ttyUSB0检查占用情况。否则你会看到“Failed to open serial port”的错误。
3.3 Rviz2可视化验证:眼见为实
启动文件写好了,雷达也转起来了,怎么知道数据对不对?这时候Rviz2就派上用场了。我个人觉得,Rviz2是ROS2里最直观的调试工具,没有之一。
启动Rviz2的命令很简单:
ros2 run rviz2 rviz2
然后在Rviz2里做这几步:
- 设置Fixed Frame:在左侧的“Global Options”里,把
Fixed Frame设成laser_frame。这个必须和启动文件里的frame_id一致。 - 添加LaserScan显示:点击左下角的“Add”按钮,选择“By topic”,找到
/scan话题,双击添加。 - 调整显示参数:在LaserScan的显示属性里,可以调整点的大小、颜色、最大显示距离等。我一般把
Size (m)设成0.05,颜色选成渐变,这样看起来更清晰。
如果一切正常,你应该能看到一个360度的点云图,就像雷达在“画”出周围的轮廓。如果看不到点,或者点云位置不对,别急,我教你几个排查方法:
- 检查话题是否存在:用
ros2 topic list看看有没有/scan话题。如果没有,说明雷达节点没启动成功。 - 检查数据频率:用
ros2 topic hz /scan看看数据发布频率。一般雷达是5-10Hz,如果频率为0,说明数据没发出来。 - 检查坐标系:用
ros2 tf echo /laser_frame看看TF变换是否正确。如果TF树断了,Rviz2里会显示“No transform from [laser_frame] to [base_link]”。
3.4 知识体系结构图
为了让你更直观地理解整个流程,我画了一张图:
这张图把整个流程串起来了。你从左往右看,每一步都依赖上一步。消息格式是基础,启动文件是桥梁,Rviz2是验证手段。缺了任何一环,你都看不到最终的点云图。
好了,关于激光雷达驱动接入,核心内容就这些。记住,调试的时候别慌,按部就班地检查话题、坐标系、数据频率,问题总能找到。我曾经在一个项目里,因为雷达的串口线接触不良,数据时断时续,排查了整整两天才发现是硬件问题。所以,有时候也要相信自己的直觉——软件没问题,那就看看硬件。
可可精品资料库