跳到主要内容

定位、导航与自主任务

2D Navigation:使用地图导航

Navigation 使用已经保存的地图进行定位、路径规划和底盘控制。它不会重新建图。启动 Navigation 后,系统会加载 map.pgm / map.yaml,启动定位模块、路径规划模块、控制器、代价地图和 RViz。Gmapping / Cartographer 负责生成地图;Navigation 负责使用地图。

Navigation / Localization 显示 active 只表示相关 Nav2 lifecycle 节点已经激活,不表示地图一定正确、AMCL 一定收敛、LaserScan 一定对齐,也不表示当前目标一定可达。发出目标前必须先确认地图、定位、雷达扫描和 costmap 状态。

注意

Navigation 使用前面保存的 map.pgmmap.yaml 进行定位和路径规划。启动 Navigation 前,请先打开 map.pgm 检查地图轮廓是否清楚,并确认当前测试环境与建图时基本一致。

如果地图有明显重影、断墙、错位、大片未知区域,或当前场地已经发生较大变化,不要继续测试 Navigation。应先重新建图或重新保存地图。

前置条件

启动 Navigation 前,先完成以下检查:

  1. 已按 查看保存的地图文件 确认 map.pgmmap.yaml 存在,并检查 map.pgm 轮廓质量;
  2. 已按 检查并释放底盘串口 确认底盘串口没有被其它程序占用;
  3. 已停止 Gmapping、Cartographer、基础 bringup、键盘控制或其它会占用底盘、雷达的终端;
  4. 测试场地空旷,UGV 旁边没有人、宠物、线缆、桌脚或其它障碍;
  5. 已确认 停止 Navigation 的流程。

nav.launch.py 会包含底盘与雷达 bringup,不要同时单独启动另一个 bringup_lidar.launch.py

危险

Navigation 会发布速度指令并驱动实体底盘。关闭终端不应作为唯一停止手段,测试时始终保留物理停止方式。

启动 Navigation

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

export UGV_MODEL=ugv_rover
ros2 launch ugv_nav nav.launch.py use_rviz:=true use_localization:=amcl use_localplan:=teb

该命令会启动 Navigation、定位、局部规划、底盘与雷达相关节点,并打开 RViz。启动后不要关闭该 Navigation 终端。

本节使用推荐组合 amcl + teb。其中 amcl 用来判断机器人在地图中的位置,teb 用来根据目标点和障碍物规划局部移动路线。首次导航时先不要修改 use_localizationuse_localplan 参数,先完成地图加载、初始位姿设置、目标点发送和底盘移动测试。

开发者补充:Navigation 参数说明

nav.launch.py 中的两个参数分别决定:

  • use_localization:机器人使用哪种方式在地图中定位,也就是判断“我现在在地图哪里”;
  • use_localplan:机器人使用哪种局部规划方式移动到目标点,也就是判断“我怎么绕开附近障碍物走过去”。
参数可选值作用建议
use_localizationamcl常用 2D 定位方式。启动后需要在 RViz 中用 2D Pose Estimate 设置初始位姿首次实车导航优先使用
use_localizationemcl另一种 2D 定位方式,也需要设置初始位姿跑通 AMCL 后再测试
use_localizationcartographer使用 Cartographer 相关定位流程前面使用 Cartographer 建图流程时再测试
use_localplanteb局部规划方式之一,用于根据目标点、障碍物和机器人运动约束生成局部运动路径当前主线使用
use_localplandwa另一种局部规划方式跑通 TEB 后再对比测试

简单理解:

  • amcl / emcl / cartographer 解决“机器人在哪里”;
  • teb / dwa 解决“机器人怎么走过去”;
  • 首次导航不要改参数,先使用 amcl + teb 跑通地图加载、初始位姿、目标点和底盘移动流程。

确认 Navigation 实际加载的地图

启动 Navigation 后,另开 Docker ROS 2 终端确认 /map_server 实际加载的地图路径。

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

ros2 param get /map_server yaml_filename

再检查源码目录和安装目录中的地图文件。

ls -lh src/ugv_main/ugv_nav/maps/map.pgm \
src/ugv_main/ugv_nav/maps/map.yaml

ls -lh install/ugv_nav/share/ugv_nav/maps/map.pgm \
install/ugv_nav/share/ugv_nav/maps/map.yaml

查看两个 map.yaml 的内容。

echo "===== src map.yaml ====="
cat src/ugv_main/ugv_nav/maps/map.yaml

echo "===== install map.yaml ====="
cat install/ugv_nav/share/ugv_nav/maps/map.yaml

Navigation 实际使用哪张地图,以 /map_serveryaml_filename 为准。如果 srcinstall 中的地图文件时间、大小或内容不一致,可能出现保存的是新地图、Navigation 加载的却是旧地图的情况。

地图不匹配时,LaserScan 与地图轮廓会错开,AMCL 定位和 costmap 会异常,近距离目标也可能无法到达。如果发现 Navigation 加载的不是预期地图,请先停止 Navigation,确认当前工作空间的地图保存脚本和 launch 加载路径,再重新启动 Navigation。

认识 Navigation RViz 界面

Navigation RViz 不是只看地图,而是把静态地图、实时雷达扫描、定位粒子、全局路径、局部控制和 costmap 叠加显示。颜色较多属于正常界面状态。

Navigation RViz 中常见显示项如下。

显示项含义
Map保存后加载的 2D 占据栅格地图
RobotModel当前机器人模型和朝向
LaserScan实时雷达扫描,用来和地图边缘对齐
Amcl Particle SwarmAMCL 定位粒子,用来估计机器人在地图中的位置
Global Planner全局规划路径
Controller局部控制器或局部代价相关显示
costmap 红色 / 紫色 / 粉色 / 青色区域导航认为靠近障碍物、有碰撞风险或需要避开的区域
Navigation / Localization显示 active 时,表示 Nav2 导航和定位模块已激活

需要区分:Map 是原始 2D 地图,LaserScan 是实时雷达扫描,costmap 是导航代价图。costmap 会把障碍物、安全距离和风险区域叠加显示,不等于原始地图。

Navigation 初始界面

查看地图时,先选择顶部 Move Camera。鼠标滚轮用于缩放,按住鼠标中键拖动可以平移地图视图。如果视图被左侧 Displays 面板挡住,可以拖动面板边界缩小左侧区域,或折叠暂时不需要查看的显示项。设置初始位姿或目标点前,可以先用 Move Camera 调整视角,再点击 2D Pose EstimateNav2 Goal

如果路径、机器人模型或地图被过多显示项遮挡,可在左侧 Displays 面板中临时取消勾选部分 costmap、粒子或调试显示项,只保留查看路径需要的 MapRobotModelLaserScanGlobal Planner 等显示项。该操作只改变 RViz 显示,不会修改导航参数,也不会停止 Navigation。

Navigation 只保留关键显示项

设置初始位姿

  1. 确认地图已经加载。
  2. 确认实时 LaserScan 大致落在地图墙体或障碍物边缘附近。
  3. 点击顶部 2D Pose Estimate
  4. 在地图上点击 UGV 实际位置,按住鼠标左键拖出车头方向箭头。
  5. 松开鼠标完成设置。

松开鼠标后,RViz 工具栏回到 Move Camera 时属于正常显示状态。判断初始位姿是否生效,不看工具栏当前按钮,而是看 Amcl Particle Swarm 是否收敛到机器人附近,以及实时 LaserScan 是否大致贴合地图中的墙体或障碍物边缘。

设置初始位姿后,先等待 10 ~ 20 秒,不要立即发送目标。观察 LaserScan 是否与地图轮廓对齐,观察 Amcl Particle Swarm 是否集中。如果粒子分散、机器人模型跳动、LaserScan 与墙体轮廓明显错开,需要重新设置 2D Pose Estimate

判断 LaserScan、AMCL 和 costmap 是否正常

设置目标点前,必须完成四项检查:

  1. 地图是当前场地的地图;
  2. LaserScan 与地图墙体或障碍物轮廓大致对齐;
  3. Amcl Particle Swarm 集中在机器人真实位置附近;
  4. 机器人自身和目标点附近没有被 costmap 高风险区域覆盖。

如果以上任意一项不满足,不要点击 Nav2 Goal

costmap 中出现红色、紫色、粉色或青色区域不一定是错误,它表示 Navigation 根据静态地图、实时雷达、障碍层和膨胀层计算出的风险区域。需要重点看机器人中心附近和目标点附近是否被高风险区域覆盖。

如果机器人中心附近被大面积高风险区域覆盖,或者目标点位于高风险区域内,或者 RViz 中无法生成路径、Feedback 显示 canceledRecoveries 持续增加,不要继续发送目标。先回到地图、LaserScan、AMCL 和传感器状态检查。

清理 costmap

需要排查代价地图缓存时,先查看当前是否存在清理服务。

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

ros2 service list | grep clear

如果存在以下服务,再执行清理命令。

ros2 service call /global_costmap/clear_entirely_global_costmap nav2_msgs/srv/ClearEntireCostmap {}
ros2 service call /local_costmap/clear_entirely_local_costmap nav2_msgs/srv/ClearEntireCostmap {}

清理 costmap 只清除当前代价地图缓存,不会修复错误地图、错误初始位姿或传感器异常。如果清理后机器人周围很快再次被大面积高风险区域覆盖,应回到地图、LaserScan、AMCL 和传感器状态检查。

设置极近距离 Nav2 Goal

危险

第一次只设置 20 ~ 30 cm 的极近距离目标。目标点必须在白色可通行区域,且不靠墙、不靠障碍、不在线缆附近。极近目标可达后,再测试 0.5 ~ 1 m 目标。不要第一次就跨房间、穿过狭窄区域或贴近障碍物。

  1. 完成 判断 LaserScan、AMCL 和 costmap 是否正常 中的四项检查。
  2. 点击顶部 Nav2 Goal
  3. 在地图上选择机器人附近 20 ~ 30 cm 的白色可通行区域。
  4. 按住鼠标左键拖出目标点到达后的车头方向箭头。
  5. 松开鼠标后,观察 RViz 中是否生成路径,以及 Navigation 面板状态是否变化。
提示

Nav2 Goal 会让导航系统发布速度指令并驱动底盘。拖出的箭头表示“到达目标点后的车头朝向”,不表示机器人一定会沿箭头方向直线行驶。实际路径由 Nav2 根据地图、定位、实时雷达扫描和 costmap 自动规划。

目标太近时,Navigation 面板可能很快显示 reached,机器人不会有明显移动;这不代表远距离目标已经可用。先用极近目标确认基础导航状态,再逐步增加距离。

执行目标后,可以在 RViz 左侧 Navigation 2 面板中查看状态:

  • Navigation: active:导航模块已激活;
  • Localization: active:定位模块已激活;
  • Feedback: active:Nav2 正在执行目标;
  • Feedback: reached:Nav2 认为目标已经到达;
  • ETA:预计剩余时间;
  • Distance remaining:距离目标的剩余距离;
  • Recoveries:恢复行为触发次数。

Recoveries 不是普通计时器。它表示导航过程中触发恢复行为的次数。如果该数值持续增加,通常说明目标点附近代价过高、路线被阻挡、定位不够准,或目标选择不合适。首次测试时可以取消当前目标,重新选择更近、更空旷的白色区域。

Navigation 执行中界面

图中 NavigationLocalization 均为 activeFeedbackactive,表示 Nav2 已接收目标并正在执行。Distance remaining 表示距离目标的剩余距离,Recoveries 表示恢复行为触发次数。若 Recoveries 持续增加,可取消当前目标,重新选择更近、更空旷的目标点。到达目标后,Feedback 会显示 reached。这些状态表示 Navigation 正在使用地图,不代表正在重新建图。

停止 Navigation

需要停止 Navigation 时,按下面顺序处理:

  1. 在 RViz 左侧 Navigation 2 面板中点击 CancelPause

  2. 另开 Docker ROS 2 终端发送一次 /cmd_vel 零速度。

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

    ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.0}, angular: {z: 0.0}}"
  3. 回到 Navigation launch 终端,按 Ctrl + C 停止 nav.launch.py

  4. 如果 UGV 仍在移动,立即断电。

发送一次零速度只能作为辅助停止动作。Navigation 控制器仍在运行时,可能继续发布新的 /cmd_vel,因此不要把该命令作为唯一停止方式。

常见异常排查

如果近距离 Nav2 Goal 也无法移动、Feedback 显示 canceled、costmap 大面积异常或 UGV 有碰撞风险,先停止 Navigation,再按下面顺序排查:

  1. Navigation 实际加载的 map.yaml 是否是当前场地地图;
  2. srcinstall 中地图文件是否不一致;
  3. LaserScan 是否与地图轮廓对齐;
  4. AMCL 粒子是否收敛;
  5. 机器人中心或目标点是否被 costmap 高风险区域覆盖;
  6. /scan 是否有稳定频率;
  7. /odom/robot_pose 是否持续输出;
  8. ugv_bringupugv_driverbase_node 是否仍在运行;
  9. Navigation launch 终端是否出现 process has diedmultiple accessKeyError、TF extrapolation、Message Filter dropping message 等日志;
  10. 目标点是否太远、靠墙、靠障碍或在未知区域。

检查关键节点:

ros2 node list | grep -E "ugv_bringup|ugv_driver|base_node|amcl|map_server|planner_server|controller_server|bt_navigator"

检查关键数据:

timeout 8 ros2 topic hz /scan
timeout 8 ros2 topic echo /odom
timeout 8 ros2 topic echo /robot_pose

如果 /scan/odom/robot_pose 没有输出,先不要继续发目标。回到 bringup、定位和地图加载检查。

行为控制与导航点任务

行为控制是产品封装的任务接口,用来把常见底盘动作和导航点操作封装成 Action 任务。它不是 Nav2 标准功能,也不是建图功能。

开发者补充:behavior_ctrl 的 topic 和 Action

behavior_ctrl 创建 /behavior Action Server,订阅 /odom/robot_pose,发布 /cmd_vel/goal_pose。短距离动作通过 /cmd_vel 驱动底盘;导航点任务通过 /robot_pose 获取当前位置,并通过 /goal_pose 发布目标点。

短距离动作与停止

短距离动作适合先验证行为控制接口,例如让 UGV 前进一小段、后退一小段或原地旋转一定角度。它依赖 /odom 判断动作进度,并通过 /cmd_vel 驱动底盘,不依赖地图。

危险

短距离动作、前往导航点和 Navigation 目标都会驱动实体底盘。测试前确认场地空旷,远离人、宠物、线缆和桌脚。测试时先使用低速、短距离任务。

  1. 确认 Docker ROS 2 终端 1 中的 bringup_lidar.launch.py 正在运行。若该终端已经关闭,先回到 启动底盘与雷达 重新启动。

启动 behavior Action Server

  1. 另开新的 Docker ROS 2 终端启动行为控制。启动后保持该终端运行,不要关闭。

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

    ros2 run ugv_tools behavior_ctrl
  2. 另开 Docker ROS 2 终端发送短距离动作。新终端也先加载 ROS 2 环境。

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

前进一小段:

ros2 action send_goal /behavior ugv_interface/action/Behavior "{command: '[{\"T\": 1, \"type\": \"drive_on_heading\", \"data\": 0.1}]'}"

后退一小段:

ros2 action send_goal /behavior ugv_interface/action/Behavior "{command: '[{\"T\": 1, \"type\": \"back_up\", \"data\": 0.1}]'}"

原地旋转:

ros2 action send_goal /behavior ugv_interface/action/Behavior "{command: '[{\"T\": 1, \"type\": \"spin\", \"data\": -1}]'}"

停止当前行为:

ros2 action send_goal /behavior ugv_interface/action/Behavior "{command: '[{\"T\": 1, \"type\": \"stop\", \"data\": 0}]'}"

如果行为动作仍在执行,优先发送停止动作;如果仍无法停止,回到行为控制终端或底盘 bringup 终端按 Ctrl + C,必要时直接关闭机器人电源。

可选验证:保存并发布导航点

保存并发布导航点用于验证 /behavior/robot_pose/goal_pose 的接口链路。它不是完整的航点管理系统,也不替代基础 Navigation 检查。

save_map_point 会把当前 /robot_pose 记录为命名点。pub_nav_point 会把已保存点发布到 /goal_pose。这相当于把“手动点 Nav2 Goal”替换为“程序发布目标点”。真正路径规划和底盘运动仍由 Navigation / Nav2 完成。

能否实际到达,仍取决于 Navigation 的地图、AMCL、TF、costmap、底盘反馈和目标容差。如果 RViz 手动 Nav2 Goal 的极近距离目标都不能稳定到达,不要继续测试保存导航点后的实际移动。

方式目标点来源
RViz Nav2 Goal在地图上手动点击目标
pub_nav_point程序把之前保存的导航点发布成目标

测试 A:接口链路验证。

  1. 先按 2D Navigation:使用地图导航 启动 Navigation,再按 启动 behavior Action Server 启动行为控制节点,并保持两个终端运行。

  2. 另开 Docker ROS 2 终端发送导航点任务命令。新终端也先加载 ROS 2 环境。

    cd /home/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash
  3. 先确认 /behavior Action Server 已经可用。

    ros2 action list | grep behavior
    ros2 action info /behavior

    如果发送行为命令时一直停在 Waiting for an action server to become available...,说明当前没有找到 /behavior Action Server。先回到第 1 步的行为控制终端,确认 ros2 run ugv_tools behavior_ctrl 仍在运行;如果该终端已经退出,重新启动行为控制节点后再发送命令。

  4. 检查 /robot_pose

    ros2 topic echo /robot_pose --once

    如果 /robot_pose 有输出,表示系统已经能得到机器人在地图中的位姿。若没有输出,先检查 Navigation 是否启动、初始位姿是否设置、定位是否正常。

  5. 保存当前位置为 A 点。

    ros2 action send_goal /behavior ugv_interface/action/Behavior "{command: '[{\"T\": 1, \"type\": \"save_map_point\", \"data\": \"a\"}]'}"

    该命令会把当前 /robot_pose 记录为一个导航点。保存时 UGV 不会因为“保存点”这个动作而主动移动。

  6. 在另一个 Docker ROS 2 终端监听 /goal_pose

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

    ros2 topic echo /goal_pose
  7. 回到发送导航点任务命令的终端,发布 A 点为 Navigation 目标。

    ros2 action send_goal /behavior ugv_interface/action/Behavior "{command: '[{\"T\": 1, \"type\": \"pub_nav_point\", \"data\": \"a\"}]'}"

    该命令会向 /goal_pose 发布已保存的 A 点。后续是否能规划路径、是否移动、是否到达,取决于 Navigation 的定位、地图、costmap 和路径规划状态。

接口链路验证的观察点:

  • /behavior Action Server 可用;
  • /robot_pose 有输出;
  • save_map_point 返回;
  • pub_nav_point/goal_pose 有输出;
  • /goal_poseframe_idmap
  • Navigation 面板是否收到目标。

测试 B:实际移动验证。

只有在基础 Navigation 已经通过 设置极近距离 Nav2 Goal 后,才继续测试实际移动。不要把精确回到物理 A 点作为通过标准。

  1. 保存当前位置为 A 点。
  2. 可以按 设置极近距离 Nav2 Goal 使用 RViz Nav2 Goal 设置一个近距离目标,也可以按 使用键盘低速移动 用键盘控制短距离移动。
  3. 移动后确认 UGV 已经离开 A 点,并保持 Navigation 正常运行。使用键盘控制时,不要同时保留其它会持续发布速度指令的程序。
  4. 发布 A 点为 Navigation 目标。

发布后只观察 Navigation 状态,不把到达某个物理点作为唯一判断:

  • 是否生成路径;
  • 是否开始执行;
  • 是否 canceled
  • Recoveries 是否增加;
  • 是否被 costmap 阻挡;
  • 是否接近目标容差范围。

如果手动 Nav2 Goal 的近距离目标都不能稳定到达,先回到 常见异常排查,不要继续测试保存导航点的实际移动。

自动探索

自动探索是进阶功能,不作为首次导航。先完成 Gmapping 建图查看保存的地图文件 和近距离 2D Navigation:使用地图导航,再测试自动探索。

  1. 先在当前 Docker ROS 2 终端加载 ROS 2 环境。

    cd /home/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash
  2. 启动建图导航。

ros2 launch ugv_nav slam_nav.launch.py use_rviz:=true

继续启动探索入口时,不要结束当前建图导航终端。

  1. 另开终端启动探索入口。新终端也先加载 ROS 2 环境。

    cd /home/ws/ugv_ws
    source /opt/ros/humble/setup.bash
    source install/setup.bash
ros2 launch explore_lite explore.launch.py

自动探索会让机器人自主选择目标点并移动。使用前确认场地封闭、规则、空旷,并全程准备 停止 Navigation 的方式。保存探索地图时,可按 Gmapping 建图 中的保存方式处理。停止时先停止探索节点,再按 停止 Navigation 中的方式停止底盘运动,最后停止 SLAM / Navigation 相关 launch。