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#
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#
@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()#
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:
Event manager applies reset events
Scene controller resets robot states
Command manager samples new commands
Managers are reset
Initial observations computed
step()#
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:
Action manager processes actions
Scene controller applies motor commands
Genesis physics simulation steps
Event manager applies interval events
Observations computed
Rewards computed
Terminations checked
Environments auto-reset if needed
Properties#
@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.
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.
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.
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#
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#
# 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#
# 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#
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 for manager details
Check components for robot/sensor configs
Review examples