目标检测与跟踪(16)-- Ubuntu 20.04 下 ROS1 + Conda 虚拟环境开机自启动方案(兼容 ROS2 共存)

引言:

🔥 在同时安装了 ROS1 Noetic 和 ROS2 Foxy 的 Ubuntu 20.04 系统上,开发基于 ROS1 的视觉节点时,常面临两大痛点:
① 每次手动激活 Conda 虚拟环境 + 加载 ROS1 环境
② 节点需要开机自启动,且必须保证 ROS1 环境不被 ROS2 干扰

本文提供一套经过验证的自动化方案,通过 systemd 服务 + 智能环境切换脚本 ,实现视觉节点的 开机自启动、环境隔离、自动重启,让你的机器人项目真正实现"一键部署、无人值守"。


📌 目录

  1. 整体思路

  2. 第一步:编写视觉节点启动脚本

  3. 第二步:创建 roscore 系统服务(可选但推荐)

  4. 第三步:创建视觉节点 systemd 服务

  5. 第四步:处理图形界面显示问题(若需要显示窗口)

  6. 第五步:启用并测试服务

  7. 常见问题与调试技巧

  8. 总结


1. 整体思路

模块 作用
启动脚本 清理 ROS2 环境变量 → 加载 ROS1 环境 → 激活 Conda 环境 → 运行视觉节点
roscore 服务 确保 ROS 核心在视觉节点前启动,并支持自动重启
systemd 服务 实现开机自启、进程守护、失败重启
环境依赖 正确配置 DISPLAYXAUTHORITY(如果节点需要 GUI)

2. 第一步:编写视觉节点启动脚本

假设你的 Conda 环境名为 vision_env,视觉节点脚本位于:

复制代码
/home/your_user/catkin_ws/src/vision_node/scripts/vision_node.py

创建文件 /home/your_user/start_vision_node.sh,内容如下:

bash 复制代码
#!/bin/bash

### 1. 清理可能冲突的 ROS 环境变量(防止 ROS2 干扰)
unset ROS_DISTRO ROS_PACKAGE_PATH ROS_MASTER_URI ROS_ROOT ROS_ETC_DIR
unset CMAKE_PREFIX_PATH AMENT_PREFIX_PATH PYTHONPATH

### 2. 加载 ROS1 Noetic 环境
source /opt/ros/noetic/setup.bash
# 如果有自定义工作空间,也加载它
source /home/your_user/catkin_ws/devel/setup.bash

### 3. 初始化 conda 并激活虚拟环境
# 注意:将下面的路径替换为你实际的 conda 安装路径
source /home/your_user/anaconda3/etc/profile.d/conda.sh
conda activate vision_env

### 4. 等待 roscore 就绪(最多等待 30 秒)
timeout=30
while ! rostopic list > /dev/null 2>&1; do
    sleep 1
    timeout=$((timeout-1))
    if [ $timeout -le 0 ]; then
        echo "[ERROR] roscore 未启动,退出"
        exit 1
    fi
done

### 5. 运行视觉节点
export ROS_MASTER_URI=http://localhost:11311
cd /home/your_user/catkin_ws
exec rosrun vision_node vision_node.py
# 如果是独立 Python 脚本,也可以用:
# exec python /home/your_user/catkin_ws/src/vision_node/scripts/vision_node.py

⚠️ 务必修改

  • /home/your_user/ 替换为你的实际用户目录

  • anaconda3 替换为你的 conda 安装名(如 miniconda3

  • vision_env 替换为你的 Conda 环境名

  • 确保 vision_node.py 具有可执行权限:chmod +x /path/to/vision_node.py

赋予脚本执行权限:

bash 复制代码
sudo chmod +x /home/your_user/start_vision_node.sh

3. 第二步:创建 roscore 系统服务(可选但推荐)

将 roscore 做成独立服务,便于管理和依赖控制。

创建文件 /etc/systemd/system/roscore.service

bash 复制代码
ini

[Unit]
Description=ROS1 roscore
After=network.target

[Service]
Type=simple
User=your_user
Environment="ROS_MASTER_URI=http://localhost:11311"
ExecStart=/opt/ros/noetic/bin/roscore
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target
复制代码

4. 第三步:创建视觉节点 systemd 服务

创建文件 /etc/systemd/system/vision_node.service

bash 复制代码
ini

[Unit]
Description=Vision Node with ROS1 and Conda
After=roscore.service network.target
Requires=roscore.service   # 确保 roscore 先启动

[Service]
Type=simple
User=your_user
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/your_user/.Xauthority"
Environment="QT_X11_NO_MITSHM=1"
ExecStart=/home/your_user/start_vision_node.sh
Restart=on-failure
RestartSec=5
WorkingDirectory=/home/your_user

# 日志输出到 journald
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
复制代码

📌 说明

  • 若节点不需要 GUI ,可删除 DISPLAYXAUTHORITY

  • 若需要访问摄像头等硬件,可能需要添加 User=your_user 并加入 video 组:
    sudo usermod -aG video your_user


5. 第四步:处理图形界面显示问题(若需要显示窗口)

如果你的视觉节点会弹出图像窗口(例如 cv2.imshowrviz 等),需要解决 systemd 服务无法访问 X11 显示 的问题。

🔹 方法一:使用用户级 systemd 服务(推荐,依赖图形会话)

将服务文件放到用户目录下,并改为**--user** 模式。

  1. 复制服务文件到用户配置目录:

    bash 复制代码
    mkdir -p ~/.config/systemd/user
    cp /etc/systemd/system/vision_node.service ~/.config/systemd/user/
  2. 修改用户级服务文件中的 AfterWantedBy

    bash 复制代码
    ini
    
    [Unit]
    Description=Vision Node with ROS1 and Conda
    After=graphical-session.target   # 等待图形会话启动
    
    [Service]
    Type=simple
    Environment="DISPLAY=:0"
    Environment="XAUTHORITY=%h/.Xauthority"
    ExecStart=/home/your_user/start_vision_node.sh
    Restart=on-failure
    
    [Install]
    WantedBy=default.target
    复制代码
  3. 启用并启动:

    bash 复制代码
    systemctl --user enable vision_node.service
    systemctl --user start vision_node.service

✅ 优点:自动继承当前登录用户的 X11 权限,无需额外配置。

🔹 方法二:使用 Xvfb 虚拟显示器(无界面场景)

如果不需要实际显示图像,但节点必须运行 GUI 代码,可使用虚拟显示器:

bash 复制代码
sudo apt install xvfb

修改启动脚本,在运行节点前加上 xvfb-run

bash 复制代码
exec xvfb-run -a rosrun vision_node vision_node.py

6. 第五步:启用并测试服务

bash 复制代码
# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 启动 roscore 服务(若创建了)
sudo systemctl enable roscore.service
sudo systemctl start roscore.service

# 启动视觉节点服务
sudo systemctl enable vision_node.service
sudo systemctl start vision_node.service

# 查看服务状态
sudo systemctl status vision_node.service

# 实时查看日志
journalctl -u vision_node.service -f

如果一切正常,重启系统后视觉节点会自动运行。


7. 常见问题与调试技巧

❌ 问题1:conda: command not found

原因 :非交互式 shell 未加载 conda 初始化脚本。
解决 :在启动脚本中显式 source conda 的 profile.d/conda.sh,如上述代码所示。

❌ 问题2:roscore 未启动,视觉节点卡在等待

原因 :roscore 服务启动较慢。
解决 :在启动脚本中增加等待逻辑(已包含);或修改服务依赖为 After=roscore.service 并去掉脚本中的等待循环。

❌ 问题3:图形窗口无法显示

原因 :systemd 服务默认无法访问 X11。
解决 :改用用户级 systemd 服务(见第四节),或在服务文件中正确设置 DISPLAYXAUTHORITY 并允许 X11 连接:

bash 复制代码
xhost +SI:localuser:your_user   # 一次性命令,重启失效

更稳妥的办法是使用用户级服务。

❌ 问题4:ROS2 环境变量污染,导致 rosrun 找不到包

原因 :系统 .bashrc 中同时 source 了 ROS1 和 ROS2。
解决 :在启动脚本开头强制清理 所有 ROS2 相关环境变量(已包含)。同时确保 .bashrc 中不要自动 source 任何 ROS 环境,或通过条件判断隔离。


8. 总结

通过本方案,你可以在 ROS1/ROS2 共存的 Ubuntu 20.04 上实现:

需求 实现方式
自动激活 Conda 环境 启动脚本中 conda activate
加载 ROS1 环境 清理冲突变量后 source /opt/ros/noetic/setup.bash
开机自启动 systemd 服务 enable
进程守护与自动重启 systemd 的 Restart=on-failure
图形界面支持 用户级 systemd 服务 + X11 权限
依赖 roscore AfterRequires 控制启动顺序

最后提醒

  • 所有路径、用户名、conda 安装目录请根据实际情况修改

  • 先手动执行启动脚本验证无误,再部署为系统服务

  • 若视觉节点需要频繁修改,建议在调试阶段使用用户级服务,方便查看终端输出

将这套方案融入你的机器人项目中,即可享受"开机即用、零人工干预"的 ROS 视觉节点运行体验!

相关推荐
Chengbei111 天前
红队专属Bing Dork自动化工具,敏感信息侦察效率拉满、自动生成可视化信息泄露审计报告
java·人工智能·安全·web安全·网络安全·自动化·系统安全
AI首席情报员_阿布1 天前
Numa:用 Rust 从零造一个 DNS 解析器,顺手解决了开发者最头疼的几件事
人工智能·rust·dns
了不起的云计算V1 天前
2027年信创大考倒计时,联想开天打出“生态+AI”的组合牌
人工智能
财经资讯数据_灵砚智能1 天前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年4月21日
人工智能·python·信息可视化·自然语言处理·ai编程
电子科技圈1 天前
IAR作为Qt Group独立BU携两项重磅汽车电子应用开发方案首秀北京车展
开发语言·人工智能·汽车·软件工程·软件构建·代码规范·设计规范
Lupino1 天前
别让服务器“吃里扒外”:从流量耗尽封禁,到一行命令瞬间反杀
ubuntu
Axis tech1 天前
Xsens:使用惯性动捕技术研究更安全的足球运动训练
人工智能
淹死在鱼塘的程序猿1 天前
🚀 告别"一次性聊天":揭秘让 AI 智能体越用越聪明的秘密武器 —— Skills
前端·人工智能·agent
醉卧考场君莫笑1 天前
NLP(正向,逆向,双向匹配法分词及代码实现)
人工智能·自然语言处理·easyui
w_t_y_y1 天前
Claude Code(二)rules
linux·运维·ubuntu