Humanoid movement through physics and optimization
Deriving jumping, throwing, running, and carrying motions from robot geometry and motor limits in MuJoCo. Simulation studies across humanoid bodies without human demonstration data.
Sat Sep 12 2026 00:00:00 GMT+0000 (Coordinated Universal Time)
At a glance
Question
Which humanoid motions can be derived from geometry, motor limits, and physics without copying human demonstrations?
My contribution
Developed MuJoCo optimization experiments for jumping, throwing, running, and carrying across different robot bodies.
Result & scope
Simulation studies with recorded successes and failures. These are not hardware deployments or a generally validated controller.
In this write-up
Work in progress. Every clip is a replay of a stored
simulation, checked at two physics time steps. Simulation only: nothing here has run on hardware.
Labels say when a body was modified (“what-if”), when an object is attached rather than gripped,
and which simulator settings a result depends on.
How these movements were made: no demonstrations, no learned policy
Nothing on this page was learned from people. No motion capture, no teleoperation, no video of
humans, no imitation dataset, and no neural network anywhere in the pipeline. Each movement is
constructed:
The robot’s own specification goes in: its geometry, masses, joint limits and each motor’s
rated torque and speed, read from the manufacturer’s model.
A physical goal goes in: release a ball fast, move the body forward, keep a load on the head.
The goal says what must happen, never how.
A starting motion is derived from the body: which joint motions move the hand or the body
most effectively given each motor’s limits.
Search on real physics refines it, and the robot discovers the technique by trial in simulation,
checked against the motors’ real limits at two simulation time steps.
The only “experience” is simulation the system generates for itself, roughly 2,400 to 38,400 trial
runs per technique (minutes to a few hours on a desktop CPU). That is the whole cost of a new skill
on a new body.
Typical learned-robot approach
This work
Human demonstrations
thousands of examples per skill
none
Learned model
large neural policy
none
New robot
recollect data, retrain
same code, new spec file
What the robot needs
a dataset
its own specification and a goal
The one place human data appears is the first jump clip below, a recorded human jump replayed on
the robot as a comparison baseline. The motion the robot derived from its own body beat it.
What is supplied by hand, and stated with every result: the broad structure of some starting
motions (for example “wind up, then release”), the balance and foot-placement controllers, and the
simulator settings. The movements themselves are found, not authored.
Jumping
Start: a recorded human jump mapped onto the G1 and tracked.A starting strategy computed from the robot's own specification: a certified deep crouch, then full extension.
The deep jump, landed by a balance controller.
Unitree G1, stock body, jumps onto a 0.20 m box, lands with both feet on top and holds its balance for 3 s. Valid at both simulation time steps with a 10 ms motor lag, and robust to most perturbations. The feet are placed ahead of the body in flight to absorb the forward momentum.The waist runs within a hair of its joint stop on the push; 0.30 m is still out of reach for this body.
Throwing
A wind-up derived from the robot's own body, refined by search: hips swivel on planted feet, the arm trails the trunk.Historical render: this version exceeded the wrist's rated speed and is not a valid speed figure. The same construction under the specified actuator limits reaches 20-23 m/s.The same construction at full search budget: 22.6 m/s release under the simulator model's motor limits (with Unitree's lower published knee limit and a 10 ms motor lag, about 15 m/s at a smaller budget), valid at both time steps. Ball flight drawn from the release state.Ball flight is computed drag-free from the release state.Change the body, and the technique reorganises: halve the arm's torque and the hips and trunk take over; halve the legs' torque and the arm does more of the work.What-if bodies (torque scaled), not robot capability.
Throwing at a target
The goal is no longer “as fast as possible” but “land the ball within 0.5 m of a target”. The body is the stock G1, its motors are held to their published torque ratings with a 10 ms response lag, and the ball is free once released.
10 m target: the ball lands 0.12 m from the centre (9.4 m/s release). It still hits on 14 of 16 randomized versions of the robot and its start that the search never saw.The hand holds the ball by an attachment until release, not a finger grip. Ball flight is drag-free. One smaller independent check passed only 2 of 4, so the margin is thin.15 m target: hit on the nominal robot (0.42 m from the centre, 11.5 m/s), but not reliably. Only 7 of 16 randomized versions land inside the circle.Shown as a limit, not a result. At this distance a 2% change in release speed moves the ball half a metre.
Kicking
G1 kicks a simulated football from one-foot support: 11.8 m/s ball speed. The weight shift, foot lift and hip-to-foot sequencing came out of the construction, not a script.Earlier, looser checks: this kick was not tested against the joint-stop and after-the-kick balance checks used below.Aimed kick into a 2 m goal 5 m away, on the stock G1 with rated torques and a 10 ms motor lag: 4.9 m/s, scored on all 16 randomized versions it was tested on and on 4 more from an independent check.Honest limits: the robot falls after every kick. Only 1 of the 12 goal setups tried passes this reliably, and the angled goals found nothing valid. The ankles hitting their joint stops are what limits it. A small sphere on the foot (an attachment) makes the ball contact.
Running
Unitree G1, stock body: a running gait constructed from its own specification and refined by search on the real physics.2 ms actuator lag.Unitree H1, same code, no changes: 3.2 m/s (its documented record is 3.3 m/s).Depends on a stiffer foot-contact setting than the simulator default.
Apptronik Apollo, a robot never used while building the method: 2.4 m/s with no code changes. With the body-derived starting motion removed, the same search never finds a valid gait.Apollo's joint speed ratings are not published and were assumed.What-if body: H1 with four-times-stronger ankles reaches 5.1 m/s. The stock ankle is too weak to push off through the foot.Modified body, not robot capability.
Same code, four bodies: G1, H1 and Apollo running side by side; Booster T1 cannot run at its published ratings, which a dynamic model computed from its specification also predicts.Lag and contact settings as labelled on each lane.
Walking
Walking is the dull-looking hard case: a periodic gait with both feet sharing the load at every step, no sliding, steady speed and heading. Both robots use their stock bodies and published motor ratings with a 10 ms motor lag, and each walk was checked at two physics time steps.
Unitree G1 walking at 0.72 m/s. It passes 14 of 16 held-out disturbances: heavier or lighter limbs, start errors, slower motors, lower friction and shoves.The controller is given the robot's true centre of mass, which a real robot would have to estimate.Unitree H1 walking at 0.99 m/s, same code: 15 of 16 held-out disturbances pass.The H1's ankle runs at its torque rating.
A failure: a sideways shove from the other side at the wrong moment of the stride knocks the G1 over. Sideways push recovery works only in some phases of the step, so it is not claimed.
Walking with a load on the head
The body-derived arm-balance law from the standing head carry, now while walking at 0.75 m/s. The load is a free object resting on the head, not attached.
G1 with hands walking 8.3 m with a free 15 kg pot on its head. The pot stays within 2 cm of the head top, and all 16 tested disturbances pass.The pot is placed at rest at the start. With the balance law switched off it falls within 0.6 s.20 kg at the same speed: a valid carry, but not a reliable one (12 of 16 disturbances pass).
Why 20 kg is not reliable: if the pot is 10% heavier than the controller assumes, it slides off within the first second. At the start of the walk the waist motors are already at their torque rating.The proposed fix, starting from a stand and ramping up the stride, is untested.
Carrying with the body’s structure
G1 with hands, standing: a free 32 kg box resting on its head, kept there by the arms, with a 10 ms motor lag. The balancing law is built from the arm's own geometry and motor limits. Second half: the same posture with the law switched off, and the box falls in under a second. Hands-only carrying tops out at 6-8 kg.Requires a cap on the servo gains (a controller choice). Without motor lag, a 40 kg pot also holds. With lag, 40 kg is fragile.A 45 kg bag is too heavy to lift; the search tips it onto its wheels and leans it against the hips instead, a use of the body nobody specified.Hands attached to the handle (not a finger grip).
Manipulation
G1 with Dex3 hands: a real finger wrap of a brush handle, then a force-controlled wipe.