在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 依赖。

  1. 安装 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
    
  2. 创建虚拟环境并安装项目依赖:

    # 创建名为 '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 包中的消息定义不匹配。

    • 解决方法:
      1. 删除旧的构建文件:
        cd /taichislam_ws
        rm -rf build devel
        
      2. 重新编译工作空间:
        # 确保在 Conda 环境中
        conda activate taichislam
        # 确保 ROS 环境已 source
        source /opt/ros/noetic/setup.bash
        # 编译
        catkin_make
        
        这会重新生成所有 ROS 消息文件。如果问题依然存在,可能需要检查 swarm_msgs 仓库的 .msg 文件是否真的包含 DroneTrajVIOFrame,或者修改 taichislam_node.py 的导入语句。
  • 修改 taichislam_node.py 以绕过缺失的依赖:
    如果 swarm_msgs 确实缺少 DroneTrajVIOFrame,并且你不想去修复它们,可以暂时修改 taichislam_node.py 以使用 PoseStamped (用于位姿) 来代替 VIOFrame (用于帧信息)。

    1. 注释掉错误的导入:
      # from swarm_msgs.msg import DroneTraj, VIOFrame
      
    2. 注释掉 if self.enable_submap: 块中的订阅逻辑:
      修改 init_subscribers 函数,使其不订阅 VIOFrameDroneTraj
      # ...
      # 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 版本问题。

    1. 修改 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 容器没有。

    1. 禁用可视化: 这是最简单直接的办法。
      • 在运行 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. 终端 1:启动 ROS Master

    • 进入容器:docker exec -it taichislam bash
    • 激活环境:conda activate taichislam
    • 启动 ROS Master:
      roscore
      
  2. 终端 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
      
    • 检查输出: 观察日志,确保没有 ImportErrorKeyErrorRuntimeError。你应该能看到 TaichiSLAMNode initialized 这样的信息,并且有关于 Taichi 后端(CPU 或 CUDA)的提示。
  3. 终端 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. 终端 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
        
    • 在 RViz 中配置:
      • 在 RViz 窗口左下角,点击 Add
      • 选择 By topic
      • 找到 /dense_mapping Topic,选择 PointCloud2
      • 点击 OK
      • 你应该能看到实时渲染的三维地图点云。

最终结果

  • 后台处理: TaichiSLAM 节点会默默地在后台处理 bag 文件中的数据,构建 TSDF/OctoMap。
  • RViz 可视化: 你可以在 RViz 中看到实时生成的三维地图。
  • 地图输出: 如果你设置了 output_map: true,地图会被发布到 /dense_mapping Topic。要保存地图,你需要修改 taichislam_node.pyoutput 函数,或使用其他 ROS 工具(如 rostopic hz /dense_mapping 查看是否还在发布,并配合 rostopic echo 结合 pcl_ros 工具保存点云)。

总结一下你遇到的问题和解决方案:

  1. ROS 节点启动失败 (ImportError): 原因是 TaichiSLAM 依赖的 swarm_msgs 包中缺少 DroneTrajVIOFrame.msg 定义。

    • 解决方案: 重新编译工作空间;或修改 taichislam_node.py 绕过这些依赖。
  2. Taichi 初始化失败 (KeyError): ti.init 中的 dynamic_index 参数在你的 Taichi 版本中已弃用。

    • 解决方案: 从 ti.init 调用中移除 dynamic_index=True
  3. RViz 无法显示 (RuntimeError: Vulkan): Taichi 的可视化模块需要 GPU 和 Vulkan,这在标准 Docker 容器中不存在。

    • 解决方案: 在 roslaunch 时设置 show:=false 来禁用可视化,或使用 docker run--gpus all 参数并正确配置 X11 转发(如使用 .Xauthority)。
  4. RViz 启动失败 (qt.qpa.xcb: could not connect to display): Docker 容器无法连接到宿主机的 X11 显示服务器,即使 DISPLAY 变量存在。

    • 解决方案: 在宿主机上使用 xhost +SI:localuser:$(whoami) 命令授权。

通过遵循以上步骤,你应该能成功运行 TaichiSLAM,并在 RViz 中看到构建的三维地图。

posted @ 2025-09-09 10:37  asandstar  阅读(61)  评论(0)    收藏  举报