Introduction#
UFO is an open-source unsupervised reinforcement learning framework for humanoid robots from RoboParty Lab, used to train Behavior Foundation Models (BFM). It pretrains a whole-body control policy and a "behavior space" in simulation. Afterwards, given a reference motion, target pose, or reward function, the same policy can directly perform the corresponding task without retraining for each task.
The framework includes two training algorithms: FB (reproducing and improving BFM-Zero) and TeCH.
Resources:
1. Overview#
This section introduces UFO's capabilities, the two code branches, and the environment setup. After completing this section, you can download the example data and get a quick training run working on a single GPU.
1.1 What UFO can do#
| Workflow | What it does | See |
|---|---|---|
| Motion Data | Import robot motion data, generate a data manifest for training, mix multiple data sources by ratio | Section 2 |
| Training | Pretrain the behavior space and whole-body control policy with FB or TeCH | Section 3 |
| Inference & Export | Invoke the policy via motion tracking, goal reaching, or reward, and export ONNX | Section 4 |
| Deployment | Validate in MuJoCo, deploy to the real robot, teleoperate with PICO | Section 5 |
| New Robot | Generate configs for a new robot and train (experimental) | Section 6 |
1.2 The two branches#
UFO's code is split across two branches with different purposes; do not merge them into each other:
| Branch | Purpose | Runs on |
|---|---|---|
main |
Training, data import, inference, ONNX export | Linux training machine with an NVIDIA GPU |
deploy |
MuJoCo simulation validation, real-robot deployment, PICO teleoperation | Workstation, and the robot's onboard compute unit |
1.3 Current support scope#
| Feature | Status |
|---|---|
| Default robot training | Supported, most thoroughly tested |
| Motion data format | RobotState CSV / NPZ, ufo_pkl |
| Mixing multiple data sources | Supported |
| Motion tracking inference | Supported, runs per robot config |
| Goal reaching inference | Supported; new robots need to provide their own target pose files |
| Reward inference | The default robot supports all default tasks; new robots currently mainly support locomotion and turning tasks |
| Real-robot deployment and teleoperation | Use the deploy branch |
| Automatic motion retargeting | Not supported; retarget first with tools such as hhtools |
| Using the same model for different robots | Not supported |
1.4 System requirements#
| Item | main (training) |
deploy (deployment) |
|---|---|---|
| Operating system | Linux | Workstation: Linux; robot: onboard compute unit |
| Python | 3.10 (managed by uv) | 3.10 (Conda on the workstation, venv on the robot) |
| GPU | NVIDIA GPU; a single card suffices for quick tests, the formal training example uses 8 cards | Optional, for computing the latent variable z in real time |
| Main dependencies | MJLab 1.4.0, MuJoCo 3.8, PyTorch 2.7 | MuJoCo, ONNX Runtime, pyzmq |
According to the UFO technical report, FB trains in about 6 hours on 8 H200s, and can also be trained on 8 RTX 4090s.
1.5 Installation (main branch)#
Clone the repository:
git clone https://github.com/Roboparty/UFO.git
cd UFOInstall uv:
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.local/bin/envInstall the project environment:
uv syncOptional: W&B logging. To view training curves in Weights & Biases, log in first, then add --use-wandb --wandb-run-name <name> to the training command:
uv run wandb login
export WANDB_ENTITY=your_entity # optional1.6 Downloading example data#
Motion data is not stored in the Git repository. Download the default LaFAN example data:
bash scripts/download_data.shThe script downloads two files from Hugging Face and verifies their SHA-256:
| File | Purpose |
|---|---|
humanoidverse/data/lafan_29dof_10s-clipped.pkl |
For training, motions clipped into about 10-second segments |
humanoidverse/data/lafan_29dof.pkl |
For inference, complete motion sequences |
1.7 Running a quick test#
./run_train.sh \
--agent fb \
--data-manifest configs/data/example_mix.yaml \
--gpu-ids single \
--smoke \
--work-dir /tmp/ufo_smoke--smoke uses 16 parallel environments and 2048 steps, and does not connect to W&B; it is used to confirm that the environment and data load correctly, and does not represent training quality.
1.8 Output directory#
Both training and inference results are written to the directory specified by --work-dir:
<work-dir>/
├── checkpoint/ # The latest model, overwritten and saved every fixed number of steps
│ ├── config.json
│ ├── train_status.json
│ └── buffers/ # Replay buffer, needed for reward inference
├── tracking_inference/ # Results of motion tracking inference and exported ONNX
├── goal_inference/ # Results of goal reaching inference
└── reward_inference/ # Results of reward inferencerun_train.sh also automatically creates a cache/ directory based on --work-dir (for example runs/ufo_fb corresponds to cache/ under the repository), storing caches for uv, PyTorch, Triton, Warp, etc.; you can also specify the location with the environment variable UFO_CACHE_DIR.
2. Motion data#
This section imports robot motion data into UFO, generates a data manifest for training, and explains how to mix multiple data sources by ratio.
Note UFO does not perform motion retargeting. Human motions or motions from other robots must first be converted into joint trajectories of the target robot using hhtools, GMR, or your own retargeting pipeline, and then imported into UFO.
2.1 Supported formats#
UFO's recommended import format is RobotState: each frame contains the root position root_pos, root orientation root_quat, and joint angles dof_pos, plus a frame rate fps or time column time.
| Format name | Content | Suitable for |
|---|---|---|
robot_state_csv |
CSV file of RobotState | New datasets, recommended |
robot_state_npz |
NPZ file of RobotState | New datasets, recommended |
ufo_pkl |
The already-converted UFO internal format | Data generated by UFO tools or existing pipelines, e.g. the example data |
CSV columns: without a header, they are, in order, the root position (x, y, z), root quaternion (x, y, z, w), then the joint angles, in the same order as the actuated joints in the MuJoCo XML; a time column may be prepended. With a header, you can specify in the data manifest which columns each item corresponds to using columns (see configs/data/example_robot_state_auto_build.yaml).
2.2 Inspecting data#
Before importing, check whether the data and robot config match:
uv run python -m humanoidverse.tools.data_inspect \
--robot configs/robots/<robot>.yaml \
--source "/path/to/motions/*.csv" \
--format robot_state_csv \
--fps 50Set --robot to the config file of the corresponding robot under configs/robots/; new robot configs are generated per Section 6.
2.3 Generating a data manifest#
uv run python -m humanoidverse.tools.data_build \
--robot configs/robots/<robot>.yaml \
--source "/path/to/motions/*.csv" \
--format robot_state_csv \
--name my_motion \
--fps 50 \
--clip-seconds 10 \
--out configs/data/my_motion_auto_build.yaml \
--rebuild-cacheThis step generates:
The data manifest YAML (at the location specified by
--out), used by both training and inference to read the data;A pkl of the complete motions, for inference;
A pkl clipped into about 10-second segments, for training.
2.4 Mixing multiple data sources#
The data manifest can list multiple data sources and set a sampling weight for each:
datasets:
- name: lafan
format: ufo_pkl
train_path: /path/to/lafan_29dof_10s-clipped.pkl
inference_path: /path/to/lafan_29dof.pkl
weight: 0.95
- name: cartwheel
format: ufo_pkl
train_path: /path/to/cartwheel_near10s.pkl
inference_path: /path/to/cartwheel_near10s.pkl
weight: 0.05Between data sources, sampling follows the fixed weight ratio; within each data source, motions that the policy fails to track are prioritized for sampling.
This is suitable for injecting a small amount of rare, high-difficulty skills while preserving the base motion distribution, for example using 5% cartwheel data to teach the policy a cartwheel.
train_pathis used for training andinference_pathfor inference.When injecting motions such as cartwheels, you can add
--cartwheel-aux-safeto the training command, which removes the contact and foot-shape penalties related to walking and reduces the motion change-rate penalty.
You can also skip the manifest and give multiple files and weights directly in the training command: --data-path a.pkl b.pkl --data-mix-weights 0.95 0.05.
Note
Each data source's name must be unique; weights must be non-negative finite numbers and sum to more than 0.
RobotState import does not resample the frame rate; make sure
--fpsmatches the actual data.Currently only hinge joints are supported.
3. Training#
This section trains a policy with FB or TeCH. Training runs on the main branch and is launched by run_train.sh.
3.1 FB vs TeCH#
| FB | TeCH | |
|---|---|---|
| Origin | Reproduces and improves BFM-Zero | Proposed by RoboParty Lab |
| Idea | Estimate "if executed with a given z, which states will be reached in the future"; the policy chooses the action that reaches the most goals | Make distances in the latent space correspond to the number of steps needed to reach, giving positive reward for being closer to the goal |
| Inference it can do | Motion tracking, goal reaching, reward inference | Motion tracking, goal reaching |
| Default latent update interval | Every 100 steps | Every 10 steps |
TeCH was called TLDR in early versions; --agent tldr still works but prints a deprecation notice.
3.2 Training commands#
FB:
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
./run_train.sh \
--agent fb \
--gpu-ids all \
--num-envs 1024 \
--num-env-steps 192000000 \
--work-dir runs/ufo_fb \
--data-path humanoidverse/data/lafan_29dof_10s-clipped.pkl \
--update-z-every-step 100 \
--buffer-size 5120000TeCH:
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
./run_train.sh \
--agent tech \
--gpu-ids all \
--num-envs 1024 \
--num-env-steps 192000000 \
--work-dir runs/ufo_tech \
--data-path humanoidverse/data/lafan_29dof_10s-clipped.pkl \
--update-z-every-step 10 \
--buffer-size 5120000When using your own data, replace --data-path with --data-manifest <manifest path>.
3.3 Default parameters#
| Parameter | Default | Description |
|---|---|---|
--num-envs |
1024 | Number of parallel environments per GPU |
--num-env-steps |
192,000,000 | Total environment steps across all GPUs |
--checkpoint-every-steps |
3,200,000 | How often to save the model |
--buffer-size |
5,120,000 | Replay buffer capacity per GPU |
--update-z-every-step |
FB 100 / TeCH 10 | How often to resample the latent variable z |
--data-path |
humanoidverse/data/lafan_29dof_10s-clipped.pkl |
Training data |
--work-dir |
runs/ufo |
Output directory |
3.4 Common parameters#
| Parameter | Purpose |
|---|---|
--gpu-ids |
single (one GPU), all (all GPUs in CUDA_VISIBLE_DEVICES), or a comma-separated list of IDs |
--data-manifest |
Use a data manifest; cannot be used together with --data-path |
--rebuild-motion-cache |
Regenerate the motion cache corresponding to the data manifest |
--robot-config |
Robot config; uses the repository's built-in config by default; used when adapting a new robot (see Section 6) |
--num-agent-updates |
Number of optimization steps per update. When changing the number of environments per card for comparison experiments, use 32 for 2048 environments and 64 for 4096 environments to align the update density with the default 1024 environments |
--disable-dr / --disable-obs-noise |
Disable domain randomization / observation noise |
--lr-scale / --clip-grad-norm |
Adjust FB's learning rate / enable gradient clipping (not used by TeCH) |
--cartwheel-aux-safe |
Used when injecting skills such as cartwheels (see Section 2.4) |
--seed |
Random seed, default 4728 |
--use-wandb / --wandb-run-name |
Enable W&B logging |
--smoke |
Quick test |
3.5 What is saved during training#
The model is saved in <work-dir>/checkpoint/, overwritten every --checkpoint-every-steps steps, along with the replay buffer (checkpoint/buffers/). Reward inference needs to sample states from the replay buffer, so do not delete this directory.
4. Inference & Export#
This section uses the trained model for three kinds of inference and exports the ONNX for deployment. The three kinds of inference correspond to three ways of specifying a task:
| Inference type | How the task is given | Entry point |
|---|---|---|
| Motion tracking | A reference motion | humanoidverse.tracking_inference |
| Goal reaching | A set of target poses | humanoidverse.goal_inference |
| Reward inference | A reward function, e.g. "walk forward at 0.7 m/s" | humanoidverse.reward_inference |
All three kinds of inference run in MuJoCo; you can save a video with --save-mp4; --disable-dr and --disable-obs-noise are used to disable randomization and observation noise, making it easier to observe the policy's own behavior.
4.1 Motion tracking#
CUDA_VISIBLE_DEVICES=0 \
uv run python -m humanoidverse.tracking_inference \
--model-folder runs/ufo_fb \
--data-path humanoidverse/data/lafan_29dof.pkl \
--device cuda:0 \
--headless \
--save-mp4 \
--motion-list 0Use the complete motion sequence (e.g.
lafan_29dof.pkl), not the 10-second training segments.--motion-listspecifies the motion indices to track; you can give several at once.When using a data manifest, instead use
--data-manifest <manifest> --dataset <data source name>.--max-stepscan limit the number of frames replayed, for quick previews.
Results are written to <model-folder>/tracking_inference/:
| File | Content |
|---|---|
tracking_<index>.mp4 |
Side-by-side video of the reference motion and the policy's execution |
zs_<index>.pkl |
The latent variable z sequence corresponding to this motion, usable directly at deployment |
<model name>.onnx, <model name>.meta.json |
The policy ONNX and its description (robot, actuated joints, input/output dimensions, etc.) |
backward_encoder.onnx |
The network that encodes a target state into z, needed for real-time teleoperation (skipped when the model does not support it) |
Motion tracking exports ONNX by default; add --export-onnx false when not needed.
4.2 Goal reaching#
CUDA_VISIBLE_DEVICES=0 \
uv run python -m humanoidverse.goal_inference \
--model-folder runs/ufo_fb \
--device cuda:0 \
--headless \
--disable-dr \
--disable-obs-noise \
--save-mp4The policy reaches a set of target poses in sequence within one episode, switching targets every 100 steps by default (
--goal-switch-interval), with an episode length of 2100 steps (--episode-len).The default robot uses the repository's built-in target pose files; other robots need to provide their own target pose files with
--goal-json, which cannot be shared between different robots.Results are written to
<model-folder>/goal_inference/, includinggoal_reaching.pkland videos.
4.3 Reward inference#
CUDA_VISIBLE_DEVICES=0 \
uv run python -m humanoidverse.reward_inference \
--model-folder runs/ufo_fb \
--device cuda:0 \
--headless \
--disable-dr \
--disable-obs-noise \
--buffer-rank 0 \
--num-samples 150000 \
--save-mp4Reward inference samples states from the replay buffer saved during training (150,000 by default), scores these states with the reward function, and thereby computes the corresponding z. So it requires
checkpoint/buffers/in the training directory; you can also specify the replay buffer location with--buffer-path.The default tasks include standing in place, walking in each direction, turning, raising a hand, squatting, etc.; use
--tasksto run only some of them, for examplemove-ego-0-0.7.To compute only z without generating videos, add
--skip-rollouts.Results are written to
<model-folder>/reward_inference/, includingreward_locomotion.pkland a video for each task.
Note New robots currently only support locomotion and turning tasks (
move-ego-*,rotate-z-*). Tasks such as raising a hand, squatting, and sitting on the ground depend on the default robot's body semantic definitions and will error out directly.
4.4 Exporting ONNX#
Goal reaching and reward inference do not export ONNX by default; add --export-onnx when needed. In the exported policy ONNX, the input partition is derived by the model itself; the accompanying JSON records the robot name, config path, XML path, actuated joints, each input dimension, the z dimension, and the output action dimension.
Note The exported ONNX is bound to the robot, motion dimension, and observation dimension it was trained with, and cannot be used for other robots.
5. Deployment#
This section uses the deploy branch to validate the policy in MuJoCo, then deploy it to the real robot and teleoperate with PICO. The deploy branch is only responsible for running, not training; each robot requires a dedicated deployment config, denoted <robot> below.
5.1 Deployment methods#
| Method | What it does | Runs on |
|---|---|---|
| Sim2Sim | Track offline motions in MuJoCo, or execute goal/reward tasks | Workstation |
| Teleoperation Sim2Sim | PICO real-time motion → retargeting → real-time z computation → policy in MuJoCo | Workstation |
| Sim2Real | Track offline motions on the real robot | Robot's onboard compute unit |
| Onboard PICO teleoperation (recommended) | PICO connects directly to the robot; retargeting, real-time z, and the policy all run on the robot | Robot's onboard compute unit |
| Split teleoperation (advanced) | Retargeting and real-time z on the workstation, the policy on the robot, with z transmitted over the network | Workstation + robot |
When running for the first time on a new machine, new model, or new teleoperation environment, proceed in this order:
Sim2Sim on the workstation;
Teleoperation Sim2Sim on the workstation;
Sim2Real with the robot suspended or supported;
Onboard PICO teleoperation: first only observe the real-time z and robot state without enabling the policy;
Using the remote controller, enter standing, enable the policy, and start tracking in sequence, and test reset and stop;
Deliberately disconnect PICO, XRoboToolkit, or the network, and confirm the watchdog stops the policy output.
5.2 Installing the workstation environment#
git clone --branch deploy --single-branch https://github.com/Roboparty/UFO.git UFO-Deploy
cd UFO-Deploy
export UFO_ROOT=$PWD
conda create -n ufo-deploy python=3.10 -y
conda activate ufo-deploy
pip install -r requirements/runtime.txtPolicy inference uses CPU by default. When a GPU is needed, install the onnxruntime-gpu matching your CUDA and set onnx_providers in config/policy/<robot>_policy.yaml.
PICO teleoperation needs another environment, ufo-teleop, as well as the XRoboToolkit service and xrobotoolkit_sdk; see scripts/teleop/README.md in the deploy branch for the installation steps.
5.3 Downloading the released models#
The model files are large and not stored in Git; they go under model/<robot>_policy/ (see the Model Files section of the deploy branch README for the download command for released models). The downloaded directory should be:
model/<robot>_policy/
├── exported/
│ ├── FBcprAuxModel.onnx # The policy
│ └── backward_encoder.onnx # Encodes a target state into z
├── tracking_inference_mjlab/*.pkl # z sequences for motion tracking
├── reward_inference_mjlab/*.pkl # z for reward tasks
├── goal_inference_mjlab/*.pkl # z for target poses
└── release_manifest.yaml # File manifest and checksumsAfter downloading, verify the SHA-256 in release_manifest.yaml using the script in the README.
Note The policy, encoder, z files, and deployment code are released as a validated whole. Do not mix old model files with the latest deployment code unless compatibility is explicitly stated.
5.4 Sim2Sim#
Terminal A starts MuJoCo:
cd "$UFO_ROOT" && conda activate ufo-deploy
python -m sim_env.base_sim \
--robot_config ./config/robot/<robot>.yaml \
--scene_config ./config/scene/<robot>.yamlTerminal B starts the policy:
cd "$UFO_ROOT" && conda activate ufo-deploy
python rl_policy/ufo_policy.py \
--robot_config config/robot/<robot>.yaml \
--policy_config config/policy/<robot>_policy.yaml \
--model_path model/<robot>_policy/exported/FBcprAuxModel.onnx \
--task config/exp/tracking/tracking.yaml--task determines which task to execute: config/exp/tracking/tracking.yaml (tracking offline motions), config/exp/goal/goal.yaml (goal reaching), config/exp/reward/locomotion.yaml (reward task).
Control with the keyboard in the policy terminal:
| Key | Purpose |
|---|---|
i |
Interpolate to the default standing pose |
] |
Enable the policy output |
[ |
Start tracking the motion |
p |
Reset the tracked motion to the stop frame |
o |
Stop the policy output and hold the current joint positions |
n |
Switch to the next reward or goal z |
5.5 Teleoperation Sim2Sim#
On the workstation, open four terminals and start them in order:
| Terminal | Environment | Launch | Purpose |
|---|---|---|---|
| A | ufo-deploy |
python -m sim_env.base_sim ... (same as 5.4) |
MuJoCo |
| B | ufo-teleop |
scripts/teleop/teleop_pose_50hz.sh |
Receive PICO data and retarget it into robot poses |
| C | ufo-deploy |
python scripts/realtime/realtime_z_server.py ... |
Use backward_encoder.onnx to encode poses into z in real time |
| D | ufo-deploy |
python rl_policy/ufo_policy.py ... --task config/exp/tracking/teleop.yaml |
Subscribe to the real-time z and run the policy |
See the Teleop Sim2Sim section of the deploy branch README for the full parameters of Terminal C; if the CUDA version of ONNX Runtime is not installed, change --device cuda to --device cpu.
Real-time z is in a "frozen" state by default. Once the policy is ready, press the right-hand A button on the PICO to start following; the left-hand X button freezes the current z.
5.6 Preparing the robot#
On the robot's onboard compute unit, you need:
| Dependency | Description |
|---|---|
| Python 3.10 venv | Install requirements/runtime.txt |
| Low-level control bindings | The robot's low-level control Python bindings, which must match the Python version and CPU architecture |
| CycloneDDS | The DDS runtime |
| Network interface | Fill in the low-level DDS interface name in config/robot/<robot>_real.yaml (check with ip -br addr) |
| Model files | The same model/<robot>_policy/ as on the workstation |
| PICO teleoperation (optional) | requirements/teleop.txt, the XRoboToolkit headless service, xrobotoolkit_sdk |
Use rsync to sync the repository and models from the workstation to the robot. Then on the robot:
Confirm that all CPU cores of the onboard compute unit are online:
cat /sys/devices/system/cpu/online;Run the preflight check that does not drive the motors:
ONBOARD_PY=<venv path>/bin/python \ scripts/onboard/run_preflight_suite.sh --profile ordinary
5.7 Sim2Real#
On the robot, after setting the environment variables for CycloneDDS and the low-level control bindings (see the deploy branch README), start the policy:
UFO_REAL_ROBOT_OK=1 python rl_policy/ufo_policy.py \
--robot_config config/robot/<robot>_real.yaml \
--policy_config config/policy/<robot>_policy.yaml \
--model_path model/<robot>_policy/exported/FBcprAuxModel.onnx \
--task config/exp/tracking/tracking.yamlUFO_REAL_ROBOT_OK=1 is the confirmation switch for real-robot control; set it only when about to control the real robot.
Operate with the robot's remote controller (the specific keys follow the robot's deployment config):
| Operation | Purpose |
|---|---|
| Enter standing | Interpolate to the default standing pose (about 10 seconds at 50 Hz) |
| Enable the policy | Enable the policy output |
| Start tracking | Start tracking the motion |
| Reset | Reset the tracked motion to the stop frame |
| Stop | Stop the policy output and hold the current joint positions |
| Switch z | Switch to the next reward or goal z |
For emergencies, use the physical emergency stop.
5.8 Onboard PICO teleoperation#
PICO connects directly to the robot, and all programs run on the robot's onboard compute unit:
PICO → XRoboToolkit service → retarget into robot poses → real-time z computation → UFO policy → robotStart the XRoboToolkit service and set the target IP to the robot's IP in the PICO app.
Robot Terminal A, start the pose bridge:
scripts/teleop/teleop_pose_50hz_onboard.shRobot Terminal B, start real-time z:
Z_PY=<venv path>/bin/python scripts/realtime/run_realtime_z_server_onboard.shRobot Terminal C, start the policy that subscribes to real-time z (must set
UFO_REAL_ROBOT_OK=1; see the deploy branch README for the launch script).
Division of labor between the two controllers:
| Device | Button | Purpose |
|---|---|---|
| Robot remote | Corresponding buttons | Stand / enable policy / start tracking / reset reference |
| Robot remote | Stop button | Global stop lock: while held, both the policy and tracking stop; after releasing, you must first release the other buttons, then re-enable |
| PICO | Right hand A | Start or resume following the real-time motion |
| PICO | Left hand X | Freeze the current z |
PICO buttons only control the reference motion; they cannot enable the policy, release the stop lock, or replace the physical emergency stop.
Safety mechanisms: when the teleoperation data is stale or invalid, the real-time z service stops publishing; if the policy does not receive a valid 256-dimensional z within ctx_zmq_timeout_ms (200 ms by default), it stops outputting; the final joint targets are clipped to the robot's joint velocity limits.
For the configuration of split teleoperation (retargeting and real-time z on the workstation), see Section 5B of the deploy branch README.
5.9 Real-robot safety checklist#
Before enabling the policy, confirm each item:
-[ ] The physical emergency stop is within reach and has been tested;
-[ ] For the first run, the robot is suspended or supported;
-[ ] All CPU cores of the onboard compute unit are online;
-[ ] Both ONNX files can be loaded on the robot;
-[ ] The interface name in <robot>_real.yaml is correct;
-[ ] Both Sim2Sim and teleoperation Sim2Sim have passed;
-[ ] The global stop lock of the remote controller has been tested;
-[ ] The real-time z watchdog has been tested by disconnecting PICO, XRoboToolkit, or the network;
-[ ] Set UFO_REAL_ROBOT_OK=1 only when about to control the real robot.
Note The MP4 included with the released models is only a simulation replay and does not prove real-robot safety. What has been verified so far is that ordinary Sim2Real and onboard PICO teleoperation can run on the real robot; systematic fault injection, long-duration free walking, and impact-limit tests have not yet been completed.
5.10 Ports#
| Port | Direction | Purpose |
|---|---|---|
| 28701 / 28702 | Real-time z service ↔ pose bridge | Request and return poses |
| 28703 | Pose bridge → real-time z service | PICO buttons |
| 28711 | Real-time z service → policy | Real-time z; 127.0.0.1 when onboard, the workstation IP when split |
| 8080 | Browser → retargeting viewer | Optional, only used for debugging |
6. New robot#
This section generates configs for a new robot and starts training. This route is experimental: the repository's built-in default robot config is the most thoroughly tested, and new robots typically still need adjustments to the controller, rewards, contacts, and termination conditions.
6.1 What you need to prepare#
The target robot's MuJoCo XML;
An optional corresponding URDF;
RobotState motion data already retargeted to the target robot (see Section 2).
6.2 Generating a config draft#
uv run python -m humanoidverse.tools.robot_inspect \
--xml /path/to/robot.xml \
--urdf /path/to/robot.urdf \
--name my_robot \
--out configs/robots/my_robot.yaml \
--hydra-out humanoidverse/config/robot/my_robot/my_robot_auto.yamlThe tool extracts body names, actuated joint order, motion dimensions, joint ranges, and the floating base from the XML. The XML is the sole basis for the joint order and motion layout.
The URDF is optional auxiliary information, used to supplement hardware parameters such as torque, velocity, damping, and friction; when the two conflict on joint limits, the XML takes precedence by default. When the joint names in the XML and URDF differ, use
--urdf-joint-name-mapto specify the correspondence.When
--hydra-outis added, the Hydra robot config needed by the training environment is also generated.
6.3 Manually checking the config#
The generated config is marked as a draft (review_status: draft), and its semantic fields are heuristic guesses. Before formal training, at least check:
The base (
base_body), feet (feet), hands (hands), and key body parts (key_bodies);The actuated joint order and initial pose;
PD gains and actuator limits;
Contact bodies, and fields related to rewards and termination conditions.
6.4 Importing data and quick training#
Per Sections 2.2 and 2.3, replace --robot with the new robot's config to inspect and import the data. Then run a quick test:
./run_train.sh \
--agent fb \
--robot-config configs/robots/my_robot.yaml \
--data-manifest configs/data/my_motion_auto_build.yaml \
--gpu-ids single \
--smoke \
--work-dir /tmp/ufo_smoke_my_robotWhen robot_config is written in the data manifest, --robot-config can be omitted; when both are present, UFO checks whether they point to the same robot. After the quick test passes, remove --smoke and set the GPU and training parameters for formal training.