test-rerun/README.md

8.8 KiB
Raw Permalink Blame History

HUSKY: Humanoid Skateboarding System via Physics-Aware Whole-Body Control

基于 HUSKY 思路的人形滑板全身控制实验代码mjlab 训练、rsl_rl 与 MuJoCo 评测脚本。本仓库包含个人开发与 Docker 封装。

目录: src/mjlab_husky · rsl_rl/ · dataset/ · test_scene/ · ckpts/


本地安装Ubuntu 22.04,推荐 uv

curl -LsSf https://astral.sh/uv/install.sh | sh
git clone https://github.com/<你的用户名>/humanoid_skateboarding.git
cd humanoid_skateboarding
uv sync && uv pip install -e .

可选LeRobot v3 导出 / 边播边录 需要额外安装 lerobot(不在默认 pyproject 依赖里):

uv pip install lerobot

若安装后出现 import torch 报 NCCL 符号错误,可尝试:

uv pip uninstall nvidia-nccl-cu12
uv pip install --force-reinstall "nvidia-nccl-cu13>=2.29"

训练

cd humanoid_skateboarding
uv run train Mjlab-Skater-Flat-Unitree-G1 --env.scene.num-envs 4096

查看全部参数:

uv run train Mjlab-Skater-Flat-Unitree-G1 --help

回放 play

任务名固定为 Mjlab-Skater-Flat-Unitree-G1(注册在 mjlab_husky.tasks)。

通用

uv run play Mjlab-Skater-Flat-Unitree-G1 --checkpoint_file ckpts/test.pt
  • --viewer auto(默认):有 DISPLAY / WAYLAND_DISPLAY 时用 native,否则 rerun
  • --viewer native:本机有图形界面时使用 MuJoCo 原生窗口。
  • --viewer rerunRerun Web Viewer无头服务器常用
  • --viewer viserViser。

完整参数:

uv run play Mjlab-Skater-Flat-Unitree-G1 --help

无头 OpenGLMuJoCo 离屏相机)

在无 DISPLAY 的 Linux 上,play 会在导入 MuJoCo 前尽量设置 MUJOCO_GL=egl(见 mjlab_husky/mujoco_gl.py)。若仍失败可手动指定:

export MUJOCO_GL=egl          # GPU 无头(常见)
# 或
export MUJOCO_GL=osmesa       # 纯 CPU 软件光栅(更慢)

Rerun端口与远程浏览器

Rerun 需要 两个端口Web(默认 8080+ gRPC(默认多为 9876,以终端打印为准)。

浏览器与 play 在同一台机器:直接打开终端里 http://127.0.0.1:<web_port>/?url=... 完整链接(不要只打开无 ?url= 的首页)。

浏览器在自己电脑、play 在云主机:必须在本机做 SSH 双端口转发(把 user@host 换成你的登录方式,端口与 play 一致):

ssh -N -L 8080:127.0.0.1:8080 -L 9876:127.0.0.1:9876 user@云主机IP

若使用 ~/.ssh/config 里的 Host 别名(例如 Seoul

ssh -N -L 8080:127.0.0.1:8080 -L 9876:127.0.0.1:9876 Seoul

指定密钥时:

ssh -i ~/.ssh/你的_key -N -L 8080:127.0.0.1:8080 -L 9876:127.0.0.1:9876 ubuntu@云主机IP

本机 8080/9876 已被占用时,改用空闲本地端口,并同时改 ?url= 里 gRPC 端口,例如:

ssh -N -L 18080:127.0.0.1:18080 -L 19876:127.0.0.1:19876 user@云主机IP

云主机上 play 需一致:

uv run play Mjlab-Skater-Flat-Unitree-G1 --checkpoint_file ckpts/test.pt \
  --viewer rerun \
  --rerun-web-port 18080 \
  --rerun-grpc-port 19876

不经 SSH、浏览器直连公网:安全组放行 Web + gRPC 端口,并指定(示例):

uv run play ... --viewer rerun --rerun-connect-host <云主机公网IP>

Rerun 常用性能参数(可选)

uv run play Mjlab-Skater-Flat-Unitree-G1 --checkpoint_file ckpts/test.pt \
  --viewer rerun \
  --rerun-viewer-width 640 --rerun-viewer-height 360 \
  --rerun-camera-log-stride 4 --rerun-qpos-log-stride 8 \
  --rerun-camera-max-side 480 \
  --no-rerun-open-browser

说明:本项目 CLI 使用 tyro,布尔开关一般为 --xxx / --no-xxx(例如 --lerobot-record--no-rerun-open-browser),不要写成 --lerobot-record True


LeRobot v3 数据(lerobot_data/

LeRobot v3Parquet + meta/(不是 HDF5。本仓库提供两种方式写入 observation.stateqposfloat32 向量)

1离线批量导出不跑 Rerun

需已 uv pip install lerobot

uv run python -m mjlab_husky.scripts.export_lerobot_qpos \
  --task-id Mjlab-Skater-Flat-Unitree-G1 \
  --checkpoint-file ckpts/test.pt \
  --out-dir lerobot_data \
  --dataset-name mjlab_husky_skater_qpos \
  --episodes 1 \
  --steps-per-episode 1000 \
  --overwrite

2play + Rerun 同时边播边录

uv run play Mjlab-Skater-Flat-Unitree-G1 \
  --checkpoint_file ckpts/test.pt \
  --viewer rerun \
  --rerun-web-port 18080 \
  --rerun-grpc-port 19876 \
  --lerobot-record \
  --lerobot-out-dir lerobot_data \
  --lerobot-dataset-name mjlab_husky_live \
  --lerobot-overwrite

要点:

  • --lerobot-overwrite:每次启动会 删除 同名数据集目录;要 累积 多次运行,请 去掉 该参数,或换 --lerobot-dataset-name
  • 默认每录满 --lerobot-steps-per-episode(默认 1000帧会 save_episode() 一次;仿真里多次 reset 不会自动切分,除非打开 --lerobot-save-on-env-reset
  • 退出 play(如 Ctrl+C时会 finalize(),避免 Parquet 不完整。

按仿真每次 done -> reset 存成一个 LeRobot episode

uv run play Mjlab-Skater-Flat-Unitree-G1 ... --lerobot-record --lerobot-save-on-env-reset

检查数据集是否可读(行数 / episode

uv run python -c "
from pathlib import Path
import json
info = json.loads(Path('lerobot_data/mjlab_husky_live/meta/info.json').read_text())
print('total_episodes', info.get('total_episodes'), 'total_frames', info.get('total_frames'))
"

Docker推荐

基础环境Ubuntu 22.04、CUDA 13、uv 与项目依赖。镜像 MUJOCO_GL=egl,默认 CMDRerun 回放(--no-rerun-open-browser)。

构建

docker build -t husky-skate:latest .

GPU 运行(需 NVIDIA Container Toolkit

docker run --gpus all -it --rm -p 8080:8080 -p 9876:9876 husky-skate:latest

宿主机浏览器打开容器日志里打印的 http://127.0.0.1:8080/?url=...(若浏览器不在宿主机,需自行把对应端口转发到本机)。

宿主机 8080/9876 已被占用(例如已有其他容器映射):换主机端口 + 覆盖容器内 play 端口,例如:

docker run --gpus all -it --rm -p 18080:18080 -p 19876:19876 husky-skate:latest \
  uv run play Mjlab-Skater-Flat-Unitree-G1 --checkpoint_file ckpts/test.pt \
    --viewer rerun \
    --rerun-web-port 18080 \
    --rerun-grpc-port 19876 \
    --no-rerun-open-browser

仅 CPU(较慢)

docker run -it --rm -p 8080:8080 -p 9876:9876 husky-skate:latest

进入容器 Shell

docker run --gpus all -it --rm --entrypoint /bin/bash husky-skate:latest

容器内训练

docker run --gpus all -it --rm husky-skate:latest \
  uv run train Mjlab-Skater-Flat-Unitree-G1 --env.scene.num-envs 4096

(可选)容器内录 LeRobot:需先安装 lerobot,并把目录挂载出来,例如:

docker run --gpus all -it --rm \
  -p 18080:18080 -p 19876:19876 \
  -v "$(pwd)/lerobot_data:/app/lerobot_data" \
  husky-skate:latest \
  bash -lc 'uv pip install lerobot && uv run play Mjlab-Skater-Flat-Unitree-G1 \
    --checkpoint_file ckpts/test.pt --viewer rerun \
    --rerun-web-port 18080 --rerun-grpc-port 19876 --no-rerun-open-browser \
    --lerobot-record --lerobot-out-dir lerobot_data --lerobot-dataset-name mjlab_docker_live \
    --lerobot-overwrite'

PyTorch / CUDA 提示

若日志出现 driver too old如 12080torch.cuda.is_available()False,多为 PyTorch cu13x 与当前驱动 API 不匹配。可选:

  • 安装与驱动匹配的 cu12x 轮子,例如:
    uv pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
  • 或升级宿主机 NVIDIA 驱动以匹配当前 PyTorch 所要求的 CUDA。

仿真侧 Warp/MuJoCo 仍可能显示 cpu,与 torch.cuda.is_available()play 选的 device 一致。


轻量 MuJoCo 评测

bash test_scene/sim.sh your-onnx-path
Viser MuJoCo

论文引用(原论文)

@article{han2026husky,
  title={HUSKY: Humanoid Skateboarding System via Physics-Aware Whole-Body Control},
  author={Jinrui Han and Dewei Wang and Chenyun Zhang and Xinzhe Liu and Ping Luo and Chenjia Bai and Xuelong Li},
  journal={arXiv preprint arXiv:2602.03205},
  year={2026}
}