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
19 changes: 19 additions & 0 deletions configs/task/microduck-walk-flat/motrix.fastsac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# @package _global_
# Task microduck-walk-flat: motrix.fastsac shared training recipe.
defaults:
- /algo_base@algo: motrix.fastsac
- _self_
task:
env: microduck-walk-flat
rllib: motrix
algo: fastsac
num_envs: 2048
play_num_envs: 16
seed: 1
checkpoint:
interval: 1000
algo:
agent:
alpha_init: 0.01
target_entropy_ratio: -0.1
num_updates: 4
19 changes: 19 additions & 0 deletions configs/task/microduck-walk-rough/motrix.fastsac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# @package _global_
# Task microduck-walk-rough: motrix.fastsac shared training recipe.
defaults:
- /algo_base@algo: motrix.fastsac
- _self_
task:
env: microduck-walk-rough
rllib: motrix
algo: fastsac
num_envs: 2048
play_num_envs: 16
seed: 1
checkpoint:
interval: 1000
algo:
agent:
alpha_init: 0.01
target_entropy_ratio: -0.1
num_updates: 4
1 change: 1 addition & 0 deletions docs/scripts/generate_robot_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"go1": {"kind": "quadruped", "lookat": (0.0, 0.0, 0.3), "distance": 1.4},
"go2": {"kind": "quadruped", "lookat": (0.0, 0.0, 0.3), "distance": 1.4},
"k1": {"kind": "humanoid", "lookat": (0.0, 0.0, 0.8), "distance": 2.1},
"microduck": {"kind": "humanoid", "lookat": (0.0, 0.0, 0.15), "distance": 0.8},
}

_DOC_CONFIGS = {
Expand Down
3 changes: 3 additions & 0 deletions docs/source/_static/images/poster/microduck-walk-flat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/source/_static/images/poster/microduck-walk-rough.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/source/_static/images/robots/microduck.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/source/en/user_guide/envs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ uv run scripts/view.py env=<env-id>
| <img src="../../_static/images/poster/k1-walk-flat.jpg" alt="k1-walk-flat" width="240"> | `k1-walk-flat` | Track walking commands with Booster K1 on flat ground. | `motrix.fastsac` |
| <img src="../../_static/images/poster/k1-walk-rough.jpg" alt="k1-walk-rough" width="240"> | `k1-walk-rough` | Track walking commands with Booster K1 over uneven terrain. | `motrix.fastsac` |
| <img src="../../_static/images/poster/k1-wbt-freekick.jpg" alt="k1-wbt-freekick" width="240"> | `k1-wbt-freekick` | Track a free-kick reference motion with Booster K1. | `motrix.fastsac` |
| <img src="../../_static/images/poster/microduck-walk-flat.jpg" alt="microduck-walk-flat" width="240"> | `microduck-walk-flat` | Track walking commands with Microduck on flat ground. | `motrix.fastsac` |
| <img src="../../_static/images/poster/microduck-walk-rough.jpg" alt="microduck-walk-rough" width="240"> | `microduck-walk-rough` | Track walking commands with Microduck over uneven terrain. | `motrix.fastsac` |
| <img src="../../_static/images/poster/peg-insert.jpg" alt="peg-insert" width="240"> | `peg-insert` | Control RM65 to grasp, align, and insert a peg into a socket. | `motrix.fastsac`, `skrl.ppo` |
| <img src="../../_static/images/poster/pendulum.jpg" alt="pendulum" width="240"> | `pendulum` | Apply joint torque to swing up and balance a pendulum. | `rslrl.ppo`, `skrl.ppo` |
| <img src="../../_static/images/poster/point_mass.jpg" alt="point_mass" width="240"> | `point_mass` | Move a two-dimensional point mass to a random target. | `skrl.ppo` |
Expand Down
18 changes: 9 additions & 9 deletions docs/source/en/user_guide/robots.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ be composed into different scenes and tasks. The table below is generated direct
<!-- ROBOT_TABLE_START -->

<!-- This table is generated; do not edit this block manually. -->

| Screenshot | Registry name | Configuration class | Type | Model format | DoF |
| ---------------------------------------------------------------------------- | ------------- | ------------------- | --------- | ------------ | --- |
| <img src="../_static/images/robots/anymal_c.png" alt="anymal_c" width="180"> | `anymal_c` | `AnymalC` | Quadruped | MJCF | 12 |
| <img src="../_static/images/robots/dex-evt.png" alt="dex-evt" width="180"> | `dex-evt` | `DexEvt` | Humanoid | URDF | 23 |
| <img src="../_static/images/robots/g1-29dof.png" alt="g1-29dof" width="180"> | `g1-29dof` | `UnitreeG129Dof` | Humanoid | MJCF | 29 |
| <img src="../_static/images/robots/go1.png" alt="go1" width="180"> | `go1` | `UnitreeGo1Robot` | Quadruped | MJCF | 12 |
| <img src="../_static/images/robots/go2.png" alt="go2" width="180"> | `go2` | `UnitreeGo2Robot` | Quadruped | MJCF | 12 |
| <img src="../_static/images/robots/k1.png" alt="k1" width="180"> | `k1` | `BoosterK1` | Humanoid | MJCF | 22 |
| Screenshot | Registry name | Configuration class | Type | Model format | DoF |
| --- | --- | --- | --- | --- | --- |
| <img src="../_static/images/robots/anymal_c.png" alt="anymal_c" width="180"> | `anymal_c` | `AnymalC` | Quadruped | MJCF | 12 |
| <img src="../_static/images/robots/dex-evt.png" alt="dex-evt" width="180"> | `dex-evt` | `DexEvt` | Humanoid | URDF | 23 |
| <img src="../_static/images/robots/g1-29dof.png" alt="g1-29dof" width="180"> | `g1-29dof` | `UnitreeG129Dof` | Humanoid | MJCF | 29 |
| <img src="../_static/images/robots/go1.png" alt="go1" width="180"> | `go1` | `UnitreeGo1Robot` | Quadruped | MJCF | 12 |
| <img src="../_static/images/robots/go2.png" alt="go2" width="180"> | `go2` | `UnitreeGo2Robot` | Quadruped | MJCF | 12 |
| <img src="../_static/images/robots/k1.png" alt="k1" width="180"> | `k1` | `BoosterK1` | Humanoid | MJCF | 22 |
| <img src="../_static/images/robots/microduck.png" alt="microduck" width="180"> | `microduck` | `Microduck` | Humanoid | MJCF | 14 |

<!-- ROBOT_TABLE_END -->

Expand Down
2 changes: 2 additions & 0 deletions docs/source/zh_CN/user_guide/envs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ uv run scripts/view.py env=<env-id>
| <img src="../../_static/images/poster/k1-walk-flat.jpg" alt="k1-walk-flat" width="240"> | `k1-walk-flat` | 控制 Booster K1 在平地上跟踪行走指令。 | `motrix.fastsac` |
| <img src="../../_static/images/poster/k1-walk-rough.jpg" alt="k1-walk-rough" width="240"> | `k1-walk-rough` | 控制 Booster K1 在起伏地形上跟踪行走指令。 | `motrix.fastsac` |
| <img src="../../_static/images/poster/k1-wbt-freekick.jpg" alt="k1-wbt-freekick" width="240"> | `k1-wbt-freekick` | 让 Booster K1 跟踪任意球射门参考动作。 | `motrix.fastsac` |
| <img src="../../_static/images/poster/microduck-walk-flat.jpg" alt="microduck-walk-flat" width="240"> | `microduck-walk-flat` | 控制 Microduck 小型双足机器人在平地上跟踪行走指令。 | `motrix.fastsac` |
| <img src="../../_static/images/poster/microduck-walk-rough.jpg" alt="microduck-walk-rough" width="240"> | `microduck-walk-rough` | 控制 Microduck 小型双足机器人在起伏地形上跟踪行走指令。 | `motrix.fastsac` |
| <img src="../../_static/images/poster/peg-insert.jpg" alt="peg-insert" width="240"> | `peg-insert` | 控制 RM65 抓取插销、对准插座并完成插入。 | `motrix.fastsac`, `skrl.ppo` |
| <img src="../../_static/images/poster/pendulum.jpg" alt="pendulum" width="240"> | `pendulum` | 施加关节力矩使单摆摆起并保持直立。 | `rslrl.ppo`, `skrl.ppo` |
| <img src="../../_static/images/poster/point_mass.jpg" alt="point_mass" width="240"> | `point_mass` | 控制二维质点移动到随机目标位置。 | `skrl.ppo` |
Expand Down
18 changes: 9 additions & 9 deletions docs/source/zh_CN/user_guide/robots.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ scene 和 task 中。下表直接根据 registry 和 robot 配置生成。
<!-- ROBOT_TABLE_START -->

<!-- This table is generated; do not edit this block manually. -->

| 截图 | Registry 名称 | 配置类 | 类型 | 模型格式 | 自由度 |
| ---------------------------------------------------------------------------- | ------------- | ----------------- | ---------- | -------- | ------ |
| <img src="../_static/images/robots/anymal_c.png" alt="anymal_c" width="180"> | `anymal_c` | `AnymalC` | 四足机器人 | MJCF | 12 |
| <img src="../_static/images/robots/dex-evt.png" alt="dex-evt" width="180"> | `dex-evt` | `DexEvt` | 人形机器人 | URDF | 23 |
| <img src="../_static/images/robots/g1-29dof.png" alt="g1-29dof" width="180"> | `g1-29dof` | `UnitreeG129Dof` | 人形机器人 | MJCF | 29 |
| <img src="../_static/images/robots/go1.png" alt="go1" width="180"> | `go1` | `UnitreeGo1Robot` | 四足机器人 | MJCF | 12 |
| <img src="../_static/images/robots/go2.png" alt="go2" width="180"> | `go2` | `UnitreeGo2Robot` | 四足机器人 | MJCF | 12 |
| <img src="../_static/images/robots/k1.png" alt="k1" width="180"> | `k1` | `BoosterK1` | 人形机器人 | MJCF | 22 |
| 截图 | Registry 名称 | 配置类 | 类型 | 模型格式 | 自由度 |
| --- | --- | --- | --- | --- | --- |
| <img src="../_static/images/robots/anymal_c.png" alt="anymal_c" width="180"> | `anymal_c` | `AnymalC` | 四足机器人 | MJCF | 12 |
| <img src="../_static/images/robots/dex-evt.png" alt="dex-evt" width="180"> | `dex-evt` | `DexEvt` | 人形机器人 | URDF | 23 |
| <img src="../_static/images/robots/g1-29dof.png" alt="g1-29dof" width="180"> | `g1-29dof` | `UnitreeG129Dof` | 人形机器人 | MJCF | 29 |
| <img src="../_static/images/robots/go1.png" alt="go1" width="180"> | `go1` | `UnitreeGo1Robot` | 四足机器人 | MJCF | 12 |
| <img src="../_static/images/robots/go2.png" alt="go2" width="180"> | `go2` | `UnitreeGo2Robot` | 四足机器人 | MJCF | 12 |
| <img src="../_static/images/robots/k1.png" alt="k1" width="180"> | `k1` | `BoosterK1` | 人形机器人 | MJCF | 22 |
| <img src="../_static/images/robots/microduck.png" alt="microduck" width="180"> | `microduck` | `Microduck` | 人形机器人 | MJCF | 14 |

<!-- ROBOT_TABLE_END -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

"""Robot-agnostic humanoid locomotion environments and configuration schemas."""

from . import dex_evt, g1, k1, walk_np # noqa: F401 register envs and expose base task
from . import dex_evt, g1, k1, microduck, walk_np # noqa: F401 register envs and expose base task
123 changes: 123 additions & 0 deletions motrix_envs/src/motrix_envs/locomotion/humanoid/microduck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright Motphys Technology Co., Ltd. 2025, 2026
# SPDX-License-Identifier: Apache-2.0

"""Pollen Robotics Microduck humanoid velocity-tracking presets and registration."""

from dataclasses import replace

from motrix_env_core import registry
from motrix_env_core.base import SimCfg
from motrix_env_core.config.scene import HFieldTerrainCfg, SystemCameraCfg
from motrix_envs.config.scene import StandardSceneObjsCfg
from motrix_envs.locomotion.humanoid import cfg as humanoid_cfg
from motrix_envs.locomotion.humanoid.walk_np import HumanoidVelocityTrackingEnv
from motrix_envs.robot import Microduck


def _make_microduck_robot() -> Microduck:
return Microduck()


# Pinned Microduck termination collision inventory, owned by the Microduck walk task.
_MICRODUCK_TERMINATION_GEOMS = ("trunk_collision",)


@registry.envcfg("microduck-walk-flat")
def make_microduck_walk_flat_cfg() -> humanoid_cfg.HumanoidVelocityTrackingEnvCfg:
"""Track walking commands with Microduck on flat ground.

zh_CN: 控制 Microduck 小型双足机器人在平地上跟踪行走指令。
"""

return humanoid_cfg.HumanoidVelocityTrackingEnvCfg(
scene=humanoid_cfg.HumanoidWalkSceneCfg(
# Microduck is a ~25 cm robot; frame the lead env much closer than
# the full-size humanoid default camera (grid center at z=0.75).
system_camera=SystemCameraCfg(
lookat=(0.0, 0.0, 0.12),
distance=0.35,
elevation=-20.0,
azimuth=180.0,
),
objs=StandardSceneObjsCfg(robot=_make_microduck_robot()),
),
control_config=humanoid_cfg.ControlCfg(action_scale=0.5),
commands=humanoid_cfg.CommandsCfg(
vel_limit=[
[-1.0, -1.0, -1.0],
[1.0, 1.0, 1.0],
],
Comment thread
wlgys8 marked this conversation as resolved.
),
gait=humanoid_cfg.GaitCfg(
period=0.5,
swing_height=0.04,
Comment thread
wlgys8 marked this conversation as resolved.
feet_phase_sigma=0.002,
),
reward_config=humanoid_cfg.RewardCfg(
scales=humanoid_cfg.RewardScales(
tracking_lin_vel=10.0,
tracking_ang_vel=3.0,
penalty_action_rate=-0.5,
feet_phase=8.0,
),
tracking_sigma=0.15,
close_feet_threshold=0.05,
pose_weights={
"left_hip_yaw": 5.0,
"left_hip_roll": 1.0,
"left_hip_pitch": 0.01,
"left_knee": 0.01,
"left_ankle": 5.0,
"neck_pitch": 50.0,
"head_pitch": 50.0,
"head_yaw": 50.0,
"head_roll": 50.0,
"right_hip_yaw": 5.0,
"right_hip_roll": 1.0,
"right_hip_pitch": 0.01,
"right_knee": 0.01,
"right_ankle": 5.0,
},
),
asset=humanoid_cfg.AssetCfg(
foot_height_site_names=("left_foot", "right_foot"),
ground_geom_name="floor",
terminate_contact_geom_names=_MICRODUCK_TERMINATION_GEOMS,
),
sim=SimCfg(dt=0.005, solver_iterations=6, solver_tolerance=1e-4),
spawn_xy_range=0.0,
)


@registry.envcfg("microduck-walk-rough")
def make_microduck_walk_rough_cfg() -> humanoid_cfg.HumanoidVelocityTrackingEnvCfg:
"""Track walking commands with Microduck over uneven terrain.

zh_CN: 控制 Microduck 小型双足机器人在起伏地形上跟踪行走指令。
"""

return replace(
make_microduck_walk_flat_cfg(),
scene=humanoid_cfg.HumanoidWalkSceneCfg(
assets=humanoid_cfg.TerrainSceneAssetsCfg(),
system_camera=SystemCameraCfg(
lookat=(0.0, 0.0, 0.12),
distance=0.35,
elevation=-20.0,
azimuth=180.0,
),
objs=StandardSceneObjsCfg(
floor=HFieldTerrainCfg(
hfield="terrain",
material="mat_ground",
),
robot=_make_microduck_robot(),
),
),
spawn_xy_range=4.0,
render_spacing=0.0,
)


registry.env("microduck-walk-flat")(HumanoidVelocityTrackingEnv)
registry.env("microduck-walk-rough")(HumanoidVelocityTrackingEnv)
14 changes: 13 additions & 1 deletion motrix_envs/src/motrix_envs/locomotion/humanoid/walk_np.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ def _init_buffers(self) -> None:
self._phase_dt = 2.0 * np.pi * self._gait_freq * cfg.ctrl_dt
self._termination_geoms = self._resolve_termination_geoms()
self._num_termination_pairs = len(self._termination_geoms)
# Foot-link gravity direction at the default pose, captured on first
# reset. Foot orientation penalties are measured against this
# reference so robots whose ankle-link frames are not world-aligned
# (e.g. onshape-to-robot exports) are scored correctly.
self._default_foot_gravity: np.ndarray | None = None

cur = cfg.curriculum
self._penalty_terms = set(cur.penalty_terms)
Expand Down Expand Up @@ -392,6 +397,9 @@ def reset(self, env_ids: np.ndarray) -> dict:
self._reset_joint_velocity[env_ids] = 0.0
self._reset_program.execute(env_ids)
self.sim_data.execute(row_ids)
if self._default_foot_gravity is None:
foot_quat = self.sim_data["foot_quat"][row_ids[0]]
self._default_foot_gravity = quaternion.rotate_inverse(foot_quat, self.gravity_vec)

info = {
"current_actions": np.zeros((num_reset, self._num_action), dtype=np.float32),
Expand Down Expand Up @@ -462,8 +470,12 @@ def _r_close_feet(self, q: StateQuantities, threshold: float) -> np.ndarray:
return (distance < threshold).astype(np.float32)

def _r_feet_ori(self, q: StateQuantities) -> np.ndarray:
# Magnitude of the cross product between the current foot-frame gravity
# and its default-pose reference. With a world-aligned default
# (gravity = (0, 0, -1)) this reduces exactly to sqrt(gx^2 + gy^2).
total = np.zeros((q.foot_quat.shape[0],), dtype=np.float32)
for foot_index in range(2):
foot_gravity = quaternion.rotate_inverse(q.foot_quat[:, foot_index], self.gravity_vec)
total = total + np.sqrt(np.sum(np.square(foot_gravity[:, :2]), axis=1))
reference = self._default_foot_gravity[foot_index]
total = total + np.linalg.norm(np.cross(foot_gravity, reference), axis=1)
Comment thread
wlgys8 marked this conversation as resolved.
return total
3 changes: 3 additions & 0 deletions motrix_envs/src/motrix_envs/robot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from motrix_envs.robot.booster import BoosterK1
from motrix_envs.robot.dex_evt import DexEvt
from motrix_envs.robot.humanoid import HumanoidRobotCfg
from motrix_envs.robot.microduck import Microduck
from motrix_envs.robot.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg
from motrix_envs.robot.unitree import (
UnitreeG129Dof,
Expand All @@ -19,12 +20,14 @@
registry.robotcfg("go1")(UnitreeGo1Robot)
registry.robotcfg("go2")(UnitreeGo2Robot)
registry.robotcfg("k1")(BoosterK1)
registry.robotcfg("microduck")(Microduck)

__all__ = [
"AnymalC",
"BoosterK1",
"DexEvt",
"HumanoidRobotCfg",
"Microduck",
"QuadrupedLegCfg",
"QuadrupedLegsCfg",
"QuadrupedRobotCfg",
Expand Down
14 changes: 14 additions & 0 deletions motrix_envs/src/motrix_envs/robot/assets/microduck/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Microduck robot model

Ported from https://github.com/pollen-robotics/microduck_rl
(`src/mjlab_microduck/robot/microduck/robot_walk.xml`, renamed to
`microduck.xml`). Relative to upstream, a named termination capsule
`trunk_collision` was added on `trunk_base` for the humanoid walk task's
fall-termination contact query; everything else is unmodified.

- Upstream code and MJCF: Apache License 2.0
- 3D mesh files (`assets/*.stl`): Creative Commons BY-SA-NC
(non-commercial), per the upstream README

The Microduck is a ~800 g, ~25 cm bipedal robot by Pollen Robotics with 14
actuated joints (5 per leg, 4 neck/head).
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Loading
Loading