跳到主要内容

Gazebo 仿真开发

Gazebo 仿真概述

本教程使用镜像内置的 House 场景。Gazebo 负责模拟 UGV Rover、环境和传感器数据,RViz 用于查看地图、定位和导航结果。预配置镜像已经包含 Ubuntu 22.04、ROS 2 Humble、Gazebo Classic 11、UGV ROS 2 工作空间和运行依赖。

提示

当前预配置镜像和 UGV 仿真功能基于 Gazebo Classic 11。界面顶部显示的生命周期提示不影响本教程中的仿真操作;不要在本教程流程中自行替换为新版 Gazebo。

首次使用快速开始

首次使用时,只需导入镜像、配置图形显示并启动仿真。

检查或启用 WSL2

在 Windows PowerShell 中执行:

wsl --status

如果命令正常显示 WSL 状态,且默认版本为 2,进入“下载并导入预配置镜像”。只有命令报错或 WSL2 尚未启用时,才执行以下步骤。

WSL2 尚未启用时展开
  1. 在 Windows "开始" 菜单中右键单击 PowerShell,选择 "以管理员身份运行"。

    以管理员身份打开 Windows PowerShell

  2. 如果 WSL 相关 Windows 可选组件尚未启用,终端可能显示 Wsl/WSL_E_WSL_OPTIONAL_COMPONENT_REQUIRED

    WSL 可选组件未启用提示

  3. 在管理员 PowerShell 中启用 "适用于 Linux 的 Windows 子系统":

    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
  4. 启用 "虚拟机平台":

    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

    在 PowerShell 中启用 WSL2 相关功能

  5. 也可以打开 "控制面板" > "程序" > "启用或关闭 Windows 功能",勾选 "适用于 Linux 的 Windows 子系统" 和 "虚拟机平台"。PowerShell 命令和图形界面选择一种方式即可。

    在 Windows 功能中启用 WSL2

  6. 重启 Windows。

  7. 重启后,以管理员身份打开 Windows PowerShell,更新 WSL 并将默认版本设为 WSL2:

    wsl --update
    wsl --set-default-version 2
提示

预配置镜像自身已经包含 Ubuntu 22.04,因此不需要另行安装 Ubuntu 发行版。

下载并导入预配置镜像

下载 UGV Gazebo Humble 预配置镜像,提取码为 WXDZ

当前正式镜像为 UGV-Gazebo-Humble-20260715-v1.0.tar,发布于 2026-07-15,已经包含 Windows 浏览器实体手柄桥接功能。导入后不需要执行 git pullcolcon build,也不需要安装额外的 apt、pip 或 npm 依赖。

首次安装

在 Windows PowerShell 中进入镜像下载目录,设置导入变量并检查 Hash。$InstallPath 是导入后 WSL2 运行数据的保存位置,必须使用新建或空目录,不得复用旧发行版的数据目录,也不得与其它发行版共用目录。$DistroName 不得与已有发行版重名。

$DistroName = "UGV-Gazebo-Humble"
$InstallPath = "C:\WSL\UGV-Gazebo-Humble"
$ImagePath = (Resolve-Path ".\UGV-Gazebo-Humble-20260715-v1.0.tar").Path

Get-FileHash $ImagePath -Algorithm SHA256

PowerShell 输出的 Hash 应与以下 SHA256 一致:

备注

SHA256 哈希值相当于镜像文件的数字指纹,用于检查文件是否下载完整、是否被意外修改。

87F3290B49CBD83370558978CB9A6ED61F1FE089793AF14CC4032D4F22B7568F
注意

SHA256 与文档记录不一致时,不要继续导入。重新确认下载是否完成,并重新获取镜像文件。

确认 Hash 一致后,在同一 Windows PowerShell 中执行导入:

New-Item -ItemType Directory -Force $InstallPath
wsl --import $DistroName $InstallPath $ImagePath --version 2

wsl --list --verbose

输出中应包含:

UGV-Gazebo-Humble Stopped 2

WSL2 发行版列表中的 UGV-Gazebo-Humble

开发者:替换已有旧版

替换旧版前,先将地图、数据库和个人文件复制到 Windows 中的其它目录。在 Windows PowerShell 中终止发行版并导出完整备份:

wsl --terminate UGV-Gazebo-Humble

wsl --export `
UGV-Gazebo-Humble `
.\UGV-Gazebo-Humble-before-update.tar

确认备份文件存在且保存位置正确后,再执行注销。

注销旧发行版

以下命令会永久删除 UGV-Gazebo-Humble 发行版中的全部数据。只有在地图、数据库和个人文件已经备份后才能执行:

wsl --unregister UGV-Gazebo-Humble

注销完成后,按照“首次安装”流程重新导入镜像。重新导入时使用新建或空的 $InstallPath;如果原目录仍包含文件,请修改 $InstallPath,使用另一个空目录。本文不提供自动删除目录的命令。

安装 VcXsrv 和 XLaunch

XLaunch 是 VcXsrv 提供的图形配置工具,随 VcXsrv 安装程序一同安装,不需要单独下载。

  1. 打开 VcXsrv GitHub Releases 页面

  2. 在最新正式版本的 Assets 中,下载适用于 64 位 Windows 的普通安装程序。

    安装文件名通常包含 vcxsrv-64installer。不要下载 Source code 压缩包或 debug 安装包;如果 Releases 页面的资产命名发生变化,以 64 位 Windows 普通安装程序为准。

    VcXsrv GitHub Releases 页面中的 64 位 Windows 安装程序

  3. 运行下载的安装程序。

  4. 保持默认安装位置和默认组件,按安装向导完成安装。

  5. 安装完成后,打开 Windows“开始”菜单,搜索并启动 XLaunch

    从 Windows 开始菜单启动 XLaunch

安装完成后,继续按照下一节配置 XLaunch。

配置并保存 XLaunch

  1. 在“Display settings”页面填写:

    • Display type 选择“Multiple windows”。
    • Display number 填写 0

    XLaunch“Multiple windows”设置页面

  2. 在“Client startup”页面中,将 Client startup 选择为“Start no client”。

    XLaunch“Start no client”设置页面

  3. 在“Extra settings”页面填写:

    • 勾选 Clipboard
    • 勾选 Native OpenGL
    • 勾选 Disable access control
    • Additional parameters 保持为空。

    Xlunch3

    注意

    “Disable access control”会关闭当前 X Server 的客户端访问控制。建议仅在可信的本地网络中使用,完成仿真后退出 VcXsrv。

  4. 进入“Finish configuration”页面后,点击“Save configuration”。

XLaunch“Finish configuration”页面中的“Save configuration”按钮

  1. 将配置文件保存为:

    UGV-Gazebo-XLaunch.xlaunch

    建议保存到 Windows 桌面或其它不易移动的固定目录。

  2. 保存完成后,点击“完成”,启动 VcXsrv。

  3. 检查 Windows 任务栏通知区域中是否显示 VcXsrv 图标。

    Windows 任务栏通知区域中的 VcXsrv 图标

运行 Gazebo 期间保持 VcXsrv 运行。

提示

Windows 重启后,双击保存的 UGV-Gazebo-XLaunch.xlaunch,即可按照相同参数启动 VcXsrv。保存配置不会使 VcXsrv 自动随 Windows 启动。

打开 UGV 仿真终端

  1. 打开 Windows“开始”菜单,在“最近添加”或应用列表中选择 UGV-Gazebo-Humble,等待镜像终端打开。

    从 Windows 开始菜单打开 UGV-Gazebo-Humble

  2. 首次打开终端时,确认显示镜像欢迎页:

    UGV-Gazebo-Humble 镜像终端欢迎页

需要第二、第三个终端时,继续从 Windows“开始”菜单打开新的 UGV-Gazebo-Humble 终端窗口。各终端分别用于 Gazebo、browser gamepad bridge、topic、SLAM 或 Nav2。

备注

如果 Windows“开始”菜单中暂时没有显示 UGV-Gazebo-Humble,可以在 Windows PowerShell 中执行:

wsl -d UGV-Gazebo-Humble -u ag

启动 UGV Gazebo 仿真

预配置镜像已经包含 use_vcxsrv_gazebo.sh。该脚本会设置 WSL2 图形显示地址以及 Gazebo 模型和资源路径,不需要手动创建或修改。

在 UGV-Gazebo-Humble 终端中执行:

cd /home/ag/ws/ugv_ws
unset ROS_DOMAIN_ID
source /opt/ros/humble/setup.bash
source install/setup.bash
source use_vcxsrv_gazebo.sh
export UGV_MODEL=ugv_rover

ros2 launch ugv_gazebo bringup.launch.py

source /opt/ros/humble/setup.bash 加载 ROS 2 Humble,source install/setup.bash 加载 UGV 工作空间,source use_vcxsrv_gazebo.sh 加载镜像内置图形环境,UGV_MODEL=ugv_rover 选择 UGV Rover 模型。

运行结果:

  • Gazebo 窗口显示在 Windows 桌面;
  • House 场景加载完成;
  • UGV Rover 模型出现在场景中;
  • 启动终端依次显示 Waiting for service /spawn_entity, timeout = 120Calling service /spawn_entitySuccessfully spawned entity [ugv_rover]
提示

冷启动时,Gazebo 服务初始化可能需要较长时间,120 秒内完成启动均属正常。在终端明确显示失败前,不要重复启动第二个 Gazebo。ALSA 音频设备错误不影响仿真;Gazebo Classic 窗口顶部的生命周期结束提示也不表示启动失败。

Gazebo House 场景和 UGV Rover 模型

Gazebo 窗口和 UGV Rover 模型正常显示后,首次配置已经完成。需要继续核对镜像、工作空间和 ROS 2 数据时,再执行下一节的可选检查。

展开可选检查

检查镜像与工作空间

在新的 UGV-Gazebo-Humble 终端中执行:

cd ~/ws/ugv_ws
source /opt/ros/humble/setup.bash
source install/setup.bash

whoami
echo "$HOME"
echo "$ROS_DISTRO"
gazebo --version
ros2 pkg prefix ugv_gazebo

test -d ~/ws/ugv_ws && echo "ugv_ws exists"
test -f ~/ws/ugv_ws/install/setup.bash && echo "workspace installed"

输出依次包含 ag/home/aghumble、Gazebo 11.10.2、/home/ag/ws/ugv_ws/install/ugv_gazebougv_ws existsworkspace installed

UGV-Gazebo-Humble 镜像环境检查结果

检查图形环境

在同一个终端中执行:

source use_vcxsrv_gazebo.sh

echo "$DISPLAY"
echo "$GAZEBO_MODEL_PATH"
echo "$GAZEBO_RESOURCE_PATH"

DISPLAY 输出非空并以 :0:0.0 结尾;GAZEBO_MODEL_PATH 包含 ugv_gazebo/share/ugv_gazebo/modelsGAZEBO_RESOURCE_PATH 应包含 /usr/share/gazebo-11。这些命令用于启动成功后的环境检查,不是创建或修复脚本的步骤。

检查 ROS 2 节点和 topic

备注

UGV Gazebo 启动入口会同时启动多个进程:gzserver 负责物理与传感器仿真,gzclient 显示 Gazebo 场景,spawn_entity.py 将 UGV Rover 模型加入仿真世界,robot_state_publisher 发布机器人 TF。

保持 Gazebo 启动终端运行,在新的 UGV-Gazebo-Humble 终端中执行:

cd ~/ws/ugv_ws
source /opt/ros/humble/setup.bash
source install/setup.bash

ros2 node list
ros2 topic list
ros2 service list

timeout 5 ros2 topic hz /clock
timeout 5 ros2 topic hz /scan

话题列表中应出现 /clock/tf/tf_static/odom/scan/cmd_vel 等接口,/clock/scan 持续更新。timeout 5 会在 5 秒后自动结束命令;如果使用不带 timeoutros2 topic hz,按 Ctrl + C 停止查看。

日常启动

首次配置完成后,后续启动 Gazebo 只需执行以下步骤:

  1. 双击保存的 UGV-Gazebo-XLaunch.xlaunch,并确认任务栏通知区域显示 VcXsrv 图标。

  2. 从 Windows“开始”菜单打开 UGV-Gazebo-Humble

  3. 在终端中执行:

    cd /home/ag/ws/ugv_ws
    unset ROS_DOMAIN_ID
    source /opt/ros/humble/setup.bash
    source install/setup.bash
    source use_vcxsrv_gazebo.sh
    export UGV_MODEL=ugv_rover

    ros2 launch ugv_gazebo bringup.launch.py

键盘与手柄控制

本节用于在 Gazebo 中复现键盘控制和 TGZ-850M 实体手柄控制。同一时间只运行一种手动控制。

使用键盘控制

  1. 保持 Gazebo 运行,另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 run ugv_tools keyboard_ctrl
  2. 保持键盘控制终端处于活动状态,按以下按键低速控制 UGV Rover:

    按键动作
    I前进
    ,后退
    J左转
    L右转
    K 或空格停止

    Gazebo 中的 UGV Rover 应按照按键方向移动。每次短距离移动后按 K 或空格,确认车辆停止后再继续。

    键盘控制终端与 Gazebo 中的 UGV Rover 运动状态

  3. 停车后在键盘控制终端按 Ctrl + C,退出键盘控制。

按键后 UGV Rover 不运动时检查 topic

保持键盘控制终端运行,另开一个 UGV-Gazebo-Humble 图形化终端并执行:

cd ~/ws/ugv_ws
source /opt/ros/humble/setup.bash
source install/setup.bash

ros2 topic info /cmd_vel
ros2 topic echo /cmd_vel

回到键盘控制终端操作按键,检查 /cmd_vel 是否随输入变化。检查完成后按 Ctrl + C 停止 topic 输出。

使用手柄控制

本节使用 UGV 配套的 TGZ-850M 2.4 GHz 实体手柄。USB 接收器由 Windows 管理,网页通过 Windows Gamepad API 读取实体手柄,再由预配置镜像中的 browser gamepad bridge 将数据发布到 ROS 2。

TGZ-850M 实体手柄
↓ 2.4 GHz
Windows USB 接收器和 Windows XInput 驱动

Windows Edge / Chrome Gamepad API
↓ HTTP
WSL2 browser gamepad bridge → /joy → joy_ctrl → /cmd_vel → Gazebo UGV Rover

本流程读取 Windows 中已连接的实体手柄,不使用网页虚拟摇杆。接收器无需通过 usbipd 连接到 WSL2,预配置镜像已包含所需功能,无需额外安装或重新编译。

提示

该流程仅用于本教程的 WSL2 Gazebo 仿真,不影响实体 UGV 原有的手柄控制方式。同一时间只运行一种手动控制。

使用实体手柄控制 UGV Rover

  1. 完成使用前准备:将 TGZ-850M 的 2.4 GHz USB 接收器插入 Windows 电脑,打开手柄电源,确认手柄指示灯稳定。在 Windows PowerShell 中执行:

    usbipd list

    在输出中找到 045e:028e 支持 Windows 的 XBOX 360 手柄,正常状态应为 Not shared

    usbipd list 中由 Windows 管理的 TGZ-850M USB 接收器

    如果状态显示为 Shared (forced)Attached,说明接收器仍被旧 usbipd 流程占用。以管理员身份打开 Windows PowerShell,执行:

    usbipd unbind --hardware-id 045e:028e

    重新插拔接收器后,再次执行 usbipd list,确认状态变为 Not shared

    在 Windows PowerShell 中执行:

    Start-Process joy.cpl

    在“游戏控制器”窗口中选择 Xbox 360 Controller,点击“属性”,再进入“测试”选项卡。分别推动左、右摇杆,按下方向键和主要按键,确认测试页面中的十字标记、轴或按钮状态随操作变化。测试完成后关闭“属性”和“游戏控制器”窗口,避免其它程序持续占用设备。

    游戏控制器窗口

    Windows“游戏控制器”中的 TGZ-850M 输入测试

    Xbox 360 Controller 是接收器向 Windows 报告的设备名称,不表示 TGZ-850M 是微软原装 Xbox 360 手柄。

  2. 保持 Gazebo 运行,确认键盘控制已经停止。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd /home/ag/ws/ugv_ws
    unset ROS_DOMAIN_ID
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_tools teleop_twist_joy.launch.py input_mode:=browser

    日志显示 browser 输入模式、http://localhost:8765browser gamepad bridgejoy_ctrl,表示 bridge 已启动。

    browser gamepad bridge 启动日志和控制页面地址

  3. 在 Windows Edge 或 Chrome 中打开 http://localhost:8765。只保留一个控制页面,然后点击“开始读取实体手柄”。确认页面显示接收器检测状态、网页与 WSL bridge 通信状态,以及控制输出状态。

    TGZ-850M browser gamepad bridge 控制页面

    提示

    控制期间保持该页面为当前活动标签页。切换到其它标签页、最小化或关闭页面时,系统会触发安全停车。

    页面显示“手柄本体状态:浏览器无法可靠判断”不表示发生故障。接收器已检测或 bridge 通信正常,都不表示手柄本体已经开机。应以控制输出和车辆是否停止为准。

  4. 观察控制页面中的原始数据:

    • 设备 ID 显示 Xbox 360 Controller
    • mapping 显示 standard
    • axes 长度为 4
    • buttons 长度为 17
    • 推动左、右摇杆时,原始 axes 数值发生变化;
    • 松开摇杆后,axes 回到接近 0
    • 按键操作时,对应 buttons 数值发生变化。

    不需要记忆所有 axes 下标。本机验证的方向参考如下,推动幅度不同时数值可能不是 -11:左摇杆向上时 axes[1] 为负值,向下时为正值;右摇杆向左时 axes[2] 为负值,向右时为正值;松开后接近 0

  5. 小幅操作手柄,确认 Gazebo 中 UGV Rover 的运动方向:

    操作预期
    左摇杆向上UGV Rover 前进
    左摇杆向下UGV Rover 后退
    右摇杆向左UGV Rover 左转
    右摇杆向右UGV Rover 右转
    松开摇杆UGV Rover 停车

    前进和转向可以组合,摇杆推动幅度影响速度。第一次操作时先小幅推动。

  6. 验证安全停车:

    • 让 UGV Rover 移动后松开摇杆,确认车辆停车;
    • 让 UGV Rover 低速移动后切换到其它标签页,确认车辆停车;
    • 关闭控制页面,确认车辆停车;
    • 拔出 USB 接收器,确认车辆停车;
    • 保持摇杆非零时关闭手柄电源,确认车辆停车;
    • 重新打开手柄并操作,确认可以恢复控制。

    手柄关闭后,页面仍可能显示“USB 接收器:已检测”或 bridge 通信正常,这不代表车辆仍在运动。不需要刷新网页才能停车,应以页面“控制输出”和 Gazebo 中车辆实际状态为准。控制输出应持续反映当前输入,不应周期性在运动和中立之间跳变。

手柄页面正常但 UGV Rover 不运动时检查 topic

另开一个 UGV-Gazebo-Humble 图形化终端,执行:

cd /home/ag/ws/ugv_ws
unset ROS_DOMAIN_ID
source /opt/ros/humble/setup.bash
source install/setup.bash

ros2 topic info /joy
ros2 topic info /cmd_vel

检查 /joy:先推动并保持一个摇杆方向,再执行:

ros2 topic echo /joy --once

预期 axes 中出现非零值。

检查 /cmd_vel:继续保持运动方向,再执行:

ros2 topic echo /cmd_vel --once

预期 linear.xangular.z 中出现非零值。松开摇杆后重新执行:

ros2 topic echo /cmd_vel --once
  • /joy 不变化:先检查浏览器页面和 Windows joy.cpl
  • /joy 变化但 /cmd_vel 不变化:检查 joy_ctrl 是否运行;
  • /cmd_vel 变化但车辆不动:检查 Gazebo 底盘控制节点;
  • 不需要修改代码或重新构建。

停止手柄控制:

  1. 松开摇杆并确认 UGV Rover 已停止。
  2. 关闭 Windows 中的控制页面。
  3. browser gamepad bridge 终端按 Ctrl + C

在 Gazebo 中复现 SLAM

SLAM 原理和实体 UGV 操作已在前面的 ROS 2 教程中介绍。本节只列出 Gazebo House 场景中的对应入口和观察结果。整个章节保持同一个 Gazebo 运行;切换算法前,停止上一套 SLAM、RViz 和手动控制。

Gmapping 建图

  1. 保持 Gazebo 运行,另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_gazebo gmapping.launch.py

    正常时会打开 RViz,窗口中显示 UGV Rover 模型、LaserScan 和正在生成的二维地图。

    Gmapping 启动后的 RViz 二维建图界面

  2. 另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 run ugv_tools keyboard_ctrl

    保持键盘控制终端处于活动状态,低速移动 UGV Rover。注意 Gazebo 中的车辆运动,避免遗漏区域、撞墙或翻车;同时观察 RViz 中的地图逐步扩展。

    按键动作
    I前进
    ,后退
    J左转
    L右转
    K 或空格停止
    提示

    在 Gazebo 和 RViz 中,可使用鼠标滚轮缩放视图,按住鼠标中键拖动调整显示位置。

    Gmapping 建图时的 Gazebo、键盘控制终端和 RViz

  3. 地图覆盖目标区域后,先结束键盘控制,保持 Gmapping 和 RViz 运行。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    MAP_DIR="$HOME/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps"
    mkdir -p "$MAP_DIR"
    ros2 run nav2_map_server map_saver_cli -f "$MAP_DIR/map"
    ls -lh "$MAP_DIR/map.pgm" "$MAP_DIR/map.yaml"

    保存过程中,终端会显示地图数据和元数据的写入路径,并输出 Map saved successfully

    Gmapping 地图保存成功日志

    随后的文件列表中应显示 map.pgmmap.yaml,且两个文件大小不为 0

    Gmapping 保存后的地图文件

    保存后在 Gmapping 终端按 Ctrl + C,停止 Gmapping 和 RViz,保留 Gazebo 运行

Cartographer 建图

  1. 保持 Gazebo 运行,停止上一套 SLAM 和 RViz。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_gazebo cartographer.launch.py

    正常时会打开 RViz,窗口中显示 UGV Rover 模型、LaserScan、地图和建图轨迹。

    Cartographer 启动后的 RViz 建图界面

  2. 另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 run ugv_tools keyboard_ctrl

    保持键盘控制终端处于活动状态,低速移动 UGV Rover,观察 RViz 中的地图和轨迹持续更新。

    按键动作
    I前进
    ,后退
    J左转
    L右转
    K 或空格停止
  3. 地图覆盖目标区域后,先结束键盘控制,保持 Cartographer 和 RViz 运行。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    MAP_DIR="$HOME/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps"
    mkdir -p "$MAP_DIR"
    ros2 run nav2_map_server map_saver_cli -f "$MAP_DIR/map"
    ros2 service call /write_state \
    cartographer_ros_msgs/srv/WriteState \
    "{filename: '$MAP_DIR/map.pbstream'}"
    ls -lh \
    "$MAP_DIR/map.pgm" \
    "$MAP_DIR/map.yaml" \
    "$MAP_DIR/map.pbstream"

    三个文件存在并且大小不为 0,表示二维地图和 Cartographer 状态已经保存。保存后在 Cartographer 终端按 Ctrl + C,停止 Cartographer 和 RViz,保留 Gazebo 运行

二维地图保存位置

Gmapping 和 Cartographer 会将地图保存到 ~/ws/ugv_ws/src/ugv_main/ugv_gazebo/maps/。镜像内置导航默认使用安装目录中与 House 场景匹配的地图,因此保存成功不表示 Nav2 已切换到新地图。当前教程继续使用镜像内置地图;不要直接修改安装目录,也不需要重新构建工作空间。

地图不更新或保存失败时检查

另开一个 UGV-Gazebo-Humble 图形化终端并执行:

cd ~/ws/ugv_ws
source /opt/ros/humble/setup.bash
source install/setup.bash

ros2 topic hz /map
ros2 run tf2_ros tf2_echo map base_footprint

两个命令会持续输出,检查完成后按 Ctrl + C。如果 /map 没有更新,先确认对应 SLAM 终端仍在运行;如果保存失败,检查保存终端中的错误和目标目录权限。

RTAB-Map RGB-D 建图

RTAB-Map 用相机、深度相机和激光雷达数据生成三维点云地图,建图结果保存在 ~/.ros/rtabmap.db

注意

该启动入口会删除默认旧数据库。已有数据库需要保留时,先在 UGV-Gazebo-Humble 终端中执行:

mkdir -p ~/rtabmap_backup

if [ -f ~/.ros/rtabmap.db ]; then
cp ~/.ros/rtabmap.db \
~/rtabmap_backup/rtabmap-$(date +%Y%m%d-%H%M%S).db
fi
  1. 保持 Gazebo 运行,停止上一套 SLAM 和 RViz。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_gazebo rtabmap_rgbd.launch.py

    正常时会打开 RTAB-Map 可视化窗口(程序名为 rtabmap_viz),其中显示相机画面、三维点云地图、里程计和建图轨迹。初始画面中可看到相机数据和已经接收的点云。

    RTAB-Map 启动后的可视化窗口

  2. 另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 run ugv_tools keyboard_ctrl

    保持键盘控制终端处于活动状态,低速移动 UGV Rover。RTAB-Map 可视化窗口中的点云地图和轨迹应随车辆移动逐步更新。

    按键动作
    I前进
    ,后退
    J左转
    L右转
    K 或空格停止

    RTAB-Map 建图时的 Gazebo、键盘控制终端和可视化窗口

  3. 建图结束后,先停止键盘控制,再在 RTAB-Map 终端按 Ctrl + C。等待数据库写入完成,然后执行:

    ls -lh ~/.ros/rtabmap.db

    数据库存在并且大小不为 0,表示建图数据已经保存。保留 Gazebo 运行

定位与导航

本节用于在 Gazebo 中快速复现实体 UGV 教程中的定位和导航操作,继续使用镜像内置的 House 场景地图。

使用已有二维地图进行 AMCL + Nav2 导航

  1. 保持 Gazebo 运行,确认键盘控制、browser 手柄控制和其它 SLAM、定位、Nav2 节点已经停止。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_gazebo nav.launch.py \
    use_localization:=amcl \
    use_localplan:=teb

    正常时会加载 House 场景对应的地图并打开 RViz。

  2. 在 RViz 中点击 2D Pose Estimate,在地图中 UGV Rover 所在位置按下鼠标并沿车头方向拖动,松开鼠标后完成初始位置设置。

    在 RViz 中设置 UGV Rover 的 AMCL 初始位置

    等待粒子聚集到 UGV Rover 周围,并确认 LaserScan 与地图中的墙壁轮廓基本对齐。出现明显偏差时,重新设置位置和方向。

    AMCL 粒子向 UGV Rover 周围聚集

  3. 在 RViz 中点击 Nav2 Goal,在已知可通行区域设置一个近距离目标。RViz 中出现规划路径后,UGV Rover 应沿路径移动并在到达目标后停止。

    Nav2 控制 UGV Rover 沿规划路径移动

    UGV Rover 到达 Nav2 导航目标

  4. 结束时先在 RViz 中取消当前目标,确认 UGV Rover 停止,再在 Nav2 终端按 Ctrl + C

切换为 DWA 局部控制

停止上一组 Nav2 后,将启动命令中的局部控制参数改为:

use_localplan:=dwa

其它操作与 TEB 相同。

SLAM Toolbox 与 Nav2 同步建图和导航

该流程用于综合演示同步建图和导航,不再重复介绍 SLAM Toolbox 和 Nav2 原理。

  1. 保持 Gazebo 运行,停止其它 SLAM、定位、Nav2、RViz 和手动控制。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_gazebo slam_nav.launch.py

    正常时会打开 RViz 建图导航窗口。窗口中显示机器人模型、激光雷达数据和初始地图,左侧 Navigation 状态显示为 active

    SLAM Toolbox 与 Nav2 启动后的 RViz 建图导航窗口

  2. 另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 run ugv_tools keyboard_ctrl

    保持键盘控制终端处于活动状态,低速移动 UGV Rover,观察 RViz 中的地图扩展。

    按键动作
    I前进
    ,后退
    J左转
    L右转
    K 或空格停止

    UGV Rover 移动后,Gazebo 中的激光扫描方向随车辆位置变化,RViz 中的空白区域逐步生成地图,墙壁轮廓和可通行区域随移动不断补充。

    使用键盘控制 UGV Rover 进行 SLAM Toolbox 同步建图

  3. 地图覆盖目标区域后,停止键盘控制。RViz 中应显示连续的墙壁轮廓和已探索区域。

    SLAM Toolbox 建图完成后的 RViz 地图

    在 RViz 中设置一个近距离 Nav2 Goal。出现规划路径后,UGV Rover 应沿路径向目标移动,左侧导航反馈会显示目标执行状态。

    SLAM Toolbox 与 Nav2 同步运行时 UGV Rover 向目标移动

  4. 结束时先取消导航目标并确认车辆停止,再在 SLAM Toolbox 与 Nav2 终端按 Ctrl + C

RTAB-Map Localization 定位验证

该进阶功能只使用已有 ~/.ros/rtabmap.db 验证定位,不会自动规划路径或控制车辆。

保持 Gazebo 运行,停止其它定位、SLAM 和 Nav2。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

cd ~/ws/ugv_ws
source /opt/ros/humble/setup.bash
source install/setup.bash

ls -lh ~/.ros/rtabmap.db
ros2 launch ugv_gazebo rtabmap_localization_launch.py

数据库应存在并且大小不为 0。检查完成后,在 RTAB-Map 定位终端按 Ctrl + C

定位或导航没有正常显示时检查

另开 UGV-Gazebo-Humble 终端,执行:

cd ~/ws/ugv_ws
source /opt/ros/humble/setup.bash
source install/setup.bash

ros2 node list
ros2 topic list
ros2 lifecycle nodes
ros2 run tf2_ros tf2_echo map base_footprint

tf2_echo 会持续输出,检查完成后按 Ctrl + C 停止。

自动探索

本节用于在 Gazebo 中快速复现自动探索。运行期间不要同时使用键盘或手柄控制。

  1. 保持 Gazebo 运行,停止其它 SLAM、定位、Nav2、RViz 和手动控制。另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch ugv_gazebo slam_nav.launch.py

    等待 RViz 中出现机器人模型和初始地图。地图开始更新后,再启动自动探索。

    explore_lite 启动前的 RViz 建图导航界面

  2. 另开一个 UGV-Gazebo-Humble 图形化终端并执行:

    cd ~/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash

    ros2 launch explore_lite explore.launch.py

    启动后,自动探索终端会输出当前探索和导航信息。RViz 中的地图和路径会逐步扩展,Gazebo 中的 UGV Rover 会自动移动。没有可探索区域时,系统可能不再产生新目标。

    Gazebo、RViz 和 explore_lite 自动探索过程

  3. 结束时先在自动探索终端按 Ctrl + C,再在 RViz 中取消当前目标并确认 UGV Rover 停止,最后在 SLAM 与 Nav2 终端按 Ctrl + C

停止与重新启动

本节说明 Gazebo、SLAM、Nav2、自动探索和控制节点的停止顺序,以及 Windows 重启后的恢复步骤。

正常停止

按照当前实际运行的功能从上层向底层停止。没有运行的终端跳过。

  1. 运行自动探索时,先在自动探索终端按 Ctrl + C,停止继续提交探索目标。

  2. 运行 Nav2 时,在 RViz 中取消当前目标。

  3. 松开键盘或实体手柄输入,确认 UGV Rover 不再运动。

  4. 使用 browser 手柄控制时,关闭 Windows 中的控制页面,在 browser gamepad bridge 终端按 Ctrl + C,然后执行:

    ss -ltnp | grep ':8765' || echo "port 8765 released"

    输出 port 8765 released 表示控制页面端口已经释放。使用键盘控制时,在键盘控制终端按 Ctrl + C

  5. 在 Nav2 终端按 Ctrl + C

  6. 在定位或 SLAM 终端按 Ctrl + C;RTAB-Map 建图结束时等待数据库写入完成。

  7. 最后回到 Gazebo 启动终端Ctrl + C,等待 5~10 秒。

运行结果:活动的控制、导航和 SLAM 节点停止,browser gamepad bridge 退出,gzclientgzserver 退出。

如果 Ctrl + C 后 Gazebo 仍未退出,在另一个 UGV-Gazebo-Humble 终端中执行备用停止工具:

source /opt/ros/humble/setup.bash
source /home/ag/ws/ugv_ws/install/setup.bash

ros2 run ugv_gazebo stop_gazebo.sh

该工具仅用于 Ctrl + C 失效的情况,不作为正常停止方式。执行后可检查 Gazebo 进程:

pgrep -a -x gzclient || echo "gzclient stopped"
pgrep -a -x gzserver || echo "gzserver stopped"
pgrep -a -f '[r]os2 launch ugv_gazebo' || echo "gazebo launch stopped"

输出 gzclient stoppedgzserver stoppedgazebo launch stopped,表示备用停止完成。不要使用 killall pythonpkill python,以免终止其它 ROS 2 节点;也不再将 Ctrl + \ 作为常规停止操作。

冷启动

  1. 在 UGV-Gazebo-Humble 终端中执行:

    exit
  2. 需要完全停止 WSL2 时,在 Windows PowerShell 中执行:

    wsl --shutdown

wsl --shutdown 会停止所有正在运行的 WSL2 发行版,请先确认其它 WSL2 任务已经保存。

Windows 重启后,按照 日常启动 恢复 Gazebo 仿真。