armins / README.md
arminfg's picture
Default GAIT to snow, so the snow gait runs without setting a Space variable (#12)
b996af7
|
Raw History Blame Contribute Delete
5.06 kB

A newer version of the Gradio SDK is available: 6.30.0

Upgrade
metadata
title: G1 Himalaya Terrain Training
emoji: 🦿
colorFrom: red
colorTo: green
sdk: gradio
sdk_version: 6.26.0
python_version: '3.11'
app_file: app.py
pinned: false
short_description: GPU training for Unitree G1 on snowy Himalayan terrain

Unitree G1 — Himalayan terrain locomotion training

Trains on real elevation data: dem_khumbu.npy is SRTM-derived terrain (AWS Terrain Tiles, 4.2 m/px, 3.2 km square) of the Khumbu glacier valley below Everest Base Camp. himalaya_terrain.py cuts random 600 m crops, squeezes them onto Playground's 20 m arena with 0.3 m of relief plus scree detail, and gives every environment its own crop through the domain randomizer. Set TERRAIN=playground to fall back to the stock 5 cm noise field; HIMALAYA_RELIEF, HIMALAYA_PATCH, NUM_TERRAINS tune the terrain.

Snow (SNOW=1, default): every environment also draws its own snow — foot–floor friction from SNOW_FRICTION (default 0.3,0.7; packed snow ≈ 0.5, rock ≈ 1.0) and a soft-contact snow depth from SNOW_DEPTH (default 0.0,0.08 m, 0–3 in: feet settle about half the depth at rest and up to twice it on a landing). Randomizing both is what makes the policy robust across snow conditions instead of tuned to one. SNOW=0 gives bare terrain. Checkpoints go under himalaya-snow/ in HF_REPO.

Trains G1JoystickRoughTerrain from MuJoCo Playground with Brax PPO on the Space's GPU. Thousands of MJX environments step in parallel, versus the 16 CPU processes a laptop manages.

Watch a checkpoint walk. The reward curve says whether training is moving; the Render rollout section says whether the robot walks. Pick a checkpoint, a forward speed, snow friction and depth, and it films the policy on a Himalaya crop (rollout.py; MJX + MUJOCO_GL=egl) and reports how long it stayed up and how far it walked. NUM_EVALS (default 40) sets how many evals — and therefore log lines and checkpoint uploads — a run makes.

Snow gait (GAIT=snow, the default)

Playground's joystick task is tuned for pavement: a 15 cm swing-height reference at 1.25–1.5 Hz with the hips pinned to a narrow stance. This Space defaults to GAIT=snow, which retunes it for deep snow via snow_gait.py — a 22 cm swing (FOOT_HEIGHT), a slower 1.0–1.3 Hz cadence (GAIT_FREQ) with more air-time reward for longer strides, a relaxed hip-deviation cost so the stance can widen, and a new cost for letting the feet come within FOOT_SEPARATION (20 cm) of each other laterally.

That last term is also a fix, not just styling. The joystick task ends an episode when the two feet touch, and the 200M-step run plateaued because the gait crossed its feet after ~45 steps and took the −100 termination every episode while still upright. The separation cost penalises exactly that, and is measured along the pelvis's y-axis so feet may still pass fore-aft as walking requires.

Checkpoints go under a -snowgait suffix.

Fall recovery (TASK=getup)

Walking and getting up are different tasks, and the joystick task cannot learn the second: it ends the episode the moment the torso tips past horizontal (with a −100 reward), so the policy never sees a timestep while fallen. TASK=getup switches the Space to g1_getup.py, a humanoid port of Playground's Go1Getup: 60% of episodes start fallen (dropped from 0.5 m with a random orientation and random joint angles, then left to settle), nothing terminates on being down, and the reward asks for an upright torso at standing height — then, only once both hold, for the nominal pose and for the policy to stop moving.

Playground's G1 is a feet-only collision model, so a fallen torso would drop through the floor. g1_getup_model.py rewrites the robot XML: it enables the thigh, shin and hand collision geoms the model already carries but leaves off, and adds torso, pelvis and head capsules sized from the visual meshes. Body geoms get contype=2 / conaffinity=1 so they collide with the ground but never with each other — without that the pelvis capsule overlaps the thighs and the standing robot is blown over by its own contacts.

Observations (93) and actions (29) keep the joystick task's layout, so a fall detector can hand control between a walking policy and a get-up policy at run time. Checkpoints go under a -getup prefix. Flat ground only: TERRAIN and SNOW are ignored for this task.

TASK=getup      # then Start; ~100M steps

Training starts automatically on boot. Checkpoints are written to /data when persistent storage is attached, and pushed to HF_REPO if that variable and a write-scoped HF_TOKEN secret are set.

Settings that matter

  • Sleep time → never. The Space idles on HTTP traffic, not CPU/GPU load, so a background training thread will not keep it awake.
  • Persistent storage — without it, checkpoints are lost on restart. Set HF_REPO so they are pushed to the Hub instead.
  • NUM_TIMESTEPS (default 200M), ENV_NAME, SEED are configurable variables.