3、传感器仿真:激光雷达(LiDAR)仿真配置、深度相机仿真、IMU仿真

传感器仿真,说白了就是给机器人装上「眼睛」和「耳朵」。

在Gazebo里,没有真实的物理传感器,全靠插件模拟数据。我刚开始接触时也觉得这玩意儿挺玄乎,后来发现其实就是配置几个参数的事。今天咱们把激光雷达、深度相机和IMU这三个最常用的传感器讲透。

3.1 激光雷达(LiDAR)仿真配置

激光雷达是机器人避障的核心传感器。它通过发射激光束,测量周围物体的距离。Gazebo里最常用的是gazebo_ros_ray_sensor插件。

我个人习惯用SDF格式来定义雷达模型。为什么?因为SDF比URDF更灵活,尤其在传感器参数调整上。

核心要点:激光雷达仿真主要关注三个参数——扫描范围、角分辨率、最大探测距离。

来看一个典型的配置示例:

<?xml version="1.0" ?>
<sdf version="1.6">
  <model name="my_lidar">
    <link name="laser_link">
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
      </visual>
      <sensor name="laser_sensor" type="ray">
        <ray>
          <scan>
            <horizontal>
              <samples>360</samples>
              <resolution>1</resolution>
              <min_angle>-3.14159</min_angle>
              <max_angle>3.14159</max_angle>
            </horizontal>
          </scan>
          <range>
            <min>0.1</min>
            <max>10.0</max>
            <resolution>0.01</resolution>
          </range>
        </ray>
        <plugin name="laser_controller" filename="libgazebo_ros_ray_sensor.so">
          <topicName>/scan</topicName>
          <frameName>laser_link</frameName>
        </plugin>
      </sensor>
    </link>
  </model>
</sdf>

这里有几个坑,我踩过:

  • samples:360表示一圈扫描360个点。如果你想要更高精度,可以设720,但CPU开销会翻倍。
  • min_angle/max_angle:单位是弧度。-3.14159到3.14159就是360度全覆盖。
  • max:最大探测距离。设太大会导致远处物体检测不准,设太小又不够用。10米是个折中值。

注意:我曾经把resolution设成0.001,结果雷达数据全是噪声。后来发现这个参数是高斯噪声的标准差,设太小反而失真。建议保留默认值0.01。

3.2 深度相机仿真

深度相机和激光雷达的区别?激光雷达只能扫一个平面,深度相机能获取整个画面的深度信息。说白了,一个是一维线扫,一个是二维矩阵。

Gazebo里深度相机用的是gazebo_ros_depth_camera插件。它模拟的是Kinect或RealSense这类设备。

配置起来其实比激光雷达还简单:

<sensor name="depth_camera" type="depth">
  <camera>
    <horizontal_fov>1.047</horizontal_fov>
    <image>
      <width>640</width>
      <height>480</height>
      <format>R8G8B8</format>
    </image>
    <clip>
      <near>0.1</near>
      <far>10.0</far>
    </clip>
  </camera>
  <plugin name="depth_controller" filename="libgazebo_ros_depth_camera.so">
    <topicName>/depth/image</topicName>
    <frameName>depth_link</frameName>
  </plugin>
</sensor>

这里要注意几个参数:

参数 说明 我的建议
horizontal_fov 水平视场角,单位弧度 1.047约等于60度,够用
width/height 图像分辨率 640x480是性价比最高的选择
near/far 最近/最远探测距离 near别小于0.1,否则会有空洞

小技巧:如果你发现深度图有黑色空洞,大概率是near设太小了。我遇到过一台仿真机器人,near设成0.01,结果地面直接消失了。改成0.1就好了。

3.3 IMU仿真

IMU(惯性测量单元)提供加速度和角速度数据。它不像激光雷达那样直接测距,但对机器人的姿态估计至关重要。

Gazebo里IMU的配置更简单,因为它不需要几何模型。直接用插件就行:

<sensor name="imu_sensor" type="imu">
  <always_on>1</always_on>
  <update_rate>100</update_rate>
  <plugin name="imu_controller" filename="libgazebo_ros_imu.so">
    <topicName>/imu/data</topicName>
    <frameName>imu_link</frameName>
    <noiseRate>0.001</noiseRate>
    <noiseAccel>0.01</noiseAccel>
  </plugin>
</sensor>

嗯,这里有个关键点——噪声参数。真实IMU是有噪声的,如果你把noiseRate和noiseAccel都设成0,那仿真数据会漂亮得不真实。你想想看,用这种数据训练出来的算法,拿到真机上肯定翻车。

经验之谈:我一般把noiseRate设在0.001到0.005之间,noiseAccel设在0.01到0.05之间。这样既不会太理想化,也不会噪声大到没法用。

3.4 传感器融合的实战思路

单个传感器都有短板。激光雷达怕玻璃、深度相机怕强光、IMU有漂移。所以实际项目中,我习惯把它们组合起来用。

比如避障场景:激光雷达负责平面障碍检测,深度相机负责立体空间感知,IMU负责运动状态估计。三者数据融合,才能让机器人稳稳地跑起来。

下面这张图展示了三个传感器在仿真中的协作关系:

传感器仿真协作框架 机器人本体 激光雷达 (LiDAR) /scan 话题 深度相机 /depth/image 话题 IMU /imu/data 话题 避障决策 三个传感器通过ROS话题向机器人发送数据,融合后用于避障决策

避坑指南:我曾经在仿真里把三个传感器的更新率都设成100Hz,结果CPU直接飙到100%。后来把激光雷达降到20Hz,深度相机30Hz,IMU保持100Hz,系统就稳了。记住,不是所有传感器都需要高频更新。

好了,传感器仿真的核心内容就这些。配置起来其实不复杂,关键是要理解每个参数的实际意义。你动手试试,跑起来就知道怎么回事了。

可可精品资料库