From 498c78be13e861b6729d7d3c11161f09fb78c481 Mon Sep 17 00:00:00 2001 From: Martino Russi Date: Sat, 18 Jul 2026 18:53:25 +0200 Subject: [PATCH] feat(unitree_g1): rest pose hangs arms straight down (elbows extended) The soft-stop/reset rest pose used all-zero arm angles, leaving the elbows at the mechanical zero (~90deg forward) so the forearms dropped as dead weight when joints went passive. Extend the rest elbows (1.5 rad) so the arms hang straight down before going passive. Tunable via _REST_ELBOW. Co-authored-by: Cursor --- .../robots/unitree_g1/config_unitree_g1.py | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/lerobot/robots/unitree_g1/config_unitree_g1.py b/src/lerobot/robots/unitree_g1/config_unitree_g1.py index 5fc4075a8..d57be5443 100644 --- a/src/lerobot/robots/unitree_g1/config_unitree_g1.py +++ b/src/lerobot/robots/unitree_g1/config_unitree_g1.py @@ -43,6 +43,23 @@ def _build_gains() -> tuple[list[float], list[float]]: _DEFAULT_KP, _DEFAULT_KD = _build_gains() +# Rest / soft-stop arm pose. The G1 elbow's mechanical zero sits ~90deg (forearm +# pointing forward); a positive elbow angle *extends* the arm toward straight (this is +# why holosoma uses 0.6 for a mildly-extended natural stance). We hang the arms nearly +# straight down so that on soft-stop they're already down and don't drop as dead weight +# when the joints go passive. If the arms curl the wrong way on your robot, flip the +# sign of _REST_ELBOW. +_LEFT_ELBOW_IDX = 18 +_RIGHT_ELBOW_IDX = 25 +_REST_ELBOW = 1.5 # rad, ~straight-down forearm + + +def _build_default_positions() -> list[float]: + pos = [0.0] * 29 + pos[_LEFT_ELBOW_IDX] = _REST_ELBOW + pos[_RIGHT_ELBOW_IDX] = _REST_ELBOW + return pos + @RobotConfig.register_subclass("unitree_g1") @dataclass @@ -50,8 +67,8 @@ class UnitreeG1Config(RobotConfig): kp: list[float] = field(default_factory=lambda: _DEFAULT_KP.copy()) kd: list[float] = field(default_factory=lambda: _DEFAULT_KD.copy()) - # Default joint positions - default_positions: list[float] = field(default_factory=lambda: [0.0] * 29) + # Default joint positions (rest / soft-stop pose; arms hang straight down) + default_positions: list[float] = field(default_factory=_build_default_positions) # Control loop timestep control_dt: float = 1.0 / 250.0 # 250Hz