激光雷达工作原理与选型实战

说到激光雷达,很多刚入门的同学第一反应就是「转起来扫一圈的那个东西」。没错,但它的核心价值在于——精确测量距离。我最早接触激光雷达是在2016年做AGV小车项目,那时候市面上能选的国产雷达还不多,价格也贵。现在不一样了,几百块就能买到不错的入门款。

这一节,我们重点聊三个事:激光雷达怎么测距的、ROS2里怎么接它、市面上常见的型号怎么选。嗯,都是干货。

一、两种主流测距原理:TOF vs 三角法

激光雷达测距,说白了就是「发射一束光,等它反射回来,算时间或算位置」。目前消费级和工业级用得最多的就两种:TOF(飞行时间法)和三角法。

1. TOF(Time of Flight)

原理很简单:激光发射器发出一束脉冲光,打到物体表面反射回来,接收器捕获。通过计算光从发射到接收的时间差,乘以光速再除以2,就是距离。

公式:距离 = (光速 × 飞行时间) / 2

我在项目中用过TOF雷达做室外巡检车。它的优势很明显:测距远(几十米甚至上百米)、抗干扰强(不受环境光影响太大)、精度稳定。缺点是成本高,功耗也大一些。

2. 三角法

三角法就不一样了。它靠的是几何关系——激光器发射一束光,打到物体后反射到CMOS/PSD传感器上。物体距离不同,光斑在传感器上的位置也不同。通过三角形相似原理,就能算出距离。

说白了,三角法就是「看光斑落在哪」。它的优点是近距离精度极高(毫米级),而且成本低。但缺点也很致命——距离越远精度越差,一般有效范围就几米到十几米。

对比项TOF三角法
测距原理光飞行时间光斑几何位置
典型测距范围10m ~ 100m+0.1m ~ 12m
近距离精度厘米级毫米级
远距离精度稳定快速下降
成本较高较低
典型代表Velodyne、思岚A3RPLIDAR 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 A3TOF25m¥1500-2000室外/大场景
YDLIDAR X4三角法10m¥200-300教育/入门
YDLIDAR G4三角法12m¥400-600室内机器人
YDLIDAR TG30TOF30m¥2000+工业/室外

我的选型建议:

  • 预算有限、做室内小机器人:YDLIDAR X4 或 RPLIDAR A1
  • 需要建图精度高一些:RPLIDAR A2 或 YDLIDAR G4
  • 要做室外或大场景:RPLIDAR A3 或 YDLIDAR TG系列
  • ROS2驱动成熟度:RPLIDAR官方支持更好,YDLIDAR社区驱动也很活跃

四、知识体系总览

下面这张图,把这一节的核心逻辑串起来了。你一看就明白。

激光雷达知识体系 测距原理 TOF 三角法 ROS2驱动接口 sensor_msgs/LaserScan 常用雷达选型 RPLIDAR YDLIDAR 核心逻辑: 理解测距原理 → 掌握ROS2数据接口 → 根据场景选型 → 接入Nav2仿真 原理选择 驱动配置 硬件选型 仿真联调 本章重点:原理 + 接口 + 选型,为后续仿真联调打好基础

嗯,这一节的内容就这些。你理解了TOF和三角法的区别,知道怎么在ROS2里发布LaserScan消息,也清楚了RPLIDAR和YDLIDAR怎么选。接下来,我们就可以把这些知识用到实际的仿真联调里了。