diff --git a/README.md b/README.md index deb33f76e..5058bd966 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ uv run eval --algo appo --task go2_joystick_flat --sim motrix --load-run -1 uv run eval --algo appo --task go2_joystick_flat --sim motrix --load-run -1 --render-mode record ``` -This routes through the `go2_joystick_flat/motrix` task owner config and keeps backend selection explicit. +This routes through the `go2_joystick_flat/motrix` task owner config and keeps backend selection explicit. Each backend owner carries an optional `play_profile` block that layers render-only overrides at eval time (`training.play_only=true`) without affecting training. On macOS / MacBook, the UniLab CLI routes Motrix interactive playback through `mxpython` when needed. Motrix defaults to interactive playback; use `--render-mode record` for headless video export or `--render-mode none` to skip playback. Detailed script-level commands are in the [Training Guide](https://unilabsim.github.io/UniLab-doc/en/2-user_guide/1-training/0-index.html). diff --git a/README_zh.md b/README_zh.md index e1e9be84f..39a50dc1a 100644 --- a/README_zh.md +++ b/README_zh.md @@ -134,7 +134,7 @@ uv run eval --algo appo --task go2_joystick_flat --sim motrix --load-run -1 uv run eval --algo appo --task go2_joystick_flat --sim motrix --load-run -1 --render-mode record ``` -这会路由到 `go2_joystick_flat/motrix` 任务 owner 配置,并保持后端选择显式化。 +这会路由到 `go2_joystick_flat/motrix` 任务 owner 配置,并保持后端选择显式化。每个后端 owner 带一个可选的 `play_profile` 块,在 eval 时(`training.play_only=true`)叠加仅渲染相关的覆盖,不影响训练。 在 macOS / MacBook 上,UniLab CLI 在需要时会通过 `mxpython` 路由 Motrix 交互式回放。Motrix 默认使用交互式回放;要导出无头视频请使用 `--render-mode record`,要跳过回放请使用 `--render-mode none`。更细的脚本级命令请参阅 [训练指南](https://unilabsim.github.io/UniLab-doc/zh_CN/2-user_guide/1-training/0-index.html)。 diff --git a/conf/ppo/task/allegro_inhand/motrix.yaml b/conf/ppo/task/allegro_inhand/motrix.yaml index d4d68902b..3608d9743 100644 --- a/conf/ppo/task/allegro_inhand/motrix.yaml +++ b/conf/ppo/task/allegro_inhand/motrix.yaml @@ -50,3 +50,7 @@ env: joint_noise: 0.0 ball_vel_noise: 0.0 ball_z_offset: 0.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/allegro_inhand/mujoco.yaml b/conf/ppo/task/allegro_inhand/mujoco.yaml index 3bfed4175..17d639913 100644 --- a/conf/ppo/task/allegro_inhand/mujoco.yaml +++ b/conf/ppo/task/allegro_inhand/mujoco.yaml @@ -54,3 +54,7 @@ env: joint_noise: 0.0 ball_vel_noise: 0.0 ball_z_offset: 0.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/allegro_inhand_grasp/motrix.yaml b/conf/ppo/task/allegro_inhand_grasp/motrix.yaml index 8dfe5c1d4..6b5cdca31 100644 --- a/conf/ppo/task/allegro_inhand_grasp/motrix.yaml +++ b/conf/ppo/task/allegro_inhand_grasp/motrix.yaml @@ -31,3 +31,7 @@ env: push_robots: false ball_vel_noise: 0.0 joint_noise: 0.25 # random sampling of the grasp poses +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/allegro_inhand_grasp/mujoco.yaml b/conf/ppo/task/allegro_inhand_grasp/mujoco.yaml index 20d565f51..e6e62f2f6 100644 --- a/conf/ppo/task/allegro_inhand_grasp/mujoco.yaml +++ b/conf/ppo/task/allegro_inhand_grasp/mujoco.yaml @@ -31,3 +31,7 @@ env: push_robots: false ball_vel_noise: 0.0 joint_noise: 0.25 # random sampling of the grasp poses +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_box_tracking/mujoco.yaml b/conf/ppo/task/g1_box_tracking/mujoco.yaml index bb39b7ee4..278a8b8f3 100644 --- a/conf/ppo/task/g1_box_tracking/mujoco.yaml +++ b/conf/ppo/task/g1_box_tracking/mujoco.yaml @@ -42,3 +42,7 @@ reward: std_joint_vel: 1.0 std_object_pos: 0.2 std_object_ori: 0.3 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_climb_tracking/motrix.yaml b/conf/ppo/task/g1_climb_tracking/motrix.yaml index 7c6407e17..0c30db38e 100644 --- a/conf/ppo/task/g1_climb_tracking/motrix.yaml +++ b/conf/ppo/task/g1_climb_tracking/motrix.yaml @@ -78,3 +78,7 @@ reward: std_body_ang_vel: 3.14 std_joint_pos: 0.2 std_joint_vel: 1.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_climb_tracking/mujoco.yaml b/conf/ppo/task/g1_climb_tracking/mujoco.yaml index 9697dc3fc..b7111e85a 100644 --- a/conf/ppo/task/g1_climb_tracking/mujoco.yaml +++ b/conf/ppo/task/g1_climb_tracking/mujoco.yaml @@ -78,3 +78,7 @@ reward: std_body_ang_vel: 3.14 std_joint_pos: 0.2 std_joint_vel: 1.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_flip_tracking/motrix.yaml b/conf/ppo/task/g1_flip_tracking/motrix.yaml index 1d17d213c..3435bd57a 100644 --- a/conf/ppo/task/g1_flip_tracking/motrix.yaml +++ b/conf/ppo/task/g1_flip_tracking/motrix.yaml @@ -32,3 +32,7 @@ reward: std_body_ang_vel: 3.14 std_joint_pos: 0.2 std_joint_vel: 1.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_flip_tracking/mujoco.yaml b/conf/ppo/task/g1_flip_tracking/mujoco.yaml index b9d736e2a..1edd403da 100644 --- a/conf/ppo/task/g1_flip_tracking/mujoco.yaml +++ b/conf/ppo/task/g1_flip_tracking/mujoco.yaml @@ -78,3 +78,7 @@ reward: std_body_ang_vel: 3.14 std_joint_pos: 0.2 std_joint_vel: 1.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_motion_tracking/mujoco.yaml b/conf/ppo/task/g1_motion_tracking/mujoco.yaml index f257cd9e6..7301e4b68 100644 --- a/conf/ppo/task/g1_motion_tracking/mujoco.yaml +++ b/conf/ppo/task/g1_motion_tracking/mujoco.yaml @@ -32,3 +32,7 @@ reward: std_body_ang_vel: 3.14 std_joint_pos: 0.2 std_joint_vel: 1.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_walk_flat/base.yaml b/conf/ppo/task/g1_walk_flat/base.yaml deleted file mode 100644 index 962e1ecf5..000000000 --- a/conf/ppo/task/g1_walk_flat/base.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# @package _global_ -# Shared cross-backend contract for g1_walk_flat. See AGENTS.md (Sim2Sim). -algo: - empirical_normalization: false - obs_groups: - actor: - - actor - policy: - actor_hidden_dims: [512, 256, 128] - critic_hidden_dims: [512, 256, 128] -env: - control_config: - action_scale: 0.25 diff --git a/conf/ppo/task/g1_walk_flat/motrix.yaml b/conf/ppo/task/g1_walk_flat/motrix.yaml index fddd5f51b..88c971936 100644 --- a/conf/ppo/task/g1_walk_flat/motrix.yaml +++ b/conf/ppo/task/g1_walk_flat/motrix.yaml @@ -1,10 +1,7 @@ # @package _global_ -# Inherits base.yaml, then overrides contract fields for Motrix-specific tuning +# Standalone Motrix owner config: carries the shared contract inline, then +# overrides contract fields for Motrix-specific tuning # (intentionally non-transferable from MuJoCo; drop overrides to restore parity). -defaults: - - /task/g1_walk_flat/base - - _self_ - training: task_name: G1WalkFlat sim_backend: motrix @@ -18,6 +15,8 @@ algo: critic: - critic policy: + actor_hidden_dims: [512, 256, 128] + critic_hidden_dims: [512, 256, 128] init_noise_std: 0.5 algorithm: learning_rate: 3.0e-4 @@ -67,3 +66,7 @@ reward: min_forward_speed_for_gait_reward: 0.05 min_base_height: 0.5 max_tilt_deg: 35.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_walk_flat/mujoco.yaml b/conf/ppo/task/g1_walk_flat/mujoco.yaml index 54d670f5d..843d7b85f 100644 --- a/conf/ppo/task/g1_walk_flat/mujoco.yaml +++ b/conf/ppo/task/g1_walk_flat/mujoco.yaml @@ -1,16 +1,22 @@ # @package _global_ -# Inherits the shared contract from base.yaml; backend-specific tuning only. -defaults: - - /task/g1_walk_flat/base - - _self_ - +# Standalone MuJoCo owner config: carries the shared cross-backend contract inline +# (formerly base.yaml), plus backend-specific tuning. training: task_name: G1WalkFlat sim_backend: mujoco algo: num_envs: 2048 max_iterations: 2200 + empirical_normalization: false + obs_groups: + actor: + - actor + policy: + actor_hidden_dims: [512, 256, 128] + critic_hidden_dims: [512, 256, 128] env: + control_config: + action_scale: 0.25 curriculum: enabled: false noise_config: @@ -37,3 +43,7 @@ reward: min_base_height: 0.55 max_tilt_deg: 25.0 pose_weights: [0.01, 1.0, 5.0, 0.01, 5.0, 5.0, 0.01, 1.0, 5.0, 0.01, 5.0, 5.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0] +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/g1_wall_flip_tracking/mujoco.yaml b/conf/ppo/task/g1_wall_flip_tracking/mujoco.yaml index 1dd234f91..e11d9b05b 100644 --- a/conf/ppo/task/g1_wall_flip_tracking/mujoco.yaml +++ b/conf/ppo/task/g1_wall_flip_tracking/mujoco.yaml @@ -78,3 +78,7 @@ reward: std_body_ang_vel: 3.14 std_joint_pos: 0.2 std_joint_vel: 1.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go1_joystick_flat/motrix.yaml b/conf/ppo/task/go1_joystick_flat/motrix.yaml index b699946ab..d84ba1b03 100644 --- a/conf/ppo/task/go1_joystick_flat/motrix.yaml +++ b/conf/ppo/task/go1_joystick_flat/motrix.yaml @@ -43,3 +43,7 @@ reward: swing_feet_z: 4.0 tracking_sigma: 0.25 base_height_target: 0.3 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go1_joystick_flat/mujoco.yaml b/conf/ppo/task/go1_joystick_flat/mujoco.yaml index e6edb90b6..794266ad3 100644 --- a/conf/ppo/task/go1_joystick_flat/mujoco.yaml +++ b/conf/ppo/task/go1_joystick_flat/mujoco.yaml @@ -34,3 +34,7 @@ reward: swing_feet_z: 4.0 tracking_sigma: 0.25 base_height_target: 0.3 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go1_joystick_rough/motrix.yaml b/conf/ppo/task/go1_joystick_rough/motrix.yaml index b24e9ccd6..21be8340a 100644 --- a/conf/ppo/task/go1_joystick_rough/motrix.yaml +++ b/conf/ppo/task/go1_joystick_rough/motrix.yaml @@ -115,3 +115,7 @@ reward: feet_gait_max_err: 0.2 feet_gait_velocity_threshold: 0.5 feet_gait_command_threshold: 0.1 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go1_joystick_rough/mujoco.yaml b/conf/ppo/task/go1_joystick_rough/mujoco.yaml index 05a43dd17..04a9dc179 100644 --- a/conf/ppo/task/go1_joystick_rough/mujoco.yaml +++ b/conf/ppo/task/go1_joystick_rough/mujoco.yaml @@ -116,3 +116,7 @@ reward: feet_gait_max_err: 0.2 feet_gait_velocity_threshold: 0.5 feet_gait_command_threshold: 0.1 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2_arm_manip_loco/mujoco.yaml b/conf/ppo/task/go2_arm_manip_loco/mujoco.yaml index a5b998089..162e0a256 100644 --- a/conf/ppo/task/go2_arm_manip_loco/mujoco.yaml +++ b/conf/ppo/task/go2_arm_manip_loco/mujoco.yaml @@ -106,3 +106,7 @@ env: freeze_arm_joints: false disable_ee_goal_trajectory: false fixed_ee_goal_cart: [0.15, 0.0, 0.25] +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2_joystick_flat/motrix.yaml b/conf/ppo/task/go2_joystick_flat/motrix.yaml index 682935bc5..aca13216d 100644 --- a/conf/ppo/task/go2_joystick_flat/motrix.yaml +++ b/conf/ppo/task/go2_joystick_flat/motrix.yaml @@ -35,3 +35,7 @@ reward: swing_feet_z: 4.0 tracking_sigma: 0.25 base_height_target: 0.3 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2_joystick_flat/mujoco.yaml b/conf/ppo/task/go2_joystick_flat/mujoco.yaml index d27260e44..35cf09bed 100644 --- a/conf/ppo/task/go2_joystick_flat/mujoco.yaml +++ b/conf/ppo/task/go2_joystick_flat/mujoco.yaml @@ -27,3 +27,7 @@ reward: swing_feet_z: 4.0 tracking_sigma: 0.25 base_height_target: 0.3 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2_joystick_rough/motrix.yaml b/conf/ppo/task/go2_joystick_rough/motrix.yaml index 93db22561..46992b1f0 100644 --- a/conf/ppo/task/go2_joystick_rough/motrix.yaml +++ b/conf/ppo/task/go2_joystick_rough/motrix.yaml @@ -114,3 +114,7 @@ reward: feet_gait_max_err: 0.2 feet_gait_velocity_threshold: 0.5 feet_gait_command_threshold: 0.1 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2_joystick_rough/mujoco.yaml b/conf/ppo/task/go2_joystick_rough/mujoco.yaml index 00d8cf446..ea665a5fa 100644 --- a/conf/ppo/task/go2_joystick_rough/mujoco.yaml +++ b/conf/ppo/task/go2_joystick_rough/mujoco.yaml @@ -116,3 +116,7 @@ reward: feet_gait_max_err: 0.2 feet_gait_velocity_threshold: 0.5 feet_gait_command_threshold: 0.1 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2w_joystick_flat/motrix.yaml b/conf/ppo/task/go2w_joystick_flat/motrix.yaml index a2b4256f7..0e86b63b0 100644 --- a/conf/ppo/task/go2w_joystick_flat/motrix.yaml +++ b/conf/ppo/task/go2w_joystick_flat/motrix.yaml @@ -45,3 +45,7 @@ reward: upward: 1.0 tracking_sigma: 0.25 base_height_target: 0.4 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2w_joystick_flat/mujoco.yaml b/conf/ppo/task/go2w_joystick_flat/mujoco.yaml index 311b6017a..602b95a27 100644 --- a/conf/ppo/task/go2w_joystick_flat/mujoco.yaml +++ b/conf/ppo/task/go2w_joystick_flat/mujoco.yaml @@ -44,3 +44,7 @@ reward: upward: 1.0 tracking_sigma: 0.25 base_height_target: 0.4 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2w_joystick_rough/motrix.yaml b/conf/ppo/task/go2w_joystick_rough/motrix.yaml index 77fc3dd72..d15620ddb 100644 --- a/conf/ppo/task/go2w_joystick_rough/motrix.yaml +++ b/conf/ppo/task/go2w_joystick_rough/motrix.yaml @@ -93,3 +93,7 @@ reward: tracking_sigma: 0.25 base_height_target: 0.4 only_positive_rewards: false +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/go2w_joystick_rough/mujoco.yaml b/conf/ppo/task/go2w_joystick_rough/mujoco.yaml index 6f29fc7fe..5bcc31038 100644 --- a/conf/ppo/task/go2w_joystick_rough/mujoco.yaml +++ b/conf/ppo/task/go2w_joystick_rough/mujoco.yaml @@ -93,3 +93,7 @@ reward: tracking_sigma: 0.25 base_height_target: 0.4 only_positive_rewards: false +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/sharpa_inhand/motrix.yaml b/conf/ppo/task/sharpa_inhand/motrix.yaml index a71dea555..91cbf1436 100644 --- a/conf/ppo/task/sharpa_inhand/motrix.yaml +++ b/conf/ppo/task/sharpa_inhand/motrix.yaml @@ -20,3 +20,7 @@ env: randomize_gravity: false randomize_gravity_direction: true randomize_pd_gains: true +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/sharpa_inhand/mujoco.yaml b/conf/ppo/task/sharpa_inhand/mujoco.yaml index 7ee973e50..638b8aaa4 100644 --- a/conf/ppo/task/sharpa_inhand/mujoco.yaml +++ b/conf/ppo/task/sharpa_inhand/mujoco.yaml @@ -99,3 +99,7 @@ env: joint_noise_scale: 0.02 contact_latency: 0.005 contact_sensor_noise: 0.01 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/sharpa_inhand_grasp/motrix.yaml b/conf/ppo/task/sharpa_inhand_grasp/motrix.yaml index 8002dfe89..86168005b 100644 --- a/conf/ppo/task/sharpa_inhand_grasp/motrix.yaml +++ b/conf/ppo/task/sharpa_inhand_grasp/motrix.yaml @@ -12,3 +12,7 @@ env: domain_rand: randomize_gravity: false randomize_gravity_direction: false +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/sharpa_inhand_grasp/mujoco.yaml b/conf/ppo/task/sharpa_inhand_grasp/mujoco.yaml index 690c9c288..871b4be0a 100644 --- a/conf/ppo/task/sharpa_inhand_grasp/mujoco.yaml +++ b/conf/ppo/task/sharpa_inhand_grasp/mujoco.yaml @@ -100,3 +100,7 @@ env: - contact_right_pinky_elastomer_force disable_tactile_ids: [] grasp_collection_target: 10000 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/stewart_balance/motrix.yaml b/conf/ppo/task/stewart_balance/motrix.yaml index 311be10be..f018225f8 100644 --- a/conf/ppo/task/stewart_balance/motrix.yaml +++ b/conf/ppo/task/stewart_balance/motrix.yaml @@ -46,3 +46,7 @@ reward: progress: 0.6 still: 3.0 fall_penalty: -6.0 +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/conf/ppo/task/stewart_balance/mujoco.yaml b/conf/ppo/task/stewart_balance/mujoco.yaml index 4d3acc67f..f4facc798 100644 --- a/conf/ppo/task/stewart_balance/mujoco.yaml +++ b/conf/ppo/task/stewart_balance/mujoco.yaml @@ -11,3 +11,7 @@ defaults: training: task_name: StewartBalance sim_backend: mujoco +play_profile: + enabled: true + env: + render_spacing: 2.0 diff --git a/tests/envs/test_stewart.py b/tests/envs/test_stewart.py index 24f3ba640..a6a5e2b78 100644 --- a/tests/envs/test_stewart.py +++ b/tests/envs/test_stewart.py @@ -19,6 +19,7 @@ def _make_env(num_envs: int = 2): + pytest.importorskip("motrixsim", reason="motrixsim not installed") ensure_registries() return registry.make("StewartBalance", sim_backend="motrix", num_envs=num_envs) diff --git a/tests/training/test_sim2sim_resolver.py b/tests/training/test_sim2sim_resolver.py index 733160105..ef31e4137 100644 --- a/tests/training/test_sim2sim_resolver.py +++ b/tests/training/test_sim2sim_resolver.py @@ -329,7 +329,7 @@ def _compose_task(task: str) -> Any: def test_g1_walk_flat_mujoco_inherits_base_contract(): - # The MuJoCo owner must inherit the shared contract from base.yaml verbatim. + # The MuJoCo owner carries the full contract in its standalone owner config. mujoco = _compose_task("g1_walk_flat/mujoco") assert OmegaConf.select(mujoco, "env.control_config.action_scale") == 0.25 assert OmegaConf.select(mujoco, "algo.empirical_normalization") is False