4 · 添加传感器与执行器
激光雷达、IMU与轮式编码器的URDF集成
好,咱们进入第四章。前面你已经有了一台能动的机器人骨架,但说实话,它还是个「盲人」——没有眼睛,没有平衡感,也不知道自己走了多远。这一章我们就给它装上传感器和执行器。我个人习惯把这一步叫做「赋予机器人知觉」。你想想看,没有激光雷达和IMU,Nav2根本没法定位和避障。所以这部分是联调的基础,也是很多新手容易出岔子的地方。
4.1 激光雷达的URDF集成
激光雷达,也就是LiDAR,是Nav2的「眼睛」。我见过不少同学直接把雷达模型往机器人顶上一放,连坐标系都歪了。结果建图全是重影。其实在URDF里加一个雷达传感器非常简单,核心就是定义一个link和一个joint,再挂上Gazebo插件。
下面是一个典型的2D激光雷达URDF片段。我用的是RPLidar A1的尺寸,但你可以换成任何雷达。
<!-- LiDAR link -->
<link name="laser_link">
<visual>
<geometry>
<cylinder length="0.04" radius="0.035"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<geometry>
<cylinder length="0.04" radius="0.035"/>
</geometry>
</collision>
</link>
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="laser_link"/>
<origin xyz="0.12 0 0.08" rpy="0 0 0"/>
</joint>
嗯,这里要注意:origin的z值决定了雷达离地高度。如果你做的是室内机器人,0.08~0.15米比较常见。我曾经在一个项目里把雷达装歪了0.5度,结果建图时走廊总是斜的……调了我一下午。所以,装雷达一定要保证水平。
gazebo_ros_ray_sensor插件。不然你的雷达在仿真里就是摆设。插件配置我一般放在单独的文件里,用xacro包含进来,保持URDF干净。
4.2 IMU的URDF集成
IMU提供角速度和加速度。Nav2的里程计融合里,IMU能大幅提升航向精度。说白了,没有IMU,你的机器人转弯时里程计容易飘。我个人习惯把IMU放在机器人的几何中心附近,这样角速度测量最准。
<link name="imu_link">
<visual>
<geometry>
<box size="0.03 0.03 0.02"/>
</geometry>
<material name="blue"/>
</visual>
</link>
<joint name="imu_joint" type="fixed">
<parent link="base_link"/>
<child link="imu_link"/>
<origin xyz="0 0 0.04" rpy="0 0 0"/>
</joint>
你看,IMU的link通常很小,一个蓝色小方块就代表它了。实际中IMU芯片也就指甲盖大小。但坐标系一定要和base_link对齐,否则后续EKF融合会出奇怪的角度偏移。我遇到过有人把IMU装反了,roll和pitch互换,定位直接炸掉。
4.3 轮式编码器模型
轮式编码器其实不是「视觉」模型,而是执行器的一部分。在URDF里,我们通常用<transmission>标签把电机和车轮关节关联起来。这样Gazebo才能模拟编码器输出里程计。
来看一个典型的差速驱动轮编码器配置:
<transmission name="left_wheel_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="left_wheel_joint">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="left_wheel_motor">
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
这里的关键是hardwareInterface。如果你用Gazebo仿真,必须声明VelocityJointInterface,这样ros_control才能给车轮发速度指令,同时读取编码器反馈。实际机器人上可能用EffortJointInterface,但原理一样。
| 组件 | URDF元素 | 作用 |
|---|---|---|
| 激光雷达 | link + joint + gazebo插件 | 提供激光扫描数据(/scan) |
| IMU | link + joint + gazebo插件 | 提供imu/data(角速度+加速度) |
| 轮式编码器 | transmission + joint + hardwareInterface | 模拟里程计(/odom) |
4.4 整合到机器人模型
把上面三个传感器/执行器加进你的robot.urdf。我习惯在<robot>根标签里按顺序放:base_link → 激光雷达 → IMU → 车轮transmission。这样结构清晰。最后别忘了在Gazebo启动脚本里加载对应的控制器(比如joint_state_controller和diff_drive_controller)。
嗯,这一章的内容其实不难,但细节很多。你只要记住:每个传感器都是一个link,通过固定关节连到base_link上,然后配上对应的Gazebo插件或transmission。下次我们会在Gazebo里实际测试这些传感器是否工作正常。