soma-retargeter: turning SOMA BVH motion into humanoid robot joint data
SOMA BVH to humanoid robot motion retargeting library built with Newton and NVIDIA Warp
At a glance
- What is it?
- NVIDIA's SOMA Retargeter converts human motion in a SOMA-skeleton BVH file into per-frame joint values for five bundled humanoid robots, solving inverse kinematics and writing CSV output for simulation or controller pipelines. It is a data preparation tool in active beta, not a controller.
- Who is it for?
- soma-retargeter fits research teams that already capture or synthesise motion in the SOMA skeleton and need it expressed as joint targets for a specific humanoid, especially when a robot configuration does not yet exist in the bundle. It does not fit teams holding arbitrary BVH files from other capture tools, since the retargeter expects the SOMA base skeleton hierarchy, and it does not produce controller-ready trajectories on its own.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the retargeter produces and where it stops
SOMA Retargeter reads a BVH file in the SOMA skeleton and produces joint animation for a humanoid robot. The output is a CSV file that holds the robot root pose and the actuated joint values over time, and the README is explicit that this is the end of the tool's responsibility: the result is something you can inspect, compare, or pass to downstream robot-control and simulation tools.
The pipeline is five steps, and the order matters. It reads a SOMA-base skeleton BVH animation, retargets the human-scale joints to the robot's proportions, solves inverse kinematics for each frame, stabilises contacts and clamps configured joint limits, and finally writes the root pose and joint values to CSV.
The critical word in that list is kinematic. The README carries a warning that the project is in active beta, so APIs and features may change without notice, and that generated motion is kinematic, meaning you must validate safety, feasibility and controller compatibility in simulation before using it on hardware. That is not a boilerplate disclaimer. The tool solves for joint angles that reproduce a human motion on a differently proportioned robot. Nothing in this pipeline accounts for the robot's ability to produce those angles, whether the resulting motion is dynamically stable, or whether the controller can track it.
So the audience is a research team preparing motion data for a humanoid, not someone looking for a way to make a robot walk.
Only the SOMA base skeleton loads, and the README says why
This is the constraint that will decide whether the project is usable for you, so it is worth stating early. The README says the retargeter currently expects the source hierarchy and naming used by the SOMA base skeleton, and that an arbitrary BVH exported from another character or motion capture package may load incorrectly or fail because its skeleton is different.
That is a hard input requirement, not a soft one. A BVH file contains a skeleton hierarchy and one pose per animation frame, and the retargeter maps joint names and hierarchy to the target robot. If the source names do not match, there is nothing to map them from.
The workaround the project suggests is to start with the bundled example. The README names assets/motions/bvh/Neutral_walk_forward_002__A057.bvh as the file to use for the first run, with the reasoning that keeping the input known removes one source of uncertainty while you test the installation. The repository ships 10 example BVH motions with matching CSV results for all five bundled robots, plus 15 more BVH motions used as inputs for inverse-kinematics weight optimisation.
If your motion data is not in the SOMA skeleton, the related projects in the same ecosystem are the path. GEM-X is described as human motion estimation from video, and the SOMA Body Model is a parametric human body model with a standardised skeleton, mesh and shape parameters. Retargeting from a different capture format is work the retargeter does not do for you, and the README does not document a converter for it.
Five bundled robots, and the naming quirk in the last one
Five robot targets ship with the project, and the README says to use these exact names: unitree_g1, unitree_h2, booster_t1, agibot_x2ultra, and agibot-a3t3.
unitree_g1 is the default target and the recommended choice for the first tutorial. The other four cover a broader set of bodies, and configuration and model assets for each are included in the repository.
Watch the last name. the fifth target name contains a hyphen where the fourth contains a low line, which is exactly the kind of inconsistency that costs an afternoon when a headless config references the wrong key. The interactive viewer lists discovered targets in its robot selector, so the name is visible there. Headless conversion reads the target from the retarget_target field in the converter configuration, where a typo surfaces as a lookup failure rather than a wrong result.
There is a second thing to know about the output. Joint columns correspond to the selected robot model, so two target robots produce different columns from the same BVH. Any comparison script you write has to be robot-aware. The bundled reference results under assets/motions/csv/ are organised by robot for exactly that reason, and the README tells you to select the folder matching your target robot.
The reference results are also a check, not a contract. The README says your result should have the same general motion, but that exact values can change when configuration or dependency versions change. That warning is about a real risk in this design, discussed further in the dependency section below.
Running the converter: one documented command and a viewer
The documentation states a command convention: run commands from the repository root, and use uv because it creates and manages the project environment without requiring you to activate it manually. The reference command for the interactive viewer is:
uv run python app/bvh_to_csv_converter.py --config assets/default_bvh_to_csv_converter_config.json --viewer glThe --viewer gl argument selects the OpenGL viewer, and the config path points at the default converter configuration that ships with the repository. Paths with forward slashes work in PowerShell and in Linux shells, and a path with spaces needs quotes.
Behind that single entry point sit two working modes. The interactive viewer is for loading, retargeting, inspecting and saving one motion at a time, which is what the first-retarget tutorial walks through. Headless mode converts folders of motions, and the documentation covers batch retargeting as converting a directory tree without opening a viewer. For anyone processing a dataset, that headless path is the one that matters.
The project also ships tooling beyond the converter itself: tools for configuring another robot, and tools for tuning and optimising inverse-kinematics weights. A guided robot configurator walks through adding a robot the project does not already ship, using Unitree H1 as its worked example, and a separate reference page documents manifests, model descriptions, retargeting objectives, scaling and post-processing settings.
The documentation structure is worth noting as a sign of how the project is meant to be used. Eleven pages run from installation through first retarget, configurator, configuration reference, contact detection, interactive retargeting, the IK weight optimiser, compare and tune, batch retargeting, a code overview and troubleshooting, with the last covering installation, viewer, input, GPU and output problems.
Contacts and joint limits are handled for you, which is where surprises live
Step four of the pipeline is where most retargeting tools get their quality: stabilising contacts and clamping configured joint limits. The project documents this in a dedicated page on contact detection and foot plant correction configuration, and the behaviour it describes is worth understanding before you judge the output.
Foot contact matters because a human walk has a planted foot that the retargeter must keep planted. If the foot slides, the resulting joint trajectory contains small errors that accumulate, and the error looks like solver noise rather than a plant failure. Correcting the plant is what keeps the retargeted motion visually and numerically consistent with the source.
Joint limits are the other half. A robot cannot bend its knee the way a human can, and a retargeter that ignores this produces joint angles outside the robot's range, which then have to be clamped somewhere else in the pipeline, usually badly. Doing it inside the retargeter keeps the output within what the model can express.
The trade is that these are configured behaviours rather than solved ones. The foot-contact page and the robot configuration reference are where you set them, and the IK weight optimiser exists because the retargeting objectives are weighted rather than fixed, meaning a configuration that suits a walk may not suit a fast turn. That is also why the project ships 15 BVH motions for weight optimisation and why the compare-and-tune page exists as a separate step.
The risk to keep in mind is that clamping hides problems. A configuration that clamps heavily can produce output that looks plausible in a viewer and still be a poor target for a controller. That is why the reference CSV comparison matters more than the visual check.
Pinned dependencies and a licence that covers bundled assets
The package metadata shows a deliberately pinned dependency set, and for a tool that produces numbers you feed to a controller, pinning is a feature rather than an inconvenience:
"newton==1.3.0",
"warp-lang>=1.14.0",
"numpy==2.4.3",
"scipy==1.17.1",
"imgui-bundle==1.92.4",
"usd-core==26.3",Newton and NVIDIA Warp are the simulation and compute foundation the project description names, and they are what the README means when it says the retargeter is built with them. The rest of the list explains the rest of the tool: pyglet and imgui-bundle for the interactive viewer, usd-core for the robot model assets, pycollada and trimesh for geometry and model description files, scipy for the optimisation work, and defusedxml for XML parsing. Python 3.12 or newer is required.
Note the asymmetry in the constraints. Some dependencies are pinned to an exact version, others have a floor. Warp is specified as greater than or equal to 1.14.0, which means a newer Warp can enter your environment. Combined with the README's warning that exact output values can change when dependency versions change, that is a genuine reproducibility concern for anyone comparing runs across machines. The uv.lock file in the repository and the uv workflow exist to control this, and pinning your environment to the lock file is the difference between comparable numbers and merely similar ones.
The licence is Apache-2.0, and the packaging metadata lists both the root LICENSE and the files under licenses/ as licence files, which means bundled assets carry their own terms. The motion data has a separate layer: the bundled BVH examples and optimiser inputs are provided with permission from Bones and are drawn from the BONES-SEED dataset, and the README points to BONES-SEED for the broader collection and its licensing options. If you publish results derived from those motions, that is the licence chain to check.
Beta status, no releases, and where this sits in the SOMA ecosystem
The repository is not archived and the last push was on 2026-10-01, so work is continuing. It has no GitHub releases, however, and the version is dynamic, read from an attribute on the package. There is a CHANGELOG.md and a CONTRIBUTING.md at the root, and a SECURITY.md for reporting issues.
Against the README's own warning that APIs and features may change without notice, the absence of tagged releases is the thing to plan around. You cannot pin to a released version, so pinning means pinning a commit, and the lock file becomes the only reproducible artefact. A team that wants monthly runs compared against each other needs to freeze the environment explicitly.
The retargeter is one tool in a wider set. The README positions it as a support tool within the SOMA ecosystem for humanoid motion data, and lists the neighbours: the SOMA Body Model for a parametric human body with a standardised skeleton, GEM-X for estimating human motion from video, Kimodo as a kinematic motion diffusion model for text and constraint-driven motion generation, ProtoMotions as a GPU-accelerated simulation and learning framework for physically simulated digital humans and humanoid robots, and SONIC for whole-body control of humanoid robots.
The last of those marks the boundary of this tool. SONIC is where a policy that actually moves the robot lives, and this retargeter's output is a target that such a controller might chase. If you are looking for something that turns motion into a walking robot on its own, this is the wrong project, and the related work list is the fastest way to see what you would need next.
Editorial conclusion
soma-retargeter fits research teams that already capture or synthesise motion in the SOMA skeleton and need it expressed as joint targets for a specific humanoid, especially when a robot configuration does not yet exist in the bundle. It does not fit teams holding arbitrary BVH files from other capture tools, since the retargeter expects the SOMA base skeleton hierarchy, and it does not produce controller-ready trajectories on its own. Before adopting it, run the bundled Neutral_walk_forward_002__A057.bvh through the default unitree_g1 configuration, compare against the reference CSV in assets/motions/csv/, and read the foot-contact and robot-configuration reference pages before trusting results on a different robot.
Frequently asked questions
What input format does soma-retargeter accept?
It expects a .bvh file using the SOMA base skeleton hierarchy and naming, and the README warns that an arbitrary BVH from another capture package may load incorrectly or fail.
What does soma-retargeter output?
A CSV file holding the robot root pose and actuated joint values over time, with joint columns matching the selected robot model.
Which robots are supported out of the box with soma-retargeter?
Five targets are bundled: unitree_g1 as the default, unitree_h2, booster_t1, agibot_x2ultra and agibot-a3t3.
How do I run the soma-retargeter converter?
The README gives the command uv run python app/bvh_to_csv_converter.py --config assets/default_bvh_to_csv_converter_config.json --viewer gl, run from the repository root, using uv to manage the environment.
Can soma-retargeter output be used directly on real robot hardware?
The README states the generated motion is kinematic and that safety, feasibility and controller compatibility must be validated in simulation before hardware use, and the project is in active beta.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nvidia-soma-retargeter)Was this useful?