第二章:机器人模型与传感器——URDF模型解析、激光雷达工作原理、里程计与IMU数据融合
各位同学,欢迎来到第二章。这一章我们聊聊机器人的“身体”和“感官”。
你想想看,一个机器人要导航避障,首先得知道自己长什么样,对吧?这就是URDF模型要干的事。然后它得感知周围环境,激光雷达就是它的“眼睛”。最后它还得知道自己走了多远、转了多少弯,这就要靠里程计和IMU这对搭档了。
我个人习惯把这三块内容放在一起讲,因为它们在导航系统里是密不可分的。模型不对,传感器数据再准也白搭;传感器数据不准,模型再精致也没用。
2.1 URDF模型解析:机器人的“骨架”
URDF,全称是Unified Robot Description Format。说白了,就是用XML格式描述机器人长什么样、关节怎么动。
我在项目中遇到过不少新手,一上来就写URDF,结果机器人在地图上显示成一团乱麻。为什么?因为坐标系没搞对。
核心要点:URDF的核心是和
来看一个最简单的两轮差速底盘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提供了“本体感觉”。这三者通过EKF融合,最终输出稳定的位姿估计,供导航避障算法使用。
好了,这一章的内容就到这里。记住,模型和传感器是导航系统的基础。基础不牢,地动山摇。下一章我们开始讲代价地图和路径规划,到时候你会感谢今天认真学完这一章的自己。
课后练习:打开你的机器人,用roslaunch urdf_tutorial display.launch model:=your_robot.urdf查看模型是否正确。然后用rostopic echo /scan看看激光雷达数据。最后用rqt_plot对比一下纯里程计和融合后的位姿差异。
可可精品资料库