
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. 系统架构一眼看懂

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
增强滤波器不可用时,优先检查:
- Jetson 是否为 Linux ARM64。
- 相机型号和固件是否受支持。
- 相机是否具备有效的 LingBot-Depth License。
model.sm4是否与扩展库版本匹配。
- CUDA/TensorRT 动态库是否可被加载。
- 深度是否已对齐到彩色流。
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. 坐标系是融合成败的分水岭

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. 外参标定的正确顺序
外参不要六个参数一起猜。严格按下面顺序:

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 实测结论

本次录包包含:
| 话题 | 消息数 | 频率 |
|---|---|---|
/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. 代码的关键技术亮点

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
依次检查:
- 网卡 IP 是否为
192.168.1.102/24。
- 雷达目标 IP 是否指向 Jetson。
- MSOP 端口是否为 6699。
tcpdump是否收到 UDP。
- 是否被防火墙或其他进程占用。
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 优先级建议
- 保持相机输入 30 FPS,但发布/处理约 10 Hz。
lidar_max_points先用 30000。
scan_cloud_max_points先用 20000。
- 使用 Cyclone DDS。
- 雷达有界队列保持 2 帧。
- 不要同时开启 RViz 和 RTABMapViz 做长期运行。
- 正式建图前观察
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. 正式建图操作流程

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 参数之间盲目试错。