Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ uv run train --algo sac --task g1_walk_flat --sim motrix
```

```bash
uv run train --algo sac --task g1_sac_wbt --sim mujoco
uv run train --algo sac --task g1_motion_tracking --sim mujoco
```

```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# backend so checkpoints trained on mujoco can be replayed via motrix's native
# renderer (`eval --sim motrix`). Training on motrix is not the intended path.
defaults:
- /task/sac/g1_sac_wbt/mujoco
- /task/sac/g1_motion_tracking/mujoco
- _self_

training:
Expand Down
65 changes: 0 additions & 65 deletions conf/offpolicy/task/sac/g1_sac_wbt/mujoco_deploy.yaml

This file was deleted.

5 changes: 2 additions & 3 deletions conf/offpolicy/task/sac/g1_wbt_obs/mujoco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
# G1 Whole-Body Tracking (WBT) FastSAC on MuJoCo — task ``g1_wbt_obs``.
#
# Field-by-field port of the active deploy training profile from
# ``feat/g1_deploy_v2`` (``conf/offpolicy/task/sac/g1_sac_wbt/mujoco_deploy.yaml``
# in that branch — Stage 4+5, the one actually used for ONNX-on-real-G1
# ``feat/g1_deploy_v2`` (Stage 4+5, the one actually used for ONNX-on-real-G1
# runs; ``mujoco_deploy_v2.yaml`` Plan B was a tuning experiment and is
# NOT what this profile ports).
#
Expand All @@ -13,7 +12,7 @@
# The task name binds to ``G1WBTObs`` (see
# ``src/unilab/envs/motion_tracking/g1/tracking_obs.py``), a strict subclass
# of ``G1MotionTrackingSACEnv`` — base classes are untouched, so other tasks
# (``g1_sac_wbt``, ``g1_motion_tracking_deploy``, locomotion / flip / box
# (``g1_motion_tracking``, ``g1_motion_tracking_deploy``, locomotion / flip / box
# tracking) are unaffected.
#
# Deploy compatibility:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
| 通用全身 tracking | `g1_motion_tracking` | PPO、MLX PPO、APPO | `dance1_subject2_part.npz` |
| flat flip clip | `g1_flip_tracking` | PPO、MLX PPO、APPO | `flip_360_001__A304.npz` |
| wall-assisted flip | `g1_wall_flip_tracking` | PPO、MLX PPO、APPO | `flip_from_wall_104__A304.npz` |
| holosoma-aligned WBT | `g1_sac_wbt` | SAC | 与 `g1_motion_tracking` 共用 |
| crawl-slope WBT (SAC) | `g1_sac_wbt` + 自定义场景 | SAC | `motion_crawl_slope_uni.npz` |
| holosoma-aligned WBT | `g1_motion_tracking` | SAC | 与 `g1_motion_tracking` 共用 |
| crawl-slope WBT (SAC) | `g1_motion_tracking` + 自定义场景 | SAC | `motion_crawl_slope_uni.npz` |
| sim2real-aligned WBT (deploy chain) | `g1_wbt_obs` | SAC | 与 `g1_motion_tracking` 共用 |

## 配置入口

- PPO / MLX PPO:`conf/ppo/task/g1_motion_tracking/`、`conf/ppo/task/g1_flip_tracking/`、`conf/ppo/task/g1_wall_flip_tracking/`
- APPO:`conf/appo/task/g1_motion_tracking/`、`conf/appo/task/g1_flip_tracking/`、`conf/appo/task/g1_wall_flip_tracking/`
- SAC WBT:`conf/offpolicy/task/sac/g1_sac_wbt/{mujoco,mujoco_deploy,motrix}.yaml`、`conf/offpolicy/task/sac/g1_wbt_obs/mujoco.yaml`
- SAC WBT:`conf/offpolicy/task/sac/g1_motion_tracking/{mujoco,motrix}.yaml`、`conf/offpolicy/task/sac/g1_wbt_obs/mujoco.yaml`

## 推荐流程

Expand Down Expand Up @@ -69,23 +69,22 @@ uv run train --algo ppo --task g1_wall_flip_tracking --sim motrix
uv run train --algo ppo --task g1_motion_tracking --sim mujoco algo.num_envs=128 algo.max_iterations=5 training.no_play=true
uv run train --algo appo --task g1_motion_tracking --sim mujoco
uv run train --algo appo --task g1_motion_tracking --sim motrix
uv run train --algo sac --task g1_sac_wbt --sim mujoco training.use_amp=true
uv run train --algo sac --task g1_sac_wbt --sim mujoco --profile deploy training.use_amp=true
uv run train --algo sac --task g1_motion_tracking --sim mujoco training.use_amp=true
uv run train --algo sac --task g1_wbt_obs --sim mujoco training.use_amp=true
uv run eval --algo ppo --task g1_motion_tracking --sim mujoco --load-run -1
uv run eval --algo ppo --task g1_motion_tracking --sim mujoco --load-run -1 training.cam_tracking=true training.cam_tracking_env_idx=0
uv run scripts/train_offpolicy.py algo=sac task=sac/g1_sac_wbt/motrix training.play_only=true algo.load_run=/abs/path/to/logs/fast_sac/G1MotionTrackingSAC/2026-04-23_14-06-57_mujoco
uv run scripts/train_offpolicy.py algo=sac task=sac/g1_motion_tracking/motrix training.play_only=true algo.load_run=/abs/path/to/logs/fast_sac/G1MotionTrackingSAC/2026-04-23_14-06-57_mujoco
```

`--profile deploy` 会切到面向部署的独立 SAC owner;`g1_wbt_obs` 是更彻底的 sim2real 部署 task(pelvis IMU + 5 步 per-term 历史 actor obs,与 deploy `ObservationManager` byte-对齐;额外 encoder-bias / foot-friction DR、`joint_acc_l2` / `joint_torque_l2` 奖励;部署工具在 `scripts/deploy/`,obs 对齐由 `tests/scripts/test_obs_alignment_g1_wbt.py` 三路 cross-check)。Motrix sim2sim 回放时用绝对路径透传 `algo.load_run`,不要塞进 `--load-run`。
`g1_wbt_obs` 是面向 sim2real 部署的 task(pelvis IMU + 5 步 per-term 历史 actor obs,与 deploy `ObservationManager` byte-对齐;额外 encoder-bias / foot-friction DR、`joint_acc_l2` / `joint_torque_l2` 奖励;部署工具在 `scripts/deploy/`,obs 对齐由 `tests/scripts/test_obs_alignment_g1_wbt.py` 三路 cross-check)。Motrix sim2sim 回放时用绝对路径透传 `algo.load_run`,不要塞进 `--load-run`。

## SAC WBT on crawl-slope 场景

在斜坡地形上跑 `g1_sac_wbt`,需要同时切换 motion 片段和 MuJoCo 场景文件,并固定 episode 长度、关闭 reset 随机化:
在斜坡地形上跑 `g1_motion_tracking`,需要同时切换 motion 片段和 MuJoCo 场景文件,并固定 episode 长度、关闭 reset 随机化:

```bash
CUDA_VISIBLE_DEVICES=1 uv run scripts/train_offpolicy.py \
algo=sac task=sac/g1_sac_wbt/mujoco training.use_amp=true algo.seed=1 \
algo=sac task=sac/g1_motion_tracking/mujoco training.use_amp=true algo.seed=1 \
+env.motion_file=src/unilab/assets/motions/g1/motion_crawl_slope_uni.npz \
+env.scene.model_file=src/unilab/assets/robots/g1/scene_crawl_slope.xml \
+env.sampling_mode=start \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ uv run scripts/generate_support_matrix.py --write
| APPO (torch) | `g1_climb_tracking` (g1 climb tracking) | Tested | Tested |
| SAC (torch) | `g1_walk_flat` (G1 walk flat) | Tested | Tested |
| SAC (torch) | `g1_walk_rough` (G1 walk rough) | Tested | Tested |
| SAC (torch) | `g1_sac_wbt` (g1 sac wbt) | Tested | Tested |
| SAC (torch) | `g1_motion_tracking` (G1 motion tracking) | Tested | Tested |
| SAC (torch) | `g1_wbt_obs` (g1 wbt obs) | Tested | Registered |
| TD3 (torch) | `go1_joystick_flat` (Go1 joystick) | Registered | Tested |
| TD3 (torch) | `go2_joystick_flat` (Go2 joystick) | Registered | Tested |
Expand Down
12 changes: 6 additions & 6 deletions scripts/deploy/export_deploy_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@
KEYFRAME_NAME = "stand"
ROOT_QPOS_DIM = 7 # free joint: xyz + quat(wxyz)

# Default obs history length — matches mujoco_deploy.yaml's
# Default obs history length — matches g1_wbt_obs/mujoco.yaml's
# `noise_config.obs_history_length`. Override via --obs-history-length when
# exporting for other training profiles (e.g. mujoco.yaml uses 1).
# exporting for other training profiles (e.g. g1_motion_tracking/mujoco.yaml uses 1).
DEFAULT_OBS_HISTORY_LENGTH = 5


Expand Down Expand Up @@ -164,21 +164,21 @@ def main():
default=DEFAULT_OBS_HISTORY_LENGTH,
help="Proprio history length H. Must match training-side "
"noise_config.obs_history_length. Default 5 = current "
"mujoco_deploy.yaml. Set 1 for the legacy 154-d schema.",
"g1_wbt_obs/mujoco.yaml. Set 1 for the legacy 154-d schema.",
)
ap.add_argument(
"--enable-zero-anchor-pos",
action="store_true",
default=True,
help="Drop motion_anchor_pos_b from actor obs (mjlab parity). "
"Matches mujoco_deploy.yaml's noise_config flag.",
"Matches g1_wbt_obs/mujoco.yaml's noise_config flag.",
)
ap.add_argument(
"--enable-zero-linvel",
action="store_true",
default=True,
help="Drop base_lin_vel from actor obs (mjlab parity). "
"Matches mujoco_deploy.yaml's noise_config flag.",
"Matches g1_wbt_obs/mujoco.yaml's noise_config flag.",
)
args = ap.parse_args()

Expand Down Expand Up @@ -253,7 +253,7 @@ def main():
# command_joint_pos(29*1) + command_joint_vel(29*1)
# + motion_anchor_ori_b(6*1) + gyro(3*5)
# + joint_pos_rel(29*5) + dof_vel(29*5) + last_actions(29*5) = 514
# Aligns with deploy-profile training run (mujoco_deploy.yaml) which
# Aligns with deploy-profile training run (g1_wbt_obs/mujoco.yaml) which
# drops motion_anchor_pos_b and base_lin_vel from actor obs to match
# Unitree's verified mjlab "No-State-Estimation" deploy yaml and
# adds BeyondMimic-style proprio history (default H=5).
Expand Down
12 changes: 6 additions & 6 deletions tests/benchmark/test_replay_buffer_placement_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def test_replay_shape_packed_width_includes_critic_fields() -> None:


def test_wbt_owner_config_is_only_included_when_present() -> None:
assert bench._owner_config_exists("sac", "g1_sac_wbt", "mujoco")
assert not bench._owner_config_exists("flashsac", "g1_sac_wbt", "mujoco")
assert bench._owner_config_exists("sac", "g1_motion_tracking", "mujoco")
assert not bench._owner_config_exists("flashsac", "g1_motion_tracking", "mujoco")


def test_default_discovery_includes_existing_offpolicy_mujoco_tasks() -> None:
Expand All @@ -68,21 +68,21 @@ def test_default_discovery_includes_existing_offpolicy_mujoco_tasks() -> None:
assert skipped == []
assert ("sac", "g1_walk_flat") in targets
assert ("sac", "g1_walk_rough") in targets
assert ("sac", "g1_sac_wbt") in targets
assert ("sac", "g1_motion_tracking") in targets
assert ("flashsac", "g1_walk_flat") in targets
assert ("flashsac", "go2_joystick_flat") in targets
assert ("td3", "g1_walk_flat") in targets
assert ("flashsac", "g1_sac_wbt") not in targets
assert ("flashsac", "g1_motion_tracking") not in targets


def test_td3_is_an_allowed_benchmark_algo() -> None:
assert "td3" in bench._parse_algos("sac,flashsac,td3")


def test_parse_tasks_deduplicates_ordered_values() -> None:
assert bench._parse_tasks("g1_walk_flat,g1_sac_wbt,g1_walk_flat") == [
assert bench._parse_tasks("g1_walk_flat,g1_motion_tracking,g1_walk_flat") == [
"g1_walk_flat",
"g1_sac_wbt",
"g1_motion_tracking",
]


Expand Down
Loading