# Engine Core simulation engine components for GenesisLab. ## Overview The engine module provides the core simulation infrastructure: - **LabScene**: Central simulation orchestrator - **Scene Patterns**: Builder, Controller, Querier patterns - **MDP Interface**: Reset and step functions - **Genesis Integration**: Interface to Genesis physics engine ## LabScene `LabScene` is the central component that manages the entire simulation. ### Class Definition ```python class LabScene: """ Central simulation manager that orchestrates all components. Attributes: cfg: Scene configuration num_envs: Number of parallel environments device: PyTorch device (CPU/GPU) scene: Genesis scene instance observation_manager: Observation computation action_manager: Action processing reward_manager: Reward calculation termination_manager: Termination checking command_manager: Command generation event_manager: Domain randomization curriculum_manager: Training curriculum """ def __init__(self, cfg: LabSceneCfg, num_envs: int = 4096): """ Initialize the scene. Args: cfg: Scene configuration num_envs: Number of parallel environments """ pass ``` ### Configuration ```python @configclass class LabSceneCfg: # Simulation settings num_envs: int = 4096 env_spacing: float = 4.0 sim_dt: float = 0.005 # 5ms control_dt: float = 0.02 # 20ms (control frequency) # Physics settings gravity: tuple[float, float, float] = (0.0, 0.0, -9.81) # Rendering settings headless: bool = True viewer_camera_cfg: ViewerCameraCfg = ViewerCameraCfg() ``` ### MDP Interface #### reset() ```python def reset( self, env_ids: torch.Tensor | None = None ) -> tuple[dict[str, torch.Tensor], dict]: """ Reset the environment. Args: env_ids: Environment indices to reset. If None, reset all. Returns: Tuple of: - observations: Dictionary with 'obs' and optionally 'obs_critic' - info: Dictionary with reset information Example: >>> obs, info = scene.reset() >>> print(obs['obs'].shape) torch.Size([4096, 48]) """ pass ``` **What happens during reset:** 1. Event manager applies reset events 2. Scene controller resets robot states 3. Command manager samples new commands 4. Managers are reset 5. Initial observations computed #### step() ```python def step( self, actions: torch.Tensor ) -> tuple[dict[str, torch.Tensor], torch.Tensor, torch.Tensor, torch.Tensor, dict]: """ Step the environment. Args: actions: Action tensor [num_envs, action_dim] Returns: Tuple of: - observations: Dictionary with 'obs' and optionally 'obs_critic' - rewards: Reward tensor [num_envs] - terminated: Boolean tensor [num_envs] - truncated: Boolean tensor [num_envs] - info: Dictionary with step information Example: >>> action = torch.randn(4096, 12) >>> obs, rew, term, trunc, info = scene.step(action) """ pass ``` **What happens during step:** 1. Action manager processes actions 2. Scene controller applies motor commands 3. Genesis physics simulation steps 4. Event manager applies interval events 5. Observations computed 6. Rewards computed 7. Terminations checked 8. Environments auto-reset if needed ### Properties ```python @property def num_envs(self) -> int: """Number of parallel environments.""" pass @property def device(self) -> torch.device: """PyTorch device.""" pass @property def dt(self) -> float: """Simulation timestep in seconds.""" pass @property def episode_length(self) -> torch.Tensor: """Current episode length for each environment.""" pass ``` ## Scene Patterns ### SceneBuilder Constructs the initial scene during setup. ```python class SceneBuilder: """ Builds the Genesis scene with terrain, robots, sensors, etc. """ def build(self, scene: gs.Scene, cfg: LabSceneCfg) -> dict: """ Build the complete scene. Args: scene: Genesis scene instance cfg: Scene configuration Returns: Dictionary of created entities """ entities = {} # Build terrain entities['terrain'] = self.build_terrain(scene, cfg.terrain) # Build robots entities['robot'] = self.build_robot(scene, cfg.robot) # Build sensors entities['sensors'] = self.build_sensors(scene, cfg.sensors) # Build objects entities['objects'] = self.build_objects(scene, cfg.objects) return entities def build_terrain( self, scene: gs.Scene, cfg: TerrainCfg ) -> gs.Entity: """Build terrain.""" pass def build_robot( self, scene: gs.Scene, cfg: RobotCfg ) -> gs.Entity: """Build robot.""" pass ``` ### SceneController Modifies scene state during simulation. ```python class SceneController: """ Controls and modifies the scene during simulation. """ def apply_actions( self, scene: gs.Scene, actions: torch.Tensor, env_ids: torch.Tensor | None = None ): """ Apply actions to robots. Args: scene: Genesis scene actions: Action tensor env_ids: Environment indices (None = all) """ pass def reset_robots( self, scene: gs.Scene, env_ids: torch.Tensor, cfg: ResetCfg ): """ Reset robot states. Args: scene: Genesis scene env_ids: Environments to reset cfg: Reset configuration """ pass ``` ### SceneQuerier Reads data from the scene without modifying it. ```python class SceneQuerier: """ Queries scene state for observations and rewards. """ def get_robot_state( self, scene: gs.Scene, env_ids: torch.Tensor | None = None ) -> dict[str, torch.Tensor]: """ Get robot state. Returns: Dictionary with robot state tensors: - 'joint_pos': Joint positions - 'joint_vel': Joint velocities - 'base_pos': Base position - 'base_quat': Base orientation - 'base_lin_vel': Base linear velocity - 'base_ang_vel': Base angular velocity """ pass def get_sensor_data( self, scene: gs.Scene, sensor_name: str ) -> torch.Tensor: """Get sensor measurements.""" pass def get_contact_forces( self, scene: gs.Scene, body_names: list[str] ) -> torch.Tensor: """Get contact forces on specified bodies.""" pass ``` ## Genesis Integration ### Scene Creation ```python import genesis as gs # Initialize Genesis gs.init(backend=gs.gpu) # Create scene scene = gs.Scene( show_viewer=not headless, sim_options=gs.options.SimOptions( dt=sim_dt, gravity=gravity ), vis_options=gs.options.VisOptions( show_world_frame=True ) ) # Build scene scene.build() ``` ### Entity Access ```python # Access robot robot = scene.entities['robot'] # Get DOF positions dof_pos = robot.get_dofs_position() # [num_envs, num_dof] # Set DOF targets robot.set_dofs_position_target(targets) # Get link states link_pos = robot.get_links_pos() # [num_envs, num_links, 3] ``` ## Usage Examples ### Basic Scene Setup ```python # Create configuration cfg = LabSceneCfg( num_envs=4096, env_spacing=4.0, sim_dt=0.005 ) # Create scene scene = LabScene(cfg) # Reset obs, info = scene.reset() # Run simulation for _ in range(1000): action = policy(obs['obs']) obs, rew, term, trunc, info = scene.step(action) ``` ### Custom Scene Builder ```python class MySceneBuilder(SceneBuilder): def build_robot(self, scene: gs.Scene, cfg: RobotCfg): # Load URDF robot = scene.add_entity( gs.morphs.URDF( file=cfg.urdf_path, pos=(0, 0, 0.5) ) ) return robot ``` ## Next Steps - See [managers](../managers/index.md) for manager details - Check [components](../components/index.md) for robot/sensor configs - Review [examples](../../user_guide/tutorials/index.md)