在Docker容器中运行TaichiSLAM
准备工作:构建包含TaichiSLAM的Docker镜像
原因: 基础ROS镜像不包含TaichiSLAM的代码,你需要创建一个新的镜像,将TaichiSLAM项目克隆并编译进去。
1. 创建一个Dockerfile文件
创建一个名为`Dockerfile`的文件,内容如下:
```dockerfile
FROM osrf/ros:noetic-desktop-full
WORKDIR /root
# 安装必要的依赖项
RUN apt-get update && apt-get install -y \
git \
python3-catkin-tools \
python3-osrf-pycommon \
build-essential \
libboost-all-dev \
libeigen3-dev \
libopencv-dev \
&& rm -rf /var/lib/apt/lists/*
# 克隆TaichiSLAM代码
RUN git clone https://github.com/taichi-dev/TaichiSLAM.git
# 创建并初始化ROS工作空间
RUN mkdir -p /root/taichi_slam_ws/src
RUN mv /root/TaichiSLAM /root/taichi_slam_ws/src/
WORKDIR /root/taichi_slam_ws
RUN catkin_make --cmake-args \
-DCMAKE_BUILD_TYPE=Release \
-DPYTHON_EXECUTABLE=/usr/bin/python3
```
**为什么这样做:** `Dockerfile`定义了如何从基础镜像构建一个新的镜像。这里我们首先安装TaichiSLAM所需的依赖,然后克隆项目代码,并使用`catkin_make`来编译它。这确保了`taichislam_node.py`和相关的可执行文件被正确地生成并添加到ROS的路径中。
2. 构建Docker镜像
在包含`Dockerfile`的目录下执行以下命令:
```bash
docker build -t taichislam-ros:noetic .
```
**为什么这样做:** 这个命令会根据你定义的`Dockerfile`来构建一个名为`taichislam-ros:noetic`的新镜像。一旦构建完成,这个镜像就包含了所有运行TaichiSLAM所需的环境和编译好的代码。
正式运行:三个终端操作步骤
目标: 在三个独立的终端中,分别启动ROS Master、播放rosbag数据,以及运行TaichiSLAM节点,从而模拟一个完整的SLAM系统运行环境。
步骤:
终端 1:启动 ROS Master
命令:
docker run -it --name taichislam-container --rm --net=host -e DISPLAY -e QT_X11_NO_MITSHM=1 -v /tmp/.X11-unix:/tmp/.X11-unix taichislam-ros:noetic bash -c "source /root/taichi_slam_ws/devel/setup.bash && roscore"
为什么这样做:
docker run ...: 启动一个新容器。--name taichislam-container: 给容器命名,方便后续使用docker exec命令进入。--rm: 容器退出时自动移除,保持环境干净。--net=host: 使用宿主机的网络,这对于ROS在多个容器或宿主机与容器之间通信至关重要。-e DISPLAY -e QT_X11_NO_MITSHM=1 -v /tmp/.X11-unix:/tmp/.X11-unix: 这几行是用来启用图形界面(GUI)的,因为TaichiSLAM的show:=true参数需要显示窗口。taichislam-ros:noetic: 使用我们刚刚构建的、包含TaichiSLAM的镜像。bash -c "...": 在容器内执行一个命令。source /root/taichi_slam_ws/devel/setup.bash: 它会把taichi_slam_ws工作空间添加到ROS的环境变量中,让ROS能找到taichislam包。roscore: 启动ROS Master,作为所有ROS节点的中心枢纽。
终端 2:播放 rosbag
命令:
docker exec -it taichislam-container bash -c "source /root/taichi_slam_ws/devel/setup.bash && rosbag play --clock -r 1.0 /bags/taichislam-realsense435.bag"
为什么这样做:
docker exec -it taichislam-container: 进入第一个终端中正在运行的容器。source /root/taichi_slam_ws/devel/setup.bash: 同样地,确保ROS路径正确。rosbag play ...: 播放数据包。请确保/bags/taichislam-realsense435.bag路径在容器内是可访问的。如果文件在你的宿主机上,你需要在docker run命令中用-v参数将宿主机的目录映射到容器内,例如:-v /path/on/host:/bags。
终端 3:启动 TaichiSLAM 节点
命令:
docker exec -it taichislam-container bash -c "source /root/taichi_slam_ws/devel/setup.bash && roslaunch taichislam taichislam-d435.launch show:=true"
为什么这样做:
docker exec -it taichislam-container: 进入同一个容器。source ...: 确保ROS路径正确。roslaunch taichislam taichislam-d435.launch show:=true: 运行taichislam包中的taichislam-d435.launch启动文件。
正确设置了ROS路径,roslaunch可以找到taichislam包,而不报“is not a launch file name”的错误。
教程:Ubuntu 20.04 安装和运行 TaichiSLAM (使用 Docker)
本教程将指导你如何在 Docker 容器中安装和运行 TaichiSLAM。我们将重点关注环境配置、ROS 集成以及解决常见的运行错误。
1. 启动并创建 Docker 容器
首先,我们需要创建一个 taichislam 的 Docker 容器,并进行必要的目录挂载。
docker run -it --name taichislam \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v "$HOME/my_code/TaichiSLAM":/taichislam_ws/src/TaichiSLAM \
-v "$HOME/my_local_data/taichislam-realsense435.bag":/data/taichislam-realsense435.bag \
osrf/ros:noetic-desktop-full bash
--name taichislam: 为容器命名,方便后续管理。-v .../TaichiSLAM":/taichislam_ws/src/TaichiSLAM: 将你本地的 TaichiSLAM 代码挂载到容器内。-v .../taichislam-realsense435.bag":/data/taichislam-realsense435.bag: 挂载你的 ROS bag 文件。-e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix: 重要,这是为了让容器能够连接到你宿主机的图形显示,以便显示rviz等图形界面。- 持久化: 容器启动时不带
--rm参数,退出后会保留。
2. 首次配置容器环境
这是一次性的配置,用于安装 Miniconda、Mamba 和项目所需的 Python 依赖。
-
安装 Miniconda 和 Mamba:
进入容器后,执行以下命令:cd /tmp && \ curl -LO https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \ bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/miniconda # 初始化 Conda 并加载配置 /opt/miniconda/bin/conda init bash && source ~/.bashrc # 配置 Conda 镜像源并安装 Mamba conda config --remove-key channels conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels defaults conda install mamba -c conda-forge -
创建虚拟环境并安装项目依赖:
# 创建名为 'taichislam' 的 Python 3.9 环境 mamba create -n taichislam python=3.9 # 激活环境 conda activate taichislam # 进入项目目录 cd /taichislam_ws/src/TaichiSLAM # 安装 Python 依赖 pip install -r requirements.txt
3. 解决 TaichiSLAM 依赖问题
在运行 TaichiSLAM 之前,可能需要确保所有 ROS 消息包都已正确安装或编译。
-
检查
swarm_msgs: 如果taichislam_node.py报错ImportError: cannot import name 'DroneTraj' from 'swarm_msgs.msg', 说明swarm_msgs包中的消息定义不匹配。- 解决方法:
- 删除旧的构建文件:
cd /taichislam_ws rm -rf build devel - 重新编译工作空间:
这会重新生成所有 ROS 消息文件。如果问题依然存在,可能需要检查# 确保在 Conda 环境中 conda activate taichislam # 确保 ROS 环境已 source source /opt/ros/noetic/setup.bash # 编译 catkin_makeswarm_msgs仓库的.msg文件是否真的包含DroneTraj和VIOFrame,或者修改taichislam_node.py的导入语句。
- 删除旧的构建文件:
- 解决方法:
-
修改
taichislam_node.py以绕过缺失的依赖:
如果swarm_msgs确实缺少DroneTraj和VIOFrame,并且你不想去修复它们,可以暂时修改taichislam_node.py以使用PoseStamped(用于位姿) 来代替VIOFrame(用于帧信息)。- 注释掉错误的导入:
# from swarm_msgs.msg import DroneTraj, VIOFrame - 注释掉
if self.enable_submap:块中的订阅逻辑:
修改init_subscribers函数,使其不订阅VIOFrame和DroneTraj。
确保# ... # if self.enable_submap: # self.frame_sub = message_filters.Subscriber('~frame_local', VIOFrame) # 注释掉或移除 # self.traj_sub = rospy.Subscriber("~traj", DroneTraj, self.traj_callback, queue_size=10, tcp_nodelay=True) # 注释掉或移除 # # ... 后续使用 frame_sub 和 self.traj_sub 的代码也需调整 # else: # 确保有fallback到 PoseStamped 的逻辑 # ...init_subscribers中会订阅~pose(PoseStamped) Topic。
- 注释掉错误的导入:
-
解决 Taichi 初始化错误:
如果ti.init报错KeyError: 'Unrecognized keyword argument(s) for ti.init: dynamic_index',这是因为 Taichi 版本问题。- 修改
taichislam_node.py:
找到ti.init()调用,移除dynamic_index=True参数:# CUDA 初始化 ti.init(arch=ti.cuda, debug=False, device_memory_GB=4) # CPU 初始化 ti.init(arch=ti.cpu, debug=False)
- 修改
-
解决 Vulkan/GUI 渲染错误:
如果你遇到RuntimeError: Vulkan must be available for GGUI,意味着 Taichi 的可视化模块(ti.ui.Window)需要 GPU 和 Vulkan 支持,但 Docker 容器没有。- 禁用可视化: 这是最简单直接的办法。
- 在运行
roslaunch时,设置show参数为false:roslaunch launch/taichislam-d435.launch show:=false - 或者,修改
launch/taichislam-d435.launch文件,将<arg name="show" default="true" />改为<arg name="show" default="false" />。
- 在运行
- 禁用可视化: 这是最简单直接的办法。
4. 运行 TaichiSLAM 项目
完成环境配置和依赖修复后,你需要使用至少四个终端来完成整个流程。
步骤:
-
终端 1:启动 ROS Master
- 进入容器:
docker exec -it taichislam bash - 激活环境:
conda activate taichislam - 启动 ROS Master:
roscore
- 进入容器:
-
终端 2:启动 TaichiSLAM 节点
- 进入容器:
docker exec -it taichislam bash - 激活环境:
conda activate taichislam - 启动 TaichiSLAM 节点(禁用可视化):
# 确保你的 /taichislam_ws/devel/setup.bash 已 source source /taichislam_ws/devel/setup.bash roslaunch launch/taichislam-d435.launch show:=false - 检查输出: 观察日志,确保没有
ImportError、KeyError或RuntimeError。你应该能看到TaichiSLAMNode initialized这样的信息,并且有关于 Taichi 后端(CPU 或 CUDA)的提示。
- 进入容器:
-
终端 3:播放 ROS Bag
- 进入容器:
docker exec -it taichislam bash - 激活环境:
conda activate taichislam - 播放 bag 文件:
# 确保你的 /taichislam_ws/devel/setup.bash 已 source source /taichislam_ws/devel/setup.bash rosbag play /data/taichislam-realsense435.bag - 观察日志: 在运行 TaichiSLAM 节点的终端(终端 2)中,你会看到它开始接收数据并打印处理时间信息(如
t_recast,t_export等),这表明它正在积极工作。
- 进入容器:
-
终端 4:启动 RViz 可视化
- 进入容器:
docker exec -it taichislam bash - 激活环境:
conda activate taichislam - 解决 RViz 图形显示问题 (无 root 权限):
- 在宿主机终端(非 Docker 容器内),运行:
注意:# 确保 DISPLAY 变量已设置(如果没设置,先 export DISPLAY=:0) echo $DISPLAY export DISPLAY=:0 # 如果 echo $DISPLAY 是空的,运行这行 # 允许容器访问你的 X11 显示 xhost +SI:localuser:$(whoami)$(whoami)会自动替换为你当前的用户名。 - 回到容器终端:
# 确保你的 /taichislam_ws/devel/setup.bash 已 source source /taichislam_ws/devel/setup.bash # 启动 RViz rosrun rviz rviz
- 在宿主机终端(非 Docker 容器内),运行:
- 在 RViz 中配置:
- 在 RViz 窗口左下角,点击 Add。
- 选择 By topic。
- 找到
/dense_mappingTopic,选择PointCloud2。 - 点击 OK。
- 你应该能看到实时渲染的三维地图点云。
- 进入容器:
最终结果
- 后台处理: TaichiSLAM 节点会默默地在后台处理 bag 文件中的数据,构建 TSDF/OctoMap。
- RViz 可视化: 你可以在 RViz 中看到实时生成的三维地图。
- 地图输出: 如果你设置了
output_map: true,地图会被发布到/dense_mappingTopic。要保存地图,你需要修改taichislam_node.py的output函数,或使用其他 ROS 工具(如rostopic hz /dense_mapping查看是否还在发布,并配合rostopic echo结合pcl_ros工具保存点云)。
总结一下你遇到的问题和解决方案:
-
ROS 节点启动失败 (ImportError): 原因是 TaichiSLAM 依赖的
swarm_msgs包中缺少DroneTraj和VIOFrame的.msg定义。- 解决方案: 重新编译工作空间;或修改
taichislam_node.py绕过这些依赖。
- 解决方案: 重新编译工作空间;或修改
-
Taichi 初始化失败 (KeyError):
ti.init中的dynamic_index参数在你的 Taichi 版本中已弃用。- 解决方案: 从
ti.init调用中移除dynamic_index=True。
- 解决方案: 从
-
RViz 无法显示 (RuntimeError: Vulkan): Taichi 的可视化模块需要 GPU 和 Vulkan,这在标准 Docker 容器中不存在。
- 解决方案: 在
roslaunch时设置show:=false来禁用可视化,或使用docker run的--gpus all参数并正确配置 X11 转发(如使用.Xauthority)。
- 解决方案: 在
-
RViz 启动失败 (qt.qpa.xcb: could not connect to display): Docker 容器无法连接到宿主机的 X11 显示服务器,即使
DISPLAY变量存在。- 解决方案: 在宿主机上使用
xhost +SI:localuser:$(whoami)命令授权。
- 解决方案: 在宿主机上使用
通过遵循以上步骤,你应该能成功运行 TaichiSLAM,并在 RViz 中看到构建的三维地图。

浙公网安备 33010602011771号