1. 为什么 realsense-viewer 在 Ubuntu 20.04 上总装不上
如果你手头有一台 D435i、D455 或者 T265,插上 Ubuntu 20.04 的机器,第一反应肯定是装个realsense-viewer看看深度图和 IMU 数据。但真正动手之后你会发现,这件事远没有想象中那么顺——apt install找不到包,源码编译到一半报内核头文件缺失,好不容易编译完了运行起来又提示No device connected,插拔几次 USB 之后设备干脆从lsusb里消失了。
这些问题的根源其实不复杂,但分散在好几个环节:librealsense 的版本和内核 uvcvideo 模块的兼容性、USB 权限规则、内核头文件、以及 Ubuntu 20.04 默认的 udev 规则版本。任何一个环节没对上,realsense-viewer 就跑不起来。而且这几个环节的报错信息往往互相掩盖,你解决了 A 问题,B 问题才暴露出来,很容易让人以为是"装不上"。
这篇内容面向的是在 Ubuntu 20.04(Focal Fossa)上第一次接触 RealSense 的开发者,不管你是做 ROS 机器人、做三维重建,还是单纯想验证一下手头相机的好坏,这套流程都能直接复用。我会把整个安装过程拆成"依赖准备 → 源码编译 → udev 规则 → 验证运行"四个阶段,每个阶段讲清楚为什么这么做,以及实测中会踩到什么坑。全程基于 librealsense 官方源码编译路线,不依赖任何第三方预编译包,这样版本可控,出问题也好排查。
先给一个整体判断:Ubuntu 20.04 上装 realsense-viewer,推荐走源码编译而不是 apt。原因后面会详细说,但简单讲就是 apt 源里的版本往往落后,而且和你的内核版本不一定匹配,源码编译虽然多花十几分钟,但可控性高得多。
2. 装之前必须搞清楚的三个前置条件
2.1 内核版本决定了你能用哪个 librealsense 版本
这是最容易被忽略的一点。librealsense 依赖内核的uvcvideo模块来访问 USB 摄像头,而不同内核版本对 UVC 元数据的支持程度不一样。Ubuntu 20.04 默认内核是 5.4,这个版本对 RealSense 的支持是基本可用但需要打补丁的状态。
具体来说,librealsense 从 2.34 版本开始引入了对内核 UVC 补丁的依赖,如果你用的是 5.4 内核,需要确认uvcvideo模块是否支持UVC_QUIRK_METADATA。检查方法很简单:
uname -r modinfo uvcvideo | grep -i version如果内核版本低于 4.16,那基本不用折腾了,深度流和 IMU 都会有问题,建议先升级内核。5.4 到 5.15 之间是相对安全的区间,5.15 以上对 RealSense 的支持更完善,但 Ubuntu 20.04 默认不带这么新的内核,需要自己装 HWE 内核:
sudo apt install linux-generic-hwe-20.04装完重启,uname -r应该能看到 5.15 或更高。这一步不是必须的,但如果你后面遇到深度流打不开、帧率不稳的问题,回头升级内核往往能解决。
2.2 USB 控制器带宽:不是插上就能跑满帧率
RealSense 相机对 USB 带宽很敏感。D435i 同时开深度 848x480@90fps 加 RGB 1920x1080@30fps,再加上 IMU,总带宽需求接近 USB 3.0 的上限。如果你的机器上同时插了其他 USB 3.0 设备(比如外接硬盘、采集卡),带宽会被瓜分,表现就是帧率掉、丢帧、甚至设备直接掉线。
实测下来,把 RealSense 单独插在一个 USB 3.0 控制器上是最稳的做法。用lsusb -t可以看到设备挂在哪个控制器下:
lsusb -t输出里Class=Video那一行就是相机,看它上面的5000M还是480M,前者是 USB 3.0,后者是 USB 2.0。如果显示 480M,说明你插错口了,或者线材不支持 USB 3.0。RealSense 原装线是 USB 3.0 的,但很多人随手拿一根手机充电线就插上了,那种线往往只有 USB 2.0 的线芯,带宽根本不够。
提示:如果
lsusb -t里相机挂在 USB 2.0 下,先换线、换口,别急着怀疑软件问题。这是最常见的"设备能识别但跑不起来"的原因。
2.3 磁盘空间和编译依赖的提前准备
源码编译 librealsense 需要下载大约 1GB 的源码和依赖,编译过程还会产生几个 GB 的中间文件。建议预留至少 10GB 空闲空间。依赖包方面,Ubuntu 20.04 上需要提前装好这些:
sudo apt update sudo apt install -y git cmake build-essential libssl-dev libusb-1.0-0-dev \ libudev-dev pkg-config libgtk-3-dev libglfw3-dev libgl1-mesa-dev \ libglu1-mesa-dev at libavcodec-dev libavformat-dev libswscale-dev \ python3-dev python3-numpy这里有几个包值得单独说:
libssl-dev:librealsense 的网络设备功能(比如以太网连接的 D455)需要它,不装的话 cmake 阶段会直接报错。libgtk-3-dev和libglfw3-dev:realsense-viewer 的 GUI 依赖,不装的话编译出来的 viewer 是空的,或者干脆编译不过。libusb-1.0-0-dev:USB 通信的核心依赖,版本不能太低,Ubuntu 20.04 自带的 1.0.22 是够用的。python3-dev:如果你后面要用 pyrealsense2,这个必须有。
这些依赖里,libssl-dev和libgtk-3-dev是最容易漏的,因为很多教程只列了前几个。漏了libgtk-3-dev的典型症状是 cmake 配置阶段提示Could NOT find GTK3,然后 viewer 被跳过编译,最后你装完发现根本没有realsense-viewer这个可执行文件。
3. 源码编译 librealsense 的完整链路
3.1 选对分支:别直接 clone master
librealsense 的 master 分支是开发分支,稳定性不如 release tag。实测下来,用最新的 release tag 比 master 稳得多。截至我写这篇内容时,比较稳的版本是 v2.54.2 和 v2.55.1,前者兼容性更好,后者对新固件支持更全。
git clone https://github.com/IntelRealSense/librealsense.git cd librealsense git tag | tail -20 git checkout v2.54.2选 v2.54.2 的理由:这个版本对 Ubuntu 20.04 + 5.4 内核的组合验证得最充分,社区里踩坑记录也最多,遇到问题好搜。v2.55 之后对内核版本要求提高了一些,5.4 内核下偶尔会有 UVC 相关的警告。
clone 完之后先别急着编译,检查一下当前目录下有没有build文件夹,有的话删掉,避免旧缓存干扰:
rm -rf build3.2 内核补丁:什么时候需要打,什么时候不用
librealsense 源码里带了一个scripts/patch-realsense-ubuntu-lts.sh脚本,用来给内核的 uvcvideo 模块打补丁,主要是为了支持硬件时间戳和元数据。这个脚本不是必须跑的,取决于你的内核版本和使用场景。
判断标准:
| 内核版本 | 是否需要打补丁 | 说明 |
|---|---|---|
| < 4.16 | 必须 | 否则深度流无法工作 |
| 4.16 - 5.4 | 建议 | 硬件时间戳需要,普通使用可跳过 |
| 5.4 - 5.15 | 可选 | 大部分场景不需要 |
| > 5.15 | 不需要 | 内核已原生支持 |
如果你只是跑 realsense-viewer 看图像,5.4 内核下可以跳过打补丁,直接编译。打补丁的风险是可能和当前内核的其他模块冲突,导致编译内核模块失败,反而更麻烦。我个人的做法是:先不打补丁编译一次,如果深度流正常、时间戳没问题,就不折腾了。
如果确实需要打补丁,脚本执行前要确保装了当前内核的头文件:
sudo apt install linux-headers-$(uname -r)然后:
./scripts/patch-realsense-ubuntu-lts.sh这个过程会重新编译 uvcvideo 模块,耗时大概 5-10 分钟。执行完需要重启,或者手动modprobe -r uvcvideo && modprobe uvcvideo重新加载模块。
3.3 cmake 配置阶段的关键参数
进入 build 目录开始配置:
mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ -DBUILD_EXAMPLES=true \ -DBUILD_GRAPHICAL_EXAMPLES=true \ -DBUILD_PYTHON_BINDINGS=true \ -DPYTHON_EXECUTABLE=$(which python3) \ -DFORCE_RSUSB_BACKEND=false逐个解释这些参数:
CMAKE_BUILD_TYPE=Release:Release 模式编译,优化级别高,viewer 跑起来流畅。Debug 模式编译慢且运行卡,除非你要调试源码,否则别用。BUILD_EXAMPLES=true:编译示例程序,包括rs-depth、rs-color这些命令行工具,排查问题时很有用。BUILD_GRAPHICAL_EXAMPLES=true:这个必须开,realsense-viewer 就属于 graphical examples,不开的话编译完没有 viewer。BUILD_PYTHON_BINDINGS=true:编译 pyrealsense2,后面用 Python 做开发的话需要。PYTHON_EXECUTABLE:指定 Python 路径,Ubuntu 20.04 默认是 python3,不指定的话 cmake 可能找到 python2,导致绑定编译失败。FORCE_RSUSB_BACKEND=false:这个参数很关键。设为 true 会强制使用 libusb 后端,绕过内核 uvcvideo,好处是不依赖内核补丁,坏处是性能略低、部分功能受限。默认用 false,走内核后端,除非你内核版本太老或者打补丁失败,才考虑设 true。
cmake 配置完成后,输出里会有一行Configuring done,然后列出哪些组件会被编译。重点看这几行:
-- Building graphical examples: yes -- Building python bindings: yes -- Building with CUDA support: no如果 graphical examples 显示 no,说明 GTK 或 GLFW 没找到,回去检查依赖。CUDA 支持一般不需要,除非你要做 GPU 加速的点云处理。
3.4 编译和安装:make -j 的坑
配置没问题就可以编译了:
make -j$(nproc)-j$(nproc)是用满所有 CPU 核心并行编译,能快不少。但这里有个坑:内存不足的机器上并行编译会 OOM。librealsense 的某些源文件(尤其是rs.cpp和device.cpp)编译时内存占用很高,4GB 内存的机器用-j4可能会被系统 kill 掉。
判断方法:如果 make 过程中突然报c++: fatal error: Killed signal terminated program cc1plus,那就是内存不够。解决办法是减少并行数:
make -j2或者干脆单线程make,慢是慢点,但稳。编译时间参考:8 核 16GB 的机器,-j8大概 8-12 分钟;4 核 8GB 的机器,-j4大概 15-20 分钟。
编译完成后安装:
sudo make install sudo ldconfigldconfig是刷新动态链接库缓存,不执行的话运行时会提示找不到librealsense2.so。
3.5 验证安装是否成功
装完之后先别急着插相机,用命令行工具确认库本身没问题:
rs-enumerate-devices如果这个命令能跑起来(哪怕提示没找到设备),说明库装好了。如果提示command not found,检查/usr/local/bin是否在 PATH 里,或者make install是否真的成功了。
再看一下库的版本:
rs-enumerate-devices --version输出的版本号应该和你 checkout 的 tag 一致。
4. udev 规则:设备识别不了的头号元凶
4.1 为什么插上相机 lsusb 能看到但程序读不到
这是最经典的问题:lsusb里能看到Intel Corp.的设备,但rs-enumerate-devices提示No device connected。原因几乎可以肯定是udev 规则没装或者没生效。
Linux 下普通用户默认没有权限直接访问 USB 设备节点,RealSense 需要 udev 规则来给设备节点设置正确的权限和用户组。librealsense 源码里带了规则文件config/99-realsense-libusb.rules,需要手动拷贝到系统目录:
sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules sudo udevadm trigger注意路径:如果你已经 cd 到 build 目录了,规则文件在上一级的config目录里,路径是../config/99-realsense-libusb.rules。
4.2 规则文件里的关键字段解读
打开这个规则文件看一眼,核心内容大概是这样:
SUBSYSTEM=="usb", ATTRS{idVendor}=="8086", ATTRS{idProduct}=="0b07", MODE="0666", GROUP="plugdev"idVendor=="8086":Intel 的 USB 厂商 ID,RealSense 全系都是这个。idProduct:不同型号不同,0b07 是 D435i,0b3a 是 D455,0b3d 是 T265,规则文件里列了一长串。MODE="0666":给设备节点设置读写权限,所有用户可读写。GROUP="plugdev":把设备归到 plugdev 组。
这里有个细节:你的用户必须属于 plugdev 组,否则即使规则生效,权限也不一定对。检查:
groups $USER如果没有 plugdev,加进去:
sudo usermod -aG plugdev $USER加完组需要重新登录才生效,或者用newgrp plugdev临时切换。很多人改完规则发现还是不行,就是因为没重新登录。
4.3 规则生效的验证方法
重新插拔相机,然后检查设备节点的权限:
ls -l /dev/video*正常的话应该看到类似crw-rw-rw- 1 root plugdev的权限。如果还是crw-rw----且属主是 root,说明规则没生效。
排查步骤:
- 确认规则文件确实在
/etc/udev/rules.d/下,文件名以.rules结尾。 - 确认
sudo udevadm control --reload-rules执行成功,没有报错。 - 确认重新插拔了设备,或者执行了
sudo udevadm trigger。 - 确认用户在 plugdev 组,且重新登录过。
如果以上都做了还是不行,可以临时用 root 跑一下sudo realsense-viewer,如果能识别设备,那就百分百是权限问题,回到 udev 规则继续排查。
注意:不建议长期用 sudo 跑 realsense-viewer,因为 GUI 程序以 root 运行会生成 root 属主的配置文件,后面普通用户跑的时候可能因为读不到配置而异常。
5. 跑起来之后才会遇到的坑
5.1 realsense-viewer 启动报 GL 相关错误
第一次运行realsense-viewer,可能会遇到这样的报错:
libGL error: MESA-LOADER: failed to open swrast或者窗口一片黑,只有标题栏。这通常是 OpenGL 驱动的问题,常见于虚拟机或者没有独立显卡的机器。
解决办法分两种情况:
- 物理机:装一下 mesa 的软件渲染驱动
sudo apt install mesa-utils libgl1-mesa-dri,然后确认glxinfo | grep "OpenGL renderer"有输出。 - 虚拟机:VMware 或 VirtualBox 里跑,需要开启 3D 加速,并且装 Guest Additions。即便如此,软件渲染下 viewer 的帧率也会很低,能看图像但别指望流畅。
如果只是想在虚拟机里验证相机能不能识别,其实用rs-enumerate-devices和rs-depth这些命令行工具就够了,不一定非要跑 GUI。
5.2 深度流能开但 RGB 流打不开
这个问题的典型表现是:viewer 里深度图正常,但 RGB 那一栏点开就报错,或者一直转圈。原因通常是USB 带宽不够,深度流和 RGB 流同时开的时候超了。
验证方法:在 viewer 里先把深度流关掉,只开 RGB,如果能开,那就是带宽问题。解决办法:
- 降低分辨率或帧率,比如 RGB 从 1920x1080 降到 1280x720。
- 确认相机插在独立的 USB 3.0 控制器上,不和其它高带宽设备共享。
- 检查线材,换一根确认支持 USB 3.0 的线。
5.3 IMU 数据读不到(D435i/D455 用户)
D435i 和 D455 带 IMU,但很多人发现 viewer 里 IMU 那一栏是灰的。这通常是因为IMU 需要单独的固件支持,且对 USB 带宽有额外要求。
先确认固件版本:
rs-fw-update -l如果固件版本太老,用rs-fw-update -f <固件文件>升级。固件文件从官方发布页下载,注意选对应型号的。
另外,IMU 在 USB 2.0 下是完全不可用的,必须 USB 3.0。如果lsusb -t显示相机挂在 480M 下,IMU 一定读不到。
5.4 编译完 viewer 找不到可执行文件
前面提过,BUILD_GRAPHICAL_EXAMPLES没开的话,编译完是没有realsense-viewer的。但还有一种情况:开了这个选项,cmake 也显示 yes,但make install之后which realsense-viewer还是找不到。
这是因为 viewer 默认安装在/usr/local/bin,而这个路径在某些 Ubuntu 配置下不在普通用户的 PATH 里。检查:
echo $PATH ls /usr/local/bin | grep realsense如果文件在但 PATH 里没有/usr/local/bin,在~/.bashrc里加一行:
export PATH=/usr/local/bin:$PATH然后source ~/.bashrc。
6. 几个能省下大量时间的实操经验
6.1 用 rs-enumerate-devices 做快速诊断
每次改完配置、插拔设备之后,别急着开 viewer,先用rs-enumerate-devices看一眼。这个命令会列出所有识别到的设备、支持的流配置、固件版本。如果它能看到设备,说明底层没问题,viewer 的问题就是 GUI 层面的;如果它看不到,那就是权限或驱动层面的问题。这个二分法能帮你快速定位问题在哪一层。
加-c参数可以看到更详细的流配置:
rs-enumerate-devices -c输出里会列出每个型号支持的分辨率、帧率、格式组合,调参的时候很有参考价值。
6.2 版本回退比死磕新版本更省事
如果你用最新 tag 编译遇到各种奇怪的编译错误,别硬扛,回退到 v2.50.1 试试。这个版本比较老,但对 Ubuntu 20.04 的兼容性经过了大量验证,社区里遇到的问题基本都有现成答案。装老版本的代价是少一些新功能,但对于"能跑起来看图像"这个基本需求来说完全够用。
回退方法:
git checkout v2.50.1 rm -rf build && mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=true -DBUILD_GRAPHICAL_EXAMPLES=true make -j$(nproc) sudo make install && sudo ldconfig6.3 卸载旧版本要彻底
如果你之前用 apt 装过librealsense2,再源码编译会冲突。卸载要彻底:
sudo apt remove --purge librealsense2* realsense-* sudo apt autoremove然后检查/usr/lib/x86_64-linux-gnu/下有没有残留的librealsense2.so,有的话手动删掉。不然运行时可能加载到旧版本的库,表现就是版本号对不上、功能异常。
6.4 记录你的环境信息
最后分享一个习惯:装完之后把关键环境信息记下来,包括内核版本、librealsense 版本、固件版本、USB 连接方式。后面如果换机器或者重装系统,直接照着这份记录来,能省掉大量重复排查的时间。
uname -r rs-enumerate-devices --version rs-fw-update -l lsusb -t | grep -A2 Video这四行输出基本涵盖了所有关键信息。我自己的记录里还加了一行dpkg -l | grep -i realsense,用来确认有没有 apt 残留。
整套流程走下来,顺利的话半小时内能搞定,遇到坑的话可能折腾一两个小时。但只要理解了每个环节的作用,排查起来就有方向,不会像无头苍蝇一样乱试。核心思路就一句话:先确认内核和 USB 没问题,再确认库编译安装没问题,最后确认 udev 权限没问题,这三层依次排查,基本没有解决不了的。