目标检测与跟踪(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 服务实现开机自启、进程守护、失败重启
环境依赖正确配置 DISPLAY 和 XAUTHORITY(如果节点需要 GUI)

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

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

/home/your_user/catkin_ws/src/vision_node/scripts/vision_node.py

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

#!/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

赋予脚本执行权限:

sudo chmod +x /home/your_user/start_vision_node.sh

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

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

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

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

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,可删除 DISPLAY 和 XAUTHORITY 行

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


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

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

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

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

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

    mkdir -p ~/.config/systemd/user
    cp /etc/systemd/system/vision_node.service ~/.config/systemd/user/

  2. 修改用户级服务文件中的 After 和 WantedBy

    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. 启用并启动:

    systemctl --user enable vision_node.service
    systemctl --user start vision_node.service

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

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

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

sudo apt install xvfb

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

exec xvfb-run -a rosrun vision_node vision_node.py

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

# 重新加载 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 服务(见第四节),或在服务文件中正确设置 DISPLAY 和 XAUTHORITY 并允许 X11 连接:

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 权限
依赖 roscoreAfter 和 Requires 控制启动顺序

最后提醒

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Techblog of HaoWANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值