type
Post
status
Published
date
Feb 27, 2026
slug
summary
Nav2导航遇到的问题
tags
具身智能
ROS
SLAM
category
项目开发
icon
password
💡
这份开发文档总结了 D435i 纯视觉导航的调试过程。文档重点梳理了遇到的各项“疑难杂症”及其彻底的解决方案,并附上了当前最新的操作流程和核心代码,方便在接下来的实验中直接复制参考。

D435i 纯视觉语义导航开发日志与问题排查记录

一、 项目环境与当前进度


  • 硬件配置:华硕天选(AMD 集显 + RTX 4060 独显),Intel RealSense D435i 深度相机(纯手持,无底盘里程计)。
  • 软件环境:Ubuntu 22.04 + ROS 2 Humble + RTAB-Map + Nav2。
  • 当前里程碑:底层视觉算法已彻底跑通。相机驱动、IMU 同步、深度图转 2D 雷达(伪激光雷达)、以及 RTAB-Map 的视觉重定位(能在 RViz 中自动修复位置并显示激光线)均已成功。目前正在解决 Nav2 生命周期的严格时序问题。
 

二、 代码运行报错


1. 启动导航时报 MapNotReceived 且无法规划路线

  • 现象:TF 树断裂,RViz 中不显示地图,Nav2 不断报等待地图的警告。
  • 原因:Nav2 默认的 bringup_launch.py 会拉起 AMCL(传统雷达定位)和 map_server,与纯视觉状态下 RTAB-Map 发布的定位与地图发生抢占冲突。另外,TF 树中缺少标准的 base_link 坐标系。
  • 解决方案
      1. 统一将参数文件和启动文件中的坐标系设置为 base_link
      1. 增加静态 TF 发布器,补全 base_link -> camera_link 的连接。
      1. 剥离 AMCL,改用 Nav2 纯导航脚本 navigation_launch.py
       

2. RViz2 报错 active samplers with a different type... 导致地图黑屏

  • 现象:终端报 GLSL 着色器链接错误,RViz 无法正常渲染 2D 栅格地图。
  • 原因:电脑的 AMD 核显驱动提供的 OpenGL 版本与 RViz2 较老的地图渲染着色器不兼容。
  • 解决方案:在运行启动文件之前,强制指定 OpenGL 的版本为 3.3。
    • 环境变量代码export MESA_GL_VERSION_OVERRIDE=3.3(或者直接写进 Launch 文件中)。
    •  

3. 点击 Nav2 Goal 目标点无任何反应

  • 现象:RViz 有地图,终端不报错,但是下发目标点后不生成绿色规划路径。
  • 原因:手持相机时视角略微朝下,Nav2 的局部代价地图(Local Costmap)把地面或操作者的脚识别成了障碍物,导致系统认为机器人“被卡死在障碍物中”,拒绝规划。
  • 解决方案:在 Nav2 参数文件 local_costmap 的避障层中增加最小高度过滤限制:
    • 参数配置:添加 min_obstacle_height: 0.2(忽略 20 厘米以下的物体)。
    •  

4. 顽固报错 Maps_to_pose action server is not available

  • 现象:Nav2 节点集体罢工,Action Server 无法连接。
  • 原因:ROS 2 Nav2 存在极其严格的生命周期(Lifecycle)超时机制与 TF 竞态条件。由于 RTAB-Map 的视觉里程计需要你手持相机晃动一段时间才能完成特征匹配并发布 map -> odom 的 TF,而 Nav2 往往在启动的前几秒内一旦找不到完整的 TF 树,就会触发保护机制,强制关闭核心导航节点。
  • 终极解决方案(分离启动法):解除 Launch 文件中将“感知定位”与“导航”强行绑定的设定,采用手动异步启动策略,确保 TF 树完整后再唤醒 Nav2。
 

三、nav2配置报错


1. 通信层:消失的话题与“幽灵”节点

问题现象:
  • ros2 topic list 只能看到两个基础话题。
  • 运行导航时报错 failed to create domain
核心成因:
  1. DDS 缓冲区限制:Linux 系统默认的 UDP 缓冲区过小,导致 CycloneDDS 无法创建通信域。
  1. 环境隔离 (LOCALHOST_ONLY):在 Launch 文件中设置了 ROS_LOCALHOST_ONLY=1,导致不同终端间无法相互发现。
解决方法:
  • 系统层面:通过 sysctl 命令调大 net.core.rmem_max
  • 配置层面:在 Launch 文件中删除 SetEnvironmentVariable('ROS_LOCALHOST_ONLY', '1')
  • 环境变量:统一 ROS_DOMAIN_ID,确保 RMW 实现一致。
 

2. 图形层:RViz2 着色器冲突

问题现象:
  • RViz2 报错 active samplers with a different type refer to the same texture image unit
核心成因:
  • OpenGL 版本冲突:手动覆盖 MESA_GL_VERSION_OVERRIDE3.3 时,驱动在处理 8-bit 地图纹理时发生采样器冲突。
解决方法:
  • 将 OpenGL 版本覆盖改为 4.5 或者彻底删除该环境变量,让系统自动匹配。
  • 备选方案:使用软件渲染 LIBGL_ALWAYS_SOFTWARE=1 绕过显卡兼容性问题。
 

3. 决策层:行为树 (BT) 加载危机

问题现象:
  1. 报错 Node not recognized: RecoveryNode
  1. 报错 ID [ComputePathToPose] already registered
  1. 报错 Could not load library: libnav2_path_expirer_condition_bt_node.so
核心成因:
  • 插件列表冗余/缺失:在 nav2_params.yamlplugin_lib_names 中,重复加载了功能重叠的库,或引用了系统中不存在的 .so 库文件。
解决方法:
  • 精简插件库:只保留核心库(如 compute_path_to_pose, follow_path, recovery_node),删除重复和报错的插件名。
  • 同步 XML 文件:确保 default_nav_to_pose_bt_xml 指向的 XML 标签与加载的插件库一一对应。
  • 遇到 ID 冲突或 .so 缺失,请直接复制此列表。
 

4. 算法层:手持模式下的代价地图 (Costmap) 优化

问题现象:
  • 代价地图“满屏紫色”,到处都是障碍物(满屏代价),机器人不敢移动。
核心成因:
  1. 膨胀半径过大:默认的 inflation_radius 对室内手持环境太宽容。
  1. 地面噪声:相机晃动导致深度图扫到地面,被误认为是墙壁。
解决方法:
  • 动态调参:使用 ros2 param set 实时修改参数。
  • 高度过滤:设置 min_obstacle_height: 0.2,过滤掉地面噪点。
  • 收缩边界:减小 inflation_radius 并增大 cost_scaling_factor
 

四、 当前测试方案:深度转雷达 + 分离启动


为了彻底解决 Action Server 的死锁,采用“先定位,后导航”的解耦操作流。

1. 核心代码备份

Launch 文件 (src/camera/launch/nav_scheme3_launch.py)注意:已将 Nav2 的启动代码注释掉,仅启动感知与地图层。
同时修改参数文件nav2_params_scheme3.yaml保证行为树的完整度和适配性。
 

2. 标准操作流程

步骤 A:启动底层感知与重定位
打开终端 1:
操作要求:观察 RViz,手持 D435i 相机在环境中缓慢晃动,直到终端刷出绿色的 Match ID 信息,且 RViz 中相机模型自动吸附到地图上的正确位置,出现激光扫描线。保持相机稳定,不要关闭此终端。
 
步骤 B:在 TF 树完美状态下唤醒 Nav2 确认重定位成功后,打开终端 2:
预期结果:终端将顺畅打印 Transitioning to active,此时 Nav2 各节点顺利激活。回到 RViz 中点击 Nav2 Goal 即可正常进行路线规划。
 
💡
有关问题,欢迎您在底部评论区留言,一起交流~
ROS2 单视觉D435i+rtabmap导航地图 Map
Loading...