type
Post
status
Published
date
Feb 28, 2026
slug
summary
视觉SLAM实操总结+关键问题总结
tags
具身智能
ROS
SLAM
category
项目开发
icon
password

一、项目概述


1. 操作环境

  • 华硕天选(AMD 集显 + RTX 4060 独显)
  • Intel RealSense D435i 深度相机(纯手持,无底盘里程计)。
 

2. 软件环境

  • Ubuntu 22.04
  • ROS 2 Humble
  • RTAB-Map + Nav2。
 

3. 步骤流程

  • 相机驱动
  • IMU同步
  • 深度图转2D雷达
  • RATB-Map视觉重定位
  • Nav2导航
 

4. 关键疑难点

  • RTAB-Map视觉重定位
  • Rviz中地图显示问题
  • 单相机TF树的处理
  • Nav2生命周期的严格时序
  • 通信问题
 

二、实操说明


1. SLAM 建图

 

2. SLAM 重定位

 

3. Nav2导航

 

4. 语义地图构建

这里展示一个最简单的语义地图(手动标注坐标)。
  • 启动你的机器人 / 仿真 / 地图节点
  • 启动 RViz2
  • 在 RViz2 左下角 Add → 选 PublishPoint
  • 顶部工具栏点那个 蓝色小点 + 坐标图标(Publish Point)
  • 终端运行:
    • 在地图上点一下,终端立刻输出:
      • x, y, z 坐标
      • 四元数姿态
      • 坐标系 id
    • 示例
      • 建立语义
       

      5. 大模型解析与任务理解:切换到qwen_2b的Conda环境保持 qwen_server.py 运行。

      qwen_server.py
      • 预期结果:返回 {"target": "kitchen"}
      • 使用 curl 命令发送测试 JSON:curl -X POST http://localhost:8000/parse_command -d '{"text": "去厨房"}'
       

      6. 语义导航任务执行 :通过话题发送测试指令:

      • 观测Rviz,机器人规划出到目的点的路线,单摄像头实验完成。
       
      GitHub

      三、解耦运行


      1. 启动感知层 (Terminal 1)

      检查点:不要急着跑导航。在这个终端里看到相机输出后,开新终端运行 ros2 topic list必须看到 /scan/tf 之后再进行下一步。
       

      2. 启动导航层 (Terminal 2)

       

      四、 核心疑难杂症与终极解决方案

      在纯视觉无底盘的环境下运行 Nav2 极其容易崩溃。以下是开发过程中遇到的高频致命问题及彻底的解决方案。

      1. Nav2 生命周期死锁与 TF 树断裂

      • 现象: 启动导航时报 MapNotReceivedMaps_to_pose action server is not available,终端提示 Action Server 无法连接,Nav2 节点集体罢工 。
      • 根本原因: ROS 2 Nav2 存在极其严格的生命周期(Lifecycle)超时机制 。在纯视觉状态下,RTAB-Map 需要你手持相机晃动一段时间才能完成特征匹配并发布 map -> odom 的 TF 。如果 Nav2 的 bringup_launch.py 统管一切,它在启动前几秒找不到完整 TF 树就会触发保护机制,导致全家桶停摆(生命周期僵局) 。此外,纯视觉配置中极易与默认拉起的 AMCL(传统雷达定位)发生资源抢占 。
      • 解决方案 (解耦启动法):
        • 剥离 AMCL: 放弃完整的 bringup_launch.py,改用 Nav2 纯导航脚本 navigation_launch.py
        • 拆分终端异步启动: 解除“感知定位”与“导航”的强行绑定 。先在一个终端运行相机与 RTAB-Map,确认终端刷出绿色的 Match ID 且 RViz 中出现激光线(TF 树完整)后,再在第二个终端唤醒 Nav2 。
        • 补全坐标系: 统一使用 base_link,并增加静态 TF 发布器,补全 base_link -> camera_link 的变换 。注意:永远不要让 camera_link 直接充当 base_link,否则由于缺少相机安装高度和俯仰角信息,导航算法生成的伪雷达障碍物位置会完全错误 。
       

      2. 视觉代价地图 (Costmap) 满屏障碍物与规划失败

      • 现象: RViz 中地图加载正常,但下发 Nav2 Goal 后无反应;局部代价地图(Local Costmap)满屏紫色(满屏代价),机器人“不敢移动” 。
      • 根本原因: 手持相机时视角不可避免会略微朝下,深度图将地面噪点或操作者的脚识别成了墙壁等物理障碍物 。同时,默认的 inflation_radius 膨胀半径对室内手持环境过于严苛 。
      • 解决方案 (伪雷达调优):
        • 核心逻辑: 采用 depthimage_to_laserscan 节点,将 3D 深度图切片伪造成 2D 激光扫描数据 (/scan),使标准 2D 局部规划器能直接处理视觉数据 。
        • 高度过滤: 在 Nav2 参数文件 local_costmapglobal_costmap 中,严格设置 min_obstacle_height: 0.15,直接跳过地面 15cm,滤除相机俯仰产生的地面噪点 。
        • 动态调参: 缩小 inflation_radius(30cm 对手持通常足够),并增大 cost_scaling_factor,让远离障碍物时的代价值下降得更快 。
       

      3. 图形层与通信层隐蔽 Bug

      • RViz2 着色器冲突黑屏:
        • 现象: 终端报 GLSL 着色器链接错误,无法渲染 2D 栅格地图 。
        • 原因: 电脑 AMD 核显驱动提供的 OpenGL 版本与 RViz2 较老的地图渲染着色器不兼容 。
        • 解决: 强制指定 OpenGL 版本,执行 export MESA_GL_VERSION_OVERRIDE=3.3
      • DDS 通信故障:
        • 现象: ros2 topic list 只能看到基础话题,或者报 failed to create domain
        • 解决: 删除 Launch 文件中引起隔离的 ROS_LOCALHOST_ONLY=1,并通过系统 sysctl 调大 Linux 的 UDP 缓冲区(net.core.rmem_max) 。
       

      四、无初始位姿问题


      “navigate_to_pose 动作服务器不可用”错误通常意味着 Nav2 协议栈尚未完全初始化、机器人缺少初始位姿,或者存在命名空间不匹配。要解决此问题,请确保 Nav2 正在运行,在 RViz 中设置 2D 姿态估计,验证主题命名空间(例如/robot1/nav2_...),并确认use_sim_time与您的模拟匹配。
      以下是解决此问题的具体步骤:
      • 验证服务器可用性:运行ros2 action list/navigate_to_pose 以检查是否列出(或类似内容)。
      • 设置初始姿态:
        • 使用 RViz 中的“2D 姿态估计”工具设置机器人的起始位置。没有此设置,导航将无法开始。
      • 检查命名空间:
        • 如果使用多个机器人或特定的启动设置,请确保您的配置和目标已发布到正确的命名空间(例如rviz2/tb3_0/navigate_to_pose,而不是仅仅发布到/navigate_to_pose)。
      • *检查仿真时间:**如果进行仿真,请确保在 ROS 2 参数中将use_sim_timeTrue其设置为True。
      • 网络配置:
        • 如果在虚拟机中运行,请使用桥接网络,并确保将 Windows 网络设置为“专用”,以允许 ROS 通信。
      💡
      有关问题,欢迎您在底部评论区留言,一起交流~
      notion image
      GitHub
      linux常用指令合集Nav2 导航:D435i+RTAB-Map
      Loading...