4. 传感器驱动与数据融合

各位同学,欢迎来到第四章。

这一章,我们聊聊机器人的「感官」。说白了,就是怎么让机器人「看见」、「感知」自己的身体姿态,以及如何把这些零散的信息整合成有用的数据。

我在做第一个移动机器人项目时,最头疼的就是传感器。激光雷达转不起来,IMU数据飘得离谱,深度相机画面一片漆黑……嗯,这些坑我都踩过。今天我把这些经验整理出来,帮你少走弯路。

4.1 激光雷达驱动配置

激光雷达,是导航的「眼睛」。它通过发射激光束,测量周围物体的距离。在ROS2中,驱动激光雷达其实不复杂,但有几个关键点要注意。

4.1.1 常见激光雷达型号与驱动

我个人习惯把激光雷达分为两类:

  • 低成本型:如RPLIDAR A1/A2、YDLIDAR X4。这类雷达通常使用串口或USB转串口通信。
  • 工业型:如SICK、Hokuyo。它们多用以太网或CAN总线,驱动相对成熟。

在ROS2中,驱动包通常以slamtec_rplidar、ydlidar_ros2_driver等形式存在。安装方式很简单:

sudo apt install ros-humble-slamtec-rplidar
# 或者从源码编译
cd ~/ros2_ws/src
git clone https://github.com/slamtec/rplidar_ros.git
cd ..
colcon build

4.1.2 配置要点

配置激光雷达,核心是设置好launch文件。我建议你重点关注这几个参数:

参数名 说明 我的建议值
serial_port 串口设备路径 /dev/ttyUSB0
frame_id 雷达坐标系名称 laser_frame
angle_min/angle_max 扫描角度范围 -3.14 / 3.14
range_min/range_max 有效测距范围 0.15 / 12.0
注意: 串口权限问题。我曾经因为忘记给串口加权限,折腾了整整一个下午。记得执行: sudo chmod 666 /dev/ttyUSB0 或者将用户加入dialout组。

4.2 IMU驱动配置

IMU(惯性测量单元)负责感知机器人的加速度和角速度。说白了,就是告诉机器人「我现在是歪的还是正的」、「我在加速还是减速」。

4.2.1 IMU选型与驱动

常用的IMU有MPU6050、BMI160、ICM20948等。在ROS2中,驱动包通常叫imu_driver或mpu6050_driver。

我个人推荐使用ros2_imu_driver这个包,它支持多种IMU芯片,配置起来比较省心。

# 安装驱动
sudo apt install ros-humble-imu-tools

# 启动IMU节点
ros2 run imu_tools imu_node --ros-args -p port:=/dev/ttyACM0

4.2.2 数据校准

IMU数据有个大问题——零偏。你想想看,静止时IMU输出的角速度应该为0,但实际往往不是。这就是零偏。

我在项目中遇到过,IMU的零偏导致导航时机器人一直往一个方向偏。解决办法是:

  • 静态校准:让机器人静止10秒,采集数据取平均,作为零偏值。
  • 动态校准:使用卡尔曼滤波器在线估计零偏。
小技巧: 启动IMU节点后,用ros2 topic echo /imu/data查看原始数据。如果角速度在静止时超过±0.1 rad/s,建议做一次校准。

4.3 深度相机驱动配置

深度相机,比如Intel RealSense D435、Orbbec Astra,能提供RGB图像和深度图像。在机械臂抓取中,深度相机用来识别物体位置。

4.3.1 驱动安装

以RealSense为例:

# 安装RealSense SDK和ROS2驱动
sudo apt install ros-humble-realsense2-camera

# 启动相机
ros2 launch realsense2_camera rs_launch.py

4.3.2 关键参数配置

深度相机配置时,我建议你关注:

  • 分辨率:640x480通常够用,太高会影响帧率。
  • 帧率:30fps是标准,如果CPU吃紧可以降到15fps。
  • 深度范围:默认0.3m-3m,根据实际场景调整。
重要: 深度相机对光照敏感。强光下深度数据会丢失,弱光下红外投影仪会开启。我建议在室内均匀光照下使用。

4.4 数据融合基础

好了,现在我们有激光雷达、IMU、深度相机。但每个传感器都有自己的坐标系、采样频率、噪声特性。怎么把它们整合起来?这就是数据融合。

4.4.1 为什么要融合?

你想想看:

  • 激光雷达精度高,但只能测二维平面。
  • IMU能测三维姿态,但漂移严重。
  • 深度相机有三维信息,但受光照影响大。

单独用哪一个都不完美。融合后,可以取长补短。

4.4.2 融合方法

最基础的方法是扩展卡尔曼滤波(EKF)。ROS2中有一个现成的包:robot_localization。

# 安装
sudo apt install ros-humble-robot-localization

# 启动EKF节点
ros2 run robot_localization ekf_node --ros-args -p config:=ekf.yaml

配置文件ekf.yaml长这样:

ekf_filter_node:
  ros__parameters:
    frequency: 30.0
    sensor_timeout: 0.1
    two_d_mode: false
    publish_tf: true
    map_frame: map
    odom_frame: odom
    base_link_frame: base_link
    world_frame: odom

    odom0: /odom
    odom0_config: [true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]

    imu0: /imu/data
    imu0_config: [false, false, false, false, false, true, false, false, false, false, false, true, true, false, false]
提示: 配置文件中,true表示该传感器提供该维度的数据。比如odom0_config前两个true表示提供x和y的位置信息。

4.4.3 时间同步

数据融合还有一个关键问题——时间同步。不同传感器的采样频率不同,数据到达时间也不同。

ROS2提供了message_filters包来做时间同步:

from message_filters import ApproximateTimeSynchronizer, Subscriber

# 创建同步器
sync = ApproximateTimeSynchronizer(
    [laser_sub, imu_sub, depth_sub],
    queue_size=10,
    slop=0.1  # 允许的时间偏差,单位秒
)
sync.registerCallback(callback)
注意: 时间同步的slop参数不要设太大。我曾经设成0.5秒,结果融合出来的位置完全不对。建议0.05-0.1秒。

4.5 本章小结

这一章我们聊了:

  • 激光雷达的驱动配置和串口权限问题
  • IMU的零偏校准方法
  • 深度相机的参数设置
  • 数据融合的基础——EKF和时间同步

说实话,传感器驱动这块,80%的问题都是配置文件和权限问题。你只要把launch文件和参数调好,剩下的就是数据融合的活了。

下一章,我们会把这些传感器数据用起来,开始构建地图和定位。嗯,那才是真正有意思的部分。