激光雷达工作原理与选型实战
说到激光雷达,很多刚入门的同学第一反应就是「转起来扫一圈的那个东西」。没错,但它的核心价值在于——精确测量距离。我最早接触激光雷达是在2016年做AGV小车项目,那时候市面上能选的国产雷达还不多,价格也贵。现在不一样了,几百块就能买到不错的入门款。
这一节,我们重点聊三个事:激光雷达怎么测距的、ROS2里怎么接它、市面上常见的型号怎么选。嗯,都是干货。
一、两种主流测距原理:TOF vs 三角法
激光雷达测距,说白了就是「发射一束光,等它反射回来,算时间或算位置」。目前消费级和工业级用得最多的就两种:TOF(飞行时间法)和三角法。
1. TOF(Time of Flight)
原理很简单:激光发射器发出一束脉冲光,打到物体表面反射回来,接收器捕获。通过计算光从发射到接收的时间差,乘以光速再除以2,就是距离。
公式:距离 = (光速 × 飞行时间) / 2
我在项目中用过TOF雷达做室外巡检车。它的优势很明显:测距远(几十米甚至上百米)、抗干扰强(不受环境光影响太大)、精度稳定。缺点是成本高,功耗也大一些。
2. 三角法
三角法就不一样了。它靠的是几何关系——激光器发射一束光,打到物体后反射到CMOS/PSD传感器上。物体距离不同,光斑在传感器上的位置也不同。通过三角形相似原理,就能算出距离。
说白了,三角法就是「看光斑落在哪」。它的优点是近距离精度极高(毫米级),而且成本低。但缺点也很致命——距离越远精度越差,一般有效范围就几米到十几米。
| 对比项 | TOF | 三角法 |
|---|---|---|
| 测距原理 | 光飞行时间 | 光斑几何位置 |
| 典型测距范围 | 10m ~ 100m+ | 0.1m ~ 12m |
| 近距离精度 | 厘米级 | 毫米级 |
| 远距离精度 | 稳定 | 快速下降 |
| 成本 | 较高 | 较低 |
| 典型代表 | Velodyne、思岚A3 | RPLIDAR A1/A2、YDLIDAR X4 |
我的建议:如果你做室内小机器人(比如扫地机、送餐机器人),三角法完全够用,性价比高。如果你做室外无人车或需要远距离感知,老老实实上TOF。
二、ROS2驱动接口:sensor_msgs/LaserScan
不管什么原理的激光雷达,到了ROS2里,数据格式是统一的。这就是sensor_msgs/LaserScan消息。我刚开始用ROS2时,最头疼的就是搞不清这些字段到底什么意思。其实你想想看,它就是描述「一圈扫描数据」的结构。
消息结构解析
# sensor_msgs/LaserScan
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 # 反射强度(可选)
举个例子,RPLIDAR A1的典型参数:
angle_min= 0.0,angle_max= 6.28319(即360度)angle_increment≈ 0.01745(约1度)ranges数组长度 ≈ 360个点
也就是说,ranges[0]对应0度方向的距离,ranges[180]对应180度方向。嗯,就是这么直白。
我曾经踩过的坑:有一次我接了一个第三方雷达,发现地图建出来全是乱的。查了半天,原来是angle_min和angle_max设置反了,导致数据镜像。所以拿到新雷达,第一件事就是打印一下angle_min和angle_max,确认方向对不对。
ROS2驱动节点示例
下面是一个最简单的ROS2激光雷达发布节点骨架。实际项目中,你只需要替换串口读取部分即可。
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import LaserScan
import math
class LidarPublisher(Node):
def __init__(self):
super().__init__('lidar_publisher')
self.publisher_ = self.create_publisher(LaserScan, 'scan', 10)
self.timer = self.create_timer(0.1, self.publish_scan)
def publish_scan(self):
scan = LaserScan()
scan.header.stamp = self.get_clock().now().to_msg()
scan.header.frame_id = 'laser_frame'
scan.angle_min = 0.0
scan.angle_max = 2 * math.pi
scan.angle_increment = math.pi / 180.0 # 1度
scan.time_increment = 0.0
scan.scan_time = 0.1
scan.range_min = 0.15
scan.range_max = 12.0
# 这里替换为实际雷达数据
scan.ranges = [float('inf')] * 360
self.publisher_.publish(scan)
def main(args=None):
rclpy.init(args=args)
node = LidarPublisher()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
注意:frame_id一定要和你的TF树对应。我习惯统一用laser_frame,然后在URDF里定义好它和机器人基座的变换关系。
三、常用雷达选型:RPLIDAR vs YDLIDAR
现在市面上消费级激光雷达,基本被思岚(RPLIDAR)和亿嘉(YDLIDAR)两家占了。我两个品牌都用过,说说真实感受。
RPLIDAR系列
- A1:入门款,三角法,6米范围,性价比高。适合学习和小型机器人。
- A2:升级款,三角法,12米范围,精度更好。我第一个项目用的就是它。
- A3:TOF款,25米范围,适合室外或大场景。
- S1:TOF款,40米,带强度信息,适合SLAM建图。
YDLIDAR系列
- X4:三角法,10米,性价比极高。很多教育机器人用这个。
- G4:三角法,12米,精度比X4好一些。
- TG系列:TOF款,30米以上,适合工业场景。
| 型号 | 原理 | 测距 | 价格区间 | 推荐场景 |
|---|---|---|---|---|
| RPLIDAR A1 | 三角法 | 6m | ¥300-400 | 入门学习 |
| RPLIDAR A2 | 三角法 | 12m | ¥600-800 | 室内机器人 |
| RPLIDAR A3 | TOF | 25m | ¥1500-2000 | 室外/大场景 |
| YDLIDAR X4 | 三角法 | 10m | ¥200-300 | 教育/入门 |
| YDLIDAR G4 | 三角法 | 12m | ¥400-600 | 室内机器人 |
| YDLIDAR TG30 | TOF | 30m | ¥2000+ | 工业/室外 |
我的选型建议:
- 预算有限、做室内小机器人:YDLIDAR X4 或 RPLIDAR A1
- 需要建图精度高一些:RPLIDAR A2 或 YDLIDAR G4
- 要做室外或大场景:RPLIDAR A3 或 YDLIDAR TG系列
- ROS2驱动成熟度:RPLIDAR官方支持更好,YDLIDAR社区驱动也很活跃
四、知识体系总览
下面这张图,把这一节的核心逻辑串起来了。你一看就明白。
嗯,这一节的内容就这些。你理解了TOF和三角法的区别,知道怎么在ROS2里发布LaserScan消息,也清楚了RPLIDAR和YDLIDAR怎么选。接下来,我们就可以把这些知识用到实际的仿真联调里了。