尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ROS2 + Intel RealSense:从驱动编译到点云订阅的完整指南

ROS2 + Intel RealSense:从驱动编译到点云订阅的完整指南 简介面向在ROS2环境中使用Intel RealSense D435/D405相机的机器人开发者与视觉工程人员这份资源梳理了从Windows端安装RealSense Viewer、Linux端配置依赖与编译RealSense-ROS2再到启动ROS2节点并通过话题读取RGB、深度、点云数据的完整链路特别适合正在开展移动机器人导航、机械臂抓取或三维重建项目的工程师也包含了安装前硬件检查、驱动冲突排查等实用经验。文件共3个以HTML文档承载说明内容辅以inscode代码配置与gitignore工程文件zip压缩包仅6KB十分轻量可作为独立参考包或随仓库分发。已有151人学习尤其适合需要同时兼顾Windows与Linux双系统开发、希望理清相机坐标系与深度信息单位换算等关键概念的中高级开发者。资源不仅给出从安装依赖、配置环境变量到启动ROS2节点的完整步骤还单独说明了如何订阅RGB、深度和点云三类话题点出深度数据以毫米为单位的处理要点避免在三维建模与仿真中出现单位错误并且对相机坐标系中的方向约定做了清晰注释能有效提升视觉感知项目的落地效率与稳定性为后续开发节省大量排查时间。 第一次把Intel RealSense插到Linux主机上准备跑ROS2的时候我原以为这就是“装个驱动、launch一个节点”的事结果被USB控制器、librealsense版本和realsense-ros分支轮番教育了一周。后来把D455、D435、T265都调顺之后发现这套流程其实有规律可循只是网上的资料太散。这篇指南把我自己踩过坑之后的完整路子整理出来包含从环境准备、驱动编译、launch参数到Python/C订阅点云与图像的全部代码适合刚接触RealSense的ROS2新手也适合从ROS1迁移过来想在Humble或Jazzy上快速起相机的人。1. 环境准备先把ROS2、librealsense和realsense-ros的关系理清楚1.1 版本匹配是最大的坑没有之一RealSense在ROS2下的链路是相机硬件 → librealsense SDK → realsense-ros节点 → ROS2话题。librealsense负责读硬件数据realsense-ros负责把SDK回调包装成sensor_msgs/Image、PointCloud2、Imu这些标准ROS2消息。很多人编译报错或者启动节点直接崩溃往往不是操作问题而是这两个东西的版本没对齐。realsense-ros的ROS2开发分支叫ros2-development官方要求librealsense最低版本是2.50.0。但我的实际经验是别卡着下限跑比如你在Ubuntu 24.04 ROS2 Jazzy上用了系统源里的旧版librealsense大概率会遇到rs2::error: null pointer或者failed to set power state这类特别玄学的问题。我整理了一个自己验证过的组合表直接照抄能省很多时间操作系统ROS2版本我测试过的稳定组合Ubuntu 22.04Humblelibrealsense 2.55.1 realsense-ros ros2-development分支Ubuntu 24.04Jazzylibrealsense 2.56.2 realsense-ros ros2-development分支Ubuntu 20.04Foxylibrealsense 2.54.2 realsense-ros ros2-development分支提示不要用apt直接装ROS2软件源里的realsense-ros版本往往滞后而且没人保证它在Humble/Jazzy上能把D455的IMU也拉起来。源码编译多花十分钟后面省心很多。有一点需要提前说清楚ROS2本身先装好推荐用ros2官方源的二进制版Humble对应Ubuntu 22.04Jazzy对应Ubuntu 24.04。如果你是新手装完ROS2以后务必先跑通ros2 run demo_nodes_cpp talker确认基础环境没问题再碰相机否则后面排查问题的时候变量太多。1.2 编译librealsense建议带上examples先安装编译依赖sudo apt install git cmake build-essential libssl-dev libusb-1.0-0-dev libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev git clone https://github.com/IntelRealSense/librealsense.git cd librealsense git checkout v2.56.2 mkdir build cd build cmake .. -DBUILD_EXAMPLEStrue -DCMAKE_BUILD_TYPERelease make -j$(nproc) sudo make install sudo ldconfig注意-j$(nproc)会让编译吃满所有核心如果机器内存小于8GB建议改成-j4否则编译到一半可能被OOM杀掉。我第一台测试机器就是8GB内存开满16线程结果librealsense编译到90%直接被系统kill重启之后再也不敢这么干。装完还要处理udev权限规则这是插上相机后能看到设备的关键一步cd librealsense sudo ./scripts/setup_udev_rules.sh这个脚本会把当前用户加入video组、写入RealSense的USB设备规则。执行完拔插一次相机再运行rs-enumerate-devices理论上能看到设备型号、序列号、固件版本和相机内参。顺带提一句有人问D455在macOS上能做什么应用。如果你用的是macOS直接用官方RealSense Viewer做深度预览、手势交互、空间测量、配合Unity做AR原型都没问题但ROS2相关的开发基本还是建议回到Linux环境macOS上跑Docker里的ROS2访问USB设备的转发链路太折腾不值得。1.3 编译realsense-ros注意rosdep这条命令驱动包本身不大编译重点在于依赖识别mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src git clone https://github.com/IntelRealSense/realsense-ros.git -b ros2-development cd ~/ros2_ws rosdep install --from-paths src --ignore-src -r -y colcon build --symlink-install source install/setup.bashrosdep install这条命令的作用是扫描src底下的package.xml把realsense-ros依赖的ROS2功能包比如diagnostic_updater、launch_ros、cv_bridge全部装好。如果提示找不到某个依赖多半是前面ROS2没装完整用rosdep check排查一下。编译完成后source install/setup.bash建议写进~/.bashrc不然每次新开终端都要手动source一遍。2. 先跑通官方案例从launch到RViz2可视化2.1 启动节点先别急着改参数环境就绪后用官方launch文件启动是最快的验证方式ros2 launch realsense2_camera rs_launch.py这个launch文件会启动realsense2_camera_node并默认打开彩色流和深度流。如果你用的是D455IMU流默认也是开着的。看到类似RealSense camera is up and running的日志说明节点启动成功。如果启动时报设备打不开先别怀疑代码大概率是两个原因一是udev规则没生效重新跑setup_udev_rules.sh二是USB线插在了USB 2.0口RealSense对带宽要求很高必须插USB 3.0以上的蓝色口。我试过把D435插在扩展坞的USB 2.0口上能枚举设备但启动后不到三秒节点就崩溃日志里全是Frame didnt arrive within 5000。2.2 熟悉话题你最终消费的是这些数据启动后开另一个终端看话题列表ros2 topic list | grep camera关键话题通常有这些/camera/color/camera_info彩色相机的内参和畸变系数/camera/color/image_raw原始彩色图像/camera/depth/image_rect_raw深度图注意是16位单通道/camera/depth/color/pointsRGB-D融合后的彩色点云/camera/imu/dataIMU六轴数据仅D455、T265等含IMU的型号我建议你启动后先看一条camera_inforos2 topic echo --once /camera/color/camera_info里面能看到fx、fy、cx、cy、畸变参数这些数值后面做相机标定、像素转三维坐标、深度图对齐都用得着。另外查一下话题消息类型ros2 interface show sensor_msgs/msg/Image ros2 interface show sensor_msgs/msg/PointCloud2确认类型之后代码订阅的逻辑就清晰了。2.3 RViz2里看图像和点云可视化是最直观的验证ros2 run rviz2 rviz2打开RViz2之后两步操作把左侧Displays面板里的Fixed Frame设置为camera_link如果保持默认的map点云和图像会因为坐标系对不上而显示异常。点击左下角Add按钮添加Image视图通道选择/camera/color/image_raw再添加PointCloud2视图选择/camera/depth/color/points。第一次看到彩色点云在RViz2里转起来的时候基本说明整个链路已经通了。要注意的是realsense-ros默认不一定发布点云话题如果/camera/depth/color/points不存在需要在启动时显式开启点云ros2 launch realsense2_camera rs_launch.py pointcloud.enable:true3. 代码实战订阅图像、点云和IMU3.1 Python订阅彩色图并实时显示很多新手把重点放在“怎么让相机出图”其实出图只是起点真正写业务代码通常是从订阅话题开始的。我用Python写的这套模板改动最小、最容易跑起来import rclpy from rclpy.node import Node from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2 class RealSenseViewer(Node): def __init__(self): super().__init__(realsense_viewer) self.bridge CvBridge() self.sub self.create_subscription( Image, /camera/color/image_raw, self.image_callback, 10 ) def image_callback(self, msg): cv_image self.bridge.imgmsg_to_cv2(msg, bgr8) cv2.imshow(color, cv_image) cv2.waitKey(1) def main(argsNone): rclpy.init(argsargs) node RealSenseViewer() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() if __name__ __main__: main()这段代码的核心是CvBridge它是ROS2图像消息和OpenCV Mat之间转换的桥梁。imgmsg_to_cv2(msg, bgr8)的第二个参数指定编码格式彩色图用bgr8深度图用16UC1。我见过有人不加编码参数结果深度图显示成一片黑或者一片白就是因为没有把16位深度数据正确解释。需要注意一点cv2.imshow和cv2.waitKey必须在主线程调用所以不能把它们放进多线程回调里执行。rclpy.spin默认是单线程阻塞调用回调执行完立即返回不会卡住消息队列。3.2 C订阅点云并做体素滤波点云数据量大、频率高Python处理起来如果性能吃紧建议直接用C。下面这个节点订阅/camera/depth/color/points再用PCL的VoxelGrid做降采样输出到新的点云话题#include rclcpp/rclcpp.hpp #include sensor_msgs/msg/point_cloud2.hpp #include pcl_conversions/pcl_conversions.h #include pcl/point_cloud.h #include pcl/point_types.h #include pcl/filters/voxel_grid.h class PointCloudDownsampler : public rclcpp::Node { public: PointCloudDownsampler() : Node(pointcloud_downsampler) { sub_ this-create_subscriptionsensor_msgs::msg::PointCloud2( /camera/depth/color/points, 10, [this](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { pcl::PointCloudpcl::PointXYZRGB::Ptr cloud( new pcl::PointCloudpcl::PointXYZRGB()); pcl::fromROSMsg(*msg, *cloud); pcl::VoxelGridpcl::PointXYZRGB voxel; voxel.setInputCloud(cloud); voxel.setLeafSize(0.01f, 0.01f, 0.01f); pcl::PointCloudpcl::PointXYZRGB::Ptr filtered( new pcl::PointCloudpcl::PointXYZRGB()); voxel.filter(*filtered); sensor_msgs::msg::PointCloud2 out_msg; pcl::toROSMsg(*filtered, out_msg); out_msg.header msg-header; pub_-publish(out_msg); }); pub_ this-create_publishersensor_msgs::msg::PointCloud2( /camera/depth/color/points_downsampled, 10); } private: rclcpp::Subscriptionsensor_msgs::msg::PointCloud2::SharedPtr sub_; rclcpp::Publishersensor_msgs::msg::PointCloud2::SharedPtr pub_; }; int main(int argc, char** argv) { rclcpp::init(argc, argv); rclcpp::spin(std::make_sharedPointCloudDownsampler()); rclcpp::shutdown(); return 0; }对应的CMakeLists.txt关键配置find_package(rclcpp REQUIRED) find_package(sensor_msgs REQUIRED) find_package(pcl_conversions REQUIRED) find_package(pcl_ros REQUIRED) add_executable(pointcloud_downsampler src/pointcloud_downsampler.cpp) ament_target_dependencies(pointcloud_downsampler rclcpp sensor_msgs pcl_conversions pcl_ros) install(TARGETS pointcloud_downsampler DESTINATION lib/${PROJECT_NAME})体素滤波这里的直觉理解就是“把三维空间切成小方块每个方块只保留一个点”。RealSense的彩色点云一帧可能几十万个点直接用octomap_server或者cartographer做建图CPU扛不住。setLeafSize(0.01f, 0.01f, 0.01f)表示1cm立方体降采样这个值在室内建图场景下已经够用你还可以根据实际距离调整。之前我给一个移动底盘做障碍物检测1cm降采样之后点云量降到原来的1/5但障碍物的轮廓信息基本没丢。3.3 launch参数分辨率、对齐和IMUrealsense-ros支持在launch时直接覆盖参数这是个非常实用的能力。比如需要1280x720分辨率同时进行深度对齐ros2 launch realsense2_camera rs_launch.py \ depth_module.profile:1280x720x30 \ color_module.profile:1280x720x30 \ pointcloud.enable:true \ align_depth.enable:truealign_depth.enable:true会把深度图对齐到彩色图坐标系这样深度图像素和彩色图像素一一对应做RGB-D语义分割、目标检测时特别方便。对齐之后会多出一个话题/camera/depth/image_rect_raw它的尺寸和彩色图一致。如果你不追求逐像素对齐只想拿原始深度那这个参数可以不开能省一点CPU。IMU如果正确启用话题/camera/imu/data的频率应该是200Hz左右用下面的命令验证ros2 topic hz /camera/imu/dataD455内置的IMU是BMI055输出三轴加速度和三轴角速度。这个数据直接用在VIO或者自动驾驶估计器里通常还需要配合imu_filter_madgwick做姿态解算因为原始IMU包含噪声和零偏。我用过的最省事组合是imu_filter_madgwickrobot_localization先发布姿态四元数再把里程计和IMU融合出机器人的位姿。这个链路比较长但每一步都有现成库不需要自己造轮子。4. 常见问题与避坑速查4.1 相机枚举正常但ROS2节点起不来这个问题我遇到不止一次。rs-enumerate-devices能看到相机说明SDK层面没问题但ros2 launch一执行就报Device open failed。原因是realsense-ros这个进程在启动时对USB带宽的申请比SDK示例程序更激进如果USB控制器下还挂了别的设备带宽不够就会申请失败。排查方法lsusb -t看一下RealSense挂在哪个USB控制器下面、当前链路速度是5000M还是480M。如果是480M说明走了USB 2.0协议换接口。另外台式机建议插后置USB口前置面板的USB延长线质量参差不齐很容易导致带宽不足。4.2 深度图有大量黑洞深度图上的黑色区域表示“测不到距离”。常见原因有三一是目标表面太近低于相机的最小工作距离比如D435最小距离约0.1米太近会产生大量无效像素二是目标表面是镜面或者透明材质红外结构光反射不回来三是相机前方有强红外干扰源比如阳光直射。代码层面可以用深度后处理缓解但治标不治本。如果你是做室内机器人导航把相机装得稍微高一点避开正前方的地面反光效果比调参数更明显。4.3 IMU消息格式和频率不对/camera/imu/data的消息类型是sensor_msgs/msg/Imu字段包括orientation四元数D455默认可能全是0需要自己融合angular_velocity角速度linear_acceleration线性加速度如果频率起不来先确认你用的是D455而不是D435D435没有IMU硬件。其次检查launch里是否开启了enable_imu有些版本默认IMU off。最后IMU数据对USB中断敏感不要和点云流同时拉满否则IMU的帧率会掉到100Hz以下。4.4 点云建图太卡配合八叉树地图导航时最怕的就是点云全量灌给octomap_server。我的建议是分成三步处理先用VoxelGrid降采样到1cm~2cm体素再通过PassThrough滤波器裁剪掉相机5米以外的点最后限制话题频率在5Hz左右。这样建图实时性和地图质量都在可接受范围内。下面是一个常用的裁剪思路ros2 run pcl_ros passthrough --ros-args \ -r input:/camera/depth/color/points_downsampled \ -p filter_field:z -p filter_limit_min:0.2 -p filter_limit_max:5.0这条命令会把z轴方向0.2米到5米范围之外的点全部裁掉。室内场景下这个范围足够用了还能大幅减小后续建图算法的计算量。最后再分享一个我自己的习惯只要插上RealSense先跑一遍rs-enumerate-devices确认固件版本和序列号再跑ROS2节点。固件版本过低时realsense-ros会打印警告但很多新手不会注意那行日志直接忽略结果后面出现诡异的重启问题。固件升级直接用RealSense Viewer自带的Updater功能几分钟就能搞定。真遇到解决不了的问题先用RealSense Viewer确认相机裸奔时是否正常这能把“硬件问题”和“ROS2集成问题”快速分开排查路径会清晰很多。本文还有配套的精品资源点击获取
返回列表