第 7 章 Gazebo 机器人实操:驱动一辆差速小车
学习目标
- 启动官方差分驱动机器人演示世界
- 发布
/cmd_vel速度指令驱动机器人 - 观察里程计、TF、激光话题
- 在 RViz 中可视化机器人模型和激光数据
- 理解 URDF/SDF 中连杆与关节的基本概念
1. 启动演示世界
上一章安装的ros-gz-sim-demos自带一个差速驱动机器人演示(一辆蓝色小车,带激光雷达):
ros2 launch ros_gz_sim_demos diff_drive.launch.py弹出两个窗口:
- Gazebo 窗口:蓝色小车停在地面上(如果不动,先点播放按钮)
- RViz 窗口:可视化机器人模型
如果仿真暂停,点 Gazebo 窗口底部的播放按钮。
2. 用话题驱动机器人
新开终端,查看话题:
ros2 topic list重点看这几个话题:
/model/vehicle_blue/cmd_vel # 小车速度指令(输入) /model/vehicle_blue/odom # 里程计(输出) /model/vehicle_blue/scan # 激光雷达数据(输出,若有)让小车一边前进一边转弯:
ros2 topic pub-r10/model/vehicle_blue/cmd_vel geometry_msgs/msg/Twist\"{linear: {x: 2.0}, angular: {z: 0.5}}"参数含义:
-r 10:以 10 Hz 持续发布linear.x:前进速度 2 m/sangular.z:旋转角速度 0.5 rad/s
在 Gazebo 窗口里可以看到小车开始移动并在地面上转弯。
观察里程计数据(另一个终端):
ros2 topicecho/model/vehicle_blue/odom输出里的pose.pose.position是小车在仿真世界里的坐标,twist是当前速度——这就是“传感器”给 ROS 的反馈。
停止小车:
ros2 topic pub-r10/model/vehicle_blue/cmd_vel geometry_msgs/msg/Twist"{linear: {x: 0.0}}"注意:不同版本/世界的话题名可能略有差异。动手前先
ros2 topic list确认实际名称,这是所有 ROS 2 调试的第一步。
3. 查看 TF 坐标变换
TF(Transform)描述机器人各部件之间的坐标关系,例如“激光雷达装在底盘上方 0.3 米”。查看当前存在的坐标变换:
ros2 run tf2_tools view_frames会在当前目录生成frames.pdf,也可以实时打印两个坐标系之间的变换:
ros2 run tf2_ros tf2_echo<父坐标系><子坐标系>先在 RViz 左侧Fixed Frame里填odom(或world),添加 TF 显示,就能看到坐标系之间的连线。TF 是机器人开发的重要基础,本章先会观察即可。
4. 在 RViz 里看激光雷达
演示启动时已经打开了 RViz。如果激光话题存在,可以手动添加显示:
- 确认话题:
ros2 topic list | grep scan(容器内 bash) - 在 RViz 左侧点击Add→By topic→ 选中激光话题(如
/model/vehicle_blue/scan,类型sensor_msgs/msg/LaserScan)→ OK - 确保Fixed Frame是
odom或world - RViz 中会出现一圈点云,就是激光雷达“看到”的周围障碍物
把小车开到墙边,可以实时看到激光点云贴近墙面。
5. URDF/SDF 基础:连杆与关节
机器人在仿真和 ROS 里长什么样,由模型文件描述。URDF(ROS 原生)和 SDF(Gazebo 原生)都是 XML 格式,核心概念一致:
- 连杆(Link):刚体部件,如底盘、轮子、激光雷达,有质量和惯性
- 关节(Joint):连接连杆并定义相对运动,如轮子的转动关节
一个最简单的“方块机器人” URDF 示意:
<robotname="box_robot"><!-- 底盘:一个 0.5m 的立方体 --><linkname="base_link"><visual><geometry><boxsize="0.5 0.5 0.1"/></geometry></visual><collision><geometry><boxsize="0.5 0.5 0.1"/></geometry></collision></link></robot>这个模型没有关节,只是一个静止的方块。真实的差速小车还需要轮子、转向/转动关节和驱动插件——官方演示世界里的vehicle_blue模型就是完整例子,其 SDF 文件里包含差速驱动系统插件,负责把/cmd_vel变成轮子转动。
本教程不要求手写完整 URDF(那是进阶章节的内容),但理解“连杆 + 关节 + 插件”这个骨架,后续看任何机器人模型都能看懂。
6. 把话题数据和仿真时间记下来(预告)
仿真期间,/clock、/model/vehicle_blue/odom、/scan都是真实可用的 ROS 话题,可以随时ros2 topic echo。下一章的 MoveIt 会用到同样的“话题通信”思想;第 9 章会教你用 rosbag 把仿真数据录下来回放。
常见问题
| 现象 | 原因与解决办法 |
|---|---|
| 小车不动 | 仿真暂停(点播放按钮);或 cmd_vel 话题名不对(用ros2 topic list确认) |
| RViz 里看不到模型 | 检查 Fixed Frame 是否设置为odom/world,并确认 RViz 与 Gazebo 同时运行 |
找不到tf2_tools命令 | 执行sudo apt install -y ros-jazzy-tf2-tools |
| 激光点云是空的 | 激光话题名可能不同,`ros2 topic list |
RViz 报No transform | 等待几秒让 TF 数据到达,或重启 RViz |
练习题
- 让小车先直行 3 秒再原地旋转 90 度,再直行 3 秒,观察它的轨迹(用
/odom验证最终位置)。 - 用
ros2 topic hz /model/vehicle_blue/odom测量数据频率,想想激光雷达数据该用什么频率。 - 在 RViz 中同时显示 TF 和 LaserScan,移动小车,观察坐标系随小车运动的变化。
- 把
/cmd_vel改成一个持续发布正弦速度的ros2 topic pub命令(提示:--rate与固定值配合即可),观察小车蛇形前进。