← All work

Bracing for a hit

Does warning a walking robot before a shove keep it on its feet? Two simulated robot dogs, identical but for a four-number warning, shoved about 148,000 times.

5× fewer falls at 250 N Unitree Go1 · MuJoCo mjlab · PPO (rsl_rl) 148k measured shoves Simulation only

Shove it yourself

The trained policies, running in your browser on MuJoCo compiled to WebAssembly. Pick a robot, set the force, and click or tap the floor to shove it from that side.

The not-warned robot walks low; it does in the clips below too. W A S D or the arrows steer, Space throws a random shove. In this browser physics, 2,000 shoves per robot at 250 N gave 1.6%, 5.4% and 52.4% falls, against 1.2%, 6.1% and 52.3% in the study.

Same shove, three robots

All three at 250 N, about 1.8× the robot's weight. The overlay calls them anticipatory, reactive and anticipatory (blind). Independent rollouts, so an illustration, not the measurement.

What I did

I trained two robots to walk while being shoved from a random direction every 3–6 s. One saw a warning before each shove: direction, strength and time to impact. Then I froze both and shoved them at seven fixed strengths, 1024 robots in parallel.

The warning only matters once the shove is hard

Up to 160 N the two tie: 0.9% and 0.8% falls. Reacting after the shove is fast enough there; the robot acts 50 times a second. The gap opens at 200 N and is large at 250 N.

Testing only up to 160 N would have said the warning does nothing.

Line chart of falls per shove against shove strength for three robots. Warned and not-warned track each other near zero until 160 N, then separate: at 250 N the warned robot falls 1.2% of the time and the unwarned one 6.1%. The warning-switched-off line climbs steeply from 120 N to 52.3% at 250 N.
Falls per shove, by shove strength. Bars are 95% Wilson intervals.

Falls per shove

ShoveWarnedNot warnedWarning off
35 N0.0%0.0%0.0%
60 N0.0%0.1%0.0%
90 N0.1%0.5%0.6%
120 N0.5%0.4%2.3%
160 N0.9%0.8%10.4%
200 N0.7%1.7%27.8%
250 N1.2% [1.0, 1.5]6.1% [5.5, 6.6]52.3% [51.4, 53.2]

Between 6,692 and 11,188 shoves per cell. Ranges are 95% confidence intervals.

How far the body tipped

ShoveWarnedNot warnedWarning off
35 N4.9°5.6°5.5°
120 N13.0°15.9°21.2°
250 N16.5°29.2°54.2°

Mean peak trunk tilt; past 70° counts as a fall. The warned robot tips about as far at 250 N as the unwarned one at 120 N.

The warning became a crutch

I fed the trained warned robot zeros where the warning goes, and changed nothing else. Its falls went from 1.2% to 52.3%.

The robot that never had a warning falls 6.1%, so this one ended up about nine times worse than never having one. It learned "brace when told", not how to recover.

That is the third clip above. A warning lost to a failed sensor would look like this, and coping without it is a separate job.

A ball, so you can see it

Every number above comes from a force applied to the body, which you can't see.

Here the same robot gets a real 5 kg ball instead. No measurement comes from these clips. About one throw in three misses: the ball is aimed where the robot will be, and the warned robot slows down when it sees it coming.

How it works

  • Flat ground, speed commands. Every 3–6 s a force hits the body from a random direction, 10 cm above its centre, so it tips rather than slides. It is announced 0.4–1.2 s ahead, lasts 0.1–0.3 s, and the robot is watched for 2 s after.
  • A curriculum raises or lowers each robot's shove strength, so all 4096 training robots sit near their limit.
  • The warning is four numbers: two for direction, one for strength, one for time to impact; all zero when nothing is coming. Removing them is the only difference between the robots.
  • The value estimator sees the warning for both robots; only the actor differs, so the unwarned robot isn't handicapped twice.
  • 4000 training rounds, 393 million simulated steps per robot, about 2.4 hours on a T4.

What this does not prove

  • Each robot was trained once. The intervals cover testing, not training. The crutch result compares one robot with itself, so it holds; the warned-vs-unwarned headline needs three to five seeds.
  • The ceiling was too low. Both robots hit my 250 N cap. I sized it for a 13.93 kg object floating in space and forgot that four legs on the ground absorb much of the blow.
  • Simulation only, with a perfect warning. A real one would be noisy and sometimes wrong, and how this robot copes with a wrong warning is untested.

What is mine and what is not

The robot model, walking task, training algorithm and rewards come from mjlab. I wrote about 450 lines: the threat command (picks a shove, counts down, warns the robot, applies the force), the curriculum, and the two configs, which differ by one line.

I wrote no reward functions; my own would have added differences unrelated to the question. I removed mjlab's built-in random push, an instant velocity change that can't be aimed or announced, so it wouldn't add a second shove neither robot could be warned about.

Links

Code on GitHub: the write-up, the ~148,000-row eval tables, and tests that check the two setups differ by one thing.

Release: both policies, every checkpoint, and all 40 clips.

Cite this

From the repository's CITATION.cff:

@software{goel2026bracing,
  author  = {Goel, Mitanshu},
  title   = {Bracing for a hit},
  year    = {2026},
  version = {1.0.0},
  license = {MIT},
  url     = {https://github.com/mitanshu-2004/brace-for-impact}
}