This repository delivers a reproducible, Docker-based workspace for the Unitree GO2-W robot. It is tuned for VS Code Dev Containers so you can open the repo, wait for the automated bootstrap to finish, and start iterating on ROS 2 or SDK code immediately.
- Containerized toolchain – Ubuntu 22.04 + CUDA 12.1 base image with ROS 2 Humble, CycloneDDS, build-essential, Eigen, Boost, fmt/spdlog, GLFW, MuJoCo 3.3.6, and Python simulator dependencies pre-installed.
- Automation-first setup –
.devcontainer/post-create.shbuilds and installsunitree_sdk2,unitree_sdk2_python, the entireunitree_ros2workspace, and theunitree_mujocoC++ simulator the first time the container starts. - Version-locked upstream code –
unitree_sdk2,unitree_sdk2_python,unitree_ros2, andunitree_mujocoare tracked as Git submodules so everyone develops against identical revisions. - Robot-ready runtime – The container runs with
--network=host; the GPU profile additionally enables--gpus=all. Both profiles use theUNITREE_NETWORK_INTERFACEenvironment variable so ROS 2 nodes can talk to the robot with CycloneDDS over the wired link. - Simulation-ready runtime – Every new shell gets
use_unitree_robotanduse_unitree_simhelpers so you can switch between the physical robot and MuJoCo loopback DDS without editing any upstream Unitree scripts. - VS Code experience – Recommended extensions (C/C++, CMake, Dev Containers, Gemini Code Assist) are pre-configured for IntelliSense, build targets, and debugging.
- Git 2.30+ (for cloning submodules).
- Docker Engine 24+ with BuildKit enabled. See the installation manual.
- Visual Studio Code with the Dev Containers extension.
- A host OS that can reach the GO2-W over Ethernet (Linux desktop or workstation recommended).
This repository ships two Dev Container profiles:
- Select
GO2-W Docker Dev GPU. - Ensure you have the NVIDIA Container Toolkit installed on your host machine.
- Select
GO2-W Docker Dev CPU-Only. - Do not use the GPU profile on non-NVIDIA machines.
Running motion commands can move the robot immediately. Before testing:
- Keep a clear area around the robot.
- Use a support stand or spotter when possible.
- Keep emergency stop access ready.
- Start with low-risk commands (
read_*state examples) before motion commands.
-
Clone with submodules
git clone --recurse-submodules https://github.com/koki67/go2w-docker-dev.git
Already cloned? Run
git submodule update --init --recursiveto pullunitree_mujocoalong with the existing Unitree repositories. -
Tell the container which NIC talks to the robot
- Run
ip a(orifconfig) on the host and note the interface that owns the static IP you use for GO2-W (e.g.enp97s0,eth0,enx...). - Edit your selected profile file (
.devcontainer/gpu/devcontainer.jsonor.devcontainer/cpu/devcontainer.json) and setUNITREE_NETWORK_INTERFACEundercontainerEnvto that interface name. This value is injected into the CycloneDDS configuration that lives insidepost-create.sh.
- Run
-
Open in VS Code Dev Containers
- Open the folder in VS Code.
- Run the command Dev Containers: Rebuild and Reopen in Container from the Command Palette (Ctrl+Shift+P) for the first time.
- Select your configuration: VS Code will prompt you to choose:
- GO2-W Docker Dev GPU: For machines with NVIDIA GPUs and NVIDIA Container Toolkit installed.
- GO2-W Docker Dev CPU-Only: For machines without NVIDIA GPUs.
- The first build can take several minutes while Docker pulls CUDA/ROS layers and the post-create script compiles SDKs + ROS 2 workspaces. Subsequent opens reuse the cached layers.
-
(Optional) Enable Host GUI Access for Container If you plan to run GUI applications like
rviz2from within the container, you need to grant the container access to your host machine's display server.- Run this command on your host machine's terminal once before starting the container to allow the Docker container to access your display:
xhost +local:docker
- Why is this needed? This command allows local clients (including Docker containers) to connect to your host's X server. Without it, GUI applications in the container won't know where to draw their windows.
- Note: This lowers access control for your display. Revoke it when done:
xhost -local:docker
- The necessary volume mounts and environment variables (
DISPLAY,/tmp/.X11-unix, etc.) are already pre-configured in.devcontainer/gpu/devcontainer.jsonand.devcontainer/cpu/devcontainer.json.
- Run this command on your host machine's terminal once before starting the container to allow the Docker container to access your display:
-
Wait for the bootstrap to finish
- Watch the “Dev Containers” terminal for the log lines from
.devcontainer/post-create.sh. - Once it prints
--- Post-create command finished ---, every new shell inside the container automatically loads the repo-owned Unitree helper functions and defaults to the real-robot DDS profile.
- Watch the “Dev Containers” terminal for the log lines from
- The repository is mounted at
/workspaceinside the container; edits sync instantly with the host. - The ROS 2 workspace and Unitree SDK paths are prepared by the shell helpers in
.devcontainer/unitree-env.sh. - Switch the current shell between hardware mode and simulator mode:
use_unitree_robot use_unitree_sim
use_unitree_robotusesUNITREE_NETWORK_INTERFACEwithROS_DOMAIN_ID=0.use_unitree_simuses the local loopback interfacelowithROS_DOMAIN_ID=1. - Run an example node to verify connectivity. The
unitree_ros2_examplebinaries are installed to/workspace/ros2_ws/install/unitree_ros2_example/bin, and the package does not currently provide aros2 runentry, so invoke the executable directly:use_unitree_robot /workspace/ros2_ws/install/unitree_ros2_example/bin/go2_sport_client 0
- Launch the C++ MuJoCo simulator:
use_unitree_sim cd /workspace/unitree_mujoco/simulate/build ./unitree_mujoco -r go2 -s scene_terrain.xml - Launch the Python MuJoCo simulator:
use_unitree_sim python3 /workspace/unitree_mujoco/simulate_python/unitree_mujoco.py
- To drive the simulator from an existing DDS or ROS 2 client, open a second terminal, run
use_unitree_sim, and then launch your low-level controller or example node there. The upstreamunitree_mujocoexample packages are available in the submodule, but this repository intentionally does not prebuild them. - Develop New ROS 2 Packages:
Add your own packages under
ros2_ws/src/. This directory is gitignored by design — only theunitree_ros2submodule is tracked by this repository. Any packages you clone or create here will not pollutegit status.Each project should live in its own Git repository so it can be developed independently.# Clone an existing project cd /workspace/ros2_ws/src git clone --recurse-submodules https://github.com/your-org/your-package.git # Or create a new one ros2 pkg create --build-type ament_cmake my_new_algorithm
- Build Your Code:
Rebuild from the workspace root to ensure your new nodes can see the Unitree messages and SDK:
cd /workspace/ros2_ws colcon build --symlink-install source install/setup.bash
- Environment Persistence:
The environment is pre-configured to find
unitree_sdk2at/opt/unitree_roboticsand MuJoCo at/opt/mujoco/mujoco-3.3.6. Theunitree_mujoco/simulate/mujocopath is recreated as a symlink to that system location during post-create.
| Path | Description |
|---|---|
.devcontainer/ |
Dev Container definition (Dockerfile, devcontainer.json, post-create.sh, and shell helper scripts). |
unitree_sdk2/ |
C++ SDK submodule, built and installed into /opt/unitree_robotics. |
unitree_sdk2_python/ |
Python SDK submodule installed editable via pip. |
unitree_mujoco/ |
MuJoCo simulator submodule. The C++ simulator is built in simulate/build, and the Python simulator uses the preinstalled mujoco + pygame packages. |
ros2_ws/src/unitree_ros2/ |
Unitree ROS 2 packages submodule (including the cyclonedds_ws overlay workspace). |
ros2_ws/src/ |
ROS 2 workspace source directory. Contains unitree_ros2 submodule; user packages cloned here are gitignored. |
- Need to rebuild everything? From VS Code hit Dev Containers: Rebuild and Reopen in Container to rerun Docker build +
post-create.sh. - Changed the NIC name? Update
UNITREE_NETWORK_INTERFACEand rebuild the container so the CycloneDDS URI in/root/.bashrcpicks up the new value. - Need simulator DDS instead of robot DDS? Run
use_unitree_simin that shell before launching simulator-aware clients. Runuse_unitree_robotto switch back. - Pulled this fix into an existing container? Run
rebuild_unitree_mujocoto reinstallunitree_sdk2into/opt/unitree_roboticsand rebuildunitree_mujoco, or rerunbash .devcontainer/post-create.sh. - Submodules out of sync?
git submodule update --remotepulls the latest upstream commits configured in.gitmodules, includingunitree_mujoco. - Re-run post-create manually? Inside the container, execute
bash .devcontainer/post-create.sh(after ensuring the workspace is clean) to force a rebuild of SDKs, ROS packages, and theunitree_mujocosimulator.
This environment uses a bind-mount to connect your host machine's folder to the container's /workspace. It is important to understand what persists:
- Container Environment: When you "Rebuild," Docker refreshes the OS, installed tools, and
/opt/unitree_robotics. This is a "fresh start" for the system. - Simulator Runtime: The container image also refreshes MuJoCo under
/opt/mujoco/mujoco-3.3.6, whileunitree_mujoco/simulate/mujocois recreated as a symlink during post-create and the simulator is rebuilt from the checked-out submodule sources. - Workspace Data: Your source code, build artifacts (e.g.,
build/,install/,log/folders), and any extra cloned repositories (like CycloneDDS) live on your host machine. They are NOT deleted when you rebuild the container.
If you encounter weird build errors or want to ensure a completely clean environment:
- Exit VS Code or the container.
- Manually delete generated folders on your host machine:
unitree_sdk2/build/unitree_mujoco/simulate/build/ros2_ws/install/,ros2_ws/build/,ros2_ws/log/ros2_ws/src/unitree_ros2/cyclonedds_ws/(if you want to re-clone DDS)
- Re-open in Container. This forces the
post-create.shto start from a truly empty state.
You now have a reproducible, GPU-enabled workspace that mirrors the intended deployment environment for Unitree GO2-W robotics development.
The original code in this repository (devcontainer configuration and post-create scripts) is licensed under the Apache License 2.0. See LICENSE for the full text.
The following Git submodules are third-party code and carry their own licenses:
| Submodule | Upstream | License |
|---|---|---|
unitree_sdk2/ |
Unitree Robotics | BSD-3-Clause |
unitree_sdk2_python/ |
Unitree Robotics | BSD-3-Clause |
unitree_mujoco/ |
Unitree Robotics | BSD-3-Clause |
ros2_ws/src/unitree_ros2/ |
Unitree Robotics | BSD-3-Clause |