ROS2 环境检查
# source /opt/ros/humble/setup.bash
# ros2 doctor
安装 rtabmap
sudo apt update
sudo apt install \
ros-humble-rtabmap \
ros-humble-rtabmap-ros \
ros-humble-rtabmap-msgs
$ ros2 pkg list | grep rtabmap
rtabmap_conversions
rtabmap_demos
rtabmap_examples
rtabmap_launch
rtabmap_msgs
rtabmap_odom
rtabmap_python
rtabmap_ros
rtabmap_rviz_plugins
rtabmap_slam
rtabmap_sync
rtabmap_util
rtabmap_viz
rtabmap 命令
核心运行与可视化工具
rtabmap- 介绍:RTAB-Map 的官方图形界面(GUI)主程序。你可以通过它直接连接相机建图、导入数据集、查看 3D 点云拼接效果以及进行在线实时 SLAM。
rtabmap-console- 介绍:RTAB-Map 的纯命令行控制台版本(无图形界面)。适合跑在没有显示器的机器人、服务器或树莓派上,在后台默默进行建图并保存数据库。
rtabmap-odometryViewer- 介绍:纯里程计可视化工具。如果你只想单独测试视觉里程计(VO)或轮式里程计的轨迹漂移情况,而不进行后端的全局建图与回环检测,用这个工具观察最轻量。
rtabmap-lidar_viewer- 介绍:一个简易的 3D 激光雷达(LiDAR)点云数据查看器,主要用来快速预览采集到的激光点云文件。
数据集与相机驱动输入工具(包含你遇到的问题核心)
rtabmap-rgbd_dataset- 介绍:重点工具。专门用来离线读取、回放和处理各大公开 RGB-D 数据集(如 TUM、EuroC、ICL-NUIM)的命令行工具。你之前遇到的
rgb_sync命名要求,正是由这个工具的内部解析机制决定的。
- 介绍:重点工具。专门用来离线读取、回放和处理各大公开 RGB-D 数据集(如 TUM、EuroC、ICL-NUIM)的命令行工具。你之前遇到的
rtabmap-rgbd_camera- 介绍:相机硬件测试驱动。无需打开庞大的主界面,直接在终端调用它即可快速验证你的外接硬件相机(如 Intel RealSense、Stereolabs ZED、Orbbec 等)能否被系统正常读取并输出图像。
rtabmap-camera- 介绍:普通的普通单目/普通普通相机读取工具。
rtabmap-kitti_dataset- 介绍:专门针对自动驾驶领域大名鼎鼎的 KITTI 室外双目/激光雷达数据集的专用读取与回放工具。
rtabmap-dataRecorder- 介绍:数据录制器。用于把相机捕捉到的 RGB 图像、深度图、时间戳等原始数据直接录制保存为一个特定的
.db文件,方便后续做离线 SLAM 实验。
- 介绍:数据录制器。用于把相机捕捉到的 RGB 图像、深度图、时间戳等原始数据直接录制保存为一个特定的
数据库维护与离线后期优化工具(核心亮点)
rtabmap-databaseViewer- 介绍:极为常用的工具。专门用来分析建图结束后保存的
.db数据库。你可以查看每一帧的视觉特征点匹配、检测被错误关联的回环、手动删除错误的闭环约束,甚至是导出拼好的 3D 模型。
- 介绍:极为常用的工具。专门用来分析建图结束后保存的
rtabmap-recovery- 介绍:数据库修复工具。当系统异常断电、闪退导致
.db数据库文件损坏打不开时(你之前遇到的错误弹窗就是它触发的),可以用它尝试将残留的节点数据捞出来修复。
- 介绍:数据库修复工具。当系统异常断电、闪退导致
rtabmap-reprocess- 介绍:离线重新处理工具。这是学术研究的神器。如果你用相同的传感器录制了一段数据,修改了提取特征点的算法(比如从 SURF 改成 ORB),可以用它在不重新录制数据的前提下,对数据库里面的数据重新跑一遍 SLAM。
rtabmap-globalBundleAdjustment- 介绍:全局光束法平差工具(GBA)。在离线状态下对已有的整个 SLAM 轨迹和点云进行高精度的非线性最小二乘优化,用于极大程度地消除长距离漂移。
rtabmap-detectMoreLoopClosures- 介绍:离线回环再检测工具。建图时有些回环可能因为计算超时漏掉了,在建图结束后运行它,可以让算法花更多的时间去数据库里死磕,强行找出更多隐藏的闭环。
数据导出与分析报告工具
rtabmap-export- 介绍:数据导出命令行版。可以把数据库里的 3D 点云无损导出为常见的 3D 模型格式(如
.ply,.pcd,.obj),供 MeshLab、CloudCompare 等软件或 3D 打印使用。
- 介绍:数据导出命令行版。可以把数据库里的 3D 点云无损导出为常见的 3D 模型格式(如
rtabmap-report- 介绍:性能报告生成器。分析数据库并输出详尽的 SLAM 统计图表(包括内存占用变化、每帧计算耗时、回环检测成功率等趋势图),非常适合写论文时拿来当实验图表。
rtabmap-info- 介绍:快速查看数据库基础信息的命令行工具,比如直接输出数据库里有多少个关键帧、有没有包含三维重构数据、文件大小等。
其他辅助小工具
rtabmap-calibration- 介绍:相机标定/校准工具。用于标定单目、双目或 RGB-D 相机的内参以及彩色镜头与红外镜头之间的外参,生成 SLAM 算法需要的 yaml 标定文件。
rtabmap-cleanupLocalGrids- 介绍:用于清理和重构栅格地图(Grid Map)的局部冗余数据。
rtabmap-extractObject- 介绍:基于 3D 边界框或点云分割,从已经建好的三维地图中强行提取出某一个特定物体的点云数据。
rtabmap-res_tool&rtabmap-res_tool-0.3.0- 介绍:资源管理与分辨率缩放的内部辅助小工具。
TUM_RGB-D 数据集
TUM RGB-D 数据集是由慕尼黑工业大学(Technical University of Munich)计算机视觉实验室发布的一个极为经典的 SLAM(同时定位与地图构建)评测基准。自2012年发布以来,它成为了评估 RGB-D SLAM(彩色+深度相机) 算法(如 ORB-SLAM2/3、RTAB-Map、ElasticFusion 等)性能的行业事实标准。
1. Freiburg 1 系列 (fr1):标准室内与基础测试
特点:使用第一代 Kinect 采集,视角较窄,深度图噪点相对较大。
| 压缩包文件名 | 场景内容 | 核心测试目的 / 算法难点 | 推荐测试阶段 / 难度 |
|---|---|---|---|
rgbd_dataset_freiburg1_xyz.zip |
纯手持前后左右平移 | 测试视觉里程计(VO)的最基础平移计算,排除旋转干扰。 | 入门冒烟测试 ★☆☆☆☆ |
rgbd_dataset_freiburg1_rpy.zip |
原地手持翻滚、俯仰、偏航(旋转) | 测试算法在无平移、纯旋转下的退化表现(特征点容易跟丢)。 | 基础功能测试 ★★☆☆☆ |
rgbd_dataset_freiburg1_desk.zip |
典型的办公桌环境(显示器/书本/键盘) | 最经典的通用基准测试。评估算法在纹理、结构丰富环境下的综合表现。 | 核心性能评估 ★★★☆☆ |
rgbd_dataset_freiburg1_room.zip |
相机在整个房间绕行一大圈回到原点 | 专门用来测试算法的回环检测(Loop Closure)与全局后端优化能力。 | 闭环能力测试 ★★★★☆ |
rgbd_dataset_freiburg1_floor.zip |
相机对着地面移动 | 弱纹理、高重复性环境,测试算法在视觉特征缺失时的鲁棒性。 | 极端环境测试 ★★★★☆ |
rgbd_dataset_freiburg1_room

2. Freiburg 2 系列 (fr2):长距离与机器人搭载
特点:使用 Asus Xtion 采集,图像质量较高,运动多由 Pioneer 先锋轮式机器人底盘驱动(Z轴稳定)。
| 压缩包文件名 | 场景内容 | 核心测试目的 / 算法难点 | 推荐测试阶段 / 难度 |
|---|---|---|---|
rgbd_dataset_freiburg2_xyz.zip |
机器人底盘驱动的纯平移 | Fr2 传感器下的平移基准线数据。 | 入门冒烟测试 ★☆☆☆☆ |
rgbd_dataset_freiburg2_desk.zip |
办公桌环境(对照 fr1_desk) | 用于对比不同传感器(Kinect vs Xtion)在相似场景下的算法表现。 | 核心性能评估 ★★★☆☆ |
rgbd_dataset_freiburg2_large_with_loop.zip |
大范围工业大厅,轨迹最终闭合 | 评估算法在长距离运动下的累积误差消除与大范围回环能力。 | 对照组实验(优) ★★★★☆ |
rgbd_dataset_freiburg2_large_no_loop.zip |
大范围工业大厅,单向推算不闭合 | 与上一个数据集形成完美对照,用于量化“回环检测”对算法精度的绝对贡献。 | 对照组实验(劣) ★★★☆☆ |
rgbd_dataset_freiburg2_360_kidnap.zip |
快速360度旋转,中途故意遮挡相机 | 魔鬼测试。遮挡模拟了机器人被“绑架”跟丢,测试算法的重定位功能。 | 鲁棒性终极挑战 ★★★★★ |
rgbd_dataset_freiburg2_pioneer_360.zip |
机器人原地360度剧烈转圈 | 测试算法在遭遇高角速度、画面剧烈模糊时的帧间匹配能力。 | 抗晃动测试 ★★★★☆ |
rgbd_dataset_freiburg2_pioneer_slam.zip |
机器人搭载,长距离室内探索(标准版) | 贴近真实的 AGV/扫地机导航场景,评估里程计在平面运动下的实用性。 | 机器人落地测试 ★★★☆☆ |
rgbd_dataset_freiburg2_pioneer_slam2.zip |
机器人长距离探索(序列二) | 变换了行进路线和局部障碍物,用于验证算法的泛化性。 | 迭代验证测试 ★★★☆☆ |
rgbd_dataset_freiburg2_pioneer_slam3.zip |
机器人长距离探索(序列三) | 进一步改变光照和运动轨迹,多用于多地图拼接或连续建图测试。 | 迭代验证测试 ★★★☆☆ |

3. Freiburg 3 系列 (fr3):视觉与结构退化控制(写论文核心)
特点:严格控制环境中的“3D几何结构”和“视觉纹理”两大变量,专门暴露各类 SLAM 的物理死穴。
| 压缩包文件名 | 几何结构 (Structure) | 视觉纹理 (Texture) | 相机距离 / 测试目的与难点 | 推荐测试阶段 / 难度 |
|---|---|---|---|---|
fr3_nostructure_notexture_far.zip |
❌ 无(平整表面) | ❌ 无(白墙) | 远距离。地狱场景,视觉特征点和点云配准全部失效,测试算法何时崩溃。 | 极限边缘测试 ★★★★★ |
fr3_nostructure_notexture_near_withloop.zip |
❌ 无(平整表面) | ❌ 无(白墙) | 近距离(含回环)。特征全无,由于距离近,仅靠极其微弱的红外噪点或回环硬撑。 | 极限边缘测试 ★★★★★ |
fr3_nostructure_texture_far.zip |
❌ 无(平整平面) | 有(贴满海报) | 远距离。平面海报,纯视觉(如 ORB)的乐园,但 3D 建图(如 ICP)由于缺乏起伏会退化。 | 纯视觉算法评测 ★★☆☆☆ |
fr3_nostructure_texture_near_withloop.zip |
❌ 无(平整平面) | 有(贴满海报) | 近距离(含回环)。测试在完美的二维像素特征下,全局后端优化的极限对齐精度。 | 算法精度上限测试 ★★☆☆☆ |
fr3_structure_notexture_far.zip |
有(白漆楼梯/方块) | ❌ 无(全是纯白) | 远距离。直接法/光流 SLAM 的噩梦,但却是 RGB-D/点云 SLAM 的天堂(全靠深度图配准)。 | 深度图配准评估 ★★★★☆ |
fr3_structure_notexture_near.zip |
有(白漆楼梯/方块) | ❌ 无(全是纯白) | 近距离。眼睛看是一片白,但深度图凹凸有致。用来测试纯几何里程计(如 Point-to-Plane ICP)。 | 几何里程计测试 ★★★☆☆ |
fr3_structure_texture_far.zip |
有(杂物台阶) | 有(丰富色彩) | 远距离。理想环境。但远距离导致第一代相机的深度数据噪点呈指数级上升,测试去噪能力。 | 综合抗噪测试 ★★★☆☆ |
fr3_structure_texture_near.zip |
有(杂物台阶) | 有(丰富色彩) | 近距离。完美教科书环境。视觉特征无限,深度极其精准,用来跑出算法的理论最高精度。 | 算法上限/基准测试 ★☆☆☆☆ |
深度相机 Orbbec Gemini 336L
Orbbec Gemini 336L 是奥比中光 Gemini 330 系列中的一款高性能双目3D相机。它最大的特点是,在 Gemini 335L 的优异性能基础上,通过过滤可见光来增强主动红外成像,从而在强光、反光等复杂光照条件下,也能输出稳定、精准的深度图像
如何打开相机

OrbbecSDK 用途
OrbbecSDK 是奥比中光(Orbbec)官方为其旗下的 3D 深度相机(Depth Cameras) 开发的跨平台软件开发工具包(SDK)。
简单来说,它是连接奥比中光 3D 相机硬件与你的上层应用程序(如 SLAM 算法、AI 识别、三维重建等)之间的桥梁。它为开发者提供了一套统一的 API 接口,用来控制相机、流式获取数据并进行图像处理。
多模态数据流的获取与同步
- 3D 相机通常集成了多个传感器,OrbbecSDK 可以帮助开发者同时获取并对齐这些数据:
- 彩色图像流 (Color Stream): 获取标准的 2D RGB 视频流。
- 深度图像流 (Depth Stream): 获取每个像素点带有距离信息的深度图(通常是 16位无符号整型)。
- 红外图像流 (IR Stream): 获取左/右红外相机的图像,常用于暗光环境或主动结构光分析。
- IMU 数据流 (IMU Stream): 如果相机内置了惯性测量单元,SDK 可以获取高频的加速度和角速度数据。
- 数据同步 (Synchronization): 提供硬件级或软件级的时间戳对齐,确保彩色图、深度图和 IMU 数据在时间上完全匹配(这是做视觉 SLAM 建图的关键)。
高级图像处理与对齐
- D2C (Depth to Color) 像素对齐: 由于深度相机和彩色相机的物理位置有偏差,SDK 支持将深度图的每个像素直接对齐到彩色图上,从而轻松获得“带有颜色和 RGB 信息的 3D 点云”。
- 点云生成 (Point Cloud Generation): 自动将 2D 的深度图像转化为 3D 空间中的点云数据(XYZ 坐标)。
- 滤波优化: 包含空间滤波、时间滤波、空洞填充等,能够减少深度图像中的噪点和边缘锯齿。
相机硬件控制与参数调节
开发者可以通过 SDK 动态调整相机的底层参数,以适应不同的光照或工作距离:
- 曝光与增益: 调节 RGB 和红外相机的曝光时间、白平衡、激光发射器功率等。
- 工作模式切换: 在“近距离高精度”与“远距离宽视野”等不同的硬件预设模式间切换。
- 相机标定参数获取: 读取出厂内置的相机内参(Camera Intrinsic)和外参(Extrinsic Matrix),用于各类 3D 视觉计算。
深度相机数据录制
/home/lxg/software/Orbbec/OrbbecViewer_v2.8.6_202604271453_db82a04_linux_x86_64/output/RecordFile/Orbbec Gemini 336L_CPC9363000F3_20260616181547.bag
学习计划
首周目标
说清项目的 4 种运行模式和适用场景。
独立启动一次完整导航链路。
能用常见排查方法定位 1 个问题(TF/话题/参数)。
完成 1 次小参数调整并记录效果。
Day 1:建立全局认知
读 README 和顶层启动脚本,画一张自己的架构草图。
输出一页笔记:
输入传感器有哪些。
定位来源有哪些。
地图来源有哪些。
控制输出到哪里。
交付物:一张“感知-定位-规划-控制”流程图(手绘也行)。
Day 2:只做一件事,跑通基础链路
选择一个最常用模式启动。
确认核心话题是否有数据(scan、odom、map、cmd_vel)。
在可视化工具里确认坐标关系是否连通。
交付物:一份“成功启动截图 + 终端关键日志摘要”。
Day 3:理解配置文件结构
只读导航参数文件,重点看这几类参数:
控制器参数(速度、采样、评价器)。
局部/全局代价地图参数。
定位相关参数(里程计、AMCL 或融合里程计入口)。
建一个自己的参数字典:参数名、作用、调大调小现象。
交付物:10 个关键参数的个人注释表。
Day 4:定位融合专项
阅读 EKF 配置。
明确每个输入源(视觉里程计、激光里程计、IMU)分别贡献什么维度。
观察融合后里程计是否平滑、是否有跳变。
交付物:一页“融合输入与输出关系说明”。
Day 5:传感器接入专项
跑雷达和相机启动链路,确认数据稳定。
学会判定“是设备问题、时序问题,还是坐标问题”。
总结你的排查顺序(先数据,再 TF,再参数)。
交付物:一份故障排查 checklist(5-8 条)。
Day 6:小改动实战
只改 1-2 个参数(例如局部代价地图膨胀半径或控制器权重)。
保持同一路径重复测试。
记录改前改后差异(是否更平滑、是否更保守、是否更容易卡住)。
交付物:参数变更记录(变更项、原因、现象、结论)。
Day 7:做一次可复现汇报
用 5 分钟讲清楚:
项目主流程。
你调过的参数与结果。
你遇到的问题和排查方法。
交付物:简版周报(建议 1 页)。
什么是IMU
IMU(Inertial Measurement Unit,惯性测量单元)是一种用于测量物体运动状态的传感器模块,可以测量:
- 加速度(Acceleration)
- 角速度(Angular Velocity)
- 有些还可以测量磁场(Magnetic Field)
建图的数据格式
RTAB-Map 建图使用的是原始传感器数据(图像、IMU、相机参数等),而 RViz 显示的是 RTAB-Map 处理后的结果数据(地图、轨迹、点云、位姿等)。
run_depth_to_rtabmap.sh
#!/usr/bin/env bash
set -euo pipefail
# 目录与环境相关配置
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_PATH="$(cd -- "$SCRIPT_DIR/../../.." && pwd)"
WORKSPACE_SETUP="$WORKSPACE_PATH/install/setup.bash"
# 是否在新终端拉起节点(1: gnome-terminal, 0: 后台 nohup)
LAUNCH_IN_NEW_TERMINAL="${LAUNCH_IN_NEW_TERMINAL:-1}"
# 话题就绪等待超时(秒)
TOPIC_WAIT_TIMEOUT_SEC="${TOPIC_WAIT_TIMEOUT_SEC:-25}"
# RTAB-Map 机体坐标系(按你的 TF 习惯可改)
RTABMAP_FRAME_ID="${RTABMAP_FRAME_ID:-camera_link}"
LOG_DIR="$WORKSPACE_PATH/logs"
# 是否加载当前工作区 overlay(install/setup.bash)
USE_WORKSPACE_OVERLAY="${USE_WORKSPACE_OVERLAY:-0}"
RTABMAP_IMU_TOPIC="${RTABMAP_IMU_TOPIC:-}"
CLEANUP_PREVIOUS_DEMO="${CLEANUP_PREVIOUS_DEMO:-1}"
# 默认关闭 IMU,先保证纯视觉链路稳定
RTABMAP_USE_IMU="${RTABMAP_USE_IMU:-0}"
RTABMAP_DATABASE_PATH="${RTABMAP_DATABASE_PATH:-$WORKSPACE_PATH/maps/learning_depth_demo.db}"
RTABMAP_DELETE_DB_ON_START="${RTABMAP_DELETE_DB_ON_START:-true}"
RTABMAP_LINEAR_UPDATE="${RTABMAP_LINEAR_UPDATE:-0.10}"
RTABMAP_ANGULAR_UPDATE="${RTABMAP_ANGULAR_UPDATE:-0.10}"
# Orbbec UVC 后端(当前默认 v4l2)
CAMERA_UVC_BACKEND="${CAMERA_UVC_BACKEND:-v4l2}"
# 安全 source:规避 set -u 导致的未定义变量报错
source_with_nounset_guard() {
set +u
# ROS setup scripts may access optional variables directly.
source "$1"
set -u
}
# 统一加载 ROS 环境,可选叠加工作区 overlay
source_demo_environment() {
source_with_nounset_guard /opt/ros/humble/setup.bash
if [[ "$USE_WORKSPACE_OVERLAY" == "1" ]]; then
if [[ ! -f "$WORKSPACE_SETUP" ]]; then
echo "未找到 $WORKSPACE_SETUP,无法启用工作区 overlay。"
exit 1
fi
source_with_nounset_guard "$WORKSPACE_SETUP"
fi
}
# 启动命令包装:优先新终端,回退到后台 nohup
launch_command() {
local title="$1"
local command="$2"
if [[ "$LAUNCH_IN_NEW_TERMINAL" == "1" ]]; then
if ! command -v gnome-terminal >/dev/null 2>&1; then
echo "未找到 gnome-terminal,自动改为后台启动模式。"
LAUNCH_IN_NEW_TERMINAL="0"
fi
fi
if [[ "$LAUNCH_IN_NEW_TERMINAL" == "1" ]]; then
gnome-terminal --title "$title" -- bash -lc "
set +u
source /opt/ros/humble/setup.bash
if [ '$USE_WORKSPACE_OVERLAY' = '1' ]; then
source '$WORKSPACE_SETUP'
fi
set -u
$command
exec bash
"
else
echo "后台启动: $title"
nohup bash -lc "
set +u
source /opt/ros/humble/setup.bash
if [ '$USE_WORKSPACE_OVERLAY' = '1' ]; then
source '$WORKSPACE_SETUP'
fi
set -u
$command
" >"$LOG_DIR/${title// /_}.log" 2>&1 &
fi
}
# 等待话题出现(存在即可)
wait_for_topic() {
local topic="$1"
local timeout_sec="$2"
local start_ts elapsed
start_ts="$(date +%s)"
while true; do
if ros2 topic info "$topic" >/dev/null 2>&1; then
return 0
fi
elapsed=$(( $(date +%s) - start_ts ))
if [[ "$elapsed" -ge "$timeout_sec" ]]; then
return 1
fi
sleep 0.5
done
}
# 等待话题有发布者(防止只有话题名但无数据源)
wait_for_topic_publisher() {
local topic="$1"
local timeout_sec="$2"
local start_ts elapsed info
start_ts="$(date +%s)"
while true; do
info="$(ros2 topic info "$topic" 2>/dev/null || true)"
if printf '%s\n' "$info" | grep -q "Publisher count: [1-9]"; then
return 0
fi
elapsed=$(( $(date +%s) - start_ts ))
if [[ "$elapsed" -ge "$timeout_sec" ]]; then
return 1
fi
sleep 0.5
done
}
# 自动探测常见 IMU 话题
detect_imu_topic() {
local timeout_sec="$1"
local candidate
if [[ -n "$RTABMAP_IMU_TOPIC" ]] && wait_for_topic "$RTABMAP_IMU_TOPIC" "$timeout_sec"; then
return 0
fi
for candidate in /imu/data /camera/gyro_accel/sample /camera/imu; do
if wait_for_topic "$candidate" "$timeout_sec"; then
RTABMAP_IMU_TOPIC="$candidate"
return 0
fi
done
return 1
}
# 清理上一次学习流程残留进程,避免重复节点/TF 冲突
cleanup_previous_demo_processes() {
if [[ "$CLEANUP_PREVIOUS_DEMO" != "1" ]]; then
return 0
fi
# Keep cleanup narrow to this learning demo's usual processes.
pkill -f 'gemini_330_series.launch.py' >/dev/null 2>&1 || true
pkill -f 'rtabmap_launch rtabmap.launch.py' >/dev/null 2>&1 || true
pkill -f 'rtabmap_slam/rtabmap' >/dev/null 2>&1 || true
pkill -f 'rtabmap_odom/rgbd_odometry' >/dev/null 2>&1 || true
pkill -f 'rtabmap_util/point_cloud_xyzrgb' >/dev/null 2>&1 || true
sleep 1
}
# 准备 RTAB-Map 数据库:按需删除旧库,避免历史状态干扰教学
prepare_demo_database() {
mkdir -p "$(dirname "$RTABMAP_DATABASE_PATH")"
if [[ "$RTABMAP_DELETE_DB_ON_START" == "true" ]]; then
rm -f "$RTABMAP_DATABASE_PATH"
echo "已重置学习数据库: $RTABMAP_DATABASE_PATH"
else
echo "复用学习数据库: $RTABMAP_DATABASE_PATH"
fi
}
mkdir -p "$LOG_DIR"
cleanup_previous_demo_processes
prepare_demo_database
# 步骤 1:加载运行环境
echo "[1/4] 加载 ROS 环境"
source_demo_environment
# 步骤 2:启动深度相机节点
echo "[2/4] 启动 Orbbec 深度相机"
launch_command "[learn] depth camera" "
ros2 launch orbbec_camera gemini_330_series.launch.py \
camera_name:=camera \
uvc_backend:=$CAMERA_UVC_BACKEND \
publish_tf:=true \
enable_color:=true \
enable_depth:=true \
color_width:=640 \
color_height:=480 \
color_fps:=30 \
depth_width:=640 \
depth_height:=480 \
depth_fps:=30
"
# 步骤 3:确认关键输入话题已就绪
echo "[3/4] 采样确认关键话题"
for topic in \
/camera/color/image_raw \
/camera/depth/image_raw \
/camera/color/camera_info
do
echo "检查话题: $topic"
if ! wait_for_topic "$topic" "$TOPIC_WAIT_TIMEOUT_SEC"; then
echo "[错误] 话题未就绪: $topic"
echo "请确认相机终端是否正常启动,或增大 TOPIC_WAIT_TIMEOUT_SEC 后重试。"
exit 1
fi
if ! wait_for_topic_publisher "$topic" "$TOPIC_WAIT_TIMEOUT_SEC"; then
echo "[错误] 话题未就绪: $topic"
echo "该话题存在但没有发布者,请检查相机是否真正完成初始化。"
exit 1
fi
done
# 根据配置决定是否启用 IMU 融合
imu_launch_args="wait_imu_to_init:=false"
if [[ "$RTABMAP_USE_IMU" == "1" ]]; then
echo "检查 IMU 话题"
if ! detect_imu_topic "$TOPIC_WAIT_TIMEOUT_SEC"; then
echo "[错误] 未找到可用 IMU 话题(尝试了 /imu/data, /camera/gyro_accel/sample, /camera/imu)。"
exit 1
fi
echo "检测到 IMU 话题: $RTABMAP_IMU_TOPIC"
imu_launch_args="imu_topic:=$RTABMAP_IMU_TOPIC wait_imu_to_init:=true"
else
echo "跳过 IMU 融合(RTABMAP_USE_IMU=$RTABMAP_USE_IMU),使用纯视觉里程计以减少静止抖动。"
fi
# 步骤 4:启动 RTAB-Map 建图与 RViz
echo "[4/4] 启动 RTAB-Map(教学最小配置)"
launch_command "[learn] rtabmap" "
ros2 launch rtabmap_launch rtabmap.launch.py \
database_path:=$RTABMAP_DATABASE_PATH \
rtabmap_viz:=false \
rviz:=true \
frame_id:=$RTABMAP_FRAME_ID \
visual_odometry:=true \
vo_frame_id:=odom \
odom_topic:=/odom \
publish_tf_map:=true \
publish_tf_odom:=true \
rgb_topic:=/camera/color/image_raw \
depth_topic:=/camera/depth/image_raw \
camera_info_topic:=/camera/color/camera_info \
$imu_launch_args \
approx_sync:=true \
approx_sync_max_interval:=0.02 \
odom_args:='--Vis/MinInliers 20 --OdomF2M/BundleAdjustment true --Odom/ResetCountdown 0' \
args:='--Reg/Force3DoF true --RGBD/LinearUpdate $RTABMAP_LINEAR_UPDATE --RGBD/AngularUpdate $RTABMAP_ANGULAR_UPDATE'
"
echo
echo "学习目录已准备完成。"
echo "请打开检查清单: docs/learning/01-depth-camera-to-rtabmap/checklist.md"
source /opt/ros/humble/setup.bash
bash run_depth_to_rtabmap.sh