mirror of
https://github.com/huggingface/lerobot.git
synced 2026-08-08 17:39:44 +00:00
fix(g1): let a whole-body controller replace the proprio state features
observation_features merged the 29 raw joint positions with the controller's own proprio features, so with SONIC the G1 advertised a 93-D state (29 + 64) while sonic_walk was trained on the 64-D token echo alone. Async inference hit "size of tensor a (93) must match the size of tensor b (64)"; rollout only escaped it because its .pos/.vel filter silently drops the .q joint keys. Substitute instead of merge, matching how action_features already hands the action space to the controller. Controllers that advertise no observation_ft (GR00T, Holosoma, none) keep the 29 joint keys unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -231,9 +231,12 @@ class UnitreeG1(Robot):
|
||||
|
||||
@cached_property
|
||||
def observation_features(self) -> dict[str, type | tuple]:
|
||||
# Controllers may contribute their own proprio features (e.g. SONIC's token state).
|
||||
controller_ft = getattr(self.controller, "observation_ft", {})
|
||||
return {**self._motors_ft, **controller_ft, **self._cameras_ft}
|
||||
# A controller advertising its own proprio state (SONIC's 64-D token echo) replaces the
|
||||
# raw joint positions rather than extending them, the way action_features hands the
|
||||
# action space over to the controller.
|
||||
controller_ft = getattr(self.controller, "observation_ft", None)
|
||||
proprio_ft = self._motors_ft if controller_ft is None else dict(controller_ft)
|
||||
return {**proprio_ft, **self._cameras_ft}
|
||||
|
||||
@cached_property
|
||||
def action_features(self) -> dict[str, type]:
|
||||
|
||||
Reference in New Issue
Block a user