☰
ROS2 Humble 下 RealSense D435i 深度图、点云与 IMU 实战
2026/10/24 6:50:58 网站建设 项目流程

玩机器人的朋友,迟早会碰到这么一天:手头多了台 RealSense D435i,想在 Ubuntu 22.04 + ROS2 Humble 的环境里把它跑起来,顺手出深度图、点云,甚至把 IMU 数据也一起接了。这套组合在视觉 SLAM、导航避障、机械臂抓取里出现频率高得离谱,几乎可以说是入门深度视觉的标准配置。这篇文章就完整记录我从系统安装到驱动运行、再到深度和点云功能落地的整个流程,包含每个命令、每个参数、每次踩坑,适合刚拿到 D435i、准备在 ROS2 里做视觉应用的朋友当作一份可直接照做的操作手册。

1. 为什么非得是这套组合:Ubuntu 22.04、Humble 与 D435i 的匹配关系

1.1 版本搭配:为什么是 22.04 配 Humble

ROS2 的版本和 Ubuntu 版本是严格绑定的。Humble Hawksbill 是 ROS2 的长期支持版本,官方明确支持 Ubuntu 22.04 Jammy。这意味着你在这套系统上装的每一个二进制包、依赖库、编译工具链,都是按 22.04 的环境验证过的。换一个组合,比如用 20.04 硬装 Humble 的 deb 包,大概率会碰到依赖冲突,最后所有时间都耗在修环境上。

很多人问过为什么不直接用 ROS1 Noetic。答案很简单:新项目没有理由再回 ROS1 了。ROS2 的话题和服务机制、参数系统、launch 方式虽然学习曲线更陡一点,但长期来看生态已经全面转向 ROS2,D435i 的官方驱动也同时维护 ROS1 和 ROS2 两个分支。既然要从头搭,就直接踩在 ROS2 Humble 这条稳定线上,省得半年后又被迫迁移一次。

1.2 D435i 的选型思考:D435 和 D435i 差在哪

RealSense 家族里 D435 和 D435i 外观几乎一样,核心差别就是 D435i 多了一颗 IMU 惯性测量单元。这颗 IMU 提供加速度计和陀螺仪数据,对做 VIO、视觉惯性导航、里程计融合的人来说是刚需。如果没有 SLAM 或姿态估计需求,只做单纯的深度测量,D435 就够用;一旦涉及机器人移动、无人机悬停、AR 设备姿态追踪,IMU 能省掉很多后期硬件改造的工夫。

D435i 本身的深度原理是主动红外立体视觉:左右两个红外相机拍下带结构光纹理的图像,通过视差计算深度。它不像 ToF 方案那样对强光敏感,室内环境非常稳,室外阳光直射下会受影响,但绝大多数机器人场景都在室内或半室内,这个特性完全够用。加上官方驱动开源、issue 区活跃、社区资料密集,踩坑时基本都能搜到答案,对个人开发者非常友好。

1.3 ROS1 转 ROS2 你需要重新认识的几个点

如果你以前熟悉 ROS1,切到 ROS2 后有几个地方必须重建习惯。首先是工具的差异:rosrun变成了ros2 run,roslaunch变成了ros2 launch,rostopic变成了ros2 topic。看着区别不大,实际用法差别不小。其次是编译系统,ROS1 用 catkin,ROS2 用 colcon,工作区结构不变,但编译命令和 package 配置逻辑完全不同。

最核心的变化是底层通信从自研的 TCPROS 换成了 DDS。DDS 这套东西引入话题发现、QoS 策略等概念,最直观的影响是:节点发现变慢、网络环境复杂时可能互相找不到。用 D435i 驱动时,如果同一台机器上多个节点通信异常,多半不是相机问题,而是 QoS 不匹配。对这些差异有心理准备,后面排错会省很多力。

2. 从零部署系统:装上 ROS2 Humble 的过程与验证

2.1 系统与基础工具准备

安装 Ubuntu 22.04 时建议给根分区留出至少 80GB。编译 librealsense 和 realsense-ros2 都需要大量临时空间,源码加中间产物动辄几十 GB,磁盘不够会出现一些非常诡异的编译报错。内存最好 16GB 起步,8GB 也能跑,但编译时make的并发数要保守,否则分分钟被系统 OOM 杀掉。

装完系统后先把基础工具补齐:

sudo apt update sudo apt install -y git cmake build-essential curl \ libssl-dev libusb-1.0-0-dev pkg-config \ libgtk-3-dev libglfw3-dev libudev-dev \ libpython3-dev python3-pip

这些包里面,libusb和libudev是相机底层通信和权限管理的关键,libgtk和libglfw是给后面的 realsense-viewer 图形界面用的。缺了它们编译时不会立刻报错,但程序运行或某些功能会异常,所以一次装齐最省事。

2.2 安装 ROS2 Humble 的完整步骤

ROS2 官方文档给的流程是标准的,我实际执行时稍微调整了顺序,避免后面的权限问题。先添加 ROS2 软件源和 GPG 密钥:

sudo apt install software-properties-common sudo add-apt-repository universe sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \ -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null sudo apt update

然后安装桌面版完整套件:

sudo apt install -y ros-humble-desktop python3-colcon-common-extensions python3-rosdep

ros-humble-desktop包含了常用工具、可视化、仿真和示例节点,对大多数用途来说完全够。装完之后把环境变量写进 bashrc,否则每次新开终端都要手动 source:

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc

rosdep 是后面编译依赖的工具,初始化一下:

sudo rosdep init rosdep update

2.3 快速验证:talker 和 listener

环境装没装好,用官方的 demo 节点验证最快。开两个终端,终端一执行:

ros2 run demo_nodes_cpp talker

终端二执行:

ros2 run demo_nodes_cpp listener

如果能看到终端一持续发布Publishing: 'Hello World'、终端二不断接收打印,说明 ROS2 核心通信已经正常。这一步一定要做,因为后面启动相机驱动时,如果 ROS2 本身有问题,你会分不清是相机的问题还是系统的问题。

3. 编译 librealsense 与固件升级:让相机先被系统看见

3.1 从源码编译 librealsense 的前因后果

ROS2 的 realsense-ros2 驱动本身不直接跟硬件通信,它依赖底层的 SDK 库。Ubuntu 官方源里其实有 librealsense 的二进制包,但版本通常偏旧。我在实际项目里遇到过旧版 SDK 不认新固件相机的情况,表现为设备能枚举但打开摄像头流失败。所以最稳的方案是直接克隆官方仓库从源码编译,锁定的 SDK 和固件版本可以完全自己控制。

也有人用 apt 装librealsense2-dkms来省事,但 DKMS 模块的灵活度有限,而且你需要自己额外配 ROS2 包装层。相比之下源码编译并不复杂,一次装好长期稳定,遇到问题也更容易定位。

3.2 编译安装的完整流程

克隆官方 SDK 仓库:

git clone https://github.com/IntelRealSense/librealsense.git cd librealsense

进入目录后执行:

mkdir build && cd build cmake ../ -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=true sudo make install

这里有两个细节值得说清楚。第一,cmake时我打开了示例和图形工具的编译开关,这会多编译 realsense-viewer、rs-enumerate-devices 等工具,后面测试和查错都要靠它们。如果磁盘紧张,至少保留BUILD_EXAMPLES=true。第二,make的并发数要看你机器配置,我自己的机器是 16GB 内存,直接make -j$(nproc)编译到一半被 OOM 杀过,后来老实改成:

sudo make -j4 install

如果你内存不大,-j2更稳妥。编译时间大概 10 到 20 分钟,取决于硬件。

编译完可以用内置工具验证 SDK 是否认识相机:

realsense-viewer

插上 D435i,界面里应该能看到设备型号、固件版本、序列号,并且能实时打开 RGB、深度和红外流。到这一步,相机在 Linux 层已经被正确识别了。

3.3 udev 权限规则与固件升级

普通用户插上相机后打开 viewer 经常提示找不到设备,原因基本是权限问题。RealSense SDK 仓库里带了一个现成的规则脚本,执行一下:

cd librealsense sudo ./scripts/setup_udev_rules.sh

脚本会往/etc/udev/rules.d/写入设备和权限规则,然后重新插拔 USB 即可。如果不执行这一步,ros2 launch启动驱动时大概率会报No device detected,即使设备能够被系统枚举。

固件版本方面,新出厂的 D435i 固件一般不会太老,但二手设备和长期搁置的库存机就需要检查。viewer 的左上角设备信息里能看到当前固件版本,如果低于官方对最新 SDK 的支持范围,建议升级。升级路径有两条:一是直接从 viewer 的界面点击升级,会提示下载对应 bin 文件;二是用命令行工具:

rs-fw-update -f 固件文件路径

升级固件时务必保证供电稳定,最好用原装线直连主板 USB 口,不要通过扩展坞。我见过升级过程中断电把相机变砖的案例,虽然不是完全无法恢复,但折腾起来非常痛苦。

4. 编译 realsense-ros2:在 ROS2 里点亮相机

4.1 创建 ROS2 工作空间并拉取驱动源码

SDK 搞定后,真正接入 ROS2 还需要驱动包。创建工作空间并克隆驱动源码:

mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src git clone https://github.com/IntelRealSense/realsense-ros2.git

克隆完成后,用 rosdep 检查缺什么依赖:

cd ~/ros2_ws rosdep install --from-paths src --ignore-src -r -y

rosdep 会把 launch 文件、消息包、依赖库一次性列出并尝试安装。如果这一步报错某个 rosdep 找不到,多刷几次rosdep update基本能解决。

4.2 colcon 编译和启动相机

依赖齐了就可以编译:

cd ~/ros2_ws colcon build --symlink-install source install/setup.bash

--symlink-install是为了开发期间改 Python 脚本或 launch 文件不用重新编译,对日常调参来说很实用。编译完成后启动相机:

ros2 launch realsense2_camera rs_launch.py

正常启动的话,终端会打印设备信息、各流开启状态,然后你可以打开另一个终端查看话题:

ros2 topic list

应该能看到类似这些话题:

/camera/color/image_raw /camera/depth/image_rect_raw /camera/depth/color/points /camera/infra1/image_rect_raw /camera/infra2/image_rect_raw /camera/imu

看到这些话题,说明驱动已经正常把相机数据发到 ROS2 里了。

4.3 launch 参数详细解读

rs_launch.py 有很多参数可以用来控制相机行为。我在实际项目里经常改的几个如下:

参数作用我的建议值
depth_module.depth_profile深度流分辨率和帧率640x480x30,别盲目上 1280x720
rgb_camera.color_profileRGB 流分辨率和帧率640x480x30,够用且资源占用小
pointcloud.enable是否开启点云需要点云时设为true
align_depth深度图是否对齐到彩色图做图像融合时设为true
enable_imu是否开启 IMU需要 IMU 时设为true
serial_no指定多相机中的某一台多相机时必填

比如我需要同时开启点云和深度对齐,会这样启动:

ros2 launch realsense2_camera rs_launch.py \ depth_module.depth_profile:=640x480x30 \ rgb_camera.color_profile:=640x480x30 \ pointcloud.enable:=true \ align_depth:=true

注意参数名的层级关系。depth_module.前缀对应的是相机节点的私有参数,align_depth这类顶层参数对应驱动的高级开关。写错层级不会报错,但参数不生效,调试时容易产生困惑。

4.4 RViz 里看点云

数据有没有真的出来,用 RViz 看一眼最直观。启动 RViz:

rviz2

左侧面板点击Add,按By topic找到/camera/depth/color/points,把Fixed Frame设置为camera_link或者camera_depth_optical_frame。如果点云没显示,九成是坐标系没设对。

彩色点云的显示需要把Color Transformer改为RGB8,Size调小一点,点云细节就出来了。第一次在 RViz 里看到 D435i 实时重建的桌面点时,整个环境基本算验收通过了。

5. 深度对齐、点云与 IMU:三个核心能力的实战用法

5.1 深度图与彩色图对齐:为什么要对、怎么对

D435i 的深度相机和彩色相机在物理上是两个镜头,成像的视野和原点都不完全一致。深度图上的某个像素点坐标,和彩色图上同一个物体的像素坐标是有偏差的。做目标检测后取深度、或者做图像分割结合深度信息时,这种偏差会直接导致测距错误。

解决方式就是把深度图对齐到彩色图。启动时加上align_depth:=true,会出现新话题:

/camera/aligned_depth_to_color/image_raw

这个话题里的深度图,像素坐标系和彩色图严格对应。你可以简单理解成:两张图像先做了一次坐标系变换,然后叠在一起,每个像素都能直接互相查。实测下来,对齐后深度图和彩色图的边缘误差能控制在几个像素以内,对大部分应用足够了。

5.2 点云输出与保存思路

开启pointcloud.enable:=true后,驱动会发布/camera/depth/color/points,类型是sensor_msgs/msg/PointCloud2。在机器人导航里,这个点云可以直接交给后续的障碍物检测、地面分割、3D 重建模块。

如果你想把点云保存下来做离线分析,最简单的办法是用 ROS2 bag 录制:

ros2 bag record /camera/depth/color/points

录制生成的 bag 可以用 rosbag2 工具离线回放,配合 PCL 库再做转换和保存 PCD 文件。实时保存 PCD 也不难,写一个订阅PointCloud2的 Python 节点,用sensor_msgs_py转成 numpy 数组再写文件即可。点云话题数据量很大,长时间录制注意磁盘占用,我建议按需录制,别一直开。

5.3 IMU 数据读取与应用

D435i 的 IMU 数据在驱动启动后自动发布,话题是/camera/imu,类型是sensor_msgs/msg/Imu,里面包含了四元数姿态、角速度、线性加速度。取消 IMU 可以用参数enable_imu:=false,需要时再开。

在视觉惯性里程计里,IMU 数据通常和图像数据做时间戳对齐后一起送入状态估计器。值得注意的一点是:D435i 的 IMU 输出频率可以在驱动内配置,默认是 200Hz 左右,实际使用时我一般配合算法需求调成 100Hz 或 400Hz。具体参数是imu_frequency,单位 Hz,根据需要设置。

如果只是拿来做简单的姿态判断,可以订阅/camera/imu里的四元数,但要注意原始 IMU 数据没有经过滤波,静止时也会有小幅漂移。想要准确姿态,需要做静态初始化、零偏估计和标定。D435i 出厂有基本标定,但每次装机后做一次快速标定能把数据质量提升不少。

5.4 一个实用的小综合:用对齐深度辅助目标测距

深度对齐带来的最直接好处,是可以在目标检测框内直接取深度值做测距。比如我用 YOLO 检测到一个目标,拿到了它在彩色图上的像素坐标,这时候订阅/camera/aligned_depth_to_color/image_raw,取出该坐标下的深度值,转成三维点就可以得到目标距离。

具体计算时要注意深度图某些位置可能是 0 或无效值,取检测框中心点不一定可靠。我的做法是取检测框内所有有效深度值的中位数,去掉异常点后稳定很多。这个思路在机械臂抓取、巡检机器人避障里都实用,能快速得到目标空间位置而不用额外做复杂的标定和变换。

6. 高频问题排查:权限、带宽、固件与多相机

6.1 常见报错与排查速查表

下面是这段时间使用中沉淀出来的问题速查表,基本覆盖了新手阶段能遇到的大多数坑:

现象可能原因解决方式
No device detected没有刷 udev 规则执行./scripts/setup_udev_rules.sh后重新插拔
viewer 打不开相机流固件过老检查并升级固件版本
画面帧率比设置的低很多USB 接口是 2.0换成主板 USB 3.0 蓝色接口
点云在 RViz 不显示Fixed Frame 错误改为camera_link或camera_depth_optical_frame
多个话题 QoS 不匹配订阅端 QoS 策略错误让订阅端使用相机的 QoS 策略或改为BEST_EFFORT
long 时间运行后掉帧温度和 USB 带宽降分辨率、检查散热、加 USB 外设供电
ros2 launch卡住不动ROS2 daemon 状态异常ros2 daemon stop && ros2 daemon start重试

6.2 USB 带宽与接口问题

D435i 对 USB 线路质量非常敏感。我一开始用笔记本右侧的 USB 口连接,深度和 RGB 都设置 640x480x30,偶尔出现掉帧和花屏,换了左侧直连主板的口之后一切正常。D435i 是 USB3.0 设备,默认以 5Gbps 带宽工作,如果插在 USB2.0 口上,虽然也能识别,但帧率和分辨率会被显著限制,画面卡顿到没法用。

另外,延长线和扩展坞尽量别用。USB3.0 对线材的质量要求很高,劣质延长线会导致传输不稳定,出现图像撕裂或者设备反复断开重连。如果线材必须很长,建议用带芯片的主动延长线,别贪便宜。

6.3 多相机同时运行的配置

一台机器带两台 D435i 时,最关键的是用序列号区分设备。用下面的命令查看设备序列号:

rs-enumerate-devices

拿到序列号后,分别启动两个驱动实例:

ros2 launch realsense2_camera rs_launch.py camera_name:=camera1 serial_no:=xxxx ros2 launch realsense2_camera rs_launch.py camera_name:=camera2 serial_no:=yyyy

camera_name参数会改变话题前缀。如果不设置,两个驱动节点都叫camera,话题互相覆盖,数据混乱。我调试多相机时还注意到两台相机的红外发射器可能互相干扰,如果深度效果不好,可以把其中一台的emitter_enabled设为 0 再观察。

6.4 Docker 容器内访问相机

很多项目把环境封装成 Docker 镜像,容器里访问 D435i 需要注意设备映射。最省事的启动参数是:

docker run -it --privileged --network=host my_image

--privileged虽然给了容器完全权限,但对相机这种 USB 设备是最直接的解决办法,适合个人开发场景。更规范的做法是映射/dev/bus/usb挂载进去:

docker run -it --device=/dev/bus/usb:/dev/bus/usb my_image

容器里需要安装相同版本的 librealsense SDK,并保证 udev 规则在主机侧生效。我在容器内跑 ros2 launch 时遇到过设备枚举问题,后来发现是主机没刷 udev 规则,容器怎么映射都没用,先检查主机侧。

7. 调参与长期运行经验:这台相机的脾性我摸得差不多了

7.1 推荐参数组合与调参心得

日常使用我固定采取这样一套参数:

depth_module.depth_profile:=640x480x30 rgb_camera.color_profile:=640x480x30 pointcloud.enable:=true align_depth:=true enable_imu:=true

640x480 在多数机器人导航任务里足够用,而且能稳定跑 30 帧,CPU 占用也可控。分辨率跳到 1280x720 后视觉质量确实提升,但点云同步开启时 CPU 和带宽压力成倍增加,换来的收益不明显。所以除非确实需要高密度点云做建模,否则尽量保持在 VGA 级别。

自动曝光方面,D435i 的深度模块有enable_auto_exposure参数,默认开启。如果测试环境光照稳定,手动固定曝光值反而能减少输出噪声。我在一个室内走廊测试时就遇到自动曝光导致深度图亮度飘忽的问题,固定曝光后点云干净了很多。

7.2 发热、掉帧与稳定性维护

D435i 长时间运行后外壳温度很高,这是正常现象,不会立刻损坏,但高温会影响深度质量和长期可靠性。在机器人上安装时别把它包在密封舱里,尽量保证散热通风。我曾经把相机用扎带固定在狭小的云台内部,跑半小时后深度图开始出现条纹,拆掉外壳散热后问题消失。

数据流稳定性方面,当点云、彩色、深多路同时开启,CPU 单核容易冲高。此时可以把点云发布频率调低,或者关掉不需要的红外流。驱动里默认会开启红外图和 RGB 等多路流,实际用不到的流可以用enable_infra1:=false和enable_infra2:=false关掉,能省出不少资源。

最后说一个每次结束时的习惯:跑完 launch 后直接Ctrl+C结束,偶尔会出现节点没退干净的情况,重新启动时报端口被占用。这时候执行一下:

ros2 daemon stop

清理速度比你手动 kill 进程快得多。这些看起来都是小事,但积累起来就是每天调试的效率差距。D435i 是一个上限很高、下限也不低的设备,和 Ubuntu 22.04 + ROS2 Humble 这套环境磨合好之后,它会成为你机器人视觉开发里最趁手的传感器之一。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询