ROS2与Navigation2入门教程-使用SLAM制图的同时进行导航
说明:
- 介绍如何使用SLAM制图的同时进行导航
概述:
- 本教程将会说明如何将Nav2与SLAM结合使用。下面的步骤会向ROS 2使用者说明如何生成空间占用栅格地图(occupancy grid maps),并使用Nav2在这些空间占用栅格地图上移动机器人
要求
必须安装Navigation2、Turtlebot3和SLAM Toolbox软件堆栈
SLAM Toolbox可以通过以下命令安装:
sudo apt install ros-<ros2-distro>-slam-toolbox
- 或者执行以下命令在您的工作空间中从源代码编译安装:
cd ~/dev_ws/src
git clone https://github.com/SteveMacenski/slam_toolbox.git --branch foxy-devel
cd ~/dev_ws
rosdep install -y -r -q --from-paths src --ignore-src --rosdistro foxy
colcon build --symlink-install –packages-select slam_toolbox
具体步骤
- 启动机器人接口,在进行本教程的过程中,每当打开一个新的终端时,都请运行以下命令以设置环境变量:
source /opt/ros/<ros2-distro>/setup.bash
export TURTLEBOT3_MODEL=waffle
如果是从源代码编译安装ROS 2的,则安装目录可能不同,需要对ROS 2安装目录下install/setup.bash脚本进行source。
执行以下命令来启动机器人接口和机器人状态发布者节点:
ros2 launch turtlebot3_bringup robot.launch.py
- 启动Navigation2
- 在不使用nav2_amcl和nav2_map_server的情况下启动Navigation2。这里假设SLAM节点会在/map话题上进行地图发布并提供map->odom坐标变换。具体命令为:
ros2 launch nav2_bringup navigation_launch.py
- 启动SLAM
- 调出您选中的SLAM实现。请确保该SLAM实现可以提供 map->odom坐标转换和/map话题。运行Rviz并添加您想要进行可视化的话题,例如/map、/tf、/laserscan等。本教程中使用的SLAM实现将会是SLAM Toolbox。具体启动命令为:
ros2 launch slam_toolbox online_async_launch.py
- 使用SLAM
- 通过RViz或ROS 2 命令行请求目标以移动您的机器人,即:
ros2 topic pub /goal_pose geometry_msgs/PoseStamped "{header: {stamp: {sec: 0}, frame_id: 'map'}, pose: {position: {x: 0.2, y: 0.0, z: 0.0}, orientation: {w: 1.0}}}"
- 这样就应该会看到地图在实时更新!要将这个地图保存到主目录下的地图文件中,请执行以下命令:
ros2 run nav2_map_server map_saver_cli -f ~/map
启动简化版
如果您只对在turtlebot3入门沙盒(sandbox)世界中运行SLAM感兴趣,则还提供了一种使用启动配置的简单方法来启用SLAM。即可以继续使用tb3_simulation_launch.py启动文件,并将slam配置设置为true,而不是单独启动机器人接口、navigation2和SLAM。
本教程提供上述说明的假设是您想要在自己的机器人上运行SLAM,该机器人将会具有分离的仿真/机器人界面和navigation2启动文件,但为方便测试,已经将这些文件合并在tb3_simulation_launch.py启动文件中。
简化版的启动命令为:
ros2 launch nav2_bringup tb3_simulation_launch.py slam:=True
- 如果运行上面这条命令时,Gazebo长时间在准备仿真世界而不能正常启动,或者不想启动Gazebo的GUI,则可以无头运行Gazebo,命令为:
ros2 launch nav2_bringup tb3_simulation_launch.py slam:=True headless:=True
- 如果没有turtlebot3物理机器人硬件,则只能在Gazebo中进行仿真了.
分步启动机器人仿真
除了上面“启动简化版”一节中介绍的方法外,也可以分开来启动机器人仿真、Nav2、SLAM等,这样就应该分别执行以下步骤及相应的命令
在沙盒仿真世界中启动仿真turtlebot3机器人,命令为:
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py
- 启动Navigation2,并同时打开rviz2以对后面要进行的SLAM制图进行可视化,命令为:
ros2 launch nav2_bringup rviz_launch.py
- 或者也可以运行turtlebot3_navigation2软件包,命令为:
ros2 launch turtlebot3_navigation2 navigation2.launch.py
- 启动SLAM(这里也用slam_toolbox实现),命令为:
ros2 launch slam_toolbox online_async_launch.py
- 这样Gazebo和Rviz2应归就会如下图所示:
从右图中可知,SLAM已经开始进行扫描制图了。但由于此时机器人并未移动,因此只能对其初始位置上可以扫描的范围进行制图。为了对整个沙盒仿真世界进行SLAM制图,需要让机器人移动起来。
导航并使用SLAM进行制图。由于在步骤(2)启动Navigation2和打开RViz2时并没有节点订阅/goal_pose话题,这可以从下面这个节点网络图中看出来:
- 在这种情况下,尝试在rviz2中设置导航目标位置或者使用ros2 topic pub /goal_pose命令来设置导航目标都不会成功,因而也就无法让机器人朝着目标位置进行导航并使用SLAM制图。这时候,最简单的方法就是运行turtlebot3_teleop软件包的teleop_keyboard节点使用键盘进行手动导航,具体命令为:
ros2 run turtlebot3_teleop teleop_keyboard
此时就可以使用键盘上w、x和a、d这4个字母键移动机器人了。
随着机器人在沙盒仿真世界中到处移动,就可以使用SLAM对整个仿真世界进行制图了。
另外,也可以想办法让某个节点订阅/goal_pose话题以便可以使用发布的目标位置消息进行turtlebot3机器人导航。
可以先来看看上面“启动简化版”(无头运行Gazebo情况下)的节点网络图:
从上图中可以看出,tb_navigator节点订阅了/goal_pose话题(当然该节点还会订阅其它诸如/tf和/clock等话题以便对turtlebot3机器人进行导航),并据此发布话题/navigate_to_pose/_action/feedback和/navigate_to_pose/_action/status(含有导航至目标位置的动作反馈和状态信息),而这两个话题又会被waypoints_follower_rclcpp_node和bt_navigator_rclcpp_node节点以及RViz订阅。
为了解决上面这个/goal_pose话题没有节点订阅使用的问题,需要修改nav2_bringup软件包中的rviz_launch.py启动文件以在该启动文件中包含导航功能所需各个节点,而实际上navigation_launch.py启动文件就恰好是用于启动导航所需各个节点的启动文件,只是该启动文件没有启动RViz2。
因此,解决办法就是在rviz_launch.py启动文件中包含navigation_launch.py启动文件即可。
有关启动文件的具体编写方法,请参见本知乎专栏文章“创建launch文件”、“用Launch启动/监视多个节点”教程及Github网站上的“launch体系结构”文档。
参考:
- https://navigation.ros.org/tutorials/docs/navigation2_with_slam.html
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号