跳到主要内容

定位、导航与自主任务

2D Navigation:使用地图导航​

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

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

注意

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

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

前置条件​

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

  1. 已按 查看保存的地图文件 确认 map.pgm 和 map.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_localization 和 use_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_server 的 yaml_filename 为准。如果 src 和 install 中的地图文件时间、大小或内容不一致,可能出现保存的是新地图、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 Estimate 或 Nav2 Goal。

如果路径、机器人模型或地图被过多显示项遮挡,可在左侧 Displays 面板中临时取消勾选部分 costmap、粒子或调试显示项,只保留查看路径需要的 Map、RobotModel、LaserScan、Global 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 显示 canceled、Recoveries 持续增加,不要继续发送目标。先回到地图、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 执行中界面

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

停止 Navigation​

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

  1. 在 RViz 左侧 Navigation 2 面板中点击 Cancel 或 Pause。

  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. src 与 install 中地图文件是否不一致;
  3. LaserScan 是否与地图轮廓对齐;
  4. AMCL 粒子是否收敛;
  5. 机器人中心或目标点是否被 costmap 高风险区域覆盖;
  6. /scan 是否有稳定频率;
  7. /odom 和 /robot_pose 是否持续输出;
  8. ugv_bringup、ugv_driver、base_node 是否仍在运行;
  9. Navigation launch 终端是否出现 process has died、multiple access、KeyError、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_pose 的 frame_id 为 map;
  • 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。