"""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 # 100 Hz default @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)"