3、让机器人动起来:URDF模型导入、配置差速驱动插件、使用键盘控制小车
好,到了这一章,咱们终于要让机器人真正跑起来了。
前面几章我们把环境搭好,把模型建好,但说白了,那都是静态的。一个不会动的机器人,跟个雕塑没啥区别。我刚开始学Gazebo的时候,最兴奋的时刻就是第一次看到小车在仿真里动起来——虽然只是原地转了个圈,但那种成就感,嗯,至今还记得。
3.1 URDF模型导入Gazebo
URDF(Unified Robot Description Format)是ROS里描述机器人最常用的格式。它用XML写,定义了机器人的连杆、关节、外观和碰撞属性。
我个人习惯把URDF文件放在功能包的urdf/目录下。比如我们的小车,结构很简单:一个底盘、四个轮子。
核心要点:URDF里必须包含<gazebo>标签,否则Gazebo不认识你的模型。很多新手会漏掉这一步。
来看一个简化版的底盘URDF示例:
<robot name="my_car">
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
<material name="blue">
<color rgba="0 0 1 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
</collision>
</link>
<!-- 轮子部分省略 -->
<gazebo>
<plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
...
</plugin>
</gazebo>
</robot>
注意看,<collision>和<visual>我通常建议分开写。视觉可以花哨点,但碰撞体尽量用简单几何体——这能大幅提升仿真性能。我在项目里见过有人把碰撞体做得跟艺术品一样精细,结果仿真卡成PPT,何必呢?
3.2 配置差速驱动插件
差速驱动,说白了就是靠左右轮速度差来控制转向。你想想看,坦克、扫地机器人,都是这个原理。
Gazebo里实现差速驱动,靠的是插件机制。我们用的是libgazebo_ros_diff_drive.so这个插件。
配置参数有点多,我列个表方便你对照:
| 参数名 | 说明 | 我的建议值 |
|---|---|---|
| left_joint | 左轮旋转关节名称 | left_wheel_joint |
| right_joint | 右轮旋转关节名称 | right_wheel_joint |
| wheel_separation | 左右轮间距(米) | 0.34 |
| wheel_diameter | 轮子直径(米) | 0.1 |
| command_topic | 接收速度指令的话题 | /cmd_vel |
| odometry_topic | 发布里程计的话题 | /odom |
小技巧:wheel_separation这个值一定要量准。我曾经因为写错了一位小数,小车在仿真里一直画圈圈,查了半天才发现是轮距设窄了5毫米。
完整的插件配置大概长这样:
<gazebo>
<plugin name="diff_drive_controller" filename="libgazebo_ros_diff_drive.so">
<ros>
<namespace>/my_car</namespace>
</ros>
<left_joint>left_wheel_joint</left_joint>
<right_joint>right_wheel_joint</right_joint>
<wheel_separation>0.34</wheel_separation>
<wheel_diameter>0.1</wheel_diameter>
<max_wheel_torque>20</max_wheel_torque>
<max_wheel_acceleration>1.0</max_wheel_acceleration>
<command_topic>/cmd_vel</command_topic>
<odometry_topic>/odom</odometry_topic>
<odometry_frame>odom</odometry_frame>
<robot_base_frame>base_link</robot_base_frame>
</plugin>
</gazebo>
这里有个坑:max_wheel_torque和max_wheel_acceleration别设太大。设太大,小车启动时会像被踹了一脚,直接飞出去。我刚开始就吃过这个亏,小车一启动就翻了个跟头,把我笑坏了。
3.3 使用键盘控制小车
插件配好了,怎么控制呢?最直接的方式就是用键盘。
ROS里有个现成的包叫teleop_twist_keyboard,装好就能用。
安装命令:
sudo apt install ros-noetic-teleop-twist-keyboard
启动方式:
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
然后你就能在终端里看到提示:按i前进,,后退,j左转,l右转。按k停车。
注意:键盘控制节点默认发布到/cmd_vel话题。如果你的机器人命名空间不同,记得用__ns:=/my_car参数重映射。
为什么会这样?因为teleop_twist_keyboard默认话题是/cmd_vel,而我们的差速驱动插件监听的就是这个。只要话题对上,数据就能流通。
我个人习惯在启动时加上_speed:=0.5参数,把默认速度调低一点。0.5米/秒的速度,在仿真里既能看到效果,又不会失控。
3.4 本章知识体系
下面这张图,帮你理清整个流程:
嗯,到这里,你的小车应该能在Gazebo里跑起来了。如果按下键盘没反应,别急,先检查三件事:
- URDF里的
<gazebo>插件段有没有写对? - 话题名是不是
/cmd_vel? - Gazebo仿真有没有暂停?按空格键可以切换暂停/运行。
避坑指南:我曾经在项目里遇到一个诡异问题——键盘控制没反应,但rostopic echo /cmd_vel能看到数据。查了两小时,发现是URDF里轮子的<joint>类型写成了fixed,轮子根本转不了。所以,<joint type="continuous">这个细节,千万别写错。
好了,去试试吧。看着自己写的小车在仿真里灵活穿梭,那种感觉,比打游戏通关还爽。