An LLM at 50 Hz
A checkable answer to a challenge posed on X on 7 September 2026.
Can you prompt an LLM to output the high frequency control commands for a legged robot in varying terrain e.g. ashish-kmr.github.io RSS 2021, CoRL 2022 (this is by now 5 year old technology, so I am not picking a particularly hard task).
@JitendraMalikCV, 7 Sep 2026
Short answer: no, and here is the receipt. I asked Claude to write the 50 Hz joint commands for the smallest legged robot on my desk, a Pollen Microduck, and ran them in the same MuJoCo plant that scores the robot's own trained policy. The LLM's open-loop command table never stood for six seconds on a flat floor, let alone on terrain. Its hand-written balance law can hold a stand but not a walk. The five-year-old recipe, a PPO policy at 50 Hz reading 61 proprioceptive numbers, walks on everything up to its training limit. What the LLM was good for was everything around the loop: the terrains, the instruments, the sign conventions, and finding that the servos cannot even hold the nominal pose without feedback.
What was tested
The robot. Pollen Robotics' Microduck: a 25 cm, roughly 800 g biped with fourteen position-servo joints the policy drives (five per leg, four in the neck and head) plus a mouth. Its runtime runs the policy at 50 Hz over a 61-value proprioceptive observation. This is not a quadruped and not the A1 or the Cassie in the cited papers. It is the legged robot I have a verified simulator for, and it is harder for open loop, not easier: the servos are weak (kp 0.55 N·m/rad, torque limit ±0.64 N·m) and the standing pose is not statically stable on them.
The plant. duckbench's scene.mjb (sha256 3f8c9ab9b409ba74…), MuJoCo 3.1.16 WASM, 5 ms timestep, four substeps per 20 ms control tick. The same plant and the same control loop that every published duckbench number went through, at duckbench commit ee7c71d.
The terrains. Eight, laid from the bench's bank of movable blocks along a 340 mm wide lane. Each block is 200 mm tall with its top at the tread, so a ledge is a real vertical face, not a slope. Pollen trains this robot on steps capped at 15 mm because, in their words in the training config, "the robot can only lift its feet ~1-2 cm". The terrains bracket that.
Three controllers
- A. The LLM's open-loop 50 Hz table. Claude wrote a parametric gait by hand (a hip pitch sinusoid, a knee lift during swing, an ankle that keeps the sole flat, a hip roll weight shift, a 1 s amplitude ramp), expanded it into a literal table of fourteen servo targets every 20 ms, and the table is played with no sensor read after t = 0. This is the challenge as posed. Its five parameters were tuned on the flat floor only with a 72-point grid, three seeds each, then frozen. The best: f = 1.5 Hz, hip 0.05 rad, knee 0.3 rad, roll -0.08 rad.
- B. The same gait plus an LLM-written balance law. Projected gravity and the gyro feed hip pitch and hip roll offsets every tick. Gains tuned on the flat floor with a 27-point grid: kp = -0.4, kr = 0.3, kd = 0. This is the "code as policy" reading of the challenge.
- C. Pollen's trained policy.
alpha_walking.onnx(sha256 e36332d383997d51…), PPO in mjlab, run through the bench's canonical observation and actuation path with a 0.3 m/s forward command. Not tuned. C+ adds a heading hold on the command input (a yaw rate proportional to lateral drift and heading) so the blind policy stays on the 340 mm lane; that is a planner-level input, the kind of thing the post says LLMs are fine at.
Two controls make the failures legible. A0 plays the measured standing servo targets with zero gait amplitude. B0 is the balance law alone, no gait. And C is also run at 0.2 m/s, which turns out to be inside the policy's command dead zone.
Protocol
Every episode: reset with a perturbed start (±2 mm trunk, ±0.02 rad per joint; seed 0 is nominal), 25 ticks of settle under the standing policy, then 300 ticks (6 s) of the controller under test. An episode fell when projected gravity z rose above −0.7 or the trunk dropped below 60 mm, and is standing if at the last tick gravity z is below −0.9 and the trunk is above 90 mm. Ten seeds per cell. The step blocks do not collide with each other (the bench's standard isolation); block-to-robot contact is untouched.
Results
Episodes still standing at six seconds, of ten, per terrain.
Below each bar count in the table: the median distance travelled along the lane, and how many runs walked off the side of the 340 mm lane before the end.
| Controller | flat | ledge10 | ledge15 | ledge20 | rough5 | rough10 | ramp5 | ramp10 |
|---|---|---|---|---|---|---|---|---|
| A. LLM open-loop 50 Hz table | 0/10 0.13 m | 0/10 0.13 m | 0/10 0.13 m | 0/10 0.13 m | 0/10 0.13 m | 0/10 0.13 m | 0/10 0.13 m | 0/10 0.13 m |
| A0. hold the measured standing targets (control) | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m |
| B. LLM gait + LLM balance law | 0/10 0.13 m | 0/10 0.12 m | 0/10 0.12 m | 0/10 0.12 m | 0/10 0.12 m | 0/10 0.12 m | 0/10 0.12 m | 0/10 0.12 m |
| B0. balance law only, no gait (control) | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m | 8/10 0.00 m |
| C. PPO policy, vx 0.3 m/s | 10/10 0.76 m | 8/10 0.74 m off bank 4 | 0/10 0.13 m | 0/10 0.15 m off bank 2 | 10/10 0.74 m | 0/10 0.34 m | 0/10 0.73 m | 0/10 0.33 m |
| C+. PPO policy, vx 0.3 m/s, heading hold on the bank centre line | 10/10 0.75 m | 5/10 0.55 m | 0/10 0.14 m | 0/10 0.08 m | 9/10 0.78 m | 0/10 0.39 m off bank 1 | 0/10 0.43 m | 0/10 0.49 m |
| C at vx 0.2 m/s (below its dead zone) | 10/10 0.01 m | 10/10 0.01 m | 10/10 0.01 m | 10/10 0.01 m | 10/10 0.01 m | 10/10 0.01 m | 10/10 0.01 m | 10/10 0.01 m |
Trunk position on the 10 mm rough terrain, seed 0
Forward position of the trunk over the six seconds. A dot marks the tick the fall criterion fired.
The same on the flat floor
What the numbers say
- Open loop cannot even stand here. Holding the robot's nominal HOME pose on its position servos falls at 0.64 s on a flat floor (see
diag.mjsin the log). The servos sag under the trunk and nothing corrects it. The LLM's fix was to measure what the trained standing policy actually asks the servos for at steady state (its hip roll targets sit 0.18 rad away from HOME, see the table below) and use that as the gait's neutral pose. That holds a stand, A0: 8/10 on flat. - The LLM's gait never walks. Best of 72 grid points on the flat floor still fell at about 2.2 s. On terrain, A stood in 0 of 80 episodes. Every open-loop table an LLM writes has this shape: its feet leave the ground on a clock, and the plant does not read the clock.
- An LLM can write a balance law that stands. B0 holds a stand 8/10 on flat with a negative pitch gain (the sign had to be found by trying both). Adding the gait to it gives B: 0 of 80. A PD on gravity is a stabiliser, not a gait.
- The trained policy walks, up to its training limit. C+ stands 10/10 on flat, 9/10 on 5 mm rough, 5/10 on a 10 mm ledge, then 0/10 at 15 mm and 0/10 at 20 mm. Pollen capped its training terrain at 15 mm; a blind proprioceptive policy trips on the first ledge past what it has felt. That is precisely the gap the cited CoRL 2022 paper closes with egocentric vision.
- Where the policy falls. Every fall on the 15 and 20 mm ledges happens at x = 0.13 to 0.21 m with the trunk within 0.11 m of the lane's centre line: the first riser, mid-lane, not a walk off the side. On the 10 mm rough terrain all ten runs fall at x = 0.39 m, the first 10 to 20 mm rise. On the 5 mm ramp all ten runs clear the first two 5 mm rises and fall at the third, around x = 0.58 m. The heading hold did not help: C+ is worse than C on the 10 mm ledge (5 vs 8 of 10), so the yaw command it adds while the robot is stepping up costs more than the drift it removes.
- A dead zone worth knowing before quoting a number. A 0.2 m/s command produces no walking at all (median 0.011 m on flat, and a perfect 10 of 10 standing on every terrain because it never reaches one). Any comparison at that command measures standing, not locomotion.
What the LLM produced
This is the literal deliverable the challenge asks for: joint targets at 50 Hz, written by the model. It is also what fails.
| t_s | left_hip_yaw | left_hip_roll | left_hip_pitch | left_knee | left_ankle | neck_pitch | head_pitch | head_yaw | head_roll | right_hip_yaw | right_hip_roll | right_hip_pitch | right_knee | right_ankle |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.00 | 0.0021 | -0.2674 | -0.4073 | -0.1054 | 0.5105 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2708 | 0.3921 | 0.0925 | -0.4592 |
| 0.02 | 0.0021 | -0.2677 | -0.4083 | -0.1043 | 0.5126 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2705 | 0.3911 | 0.0925 | -0.4582 |
| 0.04 | 0.0021 | -0.2686 | -0.4092 | -0.1010 | 0.5168 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2696 | 0.3902 | 0.0925 | -0.4573 |
| 0.06 | 0.0021 | -0.2700 | -0.4098 | -0.0958 | 0.5227 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2682 | 0.3896 | 0.0925 | -0.4567 |
| 0.08 | 0.0021 | -0.2718 | -0.4102 | -0.0890 | 0.5298 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2664 | 0.3892 | 0.0925 | -0.4563 |
| 0.10 | 0.0021 | -0.2739 | -0.4102 | -0.0811 | 0.5377 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2643 | 0.3892 | 0.0925 | -0.4563 |
| 0.12 | 0.0021 | -0.2761 | -0.4099 | -0.0728 | 0.5456 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2621 | 0.3895 | 0.0925 | -0.4566 |
| 0.14 | 0.0021 | -0.2782 | -0.4090 | -0.0647 | 0.5529 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2600 | 0.3904 | 0.0925 | -0.4575 |
| 0.16 | 0.0021 | -0.2802 | -0.4078 | -0.0575 | 0.5589 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2580 | 0.3916 | 0.0925 | -0.4587 |
| 0.18 | 0.0021 | -0.2817 | -0.4062 | -0.0518 | 0.5629 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2565 | 0.3932 | 0.0925 | -0.4603 |
| 0.20 | 0.0021 | -0.2826 | -0.4042 | -0.0483 | 0.5645 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2556 | 0.3952 | 0.0925 | -0.4623 |
| 0.22 | 0.0021 | -0.2828 | -0.4020 | -0.0476 | 0.5630 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2554 | 0.3974 | 0.0925 | -0.4645 |
| 0.24 | 0.0021 | -0.2822 | -0.3997 | -0.0499 | 0.5583 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2560 | 0.3997 | 0.0925 | -0.4668 |
| 0.26 | 0.0021 | -0.2807 | -0.3973 | -0.0557 | 0.5502 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2575 | 0.4021 | 0.0925 | -0.4692 |
| 0.28 | 0.0021 | -0.2782 | -0.3950 | -0.0649 | 0.5387 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2600 | 0.4044 | 0.0925 | -0.4715 |
| 0.30 | 0.0021 | -0.2748 | -0.3930 | -0.0776 | 0.5240 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2634 | 0.4064 | 0.0925 | -0.4735 |
| 0.32 | 0.0021 | -0.2706 | -0.3914 | -0.0934 | 0.5067 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2676 | 0.4080 | 0.0925 | -0.4751 |
| 0.34 | 0.0021 | -0.2657 | -0.3903 | -0.1054 | 0.4935 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2725 | 0.4091 | 0.0861 | -0.4826 |
| 0.36 | 0.0021 | -0.2602 | -0.3899 | -0.1054 | 0.4931 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2780 | 0.4095 | 0.0656 | -0.5035 |
| 0.38 | 0.0021 | -0.2545 | -0.3901 | -0.1054 | 0.4933 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2837 | 0.4093 | 0.0440 | -0.5249 |
| 0.40 | 0.0021 | -0.2486 | -0.3911 | -0.1054 | 0.4943 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2896 | 0.4083 | 0.0220 | -0.5459 |
| 0.42 | 0.0021 | -0.2429 | -0.3929 | -0.1054 | 0.4961 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.2953 | 0.4065 | 0.0006 | -0.5654 |
| 0.44 | 0.0021 | -0.2377 | -0.3955 | -0.1054 | 0.4987 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.3005 | 0.4039 | -0.0190 | -0.5824 |
| 0.46 | 0.0021 | -0.2332 | -0.3988 | -0.1054 | 0.5020 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.3050 | 0.4006 | -0.0358 | -0.5960 |
| 0.48 | 0.0021 | -0.2297 | -0.4028 | -0.1054 | 0.5060 | 0.2717 | 0.3586 | -0.0309 | 0.0262 | -0.0093 | 0.3085 | 0.3966 | -0.0489 | -0.6051 |
First 25 of 300 rows. Every row is one 20 ms control tick: fourteen servo position targets in radians, the whole 6 s table in commands_open_loop.csv.
The measured neutral pose the table rides on
Mean servo targets over ticks 100 to 299 of the trained standing policy on the flat floor, three seeds. The LLM's gait is written as offsets from this column, because offsets from HOME fall over in under a second.
| joint | HOME (rad) | measured standing target (rad) | delta |
|---|---|---|---|
| left_hip_yaw | 0.0000 | 0.0021 | +0.0021 |
| left_hip_roll | -0.0873 | -0.2674 | -0.1801 |
| left_hip_pitch | -0.4579 | -0.4073 | +0.0506 |
| left_knee | -0.0049 | -0.1054 | -0.1005 |
| left_ankle | 0.4530 | 0.5105 | +0.0575 |
| neck_pitch | 0.3491 | 0.2717 | -0.0774 |
| head_pitch | 0.3491 | 0.3586 | +0.0095 |
| head_yaw | 0.0000 | -0.0309 | -0.0309 |
| head_roll | 0.0000 | 0.0262 | +0.0262 |
| right_hip_yaw | 0.0000 | -0.0093 | -0.0093 |
| right_hip_roll | 0.0873 | 0.2708 | +0.1835 |
| right_hip_pitch | 0.4579 | 0.3921 | -0.0658 |
| right_knee | 0.0049 | 0.0925 | +0.0876 |
| right_ankle | -0.4530 | -0.4592 | -0.0062 |
Tuning grids, in full
Open loop (A):
72 grid points, flat floor, seeds 0 to 2 (score = 100 + metres if standing at 6 s, else seconds survived + metres)
| f | A | K | Rl | score | standing | travelled | fell at (s) |
|---|---|---|---|---|---|---|---|
| 1.5 | 0.05 | 0.3 | -0.08 | 2.172 | 0/3 | 0.132 | 2.12, 1.92, 2.08 |
| 1.5 | 0.05 | 0.3 | -0.04 | 2.137 | 0/3 | 0.131 | 2.1, 1.88, 2.04 |
| 1.5 | 0.05 | 0.3 | 0.04 | 2.031 | 0/3 | 0.131 | 1.98, 1.82, 1.9 |
| 1.5 | 0.05 | 0.3 | 0.08 | 2.025 | 0/3 | 0.131 | 1.94, 1.82, 1.92 |
| 3 | 0.05 | 0.3 | -0.08 | 2.015 | 0/3 | 0.135 | 1.84, 1.84, 1.96 |
| 3 | 0.05 | 0.3 | -0.04 | 1.968 | 0/3 | 0.134 | 1.82, 1.8, 1.88 |
| 2 | 0.05 | 0.3 | 0.08 | 1.935 | 0/3 | 0.135 | 1.82, 1.76, 1.82 |
| 3 | 0.05 | 0.3 | 0.04 | 1.933 | 0/3 | 0.133 | 1.78, 1.78, 1.84 |
| 2 | 0.05 | 0.3 | 0.04 | 1.929 | 0/3 | 0.135 | 1.8, 1.76, 1.82 |
| 2 | 0.05 | 0.3 | -0.08 | 1.927 | 0/3 | 0.134 | 1.84, 1.74, 1.8 |
| 3 | 0.05 | 0.3 | 0.08 | 1.919 | 0/3 | 0.132 | 1.76, 1.76, 1.84 |
| 1.5 | 0.05 | 0.15 | -0.08 | 1.915 | 0/3 | 0.135 | 1.84, 1.72, 1.78 |
| 2 | 0.05 | 0.3 | -0.04 | 1.914 | 0/3 | 0.134 | 1.8, 1.74, 1.8 |
| 1.5 | 0.1 | 0.3 | -0.08 | 1.910 | 0/3 | 0.130 | 1.82, 1.7, 1.82 |
| 1.5 | 0.05 | 0.15 | 0.08 | 1.905 | 0/3 | 0.131 | 1.8, 1.72, 1.8 |
| 2 | 0.05 | 0.15 | -0.04 | 1.901 | 0/3 | 0.134 | 1.78, 1.74, 1.78 |
| 1.5 | 0.05 | 0.15 | 0.04 | 1.898 | 0/3 | 0.131 | 1.8, 1.72, 1.78 |
| 1.5 | 0.05 | 0.15 | -0.04 | 1.894 | 0/3 | 0.134 | 1.78, 1.72, 1.78 |
| 3 | 0.05 | 0.15 | -0.08 | 1.894 | 0/3 | 0.134 | 1.76, 1.74, 1.78 |
| 3 | 0.05 | 0.15 | 0.04 | 1.887 | 0/3 | 0.134 | 1.76, 1.72, 1.78 |
| 2 | 0.05 | 0.15 | 0.08 | 1.885 | 0/3 | 0.138 | 1.74, 1.72, 1.78 |
| 2 | 0.05 | 0.15 | 0.04 | 1.883 | 0/3 | 0.136 | 1.76, 1.72, 1.76 |
| 1.5 | 0.1 | 0.3 | -0.04 | 1.881 | 0/3 | 0.128 | 1.8, 1.68, 1.78 |
| 1.5 | 0.15 | 0.3 | -0.04 | 1.881 | 0/3 | 0.134 | 1.78, 1.68, 1.78 |
| 2 | 0.05 | 0.15 | -0.08 | 1.880 | 0/3 | 0.133 | 1.76, 1.72, 1.76 |
| 3 | 0.05 | 0.15 | -0.04 | 1.875 | 0/3 | 0.135 | 1.74, 1.72, 1.76 |
| 3 | 0.05 | 0.15 | 0.08 | 1.873 | 0/3 | 0.133 | 1.76, 1.7, 1.76 |
| 1.5 | 0.15 | 0.3 | -0.08 | 1.862 | 0/3 | 0.136 | 1.76, 1.66, 1.76 |
| 1.5 | 0.1 | 0.3 | 0.04 | 1.861 | 0/3 | 0.128 | 1.78, 1.66, 1.76 |
| 1.5 | 0.1 | 0.3 | 0.08 | 1.843 | 0/3 | 0.129 | 1.76, 1.64, 1.74 |
| 1.5 | 0.15 | 0.3 | 0.04 | 1.843 | 0/3 | 0.137 | 1.74, 1.64, 1.74 |
| 3 | 0.1 | 0.15 | -0.08 | 1.810 | 0/3 | 0.137 | 1.68, 1.66, 1.68 |
| 1.5 | 0.1 | 0.15 | -0.08 | 1.808 | 0/3 | 0.135 | 1.72, 1.62, 1.68 |
| 1.5 | 0.15 | 0.15 | -0.08 | 1.807 | 0/3 | 0.140 | 1.72, 1.6, 1.68 |
| 1.5 | 0.15 | 0.3 | 0.08 | 1.805 | 0/3 | 0.139 | 1.7, 1.6, 1.7 |
| 3 | 0.1 | 0.3 | -0.08 | 1.801 | 0/3 | 0.135 | 1.64, 1.66, 1.7 |
| 3 | 0.1 | 0.15 | -0.04 | 1.796 | 0/3 | 0.136 | 1.66, 1.64, 1.68 |
| 1.5 | 0.1 | 0.15 | 0.08 | 1.787 | 0/3 | 0.134 | 1.7, 1.6, 1.66 |
| 3 | 0.1 | 0.3 | -0.04 | 1.787 | 0/3 | 0.133 | 1.64, 1.64, 1.68 |
| 1.5 | 0.1 | 0.15 | -0.04 | 1.786 | 0/3 | 0.133 | 1.68, 1.62, 1.66 |
| 2 | 0.1 | 0.15 | -0.04 | 1.781 | 0/3 | 0.134 | 1.64, 1.62, 1.68 |
| 3 | 0.1 | 0.15 | 0.04 | 1.776 | 0/3 | 0.136 | 1.64, 1.62, 1.66 |
| 2 | 0.1 | 0.15 | -0.08 | 1.773 | 0/3 | 0.133 | 1.64, 1.62, 1.66 |
| 1.5 | 0.1 | 0.15 | 0.04 | 1.772 | 0/3 | 0.132 | 1.66, 1.6, 1.66 |
| 3 | 0.15 | 0.15 | -0.08 | 1.765 | 0/3 | 0.138 | 1.62, 1.6, 1.66 |
| 2 | 0.1 | 0.15 | 0.08 | 1.762 | 0/3 | 0.136 | 1.62, 1.6, 1.66 |
| 3 | 0.1 | 0.15 | 0.08 | 1.762 | 0/3 | 0.135 | 1.6, 1.62, 1.66 |
| 2 | 0.1 | 0.15 | 0.04 | 1.755 | 0/3 | 0.135 | 1.62, 1.6, 1.64 |
| 3 | 0.1 | 0.3 | 0.04 | 1.754 | 0/3 | 0.134 | 1.62, 1.6, 1.64 |
| 2 | 0.15 | 0.15 | -0.08 | 1.752 | 0/3 | 0.139 | 1.62, 1.58, 1.64 |
| 2 | 0.15 | 0.3 | -0.08 | 1.750 | 0/3 | 0.136 | 1.64, 1.56, 1.64 |
| 1.5 | 0.15 | 0.15 | 0.08 | 1.748 | 0/3 | 0.141 | 1.64, 1.56, 1.62 |
| 2 | 0.1 | 0.3 | 0.08 | 1.748 | 0/3 | 0.135 | 1.62, 1.58, 1.64 |
| 3 | 0.1 | 0.3 | 0.08 | 1.747 | 0/3 | 0.133 | 1.62, 1.58, 1.64 |
| 2 | 0.1 | 0.3 | -0.08 | 1.746 | 0/3 | 0.132 | 1.64, 1.58, 1.62 |
| 2 | 0.1 | 0.3 | -0.04 | 1.746 | 0/3 | 0.133 | 1.62, 1.58, 1.64 |
| 2 | 0.1 | 0.3 | 0.04 | 1.741 | 0/3 | 0.134 | 1.62, 1.58, 1.62 |
| 1.5 | 0.15 | 0.15 | 0.04 | 1.740 | 0/3 | 0.140 | 1.62, 1.56, 1.62 |
| 2 | 0.15 | 0.3 | -0.04 | 1.739 | 0/3 | 0.139 | 1.62, 1.56, 1.62 |
| 3 | 0.15 | 0.15 | -0.04 | 1.738 | 0/3 | 0.138 | 1.6, 1.58, 1.62 |
| 1.5 | 0.15 | 0.15 | -0.04 | 1.736 | 0/3 | 0.136 | 1.64, 1.56, 1.6 |
| 2 | 0.15 | 0.15 | 0.08 | 1.736 | 0/3 | 0.143 | 1.6, 1.56, 1.62 |
| 2 | 0.15 | 0.15 | -0.04 | 1.728 | 0/3 | 0.142 | 1.6, 1.56, 1.6 |
| 2 | 0.15 | 0.3 | 0.04 | 1.726 | 0/3 | 0.139 | 1.62, 1.54, 1.6 |
| 3 | 0.15 | 0.15 | 0.04 | 1.726 | 0/3 | 0.139 | 1.58, 1.56, 1.62 |
| 3 | 0.15 | 0.3 | -0.08 | 1.725 | 0/3 | 0.139 | 1.58, 1.56, 1.62 |
| 2 | 0.15 | 0.15 | 0.04 | 1.716 | 0/3 | 0.143 | 1.58, 1.54, 1.6 |
| 3 | 0.15 | 0.3 | -0.04 | 1.713 | 0/3 | 0.140 | 1.58, 1.54, 1.6 |
| 3 | 0.15 | 0.15 | 0.08 | 1.707 | 0/3 | 0.140 | 1.54, 1.56, 1.6 |
| 2 | 0.15 | 0.3 | 0.08 | 1.701 | 0/3 | 0.141 | 1.58, 1.52, 1.58 |
| 3 | 0.15 | 0.3 | 0.04 | 1.681 | 0/3 | 0.141 | 1.54, 1.52, 1.56 |
| 3 | 0.15 | 0.3 | 0.08 | 1.675 | 0/3 | 0.141 | 1.52, 1.52, 1.56 |
Balance law (B), on top of the best A gait:
27 grid points, flat floor, seeds 0 to 2 (score = 100 + metres if standing at 6 s, else seconds survived + metres)
| kp | kr | kd | score | standing | travelled | fell at (s) |
|---|---|---|---|---|---|---|
| -0.4 | 0.3 | 0 | 3.190 | 0/3 | -0.057 | 2.82, 2.86, 4.06 |
| -0.4 | 0 | 0 | 2.902 | 0/3 | -0.058 | 2.84, 2.88, 3.16 |
| -0.4 | -0.3 | 0.02 | 2.893 | 0/3 | -0.054 | 2.5, 3.48, 2.86 |
| -0.4 | 0 | 0.02 | 2.885 | 0/3 | -0.055 | 2.52, 3.56, 2.74 |
| -0.2 | 0 | 0.05 | 2.789 | 0/3 | 0.036 | 2.76, 2.48, 3.02 |
| -0.4 | 0.3 | 0.02 | 2.779 | 0/3 | -0.141 | 2.56, 3.58, 2.62 |
| -0.2 | 0.3 | 0.05 | 2.776 | 0/3 | 0.036 | 2.76, 2.52, 2.94 |
| -0.4 | -0.3 | 0 | 2.770 | 0/3 | -0.056 | 2.66, 2.78, 3.04 |
| -0.2 | -0.3 | 0.05 | 2.764 | 0/3 | 0.038 | 2.88, 2.46, 2.84 |
| -0.2 | -0.3 | 0.02 | 2.667 | 0/3 | 0.127 | 2.82, 2.24, 2.56 |
| -0.2 | 0.3 | 0.02 | 2.622 | 0/3 | 0.128 | 2.66, 2.26, 2.56 |
| -0.2 | 0 | 0.02 | 2.621 | 0/3 | 0.127 | 2.76, 2.26, 2.46 |
| -0.4 | 0 | 0.05 | 2.476 | 0/3 | -0.138 | 2.44, 2.78, 2.62 |
| -0.2 | -0.3 | 0 | 2.470 | 0/3 | 0.130 | 2.54, 2.16, 2.32 |
| -0.4 | 0.3 | 0.05 | 2.463 | 0/3 | -0.137 | 2.42, 2.84, 2.54 |
| -0.2 | 0 | 0 | 2.423 | 0/3 | 0.129 | 2.38, 2.14, 2.36 |
| -0.4 | -0.3 | 0.05 | 2.421 | 0/3 | -0.139 | 2.44, 2.68, 2.56 |
| -0.2 | 0.3 | 0 | 2.415 | 0/3 | 0.128 | 2.42, 2.1, 2.34 |
| -0.6 | 0.3 | 0 | 2.303 | 0/3 | -0.137 | 2.32, 2.58, 2.42 |
| -0.6 | -0.3 | 0 | 2.289 | 0/3 | -0.138 | 2.36, 2.52, 2.4 |
| -0.6 | -0.3 | 0.02 | 2.286 | 0/3 | -0.134 | 2.36, 2.48, 2.42 |
| -0.6 | 0 | 0 | 2.282 | 0/3 | -0.138 | 2.36, 2.48, 2.42 |
| -0.6 | 0.3 | 0.05 | 2.266 | 0/3 | -0.127 | 2.34, 2.46, 2.38 |
| -0.6 | 0.3 | 0.02 | 2.260 | 0/3 | -0.133 | 2.32, 2.48, 2.38 |
| -0.6 | 0 | 0.02 | 2.259 | 0/3 | -0.134 | 2.32, 2.5, 2.36 |
| -0.6 | 0 | 0.05 | 2.259 | 0/3 | -0.128 | 2.34, 2.42, 2.4 |
| -0.6 | -0.3 | 0.05 | 2.245 | 0/3 | -0.129 | 2.32, 2.42, 2.38 |
Limitations, stated plainly
- Simulation only. No servo was harmed. Sim-to-real would only widen every gap shown here.
- A toy biped, not the robots in the cited papers. The challenge names quadruped and biped work at 100 Hz on A1 and Cassie. I have neither. The Microduck is a 25 cm toy whose servos cannot hold its own pose open loop, which makes the open-loop half of this test harsher than it would be on a stiff, well-damped quadruped. It does not change the shape of the answer, but it does change how far a hand-written table might get on a better-behaved robot.
- The LLM got a simulator in the loop. The 72- and 27-point grids are the model iterating against physics, which is more than "prompt an LLM" and still not enough. A fair reading is: prompting plus a hundred rollouts of tuning does not produce a walking controller.
- The trained baseline is Pollen's, not mine. It is the closest thing on hand to the cited recipe (PPO, proprioception only, 50 Hz, MuJoCo), not an RMA reimplementation; there is no adaptation module and no terrain curriculum beyond Pollen's 15 mm.
- One controller family per reading of the challenge. A cleverer open-loop gait exists somewhere. The claim is not that none exists; it is that an LLM prompted to write one, with a simulator to check against, did not find it, and that the trained policy did not need to look.
- Bench specifics. Step blocks are isolated from each other, the lane is 340 mm wide, and the terrain is a stack of overlapping 340 mm deep blocks; the profiles above are exactly what was laid. The fall criterion is a threshold on projected gravity, not a contact sensor.
What the LLM was actually useful for
Everything in the post's last sentence. Over the same afternoon the model wrote the terrain generator, the kinematic sign probe (which joint direction lifts which foot), the episode harness, the perturbation protocol, the two controls, and the analysis on this page. It found the HOME-pose instability and the 0.2 m/s dead zone, both of which would have quietly corrupted a naive comparison. Earlier this month, in the same bench, it spent about 50,000 episodes searching for stair-climbing motions for this robot and its most valuable output was finding that the staircase itself was broken. Planning, instrumentation, and review: yes. The 50 Hz loop: no.
Reproduce it
git clone https://github.com/craigm26/duckbench && cd duckbench/sim && npm install cp -r ../../llm-legged-control/sim malik # or use sim/malik in duckbench at ee7c71d node malik/probe.mjs # joint sign conventions node malik/diag.mjs # the HOME-pose control and the policy's command sweep node malik/diag2.mjs # measures neutral.json, ledge limit node malik/run.mjs # tuning grids, evaluation, results.json, commands_open_loop.csv
Node v22.23.2, onnxruntime-node 1.29.0, mujoco 3.1.16. Every episode is deterministic given its seed; the reported numbers are what run.log shows.
Data
- results.json: protocol, terrains, tuning grids, and every episode with its per-tick trunk trace (x, y, z, gravity z).
- commands_open_loop.csv: the LLM's 50 Hz command table, 300 rows.
- neutral.json: the measured standing targets.
- run.log: the run as it printed.
- sim/: lib.mjs (plant, controllers, episode), run.mjs, probe.mjs, diag.mjs, diag2.mjs.
- Plant and policies: craigm26/duckbench at
ee7c71d, filessim/scene.mjb,sim/alpha_walking.onnx,sim/BEST_alpha_stand.onnx(sha256 1569268713e40dee…).
References
- Ashish Kumar, Zipeng Fu, Deepak Pathak, Jitendra Malik. RMA: Rapid Motor Adaptation for Legged Robots. RSS 2021. project page, arXiv:2107.04034.
- Ananye Agarwal, Ashish Kumar, Jitendra Malik, Deepak Pathak. Legged Locomotion in Challenging Terrains using Egocentric Vision. CoRL 2022, best systems paper. project page, arXiv:2211.07638.
- Ashish Kumar, Zhongyu Li, Jun Zeng, Deepak Pathak, Koushil Sreenath, Jitendra Malik. Adapting Rapid Motor Adaptation for Bipedal Robots. IROS 2022. project page, arXiv:2205.15299.
- Pollen Robotics. microduck_rl: RL training environments for Microduck (mjlab, PPO, Apache-2.0). github.com/pollen-robotics/microduck_rl; the 15 mm step cap and the "~1-2 cm" foot lift are in
src/mjlab_microduck/tasks/microduck_velocity_env_cfg.py. Runtime: github.com/pollen-robotics/microduck. - Emanuel Todorov, Tom Erez, Yuval Tassa. MuJoCo: A physics engine for model-based control. IROS 2012. mujoco.org.
- Craig Merry. duckbench: the Microduck bench this ran in. github.com/craigm26/duckbench.
- The post this answers: @JitendraMalikCV on X, 7 September 2026, 9:03 PM.