HIMLocoone afternoon, one run

Junfeng Long, Zirui Wang, Quanyi Li, Liu Cao, Jiawei Gao, Jiangmiao Pang. Hybrid Internal Model: Learning Agile Legged Locomotion with Simulated Robot Response. ICLR 2024. Built on IsaacZH/himloco_lab.

HIMLoco is a blind walker. Rather than modelling the terrain, it infers what's going on from how the robot's body responds. On Sep 7 I took a community Isaac Lab port written for the Go2, moved it to the A1, and started one training run. The log ends at iteration 562 of 1,500, still on easy terrain and tracking poorly. I haven't come back to it.

Reached: Isaac sim
The checkpoint at iteration 400, in Isaac Sim. The arrow is the velocity command. Simulation only.

The idea

The paper treats terrain, friction and pushes as disturbances that show up in how the robot moves. An estimator reads a history of proprioception and outputs two things: an explicit body-velocity estimate and a latent the paper calls the hybrid internal model. The latent is trained contrastively, not by reconstruction. Its target is an encoding of the robot's next state, so a history and the response that followed it should land near each other. In the port I used, that contrastive loss is a swapped-prediction loss over 32 learned prototypes, balanced with a few Sinkhorn iterations; the training log calls it the "swap loss". The policy acts on the current observation plus both estimates. As in DreamWaQ, the critic gets privileged state in training: in this port, true velocity, the external force on the trunk, and a height scan.

What I built

Almost nothing here is mine. The estimator, the HIM runner, the velocity task and the rewards all come from IsaacZH's port. I added an A1 setup and carried over pieces from my DreamWaQ work. There were seven commits, all on Sep 7, between 13:02 and 14:49:

  • A launcher and venv on the shared Isaac Sim 5.1 install, with a wrench API back-ported to the installed Isaac Lab.
  • An A1 robot config and an A1 velocity task, copied from the Go2 one with the base body renamed to the A1's trunk. I also added the symmetric trunk model from DreamWaQ, which centres the centre of mass that the stock A1 model has off to one side.
  • PD gains moved from 25 / 0.5 to the deploy point of 34 / 0.8. Since the port shipped no gain randomization, I added Kp 32–38 and Kd 0.6–0.8.
  • The 5–10 ms actuator delay model from DreamWaQ. I turned off the port's own trunk centre-of-mass randomization, since the symmetrized trunk now handles that.
  • Automatic rendering when training ends, and a fix to video capture. The upstream recorder broke on HIM's step signature, so I capture frames manually with a camera that follows the robot.

Rendering had its own limits. The server ran out of memory just booting the renderer, so it could only train headless. On the desktop, a render can't run alongside a training process on the same GPU.

The one run

4,096 robots, 1,500 iterations planned, started at 13:26. The log stops at iteration 562, an hour and 29 minutes in, with the trainer's own estimate of 2 hours 29 minutes still to go. All numbers are from simulation.

Iteration100300500562
Mean reward2.396.507.568.84
Terrain level0.000.020.510.78
XY velocity error0.691.211.121.09
Ended by base contact84%24%14%12.5%

By the end, robots mostly survived. 87.5% of episodes ran to the time limit, averaging 956 steps of a possible 1,000 (20 seconds). They weren't going where they were told, though. The logged XY velocity error was 0.15 at iteration 50, rose past 1.2 by iteration 200, and was still above 1 when the log stops. The terrain curriculum had only just begun to climb. A single run this short says nothing about how the method does on the A1.

What's still wrong

  • The run never finished, and the repo records no reason it stopped.
  • There's no evaluation beyond the training log and one clip at iteration 400.
  • Simulation only. It never reached MuJoCo or the robot.

The blind walker that did reach the robot is DreamWaQ, which gave this port its trunk model and actuator delay.