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
4 changes: 0 additions & 4 deletions src/holosoma/holosoma/managers/command/terms/locomotion.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def reset(self, env_ids: torch.Tensor | None) -> None:
if idx.numel() == 0:
return

if self.env.is_evaluating:
commands[idx] = 0.0
return

self._resample(idx)

def step(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/holosoma/holosoma/simulator/isaacsim/isaacsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def __init__(self, tyro_config: FullSimConfig, terrain_manager: TerrainManager,
print("[INFO]: Scene manager: ", self.scene)

if self.simulator_config.viewer.enable_tracking:
viewer_config: ViewerCfg = ViewerCfg(origin_type="asset_root", asset_name="robot")
viewer_config: ViewerCfg = ViewerCfg(origin_type="asset_root", asset_name="robot", eye=(0.0, -1.5, 1.5))
else:
viewer_config: ViewerCfg = ViewerCfg()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

from __future__ import annotations

from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import Any, TypedDict

from holosoma_retargeting.config_types.robot import (
RobotDefaults,
_default_robot_defaults,
_validate_robot_type,
)

# Pre-defined constants for each data format
LAFAN_DEMO_JOINTS = [
"Hips",
Expand Down Expand Up @@ -346,13 +352,13 @@ class MotionDataConfig:
data_format: str = "smplh"
# Use str instead of Literal to allow dynamic robot types
robot_type: str = "g1"
robot_defaults: dict[str, RobotDefaults] = field(default_factory=_default_robot_defaults)

def __post_init__(self) -> None:
"""Validate data_format and robot_type."""
_validate_data_format(self.data_format)
from holosoma_retargeting.config_types.robot import _validate_robot_type

_validate_robot_type(self.robot_type)
_validate_robot_type(self.robot_type, self.robot_defaults)

# Optional overrides - if None, will use defaults from data_format
demo_joints: list[str] | None = None
Expand Down
30 changes: 20 additions & 10 deletions src/holosoma_retargeting/holosoma_retargeting/config_types/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from __future__ import annotations

from dataclasses import dataclass
from typing import TypedDict
from dataclasses import dataclass, field
from typing import Mapping, TypedDict

import numpy as np

Expand All @@ -21,14 +21,23 @@ class RobotDefaults(TypedDict):
}


def _validate_robot_type(robot_type: str) -> None:
"""Validate that robot_type exists in _ROBOT_DEFAULTS."""
if robot_type not in _ROBOT_DEFAULTS:
available = ", ".join(sorted(_ROBOT_DEFAULTS.keys()))
def _default_robot_defaults() -> dict[str, RobotDefaults]:
"""Copy robot defaults so each config instance can be customized safely."""
return {name: defaults.copy() for name, defaults in _ROBOT_DEFAULTS.items()}


def _validate_robot_type(robot_type: str, robot_defaults: Mapping[str, RobotDefaults] | None = None) -> None:
"""Validate that robot_type exists in robot defaults."""
if robot_defaults is None:
robot_defaults = _ROBOT_DEFAULTS

if robot_type not in robot_defaults:
available = ", ".join(sorted(robot_defaults.keys()))
raise ValueError(
f"Invalid robot_type: '{robot_type}'. "
f"Available robot types: {available}. "
f"Add your robot to _ROBOT_DEFAULTS in config_types/robot.py"
f"Add your robot to RobotConfig.robot_defaults "
f"(default defined by _ROBOT_DEFAULTS in config_types/robot.py)"
)


Expand All @@ -51,10 +60,11 @@ class RobotConfig:
# Robot type selector - determines which defaults to use
# Use str instead of Literal to allow dynamic robot types via _ROBOT_DEFAULTS
robot_type: str = "g1"
robot_defaults: dict[str, RobotDefaults] = field(default_factory=_default_robot_defaults)

def __post_init__(self) -> None:
"""Validate robot_type after initialization."""
_validate_robot_type(self.robot_type)
_validate_robot_type(self.robot_type, self.robot_defaults)

# Robot configuration (optional overrides)
robot_dof: int | None = None
Expand All @@ -78,7 +88,7 @@ def _robot_dof(self) -> int:
"""Get robot DOF - use override if provided, else use robot_type default."""
if self.robot_dof is not None:
return self.robot_dof
return _ROBOT_DEFAULTS[self.robot_type]["robot_dof"]
return self.robot_defaults[self.robot_type]["robot_dof"]

ROBOT_DOF = property(
_robot_dof,
Expand All @@ -89,7 +99,7 @@ def _robot_height(self) -> float:
"""Get robot height - use override if provided, else use robot_type default."""
if self.robot_height is not None:
return self.robot_height
return _ROBOT_DEFAULTS[self.robot_type]["robot_height"]
return self.robot_defaults[self.robot_type]["robot_height"]

ROBOT_HEIGHT = property(
_robot_height,
Expand Down