UGV Rover Jetson Orin ROS2 11. Gazebo 仿真调试
| ||||||||||||||||||||||
|
11. Gazebo 仿真调试
本章主要对机器人仿真调试进行介绍。在我们手边没有实物机器人时,可以通过机器人三维物理仿真平台 Gazebo 来验证机器人算法、架构等。我们提供 Gazebo 机器人模型和完整的功能包用于在虚拟机上仿真调试,帮助用户在开发初期进行系统验证与测试。
11.1 Gazebo 介绍
Gazebo 是一款 3D 动态模拟器,能够准确高效地模拟复杂的室内外环境中的机器人群体。虽然与游戏引擎类似,Gazebo 提供保真度更高的物理模拟,支持复杂的环境和传感器模拟。用户可以创建 3D 模型,设置环境,并模拟各种传感器(如激光雷达、摄像头等)。
Gazebo 仿真平台的主要方面包括:
- 物理引擎:Gazebo 使用多个物理引擎(如 ODE、Bullet、DART等),提供准确的动力学模拟,能够处理碰撞、摩擦和重力等物理现象。
- 3D 建模:用户可以使用现有的模型库,或通过软件(如 Blender)自定义创建 3D 模型。这些模型可以是机器人、障碍物或环境元素。
- 环境设置:Gazebo 允许用户设计复杂的仿真环境,包括城市、室内场景等,可以自由配置地形和光照。
- 传感器模拟:Gazebo 支持多种传感器类型,如激光雷达、摄像头、IMU 等,能够提供实时数据流,便于算法测试。
- ROS 集成:与 ROS 的结合使得用户能够轻松地将 Gazebo 作为仿真环境,进行算法开发和测试,支持 ROS 主题和服务。
- 用户界面:Gazebo 提供直观的图形用户界面,用户可以通过可视化工具实时监控仿真进程,调整参数。
11.2 加载虚拟机镜像
我们提供配置好 Gazebo 仿真、机器人模型和完整的功能包这些软件的 Ubuntu 镜像,方便用户直接进行使用。本教程适用于在 Windows 系统电脑使用虚拟机来加载 Ubuntu 镜像进行 Gazebo 仿真调试。
11.2.1 下载配置好软件的 Ubuntu 镜像
使用我们配置好软件的 Ubuntu 镜像,无需自行再进行 Gazebo 仿真环境的安装配置,根据后续的教程进行该产品的仿真测试。
- 下载链接:
下载好后进行解压缩,解压缩后所有的文件都是镜像文件,有一些虚拟机的磁盘文件系统不支持 4G 以上的单独文件,因此将配置好的 Ubuntu 镜像分解成了多个文件。
11.2.2 安装 Oracle VM VirtualBox 虚拟机
下载并安装 Oracle VM VirtualBox,这是一款免费的虚拟机软件,可以让你在自己的电脑上运行虚拟操作系统,我们在 Windows 系统电脑上运行虚拟机来安装 Ubuntu 操作系统,接着在 Ubuntu 操作系统上安装配置 ROS2 来控制机械臂。
需要注意的是,虽然 ROS2 有 Windows 的版本,但是 Windows 版本的 ROS2 相关资料并不多,所以我们默认提供虚拟机的方案来运行 ROS2。
点击 Oracle VM VirtualBox 官方下载链接,安装过程很简单,一直点击下一步即可。如果已安装,则跳过这步。
11.3 镜像加载至虚拟机软件
-
在左边工具栏处,点击“新建”。
-
设置名称,类型设置为“Linux”,版本设置为“Ubuntu(64-bit)”,点击“下一步”。
-
内存大小设置为 4096MB,处理器设置为 2 个,接着点击“下一步”。
-
选择“不添加虚拟硬盘”,点击“下一步”会显示新虚拟电脑的配置,点击“完成”后弹出警告,点击“继续”。
-
选中刚刚创建的虚拟机,选择“设置”。
-
选择“存储”,点击控制器最右边的 +号添加虚拟硬盘。
-
选择注册,将前面解压缩的 ws.vmdk 镜像文件添加进去后点击右下角的“选择”,确认保存。
-
接着选择“显示”,勾选“启用 3D 加速”,勾选后点击“确定”,双击左边你刚刚创建的虚拟电脑就可以运行了。
运行该虚拟机电脑成功,可以根据后面的内容了解使用 Gazebo 仿真完成机器人的控制。
11.4 进入 Docker 容器
在主机终端中,先允许未授权用户访问图形界面,输入指令:
xhost + 【注意:在每次虚拟机重新运行后,需要在 Docker 容器中开可视化,该步骤必须要执行。】
接着执行进入 Docker 容器的脚本:
. ros_humble.sh
输入 1 进入 Docker 容器,进入后用户名会变成 root,如下图。
11.5 加载 Gazebo 机器人模型
该镜像模型默认即为四驱六轮的 UGV Rover,因此我们可以直接加载 Gazebo 仿真环境和 UGV Rover 的机器人模型,且启动相应的 ROS 2 节点:
ros2 launch ugv_gazebo bringup.launch.py
启动需要等待一小段时间,如下图即启动成功,该指令在后续步骤中需要保持运行。
11.6 使用手柄或键盘控制
11.6.1 手柄控制
将手柄接收器接入电脑中,点击 Oracle VM VirtualBox 上方的“设备”→“USB”→带有 XBox 字样的设备名称,该设备名称前出现 √,则代表手柄连接到虚拟机上。
按 Ctrl+Alt+T 打开一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器:
. ros_humble.sh
在容器中运行手柄控制节点:
ros2 launch ugv_tools teleop_twist_joy.launch.py
接着打开手柄背后的开关,看见手柄上亮红灯之后可以控制机器人模型运动。【标注手柄三个功能键手柄:R下面的那个键锁定or解锁,手柄的摇杆,左摇杆——前进,后退;右摇杆——左转,右转】
通过按 Ctrl+C 可以关闭手柄控制节点。
11.6.2 键盘控制
关闭手柄控制节点,可以接着再运行手柄控制节点的容器终端窗口中来运行键盘控制节点:
ros2 run ugv_tools keyboard_ctrl
保持这个窗口为激活状态(即确保操作按键时位于该终端窗口界面),通过以下按键来控制机器人模型运动:
键盘按键 | 操作描述 | 键盘按键 | 操作描述 | 键盘按键 | 操作描述 |
字母 U | 左前进 | 字母 I | 直前进 | 字母 O | 右前进 |
---|---|---|---|---|---|
字母 J | 左转 | 字母 K | 停止运动 | 字母 L | 右转 |
字母 M | 左后退 | 符号 , | 直后退 | 符号 . | 右后退 |
通过按 Ctrl+C 可以关闭键盘控制节点。
11.7 建图
11.7.1 二维建图
1. 基于 Gmapping 的二维建图
保持加载 Gazebo 机器人模型的运行,按 Ctrl+Alt+T 打开一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器:
. ros_humble.sh
在容器中运行启动建图节点:
ros2 launch ugv_gazebo gmapping.launch.py
此时,RViz 界面显示的地图上只会显示出 Gazebo 仿真地图中激光雷达所扫描到的区域,若还有未扫描到的区域需要建图,则可以通过手柄或者键盘控制小车移动来扫描建图。
在一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器,运行手柄控制或键盘控制节点任意一个:
#手柄控制(确保手柄接收器插入虚拟机中) ros2 launch ugv_tools teleop_twist_joy.launch.py #键盘控制(保持运行键盘控制节点处于激活状态) ros2 run ugv_tools keyboard_ctrl
这样,你就能控制底盘移动,来实现对周边环境的建图了。
建图完,保持建图节点的运行,在一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器,给地图保存脚本增加可执行权限:
cd ugv_ws/ chmod +x ./save_2d_gmapping_map_gazebo.sh
接着运行地图保存脚本,如下图即地图保存成功:
./save_2d_gmapping_map_gazebo.sh
该脚本里的具体内容为:
cd /home/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps ros2 run nav2_map_server map_saver_cli -f ./map
执行完上述脚本文件后,会保存一个命名为 map 的 2D 栅格地图,该地图是保存于 /home/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps 目录下,可以在上述目录里看见有两个文件生成,一个是 map.pgm,一个是 map.yaml。
- map.pgm:这是地图的栅格图(通常是灰度图像文件);
- map.yaml:这是地图的配置文件。
接着 Gmapping 建图节点可以通过 Ctrl+C 关闭。
2. 基于 Cartographer 的二维建图
保持加载 Gazebo 机器人模型的运行,按 Ctrl+Alt+T 打开一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器:
. ros_humble.sh
在容器中运行启动建图节点:
ros2 launch ugv_gazebo cartographer.launch.py
此时,RViz 界面显示的地图上只会显示出 Gazebo 仿真地图中激光雷达所扫描到的区域,若还有未扫描到的区域需要建图,则可以通过手柄或者键盘控制小车移动来扫描建图。
在一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器,运行手柄控制或键盘控制节点任意一个:
#手柄控制(确保手柄接收器插入虚拟机中) ros2 launch ugv_tools teleop_twist_joy.launch.py #键盘控制(保持运行键盘控制节点处于激活状态) ros2 run ugv_tools keyboard_ctrl
这样,你就能控制底盘移动,来实现对周边环境的建图了。
建图完,保持建图节点的运行,在一个新的终端窗口,执行进入 Docker 容器的脚本,输入 1 进入 Docker 容器,给地图保存脚本增加可执行权限:
cd ugv_ws/ chmod +x ./save_2d_cartographer_map_gazebo.sh
接着运行地图保存脚本,如下图即地图保存成功:
./save_2d_cartographer_map_gazebo.sh
该脚本里的具体内容为:
cd /home/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps ros2 run nav2_map_server map_saver_cli -f ./map && ros2 service call /write_state cartographer_ros_msgs/srv/WriteState "{filename: '/home/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps/map.pbstream'}"
执行完上述脚本文件后,会保存一个命名为 map 的 2D 栅格地图,该地图是保存于 /home/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps 目录下,可以在该目录里看见有三个文件生成,分别是 map.pgm、map.yaml 和 map.pbstram。
接着 Cartographer 建图节点可以通过 Ctrl+C 关闭。
11.7.2 三维建图
1. 在 RTAB-Map 中可视化
RTAB-Map(Real-Time Appearance-Based Mapping)是一种用于同时定位与建图(SLAM,Simultaneous Localization and Mapping)的开源算法,广泛应用于机器人导航、自动驾驶汽车、无人机等领域。它采用视觉和激光雷达传感器的数据来构建环境地图并进行定位,属于基于回环检测(loop closure detection)的SLAM方法。
保持加载 Gazebo 机器人模型的运行,在容器中启动 RTAB-Map 的可视化节点:
ros2 launch ugv_gazebo rtabmap_rgbd.launch.py
在一个新的 Docker 容器终端中,运行手柄控制或键盘控制节点任意一个:
#手柄控制(确保手柄接收器插入虚拟机中) ros2 launch ugv_tools teleop_twist_joy.launch.py #键盘控制(保持运行键盘控制节点处于激活状态) ros2 run ugv_tools keyboard_ctrl
这样,你就能控制底盘移动,来实现对周边环境的建图了。建图完毕后,直接按 Ctrl+c 退出建图节点,系统将会⾃动保存地图。地图默认保存路径 ~/.ros/rtabmap.db。
2. 在 RViz 中可视化
保持加载 Gazebo 机器人模型的运行,在容器中启动 RTAB-Map 的可视化节点:
ros2 launch ugv_gazebo rtabmap_rgbd.launch.py use_rviz:=true
在一个新的 Docker 容器终端中,运行手柄控制或键盘控制节点任意一个:
#手柄控制(确保手柄接收器插入虚拟机中) ros2 launch ugv_tools teleop_twist_joy.launch.py #键盘控制(保持运行键盘控制节点处于激活状态) ros2 run ugv_tools keyboard_ctrl
这样,你就能控制底盘移动,来实现对周边环境的建图了。建图完毕后,直接按 Ctrl+c 退出建图节点,系统将会⾃动保存地图。地图默认保存路径 ~/.ros/rtabmap.db。
11.8 导航
11.8.1 启动导航
1. 二维地图导航
在启动导航之前,首先先确定您已经建了一个名为 map 的环境地图,若您没有跟着前面的教程操作下来,则先需要根据前面的教程进行建图。
建图完成后,接着启动导航,我们提供了多种自主导航模式,你可以从以下自主导航模式任选一种进行机器人导航。
- AMCL 算法
Adaptive Monte Carlo Localization(AMCL)是 ROS 2 中的一种基于粒子滤波的定位算法,它使用 2D 激光雷达在给定的已知地图中估计机器人的位置和方向(即姿势)。AMCL 主要用于移动机器人导航,它通过激光传感器(如激光雷达)与现有地图相匹配,推算出机器人在地图中的位置和朝向。其核心思想是通过大量粒子表示机器人的可能位置,并逐步更新这些粒子来缩小机器人的位姿不确定性。
AMCL 的优势:
- 自适应粒子数:AMCL会根据机器人位置的不确定性动态调整粒子的数量。
- 适用于动态环境:虽然 AMCL 假设静态环境,但它能在一定程度上处理少量动态障碍物,如行人等移动物体,这使其在实际应用中更加灵活。
- 可靠的定位能力:AMCL 在已知地图中的定位效果非常可靠,即使机器人位姿初始不确定,它也能够逐渐收敛到正确的位姿。
AMCL 是假设地图已知,不能自己创建地图。且依赖于高质量的静态地图,与传感器数据进行匹配。如果地图和真实环境有较大差异,定位效果会受影响。AMCL 常用于移动机器人自主导航,机器人在导航过程中可以通过 AMCL 确定自己的位姿,依赖已知的地图进行路径规划和避障。
在容器中,启动基于 AMCL 算法的导航,启动成功后可以看见前面所建地图的 RViz 画面:
ros2 launch ugv_gazebo nav.launch.py use_localization:=amcl
接着,你可以根据后续的教程去确定机器人的初始位置。
- EMCL 算法
EMCL 是 AMCL 的替代 Monte Carlo localization(MCL)包。与 AMCL 不同的是,KLD 采样和自适应 MCL 没有实现。相反,实现了扩展重置和其它功能。EMCL 不完全依赖自适应粒子滤波,而是引入了扩展重置等方法来改善定位性能。EMCL 实现了扩展重置策略,这是一个用于改善粒子集质量的技术,能够更好地处理定位中的不确定性和漂移。
启动基于 EMCL 算法的导航,启动成功后可以看见前面所建地图的 RViz 画面:
ros2 launch ugv_gazebo nav.launch.py use_localization:=emcl
接着,你可以根据后续的教程去确定机器人的初始位置。
- 基于 Cartographer 的纯定位
Cartographer 是 Google 开源的一个可跨多个平台和传感器配置以 2D 和 3D 形式提供实时同时定位和建图(SLAM)的系统。
Cartographer 系统架构概述:可以看到左边可选的输入有深度信息、里程计信息、IMU数据、固定 Frame 姿态。
启动基于 Cartographer 的纯定位,启动成功后可以看见前面所建地图的 RViz 画面:
注意:基于 Cartographer 纯定位的导航模式,必须使用 Cartographer 建图后,才可以进行使用。
ros2 launch ugv_gazebo nav.launch.py use_localization:=cartographer
接着,你可以根据后续的教程去确定机器人的初始位置。
- DWA 算法
动态窗口算法(Dynamic Window Approaches,DWA)是基于预测控制理论的一种次优方法,因其在未知环境下能够安全、有效的避开障碍物, 同时具有计算量小, 反应迅速、可操作性强等特点。DWA 算法属于局部路径规划算法。
该算法核心思想是根据移动机器人当前的位置状态和速度状态在速度空间 ( v , ω ) 中确定一个满足移动机器人硬件约束的采样速度空间,然后计算移动机器人在这些速度情况下移动一定时间内的轨迹, 并通过评价函数对该轨迹进行评价,最后选出评价最优的轨迹所对应的速度来作为移动机器人运动速度, 如此循环直至移动机器人到达目标点。
启动基于 DWA 算法的导航,启动成功后可以看见前面所建地图的 RViz 画面:
ros2 launch ugv_gazebo nav.launch.py use_localplan:=dwa
接着,你可以根据后续的教程去确定机器人的初始位置。
- TEB 算法
TEB 全称 Time Elastic Band Local Planner,该方法针对全局路径规划器生成的初始全局轨迹进行后续修正,从而优化机器人的运动轨迹,属于局部路径规划。在轨迹优化过程中,该算法拥有多种优化目标,包括但不限于:整体路径长度、轨迹运行时间、与障碍物的距离、通过中间路径点以及机器人动力学、运动学以及几何约束的符合性。
启动基于 TEB 算法的导航,启动成功后可以看见前面所建地图的 RViz 画面:
ros2 launch ugv_gazebo nav.launch.py use_localplan:=teb
接着,你可以根据后续的教程去确定机器人的初始位置。
2. 三维地图导航
上面介绍的都是基于激光雷达二维建的地图导航模式,根据前面教程所建的三维地图,则参考该小节的导航启动方式。
先开启 nav 定位:
ros2 launch ugv_gazebo rtabmap_localization_launch.py
需要等三维数据加载完毕后,等待一段时间出现如下图所显示的即可开启导航。
在一个新的终端中,开启导航,两种导航模式任选一种即可:
- DWA 算法
ros2 launch ugv_gazebo nav_rtabmap.launch.py use_localplan:=dwa
- TEB 算法
ros2 launch ugv_ngazebo nav_rtabmap.launch.py use_localplan:=teb
根据上述所建的地图选择一种导航模式开启导航后,则接着以下内容进行使用。
11.8.2 初始化机器人的位置
默认情况下,启动导航后,机器人最初不知道自己在哪里,地图等待您为其提供大致的起始位置。
首先,找到机器人在地图上的位置,检查你的机器人在实际中的位置。在 RViz 中手动设置机器人的初始位姿。单击 2D Pose Estimate 按钮并在地图上指出机器人的位置。绿色箭头的方向是机器人云台向前所面对的方向。
保持好启动导航终端的运行,设置好机器人大致的初始位姿后,保证导航确保机器人在实际中的位置是大致对应地上的。也可以在一个新终端通过键盘控制小车,进行简单地移动旋转,协助进行初始定位。
ros2 run ugv_tools keyboard_ctrl
11.8.3 发送目标位姿
1. 单点导航
在地图上为机器人选择一个目标位置。您可以使用 Nav2 Goal 工具向机器人发送目标位置和目标方向。在 RViz 地图上指出机器人想要自动导航至的位置(目标点),绿色箭头的方向是机器人云台向前所面对的方向。
设置好目标位姿后,导航将找到全局路径并开始在地图上导航机器人移动到目标位姿。现在,你可以看到机器人向实际中的目标位置移动。
2. 多点导航
观察 RViz 界面中的左下角,有一个 Nav2 的RViz2 小插件【Waypoint/Nav Through Poses Mode】,可以进行导航模式的切换,点击【Waypoint/Nav Through Poses Mode】该按钮即切换至多点导航模式。
接着使用 RViz2 工具栏中的 Nav2 Goal 给定多个要移动的目标点,给定后,还是点击左下角【Start Waypoint Following】开始路径规划导航。机器人会根据所选目标点的先后顺序进行移动,到了第一个目标点后会自动前往下一个目标点,无需再进行操作。到达最后一个目标点后,小车会停止。