| """Base controller interface for G1 robot.""" |
| import numpy as np |
| from abc import ABC, abstractmethod |
|
|
|
|
| class BaseController(ABC): |
| """Abstract base class for G1 robot controllers.""" |
|
|
| def __init__(self, num_joints: int = 29): |
| self.num_joints = num_joints |
| self.time = 0.0 |
| self.dt = 0.01 |
|
|
| @abstractmethod |
| def compute_action(self, obs: np.ndarray, data) -> np.ndarray: |
| """ |
| Compute control action given observation and MuJoCo data. |
| |
| Args: |
| obs: Observation vector from environment |
| data: MuJoCo data object for direct joint access |
| |
| Returns: |
| Action array of shape (num_joints,) with torques |
| """ |
| pass |
|
|
| def reset(self): |
| """Reset controller state.""" |
| self.time = 0.0 |
|
|
| def step(self, dt: float = 0.01): |
| """Advance controller time.""" |
| self.time += dt |
| self.dt = dt |
|
|
| @property |
| def name(self) -> str: |
| """Controller name for UI display.""" |
| return self.__class__.__name__ |
|
|
|
|
| class NoController(BaseController): |
| """No control - robot falls naturally.""" |
|
|
| def compute_action(self, obs: np.ndarray, data) -> np.ndarray: |
| return np.zeros(self.num_joints) |
|
|
| @property |
| def name(self) -> str: |
| return "None (Free Fall)" |
|
|