Docker + tmux + ROS:持久化的机器人开发环境
在机器人开发中,我们经常需要同时运行多个终端:roscore、相机驱动、标定节点、可视化工具......传统方式下,一旦 SSH 断开或终端关闭,所有进程都会终止。本文将介绍如何利用 Docker 和 tmux 构建一个持久化、可恢复的 ROS 开发环境,特别适合手眼标定这类需要长时间运行的任务。
一、为什么需要 Docker + tmux?
| 工具 | 解决的问题 |
|---|---|
| Docker | 环境隔离、依赖管理、跨平台部署 |
| tmux | 终端复用、会话持久化、多任务管理 |
两者结合的优势:
- 会话不丢失:即使退出容器,程序仍在后台运行
- 多窗格布局:在一个终端内同时监控多个进程
- 环境可复现:通过 Dockerfile 固化开发环境
二、环境准备
2.1 启动 Docker 容器
启动一个带有 ROS Noetic 的容器,并配置必要的权限以支持相机和图形界面:
bash
docker run -it \
--name test-tmux \
--network host \
--privileged \
-v /dev/bus/usb:/dev/bus/usb \
-v /tmp/.X11-unix:/tmp/.X11-unix \
osrf/ros:noetic-desktop-full \
/bin/bash
参数说明:
| 参数 | 作用 |
|---|---|
--network host |
使用宿主机网络,ROS 节点通信必需 |
--privileged |
访问 USB 设备(如 RealSense 相机) |
-v /dev/bus/usb:/dev/bus/usb |
挂载 USB 设备到容器 |
-v /tmp/.X11-unix:/tmp/.X11-unix |
支持 GUI 显示(rviz、rqt) |
⚠️ 如果镜像未预装 tmux,进入容器后执行
apt update && apt install tmux -y安装。
2.2 安装 tmux
在容器内执行以下命令安装 tmux:
bash
# 更新软件包列表
sudo apt update
# 安装 tmux
sudo apt install tmux -y
# 验证安装
tmux -V
# 输出示例:tmux 3.0a
三、tmux 核心操作
3.1 创建会话
bash
# 创建名为 calibration 的新会话
tmux new -s calibration
3.2 窗格管理
在 tmux 会话中,可以像拼图一样拆分多个窗格,每个窗格运行一个独立的进程。
| 操作 | 快捷键 |
|---|---|
| 水平分屏(上下拆分) | Ctrl+b " |
| 垂直分屏(左右拆分) | Ctrl+b % |
| 切换窗格 | Ctrl+b o 或 Ctrl+b 方向键 |
| 关闭当前窗格 | Ctrl+b x |
| 最大化当前窗格 | Ctrl+b z |
3.3 会话管理
| 操作 | 命令/快捷键 |
|---|---|
| 分离会话(后台运行) | Ctrl+b d |
| 列出所有会话 | tmux ls |
| 重新连接会话 | tmux a -t calibration |
| 删除会话 | tmux kill-session -t calibration |
四、实战:启动 ROS 标定环境
以下是一个典型的 ROS 标定任务布局,展示如何在 tmux 中组织多个进程。
4.1 创建会话并启动 roscore
bash
tmux new -s calibration
# 在默认窗格中执行
roscore
4.2 水平分屏启动相机驱动
# 按 Ctrl+b, " # 水平分屏
# 光标自动移动到下方新窗格
bash
# 在下方窗格执行
roslaunch realsense2_camera rs_camera.launch
4.3 垂直分屏启动标定节点
# 按 Ctrl+b, % # 垂直分屏
# 光标移动到右侧新窗格
bash
# 在右侧窗格执行
rosrun industrial_extrinsic_cal calibration_service.launch
最终布局如下:
┌─────────────────┬─────────────────┐
│ roscore │ 标定节点 │
├─────────────────┼─────────────────┤
│ 相机驱动 │ (可继续扩展) │
└─────────────────┴─────────────────┘
五、容器与会话的持久化工作流
5.1 安全退出(不终止进程)
# 1. 在 tmux 中分离会话
Ctrl+b, d
# 2. 退出容器
exit
此时,容器仍在运行,tmux 会话和其中的所有进程都在后台继续执行。
5.2 重新连接
bash
# 启动容器(如果之前已停止)
docker start test-tmux
# 重新进入容器
docker exec -it test-tmux /bin/bash
# 重新连接 tmux 会话
tmux a -t calibration
你的程序状态完全恢复,就像从未离开过一样!
六、进阶配置
6.1 自定义 tmux 配置
创建 ~/.tmux.conf 文件,提升使用体验:
bash
# 启用鼠标支持(可点击切换窗格、滚动)
set -g mouse on
# 状态栏美化
set -g status-bg black
set -g status-fg white
set -g window-status-current-bg red
set -g window-status-current-fg white
# 使用 Ctrl+a 作为前缀(可选,避免与 Ctrl+b 冲突)
# unbind C-b
# set -g prefix C-a
# bind C-a send-prefix
# 分屏后自动调整窗口大小
set -g aggressive-resize on
6.2 一键启动脚本
创建 start_calibration.sh,实现一键进入标定环境:
bash
#!/bin/bash
# 启动容器(如果不存在则创建)
if [ ! "$(docker ps -a -q -f name=calibration)" ]; then
docker run -itd \
--name calibration \
--network host \
--privileged \
-v /dev/bus/usb:/dev/bus/usb \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v /home/ubuntu/catkin_ws:/workspace \
osrf/ros:noetic-desktop-full \
tmux new -s calibrate
fi
# 进入容器并连接会话
docker exec -it calibration tmux a -t calibrate
赋予执行权限并运行:
bash
chmod +x start_calibration.sh
./start_calibration.sh
七、总结
通过 Docker 和 tmux 的结合,我们实现了:
| 需求 | 解决方案 |
|---|---|
| 环境隔离 | Docker 容器封装 ROS 环境 |
| 会话持久化 | tmux 分离/重连机制 |
| 多进程管理 | tmux 窗格布局 |
| 设备访问 | Docker 挂载 USB 和 X11 |
这套方案特别适合:
- 手眼标定等长时间运行的任务
- 远程开发(SSH 断开不受影响)
- 团队协作(多人可共享 tmux 会话)
现在,你可以放心地启动标定程序,关闭终端回家,第二天回来重新连接,一切如初。这就是 Docker + tmux 的魅力所在!