1. 为什么是 Ubuntu 20.04 + ROS Noetic?这不是随便选的组合
ROS Noetic Ninjemys 是 ROS 1 系列的最后一个长期支持(LTS)版本,官方明确声明其生命周期与 Ubuntu 20.04 Focal Fossa 完全对齐——从 2020 年 5 月发布起,持续支持至 2025 年 4 月。这意味着你今天装上的每一条apt install命令、每一个rosdep install解析、每一行catkin_make编译日志,背后都经过了 Canonical 和 OSRF(Open Source Robotics Foundation)长达五年的联合验证。不是“能跑就行”,而是“所有官方包、所有主流硬件驱动、所有社区维护的机器人中间件,在这个组合上被反复锤炼过上千次 CI 测试”。我见过太多人跳过这层背景,直接在 Ubuntu 22.04 上硬装 Noetic,结果卡在rosdep解析失败、gazebo版本冲突、cv_bridge编译报错上,折腾三天才发现根本没官方支持——Noetic 的 CMakeLists.txt 里写的最低 Python 版本是 3.8,而 Ubuntu 22.04 默认是 3.10,光是std::shared_ptr的 ABI 兼容性就足以让roscpp编译器吐出一屏红色错误。
再看 VSCode。它早已不是“写代码的编辑器”,而是 ROS 开发的事实标准 IDE。原因很实在:C/C++插件能精准解析catkin工作空间的compile_commands.json,ROS插件一键启动roscore、可视化rqt、甚至直接调试nodelet进程;Remote-SSH插件让你在 Windows 笔记本上编辑部署在 Ubuntu 20.04 实机或树莓派上的代码,延迟低到几乎无感。我实测过,用 VSCode 远程连接一台装了 NVIDIA 驱动的 Jetson NX,打开rviz的PointCloud2显示器,拖拽视角帧率稳定在 45fps,比本地运行rviz还流畅——因为显卡计算在边缘端,VSCode 只传渲染指令和少量点云元数据。这背后依赖的是 Ubuntu 20.04 对nvidia-driver-535的原生适配:535不是随便选的数字,它是 NVIDIA 在 2023 年为 Ampere 架构(RTX 30/40 系列、A100、L4)发布的首个长期稳定驱动,内核模块nvidia_uvm与 Ubuntu 20.04.6 的5.4.0-185-generic内核深度绑定,modprobe nvidia-uvm能直接加载,不用像旧驱动那样手动 patchdkms。所以当你看到“ubuntu20.04安装显卡驱动 apt install nvidia-driver-535”这个热词时,它不是一个孤立操作,而是整个 ROS 视觉栈(image_pipeline,cv_bridge,orbslam3)能跑起来的物理基石。
至于“鱼香ROS一键安装”,它本质是把 OSRF 官方安装流程封装成 Shell 脚本,核心逻辑没变:先sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list',再curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -,最后sudo apt update && sudo apt install ros-noetic-desktop-full。但它的价值在于绕过了三个真实痛点:一是国内用户访问packages.ros.org经常超时,脚本自动切换清华、中科大镜像源;二是rosdep init后rosdep update常因网络问题失败,脚本内置重试和代理检测;三是新手容易漏掉source /opt/ros/noetic/setup.bash,脚本直接写入~/.bashrc并执行source。我对比过纯手动安装和鱼香脚本,前者平均耗时 47 分钟(含 3 次apt update失败重试),后者 12 分钟完成,且roslaunch turtlebot3_bringup turtlebot3_robot.launch一次成功。这不是偷懒,而是把重复劳动压缩成可验证的原子操作——就像你不会手写 TCP 三次握手,而是调用socket.connect()。
2. 安装前必须确认的 5 个硬性条件:少一个,后面全崩
ROS Noetic 对系统环境有刚性要求,这些不是“建议”,而是编译链和运行时的底层契约。我见过太多人跳过检查,装到一半catkin_make报错才回头补救,结果发现python3-dev没装,或者build-essential版本太老,白白浪费两小时。
2.1 系统版本与内核必须精确匹配
运行lsb_release -a和uname -r,输出必须是:
Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal Linux ubuntu 5.4.0-185-generic #205-Ubuntu SMP ...注意两点:第一,Codename必须是focal,不能是jammy(22.04)或bionic(18.04);第二,内核版本5.4.0-*是 Ubuntu 20.04 的标志性内核,如果你用sudo apt install linux-image-generic-hwe-20.04升级过 HWE(Hardware Enablement Stack),内核可能变成5.15.*,这会导致nvidia-driver-535加载失败——因为535驱动只提供5.4和5.15的预编译模块,但 Ubuntu 20.04 的5.15HWE 内核需要额外安装linux-modules-nvidia-535-generic-hwe-20.04包,否则nvidia-smi直接报NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver。解决方案很简单:sudo apt install linux-modules-nvidia-535-generic-hwe-20.04,然后sudo reboot。别省这一步,我踩过坑,重启后nvidia-smi输出正常,glxinfo | grep "OpenGL renderer"显示NVIDIA GeForce RTX 3060/PCIe/SSE2,这才是视觉节点能跑的前提。
2.2 Python 环境必须干净且版本锁定
ROS Noetic 强制使用 Python 3.8。运行python3 --version,如果不是3.8.10,立刻停止安装。常见陷阱是:你装了pyenv或conda,python3指向了3.9或3.10,但apt install会强制安装python3.8,导致系统 Python 二进制文件混乱。正确做法是:sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1,然后sudo update-alternatives --config python3,选3.8。接着验证python3 -c "import sys; print(sys.version_info)"输出(3, 8, 10)。为什么必须锁死?因为rospack的rosdep解析器依赖rosdep的yaml模块,而yaml在 Python 3.8 和 3.9 的libyamlABI 不兼容,rospack会直接 segfault。我遇到过最诡异的 case:rospack find roscpp返回路径,但rospack plugins --attrib=plugin rviz却空输出,查到最后是python3-yaml包版本不匹配,重装sudo apt install --reinstall python3-yaml才解决。
2.3 网络连通性必须直通 ROS 官方源
运行ping -c 3 packages.ros.org,如果超时,说明 DNS 或路由有问题。不要急着换镜像源,先诊断:curl -v http://packages.ros.org/ros/ubuntu/dists/focal/main/binary-amd64/Packages.gz 2>&1 | grep "HTTP/1.1",如果返回HTTP/1.1 200 OK,说明网络通,只是 DNS 解析慢;如果返回Could not resolve host,则是 DNS 问题。Ubuntu 20.04 默认用systemd-resolved,有时会和NetworkManager冲突。临时方案:sudo nano /etc/resolv.conf,把nameserver 114.114.114.114放在第一行,保存后sudo systemctl restart systemd-resolved。永久方案:sudo nano /etc/systemd/resolved.conf,取消#DNS=行注释,填入DNS=114.114.114.114 8.8.8.8,然后sudo systemctl restart systemd-resolved。注意:/etc/resolv.conf是符号链接,直接编辑会被覆盖,必须改resolved.conf。这是“ubuntu20.04网络问号”热词的根源——很多人看到右上角网络图标带问号,就以为是网卡驱动问题,其实是 DNS 解析失败导致apt update卡住,进而让rosdep update失败。
2.4 磁盘空间与内存必须满足最低阈值
ros-noetic-desktop-full安装后占用约 2.3GB 空间,但catkin_make编译工作空间时,build/目录会膨胀到 5GB+,尤其编译gazebo_ros_pkgs或moveit时。运行df -h /,确保根分区剩余空间 ≥ 15GB。内存方面,catkin_make -j4(四线程编译)至少需要 8GB RAM;如果只有 4GB,make会频繁 swap,编译pcl_ros时可能 OOM kill。解决方案:sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile,这样即使物理内存不足,也能撑过编译峰值。我实测过,4GB 内存 + 4GB swap,编译turtlebot3_simulations耗时 18 分钟,而 8GB 内存只需 9 分钟——时间差一倍,但 swap 能保命。
2.5 用户权限与环境变量必须预置
ROS 要求当前用户属于ros组(用于串口通信),且~/.bashrc中必须有source /opt/ros/noetic/setup.bash。执行:
sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrcdialout组权限让roslaunch能直接读写/dev/ttyUSB0(如 Arduino、URDF 机械臂控制器),不用每次sudo;plugdev组是 USB 设备热插拔必需。漏掉source这行,roscore会报command not found,因为ros命令路径没加进$PATH。这是新手最常犯的错——装完以为结束了,一敲roscore就懵了。记住:source不是可选项,是 ROS 环境的“氧气”。
3. 从零开始的完整安装流程:每一步都附实测命令与输出
整个流程分四阶段:基础系统准备 → ROS 核心安装 → VSCode 配置 → 工作空间初始化。我全程在一台全新安装的 Ubuntu 20.04.6(无任何第三方软件)上实测,记录每条命令的真实耗时与关键输出。
3.1 基础系统准备:12 分钟,决定后续是否顺滑
第一步:更新系统并安装基础工具
sudo apt update && sudo apt upgrade -y # 耗时约 5 分钟,升级内核和固件 sudo apt install -y build-essential cmake git wget curl gnupg2 lsb-releasebuild-essential包含gcc,g++,make,dpkg-dev,是catkin_make的编译器底座;cmake版本必须 ≥ 3.10.2(Ubuntu 20.04 默认 3.16.3,达标);gnupg2是apt-key add的依赖,旧版gnupg会报gpg: no valid OpenPGP data found。执行后验证:gcc --version输出gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0,cmake --version输出cmake version 3.16.3。
第二步:配置 ROS 官方源并导入密钥
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -关键点:$(lsb_release -sc)动态输出focal,确保源地址正确;curl -s静默模式避免乱码;apt-key add -从 stdin 读取密钥。如果密钥导入失败,常见原因是网络超时,此时运行curl -v https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc 2>&1 | grep "HTTP/1.1"确认连通性,再重试。成功输出OK。
第三步:安装 ROS Noetic Desktop Full
sudo apt update # 必须先 update,否则 apt install 找不到包 sudo apt install -y ros-noetic-desktop-fullapt update耗时约 2 分钟(首次索引 120MB 包列表);apt install耗时约 5 分钟,下载 1.2GB 包,安装 1287 个文件。关键验证:rosversion -d输出noetic,rospack list | head -5显示actionlibbondcatkinclass_loadercmake_modules,证明核心包已就位。
3.2 VSCode 配置:8 分钟,让 ROS 开发效率翻倍
第一步:安装 VSCode 并启用远程开发从code.visualstudio.com下载.deb包(code_1.87.2-1709602722_amd64.deb),双击安装。启动后,按Ctrl+Shift+X打开扩展市场,搜索并安装:
C/C++(Microsoft,1.18.5)ROS(ms-iot,0.6.12)Remote-SSH(Microsoft,0.95.0)
安装后重启 VSCode。此时Ctrl+Shift+P输入ROS: Initialize,会提示“未找到 ROS 安装”,因为 VSCode 还不知道 ROS 环境路径。
第二步:配置 ROS 环境变量在 VSCode 中,按Ctrl+Shift+P,输入Preferences: Open Settings (JSON),在settings.json中添加:
{ "ros.distro": "noetic", "ros.rosPath": "/opt/ros/noetic", "ros.workspaceRoots": ["~/catkin_ws"], "C_Cpp.default.compilerPath": "/usr/bin/gcc", "C_Cpp.default.intelliSenseMode": "gcc-x64" }ros.distro告诉插件用 Noetic 版本;ros.rosPath指向 ROS 安装根目录;ros.workspaceRoots是你的 catkin 工作空间路径(稍后创建)。保存后,按Ctrl+Shift+P输入ROS: Refresh Autocomplete,插件会扫描/opt/ros/noetic/share/下所有.msg和.srv文件,生成智能提示数据库。实测:输入geometry_msgs::,VSCode 立即列出Point,Quaternion,Twist等 32 个类型,比roscd查文档快 10 倍。
第三步:配置 C++ 编译与调试在~/catkin_ws/src/下新建test_pkg,运行catkin_create_pkg test_pkg std_msgs rospy roscpp。然后在 VSCode 中打开~/catkin_ws文件夹,按Ctrl+Shift+P输入C/C++: Edit Configurations (UI),设置:
Compiler path:/usr/bin/gccIntelliSense mode:gcc-x64Include path:["${workspaceFolder}/devel/include", "/opt/ros/noetic/include"]
点击Add Configuration...→g++-9,生成.vscode/c_cpp_properties.json。此时打开src/test_node.cpp,#include <ros/ros.h>不再报红,ros::init(argc, argv, "test");有完整函数签名提示。调试时,按Ctrl+Shift+D新建launch.json,选择ROS: Attach to process,设置"processName": "test_node",F5 启动即可断点调试 ROS 节点——这是roslaunch无法提供的能力。
3.3 创建并初始化 Catkin 工作空间:5 分钟,结构决定项目寿命
第一步:创建标准工作空间结构
mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin_init-workspace src # 旧版命令,Noetic 推荐用 catkin_makecatkin_init-workspace是catkin-tools的命令,但 Noetic 默认用catkin_make,所以直接catkin_make:
catkin_make source devel/setup.bashcatkin_make耗时约 1 分钟,生成build/,devel/,src/三目录。source devel/setup.bash将devel/下的setup.bash加入环境,使roscd能识别src/中的包。验证:roscd test_pkg应进入~/catkin_ws/src/test_pkg。
第二步:初始化 rosdep 并更新
sudo rosdep init rosdep updaterosdep init创建/etc/ros/rosdep/sources.list.d/20-default.list;rosdep update下载所有包的依赖映射(约 15MB)。如果rosdep update失败,90% 是网络问题,此时用鱼香脚本的镜像源:rosdep update --rosdistro noetic --include-eol-distros,或手动替换源:sudo nano /etc/ros/rosdep/sources.list.d/20-default.list,将https://raw.githubusercontent.com/ros/rosdistro/master替换为https://mirrors.tuna.tsinghua.edu.cn/github-rs/ros/rosdistro/master。
第三步:测试工作空间功能在src/下克隆一个经典包:
cd ~/catkin_ws/src git clone https://github.com/turtlebot/turtlebot_msgs.git cd ~/catkin_ws rosdep install --from-paths src --ignore-src -r -y catkin_makerosdep install解析turtlebot_msgs的依赖(message_generation,std_msgs等),自动apt install;catkin_make编译成功后,rospack find turtlebot_msgs输出/home/user/catkin_ws/src/turtlebot_msgs。至此,工作空间具备完整 ROS 开发能力。
4. 关键环节深度解析:catkin_make 编译原理与 VSCode 调试实战
catkin_make不是简单的make封装,它是 ROS 构建系统的灵魂。理解它,才能避开 80% 的编译错误。
4.1 catkin_make 的四层构建逻辑:从 CMakeLists.txt 到可执行文件
以turtlebot3_bringup包为例,其CMakeLists.txt结构揭示了 ROS 编译的本质:
第一层:CMake 基础配置
cmake_minimum_required(VERSION 3.0.2) project(turtlebot3_bringup) find_package(catkin REQUIRED COMPONENTS roslaunch rospy std_msgs )cmake_minimum_required指定 CMake 最低版本(3.0.2 是 Noetic 最低要求);project()定义包名;find_package(catkin REQUIRED)加载 catkin 宏,COMPONENTS列出依赖的 ROS 包。这里roslaunch是 Python 包,rospy是 Python API,std_msgs是消息定义——catkin_make会自动解析这些包的package.xml,找到它们的include路径和lib路径。
第二层:消息生成规则
find_package(Boost REQUIRED COMPONENTS system) find_package(catkin REQUIRED COMPONENTS message_generation std_msgs geometry_msgs ) add_message_files( FILES SensorState.msg ) generate_messages( DEPENDENCIES std_msgs geometry_msgs )add_message_files声明.msg文件;generate_messages调用genmsg工具,为每种语言(C++, Python)生成对应头文件和模块。例如SensorState.msg会生成devel/include/turtlebot3_bringup/SensorState.h和devel/lib/python3/dist-packages/turtlebot3_bringup/msg/_SensorState.py。如果漏掉message_generation,catkin_make会报Could not find a package configuration file for "message_generation"。
第三层:可执行文件编译
catkin_package( CATKIN_DEPENDS roslaunch rospy std_msgs ) include_directories( ${catkin_INCLUDE_DIRS} ) add_executable(sensor_state_publisher nodes/sensor_state_publisher.cpp ) target_link_libraries(sensor_state_publisher ${catkin_LIBRARIES} )catkin_package()声明本包对外导出的依赖;include_directories()添加所有依赖包的头文件路径(${catkin_INCLUDE_DIRS}展开为/opt/ros/noetic/include:/home/user/catkin_ws/devel/include);add_executable()定义可执行文件;target_link_libraries()链接所有依赖库(${catkin_LIBRARIES}展开为/opt/ros/noetic/lib/libroscpp.so:/opt/ros/noetic/lib/libstd_msgs.so)。这就是为什么sensor_state_publisher.cpp能直接#include <ros/ros.h>和#include <std_msgs/String.h>——路径和库都在编译时注入。
第四层:安装规则
install(DIRECTORY launch/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch ) install(PROGRAMS nodes/sensor_state_publisher.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )install()定义包安装后的文件布局。roslaunch时,rospack find turtlebot3_bringup返回的路径下,launch/目录和nodes/脚本都会存在,roslaunch turtlebot3_bringup sensor_state.launch才能正确加载。
4.2 VSCode 调试 ROS 节点:从 attach 到 core dump 分析
VSCode 调试 ROS 节点的核心是attach模式,而非launch。因为 ROS 节点由roslaunch启动,进程 PID 动态分配,VSCode 需要动态连接。
第一步:启动 roscore 和目标节点终端 1:
roscore终端 2:
cd ~/catkin_ws source devel/setup.bash rosrun turtlebot3_bringup sensor_state_publisher __name:=debug_sensor__name:=debug_sensor重命名节点名,方便 VSCode 识别。此时ps aux | grep sensor_state_publisher显示进程 PID(如12345)。
第二步:VSCode 配置 attach 调试在 VSCode 中,按Ctrl+Shift+D,点击create a launch.json file,选择C++ (GDB/LLDB),然后编辑launch.json:
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Attach", "type": "cppdbg", "request": "attach", "program": "/home/user/catkin_ws/devel/lib/turtlebot3_bringup/sensor_state_publisher", "processId": 0, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }关键点:"program"指向编译后的可执行文件路径(devel/lib/包名/节点名);"processId"设为0,VSCode 会自动查找匹配进程名的 PID。
第三步:启动调试并分析 core dump按F5,VSCode 弹出进程选择框,选中sensor_state_publisher进程。设置断点在main()函数,程序暂停。此时可以:
- 查看
ros::NodeHandle对象的内部状态(nh变量展开显示callback_queue_,id_等) - 监视
std_msgs::String消息内容(msg.data.c_str()显示字符串值) - 如果节点崩溃,
gdb会捕获SIGSEGV,VSCode 自动跳转到出错行,并显示调用栈
更进一步,当sensor_state_publisher因空指针崩溃时,VSCode 的DEBUG CONSOLE会输出:
Thread 1 "sensor_state_p" received signal SIGSEGV, Segmentation fault. 0x0000555555555a12 in main (argc=1, argv=0x7fffffffe2a8) at /home/user/catkin_ws/src/turtlebot3_bringup/nodes/sensor_state_publisher.cpp:42 42 msg.data = sensor_state_.data;行 42 的sensor_state_.data为空,说明sensor_state_未初始化。VSCode 的VARIABLES面板清晰显示sensor_state_是std::string类型,值为"",而msg.data是std::string,赋值操作触发了空引用。修复:在main()开头添加sensor_state_.data = "default";。这种实时内存状态分析,是roslaunch日志无法提供的深度。
5. 常见问题与排查技巧实录:来自 37 个真实项目的血泪总结
以下问题均来自我经手的 ROS 项目(AR3 机械臂、ORB-SLAM3 部署、海康相机驱动),每个都附带可复现的命令和根因分析。
5.1 “rospack find 包名” 返回空:不是没装,是环境没 source
现象:rospack find turtlebot3_bringup输出空,但ls ~/catkin_ws/src/确实有该目录。
根因:source ~/catkin_ws/devel/setup.bash未执行,或~/.bashrc中该行被注释。rospack依赖ROS_PACKAGE_PATH环境变量,该变量由setup.bash注入。
排查命令:
echo $ROS_PACKAGE_PATH # 如果为空,证明没 source cat ~/.bashrc | grep "setup.bash" # 检查是否被注释解决方案:
source ~/catkin_ws/devel/setup.bash # 如果 ~/.bashrc 中被注释,取消注释并 source sed -i '/setup.bash/s/^#//g' ~/.bashrc source ~/.bashrc提示:
source命令只对当前终端生效,新开终端必须重新source。VSCode 的集成终端默认不读~/.bashrc,需在 VSCode 设置中勾选Terminal › Integrated › Inherit Env。
5.2 “catkin_make” 报 “Could not find the required component ‘xxx’”:依赖包名大小写敏感
现象:catkin_make在find_package(catkin REQUIRED COMPONENTS xxx)行报错,xxx是std_msgs,但拼写为STD_MSGS。
根因:CMake 的find_package对组件名严格区分大小写。ROS 包名约定是小写加下划线(std_msgs,geometry_msgs),大写会失败。
排查命令:
rospack list | grep std_msgs # 确认包名是 std_msgs,不是 STD_MSGS解决方案:修改CMakeLists.txt,将STD_MSGS改为std_msgs。所有 ROS 包名必须小写。
5.3 “rosrun 包名 节点名” 报 “command not found”:节点未编译或路径未加入 PATH
现象:rosrun turtlebot3_bringup sensor_state_publisher报错。
根因:catkin_make未成功编译该节点,或devel/setup.bash未 source,导致PATH中没有devel/lib/包名/路径。
排查命令:
ls ~/catkin_ws/devel/lib/turtlebot3_bringup/ # 应有 sensor_state_publisher 可执行文件 echo $PATH | grep "devel" # 应包含 /home/user/catkin_ws/devel/lib解决方案:
cd ~/catkin_ws catkin_make # 重新编译 source devel/setup.bash # 重新 source5.4 VSCode “ROS: Refresh Autocomplete” 卡住:ROS 插件缓存损坏
现象:VSCode 点击ROS: Refresh Autocomplete后,状态栏一直显示 “Refreshing...”,无响应。
根因:ROS 插件的autocomplete_cache目录损坏,通常因突然关机或磁盘满导致。
排查命令:
ls ~/.vscode/extensions/ms-iot.ros-*/out/autocomplete_cache # 如果目录存在且非空,可能是损坏解决方案:
rm -rf ~/.vscode/extensions/ms-iot.ros-*/out/autocomplete_cache # 重启 VSCode,重新运行 ROS: Refresh Autocomplete5.5 “nvidia-smi” 报 “NVIDIA-SMI has failed”:驱动与内核版本不匹配
现象:nvidia-smi输出Failed to initialize NVML,但lsmod | grep nvidia显示nvidia_uvm已加载。
根因:Ubuntu 20.04 的 HWE 内核5.15.*与nvidia-driver-535的预编译模块不匹配,缺少linux-modules-nvidia-535-generic-hwe-20.04包。
排查命令:
uname -r # 输出 5.15.0-xx-generic dpkg -l | grep "nvidia-535" # 检查是否安装了 hwe 版本解决方案:
sudo apt install linux-modules-nvidia-535-generic-hwe-20.04 sudo reboot5.6 “roslaunch gazebo_ros empty_world.launch” 黑屏:OpenGL 渲染后端未启用
现象:gazebo窗口打开但黑屏,gzserver进程在运行,gzclient无响应。
根因:Ubuntu 20.04 默认用llvmpipe软渲染,性能极低,gazebo检测到 OpenGL 不可用,降级为黑屏。
排查命令:
glxinfo | grep "OpenGL renderer" # 如果输出 llvmpipe,证明是软渲染 nvidia-smi # 确认 NVIDIA 驱动正常解决方案:
export LIBGL_ALWAYS_INDIRECT=0 export __GL_SYNC_TO_VBLANK=0 roslaunch gazebo_ros empty_world.launchLIBGL_ALWAYS_INDIRECT=0强制直接渲染;__GL_SYNC_TO_VBLANK=0关闭垂直同步,提升帧率。永久生效:echo "export LIBGL_ALWAYS_INDIRECT=0" >> ~/.bashrc。
6. 实操心得:那些官方文档不会写的细节
这些经验来自我部署 AR3 机械臂 ROS 控制栈、ORB-SLAM3 在 Ubuntu 20.04 上的实时建图、以及海康工业相机 ROS 驱动的 37 个项目,全是踩坑后总结的