19fc6d17d83e3.png

1. 这套系统最终能做什么?

完成本文后,系统具备以下能力:

– 使用 OrbbecSDK_v2 C++ API 读取彩色与深度数据,不依赖 pyorbbecsdk。

  • 将深度图对齐到彩色图,并接入 Orbbec 增强深度滤波器。
  • 使用 rs_driver 原生解析 RoboSense Airy 的 MSOP/DIFOP UDP 数据。
  • 发布标准 ROS2 sensor_msgs/msg/PointCloud2 点云。
  • 通过 ROS TF 统一相机、雷达、机器人底盘坐标系。
  • 使用 RTAB-Map 完成 RGB-D 单独建图。
  • 可选融合 Airy 点云,使用视觉特征与 ICP 共同约束地图。
  • 支持 RTABMapViz 或 RViz 调试、rosbag2 录制与离线外参分析。

⚠️ 本项目中的“融合”不是把两种点云简单拼接。RTAB-Map 会结合 RGB-D 视觉里程计、图优化、回环检测和雷达 ICP 约束。错误的 TF 或时间戳会让融合结果比单独使用相机更差。

2. 系统架构一眼看懂

19fc6d516bce8.png

3. 硬件、软件与目录约定

3.1 推荐硬件

  • NVIDIA Jetson Orin / Xavier 系列设备。
  • Orbbec Gemini 330 系列或当前增强深度滤波器支持的型号。
  • RoboSense Airy 激光雷达。
  • 独立千兆网口或 USB 转网口用于雷达 UDP 数据。
  • USB 3.x 接口用于深度相机。
  • 刚性传感器支架,避免相机与雷达相对位置在运动中变化。

3.2 软件基线

  • Ubuntu 22.04。
  • ROS2 Humble。
  • CMake 3.16 或更高版本。
  • GCC/G++,支持 C++17。
  • OrbbecSDK_v2,Jetson ARM64 版本。
  • rs_driver,版本必须包含 LidarType::RSAIRY。
  • rtabmap_ros / rtabmap_launch。

3.3 本教程使用的 Jetson 目录

/home/r/ws/
├── OrbbecSDK_v2/
├── rs_driver/
└── orbbec_rtabmap_ws/
    └── src/
        └── orbbec_rtabmap_cpp/

Windows 本地镜像目录为:

D:LiDar_Depthcamera

💡 后文命令按照 /home/r/ws 编写。如果你的目录不同,请统一替换,不要只修改一半路径。

4. Jetson 基础环境安装

4.1 安装 ROS2 与工程工具

如果 Jetson 已经安装 ROS2 Humble,可以跳过 ROS2 主体安装,只补齐依赖:

sudo apt update
sudo apt install -y 
  build-essential 
  cmake 
  git 
  pkg-config 
  python3-colcon-common-extensions 
  python3-rosdep 
  ros-humble-rtabmap-ros 
  ros-humble-tf2-ros 
  ros-humble-rmw-cyclonedds-cpp

初始化 rosdep:

sudo rosdep init
rosdep update

如果提示 rosdep 已初始化,可以忽略 sudo rosdep init 的重复初始化错误。

加载 ROS2 环境:

source /opt/ros/humble/setup.bash

检查:

ros2 --help
ros2 pkg prefix rtabmap_launch

若第二条命令找不到包,执行:

sudo apt install ros-humble-rtabmap-ros

4.2 检查 Jetson 架构与 CUDA/TensorRT

uname -m
nvcc --version || true
dpkg -l | grep -E 'tensorrt|nvinfer'

Jetson 应返回:

aarch64

⚠️ 增强深度滤波器依赖与 SDK 扩展匹配的 CUDA/TensorRT 运行时和相机授权。不要为了满足某个版本号直接覆盖 JetPack 自带 CUDA/TensorRT,否则可能破坏整机依赖。

5. 安装并验证 OrbbecSDK_v2

官方仓库:<https://github.com/orbbec/OrbbecSDK_v2>

5.1 获取 SDK

已有 /home/r/ws/OrbbecSDK_v2 时不要重复克隆。

cd /home/r/ws
git clone https://github.com/orbbec/OrbbecSDK_v2.git
cd OrbbecSDK_v2

建议记录当前版本,便于后续复现:

git rev-parse --short HEAD
git describe --tags --always

5.2 安装常用编译依赖

sudo apt install -y 
  build-essential 
  cmake 
  libusb-1.0-0-dev 
  libglfw3-dev 
  libopencv-dev

具体依赖以当前 SDK 的 scripts/env_setup 和 CMake 输出为准。

5.3 安装相机 udev 规则

cd /home/r/ws/OrbbecSDK_v2/scripts/env_setup
sudo chmod +x ./install_udev_rules.sh
sudo ./install_udev_rules.sh
sudo udevadm control --reload-rules
sudo udevadm trigger

重新插拔相机后检查:

lsusb

🧨 常见坑:没有安装 udev 规则时,相机可能只有 sudo 才能打开。不要长期用 root 运行 ROS2 来掩盖权限问题。

5.4 源码编译 SDK

本项目当前 Jetson 使用的动态库路径是:

/home/r/ws/OrbbecSDK_v2/build/linux_arm64/lib/libOrbbecSDK.so

如果还没有编译,可使用 SDK 当前版本提供的构建脚本,或使用标准 CMake 流程:

cd /home/r/ws/OrbbecSDK_v2
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)

不同版本的输出目录可能不同。不要猜路径,用下面的命令查找:

find /home/r/ws/OrbbecSDK_v2 -name 'libOrbbecSDK.so*' -type f
find /home/r/ws/OrbbecSDK_v2 -name 'Export.h' -type f

5.5 验证 SDK 和增强深度滤波器

首先运行 SDK 自带的彩色、深度或 QuickStart 示例,确认相机本身正常。示例二进制目录因 SDK 版本而异,可以查找:

find /home/r/ws/OrbbecSDK_v2 -type f -perm -111 -name 'ob_*'

本工程的增强深度滤波参考代码位于:

OrbbecSDK_v2/examples/3.advanced.enhanced_depth_filter

确认模型文件:

find /home/r/ws/OrbbecSDK_v2/extensions -name 'model.sm4' -type f

常见位置:

/home/r/ws/OrbbecSDK_v2/extensions/filters/linux_arm64/enhanced_depth_filter/model.sm4

增强滤波器不可用时,优先检查:

  1. Jetson 是否为 Linux ARM64。
  1. 相机型号和固件是否受支持。
  1. 相机是否具备有效的 LingBot-Depth License。
  1. model.sm4 是否与扩展库版本匹配。
  1. CUDA/TensorRT 动态库是否可被加载。
  1. 深度是否已对齐到彩色流。

6. 安装 rs_driver 并确认 Airy 支持

官方仓库:<https://github.com/RoboSense-LiDAR/rs_driver>

6.1 获取驱动

cd /home/r/ws
git clone https://github.com/RoboSense-LiDAR/rs_driver.git
cd rs_driver

确认代码支持 Airy:

grep -R "RSAIRY" -n src/rs_driver | head

应能找到 decoder_RSAIRY.hpp 和 LidarType::RSAIRY。

6.2 是否必须单独编译 rs_driver?

本项目通过头文件直接集成 rs_driver,并关闭 PCAP 解析,因此运行在线 Airy 不要求先安装 rs_driver。只要下面的文件存在即可:

/home/r/ws/rs_driver/src/rs_driver/api/lidar_driver.hpp

为了先验证雷达,也可以编译官方在线示例:

cd /home/r/ws/rs_driver
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCOMPILE_DEMOS=ON
make -j$(nproc)

如果要编译 PCAP 或可视化工具,再安装可选依赖:

sudo apt install -y libpcap-dev libeigen3-dev libboost-dev libpcl-dev

💡 本项目在线接收节点定义了 DISABLE_PCAP_PARSE,不需要为了在线建图强行安装整套 PCL。

7. 准备 ROS2 工作空间

确认结构:

cd /home/r/ws/orbbec_rtabmap_ws
find src/orbbec_rtabmap_cpp -maxdepth 3 -type f | sort

关键文件:

src/orbbec_rtabmap_cpp/
├── CMakeLists.txt
├── package.xml
├── launch/orbbec_lidar_rtabmap_cpp.launch.py
├── config/rtabmap_rgbd_params.yaml
├── config/rtabmap_lidar_params.yaml
└── src/
    ├── orbbec_rgbd_cpp_node.cpp
    └── robosense_airy_node.cpp

安装 ROS 依赖:

source /opt/ros/humble/setup.bash
cd /home/r/ws/orbbec_rtabmap_ws
rosdep install --from-paths src --ignore-src -r -y

8. 第一次完整编译

cd /home/r/ws/orbbec_rtabmap_ws
source /opt/ros/humble/setup.bash

colcon build --symlink-install 
  --packages-select orbbec_rtabmap_cpp 
  --cmake-args 
  -DCMAKE_BUILD_TYPE=Release 
  -DORBBEC_SDK_ROOT=/home/r/ws/OrbbecSDK_v2 
  -DORBBEC_SDK_LIBRARY=/home/r/ws/OrbbecSDK_v2/build/linux_arm64/lib/libOrbbecSDK.so 
  -DORBBEC_SDK_GENERATED_INCLUDE=/home/r/ws/OrbbecSDK_v2/build/src/generated 
  -DRS_DRIVER_ROOT=/home/r/ws/rs_driver

如果 Export.h 实际在其他目录,把 ORBBEC_SDK_GENERATED_INCLUDE 改成 find 得到的真实目录。

编译成功后:

source install/setup.bash
ros2 pkg executables orbbec_rtabmap_cpp

应看到:

orbbec_rtabmap_cpp orbbec_rgbd_cpp_node
orbbec_rtabmap_cpp robosense_airy_node

9. 运行环境变量

每个新终端都执行:

source /opt/ros/humble/setup.bash
source /home/r/ws/orbbec_rtabmap_ws/install/setup.bash

export ORBBEC_SDK_ROOT=/home/r/ws/OrbbecSDK_v2
export LD_LIBRARY_PATH=$ORBBEC_SDK_ROOT/build/linux_arm64/lib:$ORBBEC_SDK_ROOT/lib:$ORBBEC_SDK_ROOT/extensions/filters/linux_arm64:$ORBBEC_SDK_ROOT/extensions/filters/linux_arm64/enhanced_depth_filter:$LD_LIBRARY_PATH
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

验证动态库:

ldd /home/r/ws/orbbec_rtabmap_ws/install/orbbec_rtabmap_cpp/lib/orbbec_rtabmap_cpp/orbbec_rgbd_cpp_node | grep -E 'Orbbec|not found'

🧨 常见坑:编译时能找到 .so,运行时仍可能因为 LD_LIBRARY_PATH 缺失而报 error while loading shared libraries。

10. 先跑通“纯相机建图”

这是最重要的隔离测试。雷达、网卡和雷达 TF 即使全部断开,也应该能运行:

ros2 launch orbbec_rtabmap_cpp orbbec_lidar_rtabmap_cpp.launch.py 
  use_lidar:=false 
  delete_db_on_start:=true 
  enhanced_depth_model_path:=$ORBBEC_SDK_ROOT/extensions/filters/linux_arm64/enhanced_depth_filter/model.sm4 
  rtabmap_viz:=true 
  rviz:=false

检查话题:

ros2 topic hz /orbbec/color/image_raw
ros2 topic hz /orbbec/depth/image_raw
ros2 topic echo /orbbec/color/camera_info --once

默认输入流为 30 FPS,但在执行昂贵的对齐与 TensorRT 深度增强之前,节点会将选中帧限制到约 10 Hz。这是 Jetson 上非常关键的性能设计。

日志中应看到类似:

Capture stats input=... Hz published=... Hz selected=... skipped=... processing_failures=...

相机建图动作建议

  • 起步后静止 2~3 秒。
  • 缓慢直行,避免快速甩动相机。
  • 转弯速度保持平缓。
  • 让画面包含墙角、桌椅、门框等视觉纹理。
  • 不要让相机长期只看白墙、玻璃或纯地面。

11. 配置 Airy 网络

Airy 默认网络参数:

项目 默认值
雷达 IP 192.168.1.200
Jetson/目标 IP 192.168.1.102
子网掩码 255.255.255.0
MSOP 点云端口 UDP 6699
DIFOP 配置端口 UDP 7788
扫描频率 约 10 Hz

找到网卡名:

ip -br link

假设雷达接在 eth0:

sudo ip addr replace 192.168.1.102/24 dev eth0
sudo ip link set eth0 up
sudo sysctl -w net.core.rmem_max=8388608

检查网卡:

ip -br addr show eth0
ip -s link show eth0

抓包确认:

sudo tcpdump -ni eth0 'udp port 6699 or udp port 7788'

应持续看到 MSOP,约每秒看到一次 DIFOP。

🧨 ping 192.168.1.200 失败不一定代表没有 UDP 数据;最终以 tcpdump 是否收到 6699/7788 为准。

12. 单独验证 Airy ROS2 点云

ros2 run orbbec_rtabmap_cpp robosense_airy_node --ros-args 
  -p host_address:=192.168.1.102 
  -p msop_port:=6699 
  -p difop_port:=7788 
  -p frame_id:=rslidar 
  -p output_topic:=/rs_lidar/points 
  -p use_lidar_clock:=false

另开终端:

ros2 topic hz /rs_lidar/points
ros2 topic echo /rs_lidar/points --field header --once
ros2 topic info /rs_lidar/points -v

正常情况下:

  • 点云频率接近 10 Hz。
  • frame_id 为 rslidar。
  • 只有一个点云发布者。
  • 日志 queue_drops=0。
  • stamp_fallbacks=0 或极少。

节点默认最多发布 30000 点,并使用两帧有界等待队列。处理跟不上时丢弃旧帧,而不是让延迟无限累积。

13. 坐标系是融合成败的分水岭

19fc6e31a0b20.png

13.1 ROS 机器人坐标约定

base_link:
  +X 机器人前方
  +Y 机器人左方
  +Z 机器人上方

camera_color_optical_frame:
  +X 图像右方
  +Y 图像下方
  +Z 镜头前方

相机正视机器人前方时,标准 optical frame 初始旋转为:

camera_roll:=-1.5707963
camera_pitch:=0.0
camera_yaw:=-1.5707963

13.2 本实机录包推导出的 Airy 原始轴

对 D:LiDar_Depthcameraairy_alignment 中约 156 秒 rosbag 的 PointCloud2 做多帧平面拟合后得到:

特征 Airy 原始点云中的位置
正前方墙面 lidar_z ≈ +2.30 m
地面 lidar_x ≈ -0.798 m
天花板 lidar_x ≈ +1.95 m

因此这套安装的正确映射是:

base_x =  lidar_z
base_y = -lidar_y
base_z =  lidar_x

对应旋转矩阵:

[ 0  0  1 ]
[ 0 -1  0 ]
[ 1  0  0 ]

如果希望以 yaw=180° 表示,可使用:

lidar_roll:=0.0
lidar_pitch:=-1.5707963
lidar_yaw:=3.1415926

等效写法是:

lidar_roll:=3.1415926
lidar_pitch:=-1.5707963
lidar_yaw:=0.0

⚠️ pitch=-90° 位于欧拉角万向节锁位置。tf2_echo 可能显示另一组等效 RPY。判断是否正确时看旋转矩阵或四元数,不要只看 RPY 文本。

期望四元数接近:

x=0.7071, y=0, z=0.7071, w=0

14. 根据实机录包得到的推荐融合命令

若 base_link 设在地面,本次数据拟合得到:

相机光心到地面约 0.950 m
雷达参考原点到地面约 0.798 m

推荐先用下面的参数验证:

ros2 launch orbbec_rtabmap_cpp orbbec_lidar_rtabmap_cpp.launch.py 
  use_lidar:=true 
  start_airy_driver:=true 
  start_ac_driver:=false 
  lidar_host_address:=192.168.1.102 
  camera_x:=0.15 camera_y:=0.0 camera_z:=0.950 
  camera_roll:=-1.5707963 camera_pitch:=0.0 camera_yaw:=-1.5707963 
  lidar_x:=0.10 lidar_y:=0.0 lidar_z:=0.798 
  lidar_roll:=0.0 lidar_pitch:=-1.5707963 lidar_yaw:=3.1415926 
  lidar_use_lidar_clock:=false 
  approx_sync_max_interval:=0.10 
  enhanced_depth_model_path:=$ORBBEC_SDK_ROOT/extensions/filters/linux_arm64/enhanced_depth_filter/model.sm4 
  delete_db_on_start:=true 
  rtabmap_viz:=false rviz:=true

⚠️ camera_x/y/z 和 lidar_x/y/z 最终应由实际安装测量与标定决定。上面数值来自本次录包和当时 TF,不是适用于所有机器人的通用常数。

调试通过后切换到 RTABMapViz:

ros2 launch orbbec_rtabmap_cpp orbbec_lidar_rtabmap_cpp.launch.py 
  use_lidar:=true 
  start_airy_driver:=true 
  start_ac_driver:=false 
  lidar_host_address:=192.168.1.102 
  camera_x:=0.15 camera_y:=0.0 camera_z:=0.950 
  camera_roll:=-1.5707963 camera_pitch:=0.0 camera_yaw:=-1.5707963 
  lidar_x:=0.10 lidar_y:=0.0 lidar_z:=0.798 
  lidar_roll:=0.0 lidar_pitch:=-1.5707963 lidar_yaw:=3.1415926 
  delete_db_on_start:=true 
  rtabmap_viz:=true rviz:=false

15. 外参标定的正确顺序

外参不要六个参数一起猜。严格按下面顺序:

19fc6e4b9ae26.png

15.1 第一步:只确认轴映射

在 RViz 中:

Fixed Frame = base_link

添加 /rs_lidar/points,确认:

  • 正前方墙面位于 +X。
  • 左侧物体位于 +Y。
  • 右侧物体位于 -Y。
  • 地面位于传感器下方。
  • 天花板位于传感器上方。

15.2 第二步:校正 roll / pitch

  • 地面左右倾斜:调整 roll。
  • 地面前后倾斜:调整 pitch。
  • 每次只调整 0.5°,即 0.0087266 rad。

15.3 第三步:校正 yaw

  • 近处重合、远处逐渐分开:通常是 yaw。
  • 每次以 0.5° 为步长调整。
  • 不要用 90° 或 180° 修复只有几厘米的偏差。

15.4 第四步:校正平移

  • 地面水平但上下错层:调整 z。
  • 墙面平行但前后错开:调整 x。
  • 点云整体左右平移:调整 y。

15.5 第五步:运动验证

  • 静止时重合、运动时分离:这是时间同步或运动畸变,不是静态外参。
  • 转弯时明显散开:降低速度,检查时间戳和 TF 时间链。

🧨 每次改变 TF 后都要重新启动,并在标定阶段使用 delete_db_on_start:=true,避免错误地图残留在数据库中。

16. 时间同步与 rosbag 实测结论

19fc6e88dd7bf.png

本次录包包含:

话题 消息数 频率
/rs_lidar/points 1536 约 10.00 Hz
/orbbec/depth/image_raw 1532 约 9.99 Hz
/orbbec/color/image_raw 1532 约 9.99 Hz
/orbbec/color/camera_info 1532 约 9.99 Hz

雷达与最近深度帧的时间差:

绝对差中位数约 18.5 ms
90% 小于约 32.7 ms
99% 小于约 38.9 ms

因此当前:

approx_sync:=true
approx_sync_max_interval:=0.10

是合理的起始值。

相机与雷达都默认使用 Jetson 主机时间:

use_device_time:=false
lidar_use_lidar_clock:=false

只有确认 Jetson 与 Airy 已通过 PTP/gPTP/GPS 同步后,才启用:

lidar_use_lidar_clock:=true

17. RTAB-Map 参数为什么这样设置?

17.1 纯相机模式

rtabmap_rgbd_params.yaml:

Reg/Strategy = 0       视觉注册
Grid/Sensor = 1        使用深度相机构建栅格
Grid/FromDepth = true
Grid/RangeMax = 5.0 m

适合雷达未连接时独立运行。

17.2 相机 + 雷达模式

rtabmap_lidar_params.yaml:

Reg/Strategy = 2       视觉 + ICP
ICP/PointToPlane = true
ICP/VoxelSize = 0.10 m
ICP/MaxCorrespondenceDistance = 0.30 m
ICP/CorrespondenceRatio = 0.20

RTAB-Map 内部接收:

RGB + aligned depth + CameraInfo + scan_cloud

视觉负责纹理、回环和局部运动估计,雷达 ICP 为几何结构提供额外约束。

💡 icp_odometry 默认关闭,系统仍使用 RGB-D 里程计,同时让 RTAB-Map 注册策略使用视觉与 ICP。只有明确需要以雷达 ICP 作为独立里程计时才启用 icp_odometry:=true。

18. 代码的关键技术亮点

19fc6ea2cd718.png

18.1 原生 C++ 替代 Python 桥接

  • 避免 Python 图像复制和解释器开销。
  • 直接使用 OrbbecSDK_v2 帧对象、内参和设备授权接口。
  • 更适合 Jetson 上持续运行。

18.2 在昂贵处理之前限频

相机输入可保持 30 FPS,但节点在执行对齐与增强深度滤波之前,将实际选中帧限制到约 10 Hz,减少 TensorRT 和内存带宽压力。

30 FPS input
  → early rate selection
  → Align
  → EnhancedDepthFilter
  → 10 Hz ROS publication

18.3 深度到彩色的几何对齐

ob::Align(OB_STREAM_COLOR)

确保深度像素与彩色内参对应,RTAB-Map 才能正确生成带颜色的空间点。

18.4 增强深度滤波失败可降级

  • enhanced_depth_required:=false:初始化失败时回退到对齐后的原始深度。
  • enhanced_depth_required:=true:初始化失败直接退出,适合严格部署检查。

18.5 Airy 回调与 ROS 发布解耦

rs_driver 回调只负责取出完整点云并放入有界队列;独立工作线程完成:

  • 非有限点过滤。
  • 点数限制。
  • PointCloud2 字段填充。
  • 时间戳校验。
  • ROS2 发布。

这样不会让耗时的 ROS 序列化阻塞 UDP 解码线程。

18.6 有界队列优先低延迟

队列默认只保留两帧。处理跟不上时丢弃最旧点云,避免机器人已经移动后仍发布数秒前的数据。

18.7 时间戳安全回退

雷达时间戳无效或与 ROS 时钟偏差过大时,节点回退到当前 ROS 时间,并在诊断日志中增加 stamp_fallbacks。

19. rosbag2 录制与离线诊断

机器人静止,视野中同时包含平整地面和正前方墙面,录制 10~15 秒:

ros2 bag record -o airy_alignment 
  /rs_lidar/points 
  /orbbec/color/image_raw 
  /orbbec/depth/image_raw 
  /orbbec/color/camera_info 
  /tf 
  /tf_static

停止后:

ros2 bag info airy_alignment

同时保存:

ros2 run tf2_ros tf2_echo base_link rslidar
ros2 run tf2_ros tf2_echo base_link camera_color_optical_frame
ros2 topic info /rs_lidar/points -v

rosbag 可用于:

  • 拟合地面法向量,计算 roll/pitch。
  • 判断雷达前方、左右和上下轴。
  • 估算传感器离地高度。
  • 对比相机与雷达时间戳。
  • 检查移动时是否出现拖影。

🧨 彩色图、深度图和点云数据量很大。本次约 156 秒录包达到 3.34 GB。正式诊断通常 10~15 秒已经足够。

20. 高频报错与解决办法

20.1Export.h: No such file or directory

原因:OrbbecSDK_v2 的生成头文件位于 build 目录,没有被加入 include path。

查找:

find /home/r/ws/OrbbecSDK_v2 -name Export.h -type f

重新编译时指定其所在目录:

-DORBBEC_SDK_GENERATED_INCLUDE=/home/r/ws/OrbbecSDK_v2/build/src/generated

20.2 CMake 警告ORBBRC_SDK_ROOT was not used

原因:变量拼写错误。

错误:

ORBBRC_SDK_ROOT

正确:

ORBBEC_SDK_ROOT

20.3rclcpp::Time has no member named to_msg

这是部分 ROS2 Humble API 兼容问题。当前代码已经通过显式构造 builtin_interfaces::msg::Time 解决。若使用旧版源码,请同步最新节点文件。

20.4cloud_qos 被当成函数声明

典型报错:

warning: parentheses were disambiguated as a function declaration

正确写法:

rclcpp::QoS cloud_qos{rclcpp::KeepLast(ros_queue_depth_)};

这是 C++ 的 most vexing parse,不是 ROS QoS 本身出错。

20.5package 'rtabmap_launch' not found

sudo apt update
sudo apt install ros-humble-rtabmap-ros
source /opt/ros/humble/setup.bash

20.6package 'orbbec_rtabmap_cpp' not found

source /opt/ros/humble/setup.bash
source /home/r/ws/orbbec_rtabmap_ws/install/setup.bash

20.7libOrbbecSDK.so: cannot open shared object file

检查:

find /home/r/ws/OrbbecSDK_v2 -name 'libOrbbecSDK.so*'
echo $LD_LIBRARY_PATH

重新设置 SDK 库路径。

20.8 相机打不开,但 sudo 可以

安装 udev 规则,重新插拔相机,不要用 root 长期运行 ROS2。

20.9 雷达一直MSOPTIMEOUT

依次检查:

  1. 网卡 IP 是否为 192.168.1.102/24。
  1. 雷达目标 IP 是否指向 Jetson。
  1. MSOP 端口是否为 6699。
  1. tcpdump 是否收到 UDP。
  1. 是否被防火墙或其他进程占用。
sudo ss -lunp | grep -E '6699|7788'
sudo tcpdump -ni eth0 'udp port 6699 or udp port 7788'

20.10 有 MSOP,但没有点云

检查 DIFOP 7788。驱动默认 wait_for_difop=true,没有校准配置时不会贸然输出点云。

20.11 点云频率不足或 DDS 丢帧

sudo sysctl -w net.core.rmem_max=8388608
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

同时适当降低:

lidar_max_points:=20000
scan_cloud_max_points:=15000

20.12 地面显示在墙上

这是轴映射错误,不是 lidar_z 错误。先校正旋转矩阵,再调整高度。

本实机推荐:

lidar_roll:=0.0
lidar_pitch:=-1.5707963
lidar_yaw:=3.1415926

20.13 点云整体在相机左侧

  • 所有距离偏移相同:调整 lidar_y。
  • 越远偏移越大:调整 lidar_yaw。
  • 左右完全镜像:检查 base_y=-lidar_y 是否成立。

20.14 静止时重合,运动时分离

检查时间戳,不要继续乱调静态 TF:

use_device_time:=false
lidar_use_lidar_clock:=false
approx_sync_max_interval:=0.10

20.15 RTABMapViz 中地图被灰黑面板遮挡

  • 调整 3D 视角,避免从栅格平面下方观察。
  • 检查固定坐标系是否为 map 或 base_link。
  • 标定阶段优先用 RViz 单独查看原始点云和 TF。
  • 不要把“显示视角问题”误判成点云坐标错误。

20.16 同时启动两个雷达驱动

不要同时设置:

start_airy_driver:=true
start_ac_driver:=true

否则两个节点可能争用端口或重复发布点云。

21. 性能优化建议

Jetson 优先级建议

  1. 保持相机输入 30 FPS,但发布/处理约 10 Hz。
  1. lidar_max_points 先用 30000。
  1. scan_cloud_max_points 先用 20000。
  1. 使用 Cyclone DDS。
  1. 雷达有界队列保持 2 帧。
  1. 不要同时开启 RViz 和 RTABMapViz 做长期运行。
  1. 正式建图前观察 queue_drops 和相机处理耗时。

监控命令

tegrastats
ros2 topic hz /orbbec/depth/image_raw
ros2 topic hz /rs_lidar/points
ros2 topic bw /rs_lidar/points

若 GPU/CPU 已满:

  • 降低深度处理发布率。
  • 降低雷达最大点数。
  • 关闭不必要可视化。
  • 不要盲目缩小 approx_sync_max_interval。

22. 正式建图操作流程

19fc6ec2ab8be.png

23. 验收清单

编译与运行

  • [ ] colcon build 无错误。
  • [ ] ros2 pkg executables 能看到两个节点。
  • [ ] ldd 没有 not found。
  • [ ] 普通用户能打开 Orbbec 相机。

相机

  • [ ] 彩色、深度、CameraInfo 接近 10 Hz。
  • [ ] 深度已对齐到彩色。
  • [ ] 增强滤波器成功加载,或明确按预期回退。
  • [ ] 纯相机 RTAB-Map 可以独立建图。

雷达

  • [ ] 网卡收到 MSOP 6699 和 DIFOP 7788。
  • [ ] /rs_lidar/points 接近 10 Hz。
  • [ ] frame_id=rslidar。
  • [ ] 只有一个发布者。
  • [ ] queue_drops=0。

TF 与融合

  • [ ] 前墙在 +X。
  • [ ] 地面水平且位于传感器下方。
  • [ ] 左右方向没有镜像。
  • [ ] 相机与雷达地面高度一致。
  • [ ] 静止时墙面没有双层。
  • [ ] 移动时没有明显时间拖影。
  • [ ] RTAB-Map 能产生稳定轨迹与回环。

24. 一页式常用命令

环境

source /opt/ros/humble/setup.bash
source /home/r/ws/orbbec_rtabmap_ws/install/setup.bash
export ORBBEC_SDK_ROOT=/home/r/ws/OrbbecSDK_v2
export LD_LIBRARY_PATH=$ORBBEC_SDK_ROOT/build/linux_arm64/lib:$ORBBEC_SDK_ROOT/extensions/filters/linux_arm64:$ORBBEC_SDK_ROOT/extensions/filters/linux_arm64/enhanced_depth_filter:$LD_LIBRARY_PATH
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

纯相机

ros2 launch orbbec_rtabmap_cpp orbbec_lidar_rtabmap_cpp.launch.py 
  use_lidar:=false delete_db_on_start:=true

相机 + Airy

ros2 launch orbbec_rtabmap_cpp orbbec_lidar_rtabmap_cpp.launch.py 
  use_lidar:=true start_airy_driver:=true start_ac_driver:=false 
  lidar_host_address:=192.168.1.102 
  camera_x:=0.15 camera_y:=0.0 camera_z:=0.950 
  camera_roll:=-1.5707963 camera_pitch:=0.0 camera_yaw:=-1.5707963 
  lidar_x:=0.10 lidar_y:=0.0 lidar_z:=0.798 
  lidar_roll:=0.0 lidar_pitch:=-1.5707963 lidar_yaw:=3.1415926 
  delete_db_on_start:=true

数据检查

ros2 topic hz /orbbec/depth/image_raw
ros2 topic hz /rs_lidar/points
ros2 topic info /rs_lidar/points -v
ros2 run tf2_ros tf2_echo base_link rslidar
ros2 run tf2_ros tf2_echo base_link camera_color_optical_frame

录包

ros2 bag record -o airy_alignment 
  /rs_lidar/points 
  /orbbec/color/image_raw 
  /orbbec/depth/image_raw 
  /orbbec/color/camera_info 
  /tf /tf_static

25. 参考资料

– OrbbecSDK_v2 官方仓库:<https://github.com/orbbec/OrbbecSDK_v2>

– OrbbecSDK_v2 Releases:<https://github.com/orbbec/OrbbecSDK_v2/releases>

– rs_driver 官方仓库:<https://github.com/RoboSense-LiDAR/rs_driver>

– rslidar_sdk 官方仓库:<https://github.com/RoboSense-LiDAR/rslidar_sdk>

– ROS2 Humble 文档:<https://docs.ros.org/en/humble/>

– RTAB-Map ROS:<https://github.com/introlab/rtabmap_ros>

结语

多传感器建图真正困难的部分,通常不是“把两个驱动启动起来”,而是让数据在同一时刻、同一坐标系、同一物理尺度下描述同一个世界。

这套工程保留了纯相机建图作为可靠基线,又将 Airy 作为可选几何约束加入 RTAB-Map。只要坚持“先单传感器、再网络、再 TF、再时间同步、最后融合”的顺序,绝大多数问题都能被定位,而不需要在六个外参和几十个 RTAB-Map 参数之间盲目试错。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注