This guide describes how to set up the deployment environment and run the trained policy on a physical Unitree G1 robot.
The 29 DOF configuration includes:
- 12 leg joints (6 per leg)
- 3 waist joints (yaw, roll, pitch)
- 14 arm joints (7 per arm)
This guide provides two deployment methods:
| Deployment Method | Target Platform |
|---|---|
| Laptop Deployment | Laptop/Desktop PC |
| PC2 Docker Deployment | G1 Robot's PC2 |
Choose the appropriate method based on your setup:
- For laptop/desktop deployment: Follow the Laptop Deployment section
- For PC2 on robot hardware: Follow the PC2 Docker Deployment section
For safety reasons, it is strongly recommended to remove the dexterous hands before running the policy.
Ensure the following are installed before proceeding:
- Anaconda or Miniconda
- ROS 2 Humble installed at
/opt/ros/humble - MCAP for efficient ROS 2 data recording
- Unitree ROS 2 SDK installed at
~/unitree_ros2/
cd <your_holomotion_repo_path>/deployment
chmod +x deploy_environment.sh
./deploy_environment.shThis script will:
- Create a new conda environment (with CUDA support if available)
- Install Python packages from
requirements/requirements_deploy.txt - Install Unitree SDK Python bindings
- Build the ROS 2 workspace under
unitree_g1_ros2_29dof/
The deployment process consists of two types of steps:
| One-Time Setup (per computer) | Every Run (each time you use the robot) |
|---|---|
| Step 1: Network Configuration | Step 3: Power On & Initialize Robot |
| Step 2: Launch Script Setup | Step 4: Launch Policy Controller |
Note: Once you complete Steps 1-2, you only need to do Steps 3-4 for each robot session!
- Power on the robot and wait for it to fully boot
- Use an Ethernet cable to connect your PC to the robot's LAN port
- Ensure both devices are powered on during configuration
Configure your PC's network interface with the following static IP settings:
- Static IP:
192.168.123.222 - Netmask:
255.255.255.0 - Gateway: (leave empty)
You can use the following script to configure it automatically (use command nmcli con show to check your actual connection name):
Click to view set_static_ip.sh
#!/bin/bash
# Replace with your actual connection name (use `nmcli con show` to check)
CON_NAME="Wired connection 1"
IP_ADDRESS="192.168.123.222"
NETMASK="24"
GATEWAY=""
nmcli con modify "$CON_NAME" ipv4.addresses "$IP_ADDRESS/$NETMASK"
nmcli con modify "$CON_NAME" ipv4.method manual
if [ -n "$GATEWAY" ]; then
nmcli con modify "$CON_NAME" ipv4.gateway "$GATEWAY"
fi
nmcli con modify "$CON_NAME" ipv4.dns ""
nmcli con down "$CON_NAME" && nmcli con up "$CON_NAME"-
Check your network interface name (while connected to the robot):
ifconfig
Look for the interface connected to the robot (e.g.,
enxf8e43ba00afd,eth0,enp0s31f6) -
Update the launch configuration:
# Edit the launch file nano <your_holomotion_repo_path>/deployment/unitree_g1_ros2_29dof/src/launch/holomotion_29dof_launch.py
Find and update the
network_interfaceparameter with your actual interface name.
Do this every time you want to run the robot.
- Power on the robot - Start the robot in the hanging position
- Wait for zero torque mode - The robot will automatically enter zero torque mode (joints feel loose)
- Connect your computer - Use the same Ethernet cable to connect to the robot's LAN port
- Enter debugging mode - On the remote controller, press
L2 + R2simultaneously. Note: the new deployment automatically enters this mode on startup, so manual entry is usually not required.
Before running, ensure the following are ready.
- Model folders configured in
g1_29dof_holomotion.yamlexistmotion_tracking_model_folder: undersrc/models/velocity_tracking_model_folder: undersrc/models/
- Motion data directory exists and contains .npz files (retargeted results)
motion_clip_dir: undersrc/motion_data/
- Config file path used by launch is correct
cd <your_holomotion_repo_path>/deployment/unitree_g1_ros2_29dof
bash launch_holomotion_29dof.shSuccess indicator: On startup, the robot joints should remain in zero torque state and feel free to move.
The 29 DOF robot operates in two main modes:
| Mode | How to Enter | Controls | Switch |
|---|---|---|---|
| Velocity tracking | 1) Press Start to stand up, then press A 2) From motion tracking: press Y |
Left stick: move (vx, vy) Right stick: rotate (yaw) D-Pad: select motion clip (Left=first, Right=last, Up=prev, Down=next) |
B: enter motion tracking |
| Motion tracking | Press B | Executes selected motion clip automatically | Y: back to velocity tracking |
Here is the robot control flowchart for 29 DOF:
flowchart TD
subgraph prepPhase ["Setup Phase"]
direction TB
A[Set Robot<br/>to Hanging Position] --> B[Power On and<br/>Zero Torque Mode]
B --> C[L2+R2: Enter Debug Mode]
C --> D[Launch Program]
end
%% Main flow
prepPhase --> E[Start: Stand Up]
E --> F[Lower Robot to Ground]
F --> G[A: Enter Velocity tracking Mode]
%% Velocity tracking mode controls
G --> H[Velocity tracking Mode]
H --> H1[Left Stick: Move]
H --> H2[Right Stick: Rotate]
H --> H3[D-Pad: Select Motion Clip]
H --> H4[B: Enter Motion tracking Mode]
%% Motion tracking mode
H4 --> I[Motion tracking Mode]
I --> I1[Execute Selected Motion Clip]
I --> I2[Y: Back to Velocity tracking]
%% Mode switching
I2 --> H
%% Emergency stop
D --> N[Select: Emergency Stop]
E --> N
F --> N
G --> N
H --> N
I --> N
N --> O[Close Program]
classDef startEnd fill:#e1f5fe,stroke:#01579b,stroke-width:2px
classDef control fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
classDef velocityTracking fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
classDef motionTracking fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef emergency fill:#ffebee,stroke:#b71c1c,stroke-width:2px,stroke-dasharray: 5 5
classDef preparationFrame fill:#f9f9f9,stroke:#666,stroke-width:2px,stroke-dasharray: 5 5
class A,O startEnd
class B,C,D,E,F,G control
class H,H1,H2,H3,H4 velocityTracking
class I,I1,I2 motionTracking
class N emergency
class prepPhase preparationFrame
System Configuration
- File:
holomotion/deployment/unitree_g1_ros2_29dof/src/config/g1_29dof_holomotion.yaml - Key parameters:
motion_tracking_model_folder: motion tracking model folder undermodels/velocity_tracking_model_folder: velocity tracking model folder undermodels/motion_clip_dir: motion clip data folder undersrc/
Pre-trained Models
We provide a pre-trained velocity tracking model that you can download and use:
- Velocity Tracking Model: Download from Hugging Face
To use this model:
- Download the
holomotion_v1.2_velocity_tracking_modelfolder from the Hugging Face repository - Place the downloaded folder under
models/(e.g.,models/holomotion_v1.2_velocity_tracking_model/) - Update
velocity_tracking_model_folderin theg1_29dof_holomotion.yamlto point to this folder
Adding New Motion Tracking Models
- Create a new folder under
models/based on the following example model folder structure (e.g.,models/your_model_dir_name/) - Update
motion_tracking_model_folderin theg1_29dof_holomotion.yaml - Ensure the motion clip data files are in the
motion_clip_dir
Example model folder structure (motion model):
Holomotion/deployment/unitree_g1_ros2_29dof/src/models/your_model_dir_name
├── config.yaml
├── exported
└── your_model_name.onnxThis deployment is intended for demonstration only. It is not a production-grade control system. Do not interfere with the robot during operation. If unexpected behavior occurs, exit control immediately via the controller or keyboard to ensure safety.
To stop the control process, press Select or use Ctrl+C in the terminal.
The deployment process consists of two types of steps:
| One-Time Setup (per PC2) | Every Run (each time you use the robot) |
|---|---|
| Step 1: Configure Docker | Step 4: Start Docker Container |
| Step 2: Load Docker Image | Step 5: Power On & Initialize Robot |
| Step 3: Configure Launch File Network Interface | Step 6: Launch Policy Controller |
Note: Once you complete Steps 1-3, you only need to do Steps 4-6 for each robot session!
- Platform: NVIDIA Jetson Orin
- JetPack: 5.1
- Ubuntu: 20.04
- ROS 2: Foxy
- Docker: Installed with NVIDIA Container Runtime support
Modify /etc/docker/daemon.json:
{
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
},
"default-runtime": "nvidia"
}Restart Docker and verify:
sudo systemctl restart docker
sudo docker info | grep -i runtimePull the image from dockerhub with:
docker pull horizonrobotics/holomotion:orin_foxy_jp5.1_docker_humble_deploy_20260105Or if you have the image locally, tag it appropriately:
docker tag <your_image_name> holomotion:orin_foxy_jp5.1_docker_humble_deploy_20260105-
Check your network interface name on the robot:
ifconfig
Look for the interface with IP
192.168.123.164. The interface is typicallyeth0. -
Update the launch configuration if your interface is not
eth0:nano <your_holomotion_repo_path>/deployment/unitree_g1_ros2_29dof/src/launch/holomotion_29dof_launch.py
Find line 103 and update the
network_interfaceparameter:network_interface = "eth0" # Change to your actual interface name
Important: Before running Docker commands, ensure your user is added to the docker group. If you encounter permission errors, add your user to the docker group:
sudo usermod -aG docker $USERAfter adding your user to the docker group, you need to log out and log back in (or restart your session) for the changes to take effect. Verify with:
groupsYou should see docker in the list of groups.
Important: You need to run this step every time you want to use the robot. The script will automatically remove any existing container and start a fresh one.
cd <your_holomotion_repo_path>/deployment/unitree_g1_ros2_29dof
bash start_container.shWhen prompted, enter the holomotion repository path:
- The script will ask:
Please enter the holomotion local repository path: - Enter the full path to your holomotion repository, for example:
/home/unitree/HoloMotion(if the repository is at this location)- Or the actual path where your holomotion repository is located
Do this every time before launching the policy controller.
- Put the robot in hanging position
- Wait for zero torque mode
- Press
L2 + R2on remote controller for debug mode
Do this every time you want to run the robot (after Steps 4 and 5).
Preflight Checklist
Before running, ensure the following are ready.
- Model folders configured in
g1_29dof_holomotion.yamlexistmotion_tracking_model_folder: undersrc/models/velocity_tracking_model_folder: undersrc/models/
- Motion data directory exists and contains .npz files (retargeted results)
motion_clip_dir: undersrc/motion_data/
- Config file path used by launch is correct
Pre-trained Models
You can download and use the pre-trained velocity tracking model. Refer to the Pre-trained Models section above for general instructions.
Note: The model folder should be placed in your local repository before starting the Docker container, as the repository is mounted into the container.
One-click start in the docker
cd /home/unitree/holomotion/deployment/unitree_g1_ros2_29dof
bash launch_holomotion_29dof_docker.shNote: The control flow is the same as described in the Control Flow section above.
This deployment is intended for demonstration only. It is not a production-grade control system. Do not interfere with the robot during operation. If unexpected behavior occurs, exit control immediately via the controller or keyboard to ensure safety.
To stop the control process:
- Press
Selecton the remote controller, or - Use
Ctrl+Cin the terminal (inside Docker container)