第二章:机器人模型与传感器——URDF模型解析、激光雷达工作原理、里程计与IMU数据融合

各位同学,欢迎来到第二章。这一章我们聊聊机器人的“身体”和“感官”。

你想想看,一个机器人要导航避障,首先得知道自己长什么样,对吧?这就是URDF模型要干的事。然后它得感知周围环境,激光雷达就是它的“眼睛”。最后它还得知道自己走了多远、转了多少弯,这就要靠里程计和IMU这对搭档了。

我个人习惯把这三块内容放在一起讲,因为它们在导航系统里是密不可分的。模型不对,传感器数据再准也白搭;传感器数据不准,模型再精致也没用。

2.1 URDF模型解析:机器人的“骨架”

URDF,全称是Unified Robot Description Format。说白了,就是用XML格式描述机器人长什么样、关节怎么动。

我在项目中遇到过不少新手,一上来就写URDF,结果机器人在地图上显示成一团乱麻。为什么?因为坐标系没搞对。

核心要点:URDF的核心是和。link是刚体部件,joint是连接两个link的关节。

来看一个最简单的两轮差速底盘URDF示例:

<robot name="my_robot">
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.4 0.3 0.1"/>
      </geometry>
      <origin xyz="0 0 0" rpy="0 0 0"/>
    </visual>
  </link>

  <joint name="left_wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="left_wheel"/>
    <origin xyz="-0.15 0.2 -0.05" rpy="0 0 0"/>
    <axis xyz="0 1 0"/>
  </joint>
</robot>

嗯,这里要注意几个坑:

  • 坐标系原点:base_link通常放在机器人底盘中心投影到地面的位置。我见过有人把原点放在轮子上,结果整个模型都歪了。
  • 关节类型:continuous用于轮子这种可以无限旋转的关节,revolute用于有角度限制的关节(比如机械臂)。
  • 轴方向:axis xyz定义了旋转轴。轮子绕Y轴旋转,那就写"0 1 0"。

我的小技巧:写URDF时,先用rviz可视化检查。如果模型在地图上飘着或者陷进地里,八成是base_link的z轴高度不对。

2.2 激光雷达工作原理:机器人的“眼睛”

激光雷达,英文叫LiDAR。它通过发射激光束并测量反射时间,来计算周围物体的距离。

你想想看,它就像拿着一把尺子,朝各个方向“啪”地打一下,然后听回声。转一圈下来,周围360度的障碍物距离就全知道了。

常用的激光雷达有两种:

类型 工作原理 典型型号 优缺点
三角测距 激光照射目标,通过摄像头捕捉反射光斑的位置变化计算距离 RPLIDAR A1/A2 成本低,近距离精度好;远距离精度下降
TOF(飞行时间) 直接测量激光发射和接收的时间差 RPLIDAR S1, Velodyne 精度高,测距远;成本高

我在项目中遇到过一个问题:用三角测距的雷达在强光下数据会跳变。后来换成TOF的,问题就解决了。所以选型时一定要考虑使用环境。

避坑指南:我曾经在调试时发现激光雷达数据有“鬼影”——明明前面没东西,却显示有障碍物。后来排查发现是雷达安装位置太低,地面反射造成的。解决办法是调整安装角度或加装遮光罩。

激光雷达输出的数据格式通常是,包含以下关键字段:

  • angle_min/angle_max:扫描角度范围,比如-135°到135°
  • angle_increment:角度分辨率,比如0.5°
  • range_min/range_max:有效测距范围
  • ranges[]:每个角度对应的距离值

2.3 里程计与IMU数据融合:让机器人“知道自己在哪”

里程计(Odometry)和IMU(惯性测量单元)是机器人定位的两大法宝。但单独用哪个都有问题。

里程计靠轮子编码器计算位移,优点是短期精度高,缺点是轮子打滑就会累积误差。IMU靠加速度计和陀螺仪,优点是角度测量准,缺点是加速度积分会漂移。

所以,得把它们融合起来用。

核心思想:用IMU修正里程计的角度漂移,用里程计修正IMU的位置漂移。两者互补,效果1+1>2。

常用的融合方法是扩展卡尔曼滤波(EKF)。ROS里有个robot_localization包,专门干这个事。

配置示例:

ekf_localization_node:
  frequency: 30
  sensor_timeout: 0.1
  two_d_mode: true
  map_frame: map
  odom_frame: odom
  base_link_frame: base_link
  world_frame: odom

  odom0: /wheel_odom
  odom0_config: [true, true, false, false, false, true, 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, false, false, false]

嗯,这里要注意:odom0_config和imu0_config里的15个布尔值,分别对应[x, y, z, roll, pitch, yaw, vx, vy, vz, vroll, vpitch, vyaw, ax, ay, az]。你只需要把能提供的数据对应的位置设为true就行。

我的经验:刚开始做融合时,别急着把所有传感器数据都加进去。先只融合里程计和IMU的角度,跑通了再加位置融合。否则出了问题都不知道是哪个传感器在捣乱。

2.4 本章知识体系总览

为了让大家更直观地理解这三块内容的关系,我画了一张图:

机器人导航避障 - 传感器与模型知识体系 URDF模型 机器人物理描述 激光雷达 环境感知 里程计 + IMU 位姿估计 link + joint 定义 坐标系与原点 三角测距 vs TOF LaserScan数据格式 编码器里程计 IMU加速度+陀螺仪 EKF数据融合 (robot_localization) 输出:稳定的位姿估计 → 导航避障

从这张图可以看得很清楚:URDF定义了机器人的“骨架”,激光雷达提供了“眼睛”,里程计和IMU提供了“本体感觉”。这三者通过EKF融合,最终输出稳定的位姿估计,供导航避障算法使用。

好了,这一章的内容就到这里。记住,模型和传感器是导航系统的基础。基础不牢,地动山摇。下一章我们开始讲代价地图和路径规划,到时候你会感谢今天认真学完这一章的自己。

课后练习:打开你的机器人,用roslaunch urdf_tutorial display.launch model:=your_robot.urdf查看模型是否正确。然后用rostopic echo /scan看看激光雷达数据。最后用rqt_plot对比一下纯里程计和融合后的位姿差异。

可可精品资料库