预计完成时间:14 分钟
现在你的机器人已经具备移动能力了!下一步就是把它接入 ROS2,这样你就可以通过向 ROS2 话题发布消息来控制机器人运动。这个功能可以通过一个插件实现,并且可以借助 Gazebo 标签把它写入 URDF 模型中。具体做法如下:
把下面这段包含 Differential Drive Plugin 的代码复制到你的 URDF 文件底部,也就是放在结束的 </robot> XML 标签之前。
复制并粘贴
<!-- Differential Drive Plugin -->
<gazebo>
<plugin
filename="libignition-gazebo-diff-drive-system.so"
name="ignition::gazebo::systems::DiffDrive">
<left_joint>joint_chassis_left_wheel</left_joint>
<right_joint>joint_chassis_right_wheel</right_joint>
<wheel_separation>1.66</wheel_separation>
<wheel_radius>0.4</wheel_radius>
<odom_publish_frequency>20</odom_publish_frequency>
<topic>cmd_vel</topic>
<odom_topic>odom</odom_topic>
<tf_topic>tf</tf_topic>
<frame_id>odom</frame_id>
<child_frame_id>link_chassis</child_frame_id>
</plugin>
</gazebo>

对应的新 Gazebo Sim 写法:
<gazebo>
<plugin
filename="libgz-sim-diff-drive-system.so"
name="gz::sim::systems::DiffDrive">
...
</plugin>
</gazebo>
粘贴完成后,保存你的 URDF 文件。接下来需要重新构建 ROS2 功能包,并重新生成机器人。
在 Web Shell 1 中执行
cd /workspace/gazebo_sim_ros2
rm -rf ./build ./install ./log
colcon build --packages-select robot_description && source install/setup.bash
ros2 launch robot_description empty_world.launch.py
在 Web Shell 2 中执行
cd /workspace/gazebo_sim_ros2
source install/setup.bash
ros2 launch robot_description spawn.launch.py
你已经添加了 diff_drive 插件。现在是不是就应该可以直接控制机器人运动了呢?
先检查一下在 ros2 topic list 中是否能看到 cmd_vel 话题。
你找到 cmd_vel 了吗?我可以肯定,它现在还没有出现。
之所以现在还不能移动机器人,是因为你还没有可用于发布速度消息的 cmd_vel 话题。因此,接下来需要创建一个双向的 ros_gz_bridge,用来在 ROS2 和 IGN Gazebo Sim 之间传递速度指令。
请打开一个新的 web shell,为 cmd_vel 话题启动双向桥接。你可以先尝试根据前一节学到的内容自己写命令;如果暂时写不出来,也可以直接参考下面给出的命令。
桥接启动之后,需要让它持续保持运行。
在 Web Shell 3 中执行
ros2 run ros_gz_bridge parameter_bridge /cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist

对应的新 Gazebo Sim 写法:
ros2 run ros_gz_bridge parameter_bridge /cmd_vel@geometry_msgs/msg/Twist@gz.msgs.Twist
桥接激活之后,你现在应该就能在 ros2 topic list 中看到 cmd_vel 话题了。
最后,向 cmd_vel 话题发送速度指令来控制机器人运动。这里我们使用键盘遥操作程序来完成这项任务。
在 Web Shell 4 中执行
ros2 run teleop_twist_keyboard teleop_twist_keyboard
现在,按照 teleop 程序所在 web shell 中显示的按键说明,你就可以在 Gazebo Sim 中移动机器人了!
现在你已经可以在 Gazebo Sim 中自由操控并测试这台机器人了。
**注意:** 如果你停止了 ros_gz_bridge,机器人会保持执行你在 teleop 程序中最后一次发送的动作。因此,如果你在关闭桥接之前先把机器人停下来,它就会保持静止;反之,如果它在桥接关闭时还在移动,那么它会继续移动。你可以自己试试看!
按照当前的配置,你可以通过向 /cmd_vel 发布消息来控制机器人运动。角速度会考虑左右车轮之间的间距,线速度则会考虑你配置的车轮半径。这也正是为什么你需要在 diff_drive 插件中显式填写这两个参数。
此外,你还会得到一个 /odom 话题,它接收来自该 Gazebo 插件的消息,其中包含机器人的位置信息。不过,你还没有为这个话题配置桥接,接下来的练习中就会处理它。

编写一个简单的 Python 脚本,根据两个参数来控制机器人运动:线速度和角速度。
在机器人运动过程中,程序还需要显示机器人在 X 和 Y 轴上的位置。
提示: 你需要同时为 /cmd_vel 和 /odom 这两个话题创建桥接。你已经知道 /cmd_vel 需要使用双向桥接;而 /odom 则应使用单向桥接,也就是 IGN 到 ROS 的桥接。可用命令如下:
ros2 run ros_gz_bridge parameter_bridge /cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist /odom@nav_msgs/msg/Odometry[ignition.msgs.Odometry

对应的新 Gazebo Sim 写法:
ros2 run ros_gz_bridge parameter_bridge /cmd_vel@geometry_msgs/msg/Twist@gz.msgs.Twist /odom@nav_msgs/msg/Odometry[gz.msgs.Odometry
注意: 别忘了更新你的 setup.py 文件,这样你才能通过 ros2 run 命令运行自己的程序。
预期结果:

