robot_skating_03/README.md

295 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# HUSKY: Humanoid Skateboarding System via Physics-Aware Whole-Body Control
基于 [HUSKY](https://arxiv.org/abs/2602.03205) 思路的人形滑板全身控制实验代码mjlab 训练、`rsl_rl` 与 MuJoCo 评测脚本。本仓库包含个人开发与 **Docker** 封装。
**目录:** [`src/mjlab_husky`](src/mjlab_husky) · [`rsl_rl/`](rsl_rl/) · [`dataset/`](dataset/) · [`test_scene/`](test_scene/) · [`ckpts/`](ckpts/)
---
## 本地安装Ubuntu 22.04,推荐 `uv`
```bash
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` 依赖里):
```bash
uv pip install lerobot
```
若安装后出现 `import torch` 报 NCCL 符号错误,可尝试:
```bash
uv pip uninstall nvidia-nccl-cu12
uv pip install --force-reinstall "nvidia-nccl-cu13>=2.29"
```
---
## 训练
```bash
cd humanoid_skateboarding
uv run train Mjlab-Skater-Flat-Unitree-G1 --env.scene.num-envs 4096
```
查看全部参数:
```bash
uv run train Mjlab-Skater-Flat-Unitree-G1 --help
```
---
## 回放 `play`
任务名固定为 **`Mjlab-Skater-Flat-Unitree-G1`**(注册在 `mjlab_husky.tasks`)。
### 通用
```bash
uv run play Mjlab-Skater-Flat-Unitree-G1 --checkpoint_file ckpts/test.pt
```
- **`--viewer auto`**(默认):有 `DISPLAY` / `WAYLAND_DISPLAY` 时用 **native**,否则 **rerun**
- **`--viewer native`**:本机有图形界面时使用 MuJoCo 原生窗口。
- **`--viewer rerun`**Rerun Web Viewer无头服务器常用
- **`--viewer viser`**Viser。
完整参数:
```bash
uv run play Mjlab-Skater-Flat-Unitree-G1 --help
```
### 无头 OpenGLMuJoCo 离屏相机)
在无 `DISPLAY` 的 Linux 上,`play` 会在导入 MuJoCo 前尽量设置 **`MUJOCO_GL=egl`**(见 `mjlab_husky/mujoco_gl.py`)。若仍失败可手动指定:
```bash
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` 一致):
```bash
ssh -N -L 8080:127.0.0.1:8080 -L 9876:127.0.0.1:9876 user@云主机IP
```
若使用 `~/.ssh/config` 里的 `Host` 别名(例如 `Seoul`
```bash
ssh -N -L 8080:127.0.0.1:8080 -L 9876:127.0.0.1:9876 Seoul
```
指定密钥时:
```bash
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 端口,例如:
```bash
ssh -N -L 18080:127.0.0.1:18080 -L 19876:127.0.0.1:19876 user@云主机IP
```
云主机上 `play` 需一致:
```bash
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 端口,并指定(示例):
```bash
uv run play ... --viewer rerun --rerun-connect-host <云主机公网IP>
```
### Rerun 常用性能参数(可选)
```bash
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 **v3****Parquet + `meta/`**(不是 HDF5。本仓库提供两种方式写入 **`observation.state`qposfloat32 向量)**。
### 1离线批量导出不跑 Rerun
需已 `uv pip install lerobot`
```bash
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
```
### 2`play` + Rerun 同时边播边录
```bash
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
```bash
uv run play Mjlab-Skater-Flat-Unitree-G1 ... --lerobot-record --lerobot-save-on-env-reset
```
### 检查数据集是否可读(行数 / episode
```bash
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`**,默认 **`CMD`** 为 **Rerun** 回放(`--no-rerun-open-browser`)。
**构建**
```bash
docker build -t husky-skate:latest .
```
**GPU 运行**(需 [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)
```bash
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` 端口,例如:
```bash
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**(较慢)
```bash
docker run -it --rm -p 8080:8080 -p 9876:9876 husky-skate:latest
```
**进入容器 Shell**
```bash
docker run --gpus all -it --rm --entrypoint /bin/bash husky-skate:latest
```
**容器内训练**
```bash
docker run --gpus all -it --rm husky-skate:latest \
uv run train Mjlab-Skater-Flat-Unitree-G1 --env.scene.num-envs 4096
```
**(可选)容器内录 LeRobot**:需先安装 `lerobot`,并把目录挂载出来,例如:
```bash
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如 12080**`torch.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
bash test_scene/sim.sh your-onnx-path
```
| Viser | MuJoCo |
|-------|--------|
| ![](media/viser.gif) | ![](media/mjc.gif) |
---
## 论文引用(原论文)
```bibtex
@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}
}
```