灵犀 X2 虚拟仿真空间部署(Docker)

本文记录在一台 x86_64 Ubuntu 机器上,用 Docker 部署灵犀 X2 的 MuJoCo 虚拟仿真空间,从镜像构建到仿真与运动控制器(MC)通信打通的完整过程。
参考
1. 环境要求
| 项目 | 要求 |
|---|---|
| 电脑 | x86_64,建议 16 GB 或以上内存(实测 8 GB 偏紧,容易卡死) |
| 系统 | Ubuntu 22.04 或 24.04,带图形桌面 |
| 软件 | Docker(宿主机无需安装 ROS 2) |
| GPU | 可选,无独显也能跑(默认走核显/软件渲染) |
| 网络 | 首次部署需下载基础镜像和软件包 |
先在宿主机确认 X11 转发工具已装:
if ! command -v xhost >/dev/null 2>&1; then sudo apt update sudo apt install -y x11-xserver-utilsfi2. 准备软件目录
把交付文件放到同一工作目录,目录名可自定,下面以 x2_simulation/ 为例:
x2_simulation/├── aimdk/ # SDK 源码(aimdk_msgs、py_examples、examples、robotop、ruckig)├── x2_rl_deploy/ # 官方 MuJoCo 仿真 + 运控扩展包│ ├── aimdk_msgs/ # 含 ProcessInfo 的完整消息集│ ├── x2_rl_deploy_controller/ # 运动控制器(MC)│ ├── x2_rl_deploy_mujoco/ # MuJoCo 仿真(HAL 层)│ └── third_party/onnxruntime-linux-x64-1.23.2/ # RL 策略推理依赖├── sim_mujoco/ # 指向 x2_rl_deploy/x2_rl_deploy_mujoco├── Dockerfile└── run_docker.sh控制链路:
SDK(py_examples) ──高层指令──> MC(x2_rl_deploy_controller) ──关节命令──> sim_mujoco ^ │ └────── 关节与 IMU 状态回传 <───────────┘3. 构建镜像
工作目录下的 Dockerfile 以 ROS 2 Humble 官方镜像为基础,装齐编译和运行依赖:
FROM osrf/ros:humble-desktop-full
ENV DEBIAN_FRONTEND=noninteractiveENV RMW_IMPLEMENTATION=rmw_fastrtps_cpp
RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential ca-certificates cmake curl \ libcurl4-openssl-dev libeigen3-dev libgflags-dev \ libgl1 libgl1-mesa-dri libglx-mesa0 libncurses-dev \ liboctomap1.9 libopencv-dev libscrypt0 libyaml-cpp-dev \ mesa-utils pkg-config python3-colcon-common-extensions python3-pip \ ros-humble-cv-bridge ros-humble-grid-map-msgs ros-humble-grid-map-ros \ ros-humble-joy ros-humble-rmw-fastrtps-cpp \ && rm -rf /var/lib/apt/lists/*
RUN printf '%s\n' \ 'source /opt/ros/humble/setup.bash' \ 'export RMW_IMPLEMENTATION=rmw_fastrtps_cpp' \ 'if [ -f /workspace/aimdk/install/local_setup.bash ]; then source /workspace/aimdk/install/local_setup.bash; fi' \ >> /root/.bashrc
WORKDIR /workspaceCMD ["bash"]国内网络建议先配 Docker 镜像加速,再拉基础镜像:
sudo mkdir -p /etc/dockersudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak 2>/dev/null || trueecho '{"registry-mirrors":["https://docker.m.daocloud.io","https://docker.1ms.run"]}' | sudo tee /etc/docker/daemon.json >/dev/nullsudo systemctl restart dockerdocker pull osrf/ros:humble-desktop-fulldocker build -t x2-simulation:latest .目标架构是 x86_64,如果镜像文件名带 aarch64 说明是 ARM 包,不能用。编译产物不能跨架构混用。
4. 启动容器
run_docker.sh 负责挂载工作目录、转发 X11 显示、并把宿主机 /agibot 挂进容器(MC 运行时目录):
#!/usr/bin/env bashset -euo pipefailROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)IMAGE_NAME=x2-simulation:latestCONTAINER_NAME=x2-simxhost +si:localuser:root >/dev/null 2>&1 || truedocker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || trueDOCKER_ARGS=( run -it --name "${CONTAINER_NAME}" --network host --ipc host -e "DISPLAY=${DISPLAY:-:0}" -e QT_X11_NO_MITSHM=1 -e RMW_IMPLEMENTATION=rmw_fastrtps_cpp -v "${ROOT_DIR}/aimdk:/workspace/aimdk:rw" -v "${ROOT_DIR}/sim_mujoco:/workspace/sim_mujoco:rw" -v "${ROOT_DIR}/x2_rl_deploy:/workspace/x2_rl_deploy:rw" -v /agibot:/agibot:rw -v /tmp/.X11-unix:/tmp/.X11-unix:rw -w /workspace)if [[ -d /dev/dri ]]; then DOCKER_ARGS+=(--device /dev/dri)fidocker "${DOCKER_ARGS[@]}" "${IMAGE_NAME}" bash宿主机准备好 MC 运行时目录,然后执行脚本:
sudo mkdir -p /agibot/data/var/sudo chown "$USER:$USER" -R /agibotchmod +x run_docker.sh./run_docker.sh执行后进入容器,这个终端作为后续的「终端 1」。要后台常驻(不占用交互终端)可用:
docker exec -d x2-sim bash /workspace/x2_rl_deploy/start_simulation_stack.sh5. 编译 SDK 与运控栈
容器内先编译 aimdk:
cd /workspace/aimdksource /opt/ros/humble/setup.bashcolcon buildsource install/local_setup.bash再编译 x2_rl_deploy(运控 + 消息)。编译前需要给 x2_rl_deploy_controller 准备 onnxruntime(见第 6 节)。
6. 准备 onnxruntime 依赖
x2_rl_deploy_controller 用 ONNX 推理 RL 策略,CMake 里 find_package(onnxruntime REQUIRED)。容器内没有安装 onnxruntime,也没有 root 权限装到系统目录,解决办法是下载官方预编译包放到 third_party/,并让 CMake 用这个本地路径。
下载并解压(宿主机或容器内均可):
cd /workspace/x2_rl_deploymkdir -p third_partycurl -L https://github.com/microsoft/onnxruntime/releases/download/v1.23.2/onnxruntime-linux-x64-1.23.2.tgz \ -o third_party/onnxruntime.tgztar -xzf third_party/onnxruntime.tgz -C third_party按 CMake 目标里约定的目录补全 lib64 和头文件布局:
cd third_party/onnxruntime-linux-x64-1.23.2mkdir -p lib64 include/onnxruntimecp -a lib/*.so* lib64/cp -a include/*.h include/onnxruntime/然后把 x2_rl_deploy_controller/CMakeLists.txt 里的 find_package(onnxruntime REQUIRED) 改成指向本地目录:
set(ONNXRUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/onnxruntime-linux-x64-1.23.2")find_package(onnxruntime REQUIRED PATHS "${ONNXRUNTIME_DIR}/lib/cmake/onnxruntime" NO_DEFAULT_PATH HINTS "${ONNXRUNTIME_DIR}")并在 target_include_directories 里加上 ${ONNXRUNTIME_DIR}/include。
改好后编译:
cd /workspace/x2_rl_deploysource /opt/ros/humble/setup.bashsource /workspace/aimdk/install/local_setup.bashcolcon build编译产物:install/x2_rl_deploy_controller/lib/x2_rl_deploy_controller/x2_rl_deploy_controller。
7. 安装 CycloneDDS
仿真二进制默认用 CycloneDDS 作为 RMW,镜像里只有 Fast DDS,不装会报:
Error getting RMW implementation identifier / RMW implementation not installed(expected identifier of 'rmw_cyclonedds_cpp')容器内安装:
apt-get updateapt-get install -y --no-install-recommends ros-humble-rmw-cyclonedds-cpp之后启动一律设 export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp,让仿真、MC、SDK 三方用同一个 RMW,否则通信不通。
8. 解决 ProcessInfo 符号缺失
两套 aimdk_msgs 并存时容易踩坑:/workspace/aimdk/install/aimdk_msgs 里没有 ProcessInfo 消息,/workspace/x2_rl_deploy/install/aimdk_msgs 里有。仿真加载 monitor_plugin 时会因为找不到 ProcessInfo 的类型支持而段错误:
undefined symbol: ...get_message_type_support_handle<aimdk_msgs::msg::ProcessInfo...>解决办法是把带 ProcessInfo 的那套消息库放在 LD_LIBRARY_PATH 最前面:
export LD_LIBRARY_PATH=/workspace/x2_rl_deploy/install/aimdk_msgs/lib:$LD_LIBRARY_PATH9. 启动仿真与运控
把上面的环境变量和步骤整合成一键脚本 start_simulation_stack.sh:
#!/bin/bashset -esource /opt/ros/humble/setup.bashsource /workspace/x2_rl_deploy/install/local_setup.bashsource /workspace/aimdk/install/local_setup.bashexport RMW_IMPLEMENTATION=rmw_cyclonedds_cppexport MUJOCO_GL=eglexport LD_LIBRARY_PATH=/workspace/x2_rl_deploy/install/aimdk_msgs/lib:/workspace/x2_rl_deploy/third_party/onnxruntime-linux-x64-1.23.2/lib:/workspace/sim_mujoco/bin:/workspace/sim_mujoco/lib:/opt/ros/humble/lib:$LD_LIBRARY_PATH
cd /workspace/sim_mujoco/binecho lx2501_3_t2d5 > sim_robot_name_cache.txtecho /workspace/sim_mujoco/configuration > sim_configuration_directory_cache.txtmkdir -p log/crashnohup bash ./start_sim.sh > /tmp/sim.log 2>&1 &echo "sim PID=$!"sleep 8
cd /workspace/x2_rl_deploynohup ./install/x2_rl_deploy_controller/lib/x2_rl_deploy_controller/x2_rl_deploy_controller > /tmp/mc.log 2>&1 &echo "mc PID=$!"启动:
docker exec -d x2-sim bash /workspace/x2_rl_deploy/start_simulation_stack.sh日志分别在容器的 /tmp/sim.log 和 /tmp/mc.log。
10. 验证通信
查看话题(只 source x2_rl_deploy 的 install,避开两套消息的 Python 类型冲突,见第 8 节):
docker exec -it x2-sim bashsource /opt/ros/humble/setup.bashsource /workspace/x2_rl_deploy/install/local_setup.bashexport RMW_IMPLEMENTATION=rmw_cyclonedds_cppexport LD_LIBRARY_PATH=/workspace/x2_rl_deploy/install/aimdk_msgs/lib:$LD_LIBRARY_PATH
ros2 topic listros2 topic echo /aima/hal/joint/arm/state --onceros2 topic info /aima/hal/joint/leg/command正常时应看到 Publisher count: 1, Subscription count: 1(MC 发布、仿真订阅),并且 echo 能打印出实时关节数据,说明仿真与运控通信链路已打通。
常见问题
| 问题 | 解决办法 |
|---|---|
| 基础镜像拉取失败 | 重试 docker pull,或先配镜像加速再拉 |
| MuJoCo 窗口不显示 | 宿主机执行 xhost +si:localuser:root,确认在图形桌面会话 |
报 rmw_cyclonedds_cpp 未安装 | 第 7 节安装 CycloneDDS,三方统一用同一个 RMW |
段错误 + ProcessInfo 符号缺失 | 第 8 节,把带 ProcessInfo 的消息库放 LD_LIBRARY_PATH 最前 |
start_sim.sh 提示已有实例在跑 | 真没有实例时,是脚本 pgrep 把调用它的命令行自己匹配上了;用独立脚本文件启动,别写在 bash -c "..." 单行里 |
| 内存不足导致仿真被杀 | 见下一篇「内存占用优化」,减渲染分辨率、关多余插件 |
本网站提供的所有教程仅供学习使用,无任何商务用途!
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!

