Configuration Guide#
EmbodiChain uses a declarative configuration system built on Python dataclasses. This guide explains the key patterns: @configclass, FunctorCfg, and JSON/YAML configuration files.
The @configclass Decorator#
All configuration objects use the @configclass decorator, which is similar to Python’s @dataclass with additional validation and serialization support.
from embodichain.utils import configclass
from dataclasses import MISSING
@configclass
class MyManagerCfg:
param_a: float = 1.0
param_b: str = MISSING # Required — must be set by caller
param_c: int = 10
Optional parameters have default values.
Required parameters use
MISSINGas the default — callers must provide them.All parameters are typed for IDE auto-completion and static analysis.
Configuration Hierarchy#
EmbodiChain configs form a nested hierarchy:
EmbodiedEnvCfg
├── sim_cfg: SimulationManagerCfg
│ ├── render_cfg: RenderCfg
│ ├── physics_config: PhysicsCfg
│ └── gpu_memory_config: GPUMemoryCfg
├── robot: RobotCfg
│ ├── urdf_cfg: URDFCfg
│ ├── drive_pros: JointDrivePropertiesCfg
│ └── solver_cfg: Dict[str, SolverCfg]
├── sensor: List[SensorCfg]
├── events: EventCfg
├── observations: ObservationCfg
├── rewards: RewardCfg
├── actions: ActionTermCfg
├── dataset: DatasetFunctorCfg
└── extensions: Dict[str, Any]
Each sub-config can be set independently, allowing fine-grained control over the environment.
Functor Configuration#
Functors are configured through specialized config classes that inherit from FunctorCfg. The base class has three fields:
@configclass
class FunctorCfg:
func: Callable | Functor = MISSING # The function or class to call
params: dict[str, Any] = dict() # Keyword arguments
extra: dict[str, Any] = dict() # Optional metadata
Specialized Config Classes#
Config Class |
Extra Fields |
Used By |
|---|---|---|
|
|
ObservationManager |
|
|
EventManager |
|
|
RewardManager |
|
|
ActionManager |
|
|
DatasetManager |
Python Config Example#
from embodichain.utils import configclass
from embodichain.lab.gym.envs.managers.cfg import (
ObservationCfg,
RewardCfg,
EventCfg,
SceneEntityCfg,
)
from embodichain.lab.gym.envs.managers.observations import get_object_pose
@configclass
class MyObsCfg:
object_pose: ObservationCfg = ObservationCfg(
func=get_object_pose,
mode="add",
name="object/pose",
params={"entity_cfg": SceneEntityCfg(uid="my_cube")},
)
@configclass
class MyRewardCfg:
distance: RewardCfg = RewardCfg(
func="distance_between_objects",
weight=0.5,
params={
"source_entity_cfg": SceneEntityCfg(uid="cube"),
"target_entity_cfg": SceneEntityCfg(uid="target"),
},
)
@configclass
class MyEventCfg:
randomize_light: EventCfg = EventCfg(
func="randomize_light",
mode="interval",
interval_step=5,
params={"light_uid": "main_light"},
)
JSON and YAML Configuration#
For RL training and data generation, EmbodiChain uses file-based configs (.json, .yaml, or .yml). The file format mirrors the Python config structure but uses string names instead of direct function references.
Configs are loaded with embodichain.utils.utility.load_config, which selects the parser from the file extension. Both formats produce the same in-memory dictionary and are passed to config_to_cfg() for environment setup.
Example paths in the repository:
Use case |
JSON example |
YAML example |
|---|---|---|
Gym environment |
|
|
RL training |
|
|
When a training config references a gym config (via trainer.gym_config), the nested path may also use any supported extension.
Environment Config (gym_config.json / gym_config.yaml)#
{
"max_episodes": 100,
"max_episode_steps": 600,
"env": {
"num_envs": 4,
"sim_cfg": {
"sim_device": "cuda:0",
"headless": true
},
"robot": {
"uid": "robot",
"urdf_cfg": {"fpath": "robots/my_robot/my_robot.urdf"}
},
"control_parts": ["arm"],
"sensor": [
{
"uid": "cam_high",
"type": "StereoCamera",
"height": 540,
"width": 960
}
],
"actions": {
"delta_qpos": {
"func": "DeltaQposTerm",
"params": {"scale": 0.1}
}
},
"events": {
"randomize_table": {
"func": "randomize_visual_material",
"mode": "interval",
"interval_step": 10,
"params": {"uid": "table"}
}
},
"observations": {
"obj_pose": {
"func": "get_object_pose",
"mode": "add",
"name": "object/pose",
"params": {"entity_cfg": {"uid": "cube"}}
}
},
"rewards": {
"distance": {
"func": "distance_between_objects",
"weight": 0.5,
"params": {
"source_entity_cfg": {"uid": "cube"},
"target_entity_cfg": {"uid": "target"}
}
}
},
"dataset": {
"lerobot": {
"func": "LeRobotRecorder",
"mode": "save",
"params": {
"save_path": "/path/to/output",
"robot_meta": {"robot_type": "DexforceW1"},
"use_videos": true
}
}
},
"extensions": {
"success_threshold": 0.1
}
}
}
RL Training Config (train_config.json / train_config.yaml)#
{
"trainer": {
"exp_name": "push_cube",
"seed": 42,
"device": "cuda:0",
"iterations": 500,
"buffer_size": 1024
},
"env": {
"id": "PushCubeRL",
"cfg": {
"num_envs": 4,
"actions": {
"delta_qpos": {
"func": "DeltaQposTerm",
"params": {"scale": 0.1}
}
}
}
},
"policy": {
"name": "actor_critic",
"actor": {
"type": "mlp",
"network_cfg": {"hidden_sizes": [256, 256], "activation": "relu"}
},
"critic": {
"type": "mlp",
"network_cfg": {"hidden_sizes": [256, 256], "activation": "relu"}
}
},
"algorithm": {
"name": "ppo",
"cfg": {
"learning_rate": 0.0001,
"n_epochs": 10,
"batch_size": 64,
"gamma": 0.99,
"gae_lambda": 0.95,
"clip_coef": 0.2
}
}
}
The same structure in YAML:
trainer:
exp_name: push_cube
seed: 42
device: cuda:0
iterations: 500
buffer_size: 1024
gym_config: configs/agents/rl/basic/cart_pole/gym_config.yaml
policy:
name: actor_critic
actor:
type: mlp
network_cfg:
hidden_sizes: [256, 256]
activation: relu
algorithm:
name: ppo
cfg:
learning_rate: 0.0001
batch_size: 64
gamma: 0.99
String-Based Function Resolution#
In JSON and YAML configs, functor functions are specified by name (string). EmbodiChain resolves these strings at runtime by searching registered modules. For example:
"distance_between_objects"resolves toembodichain.lab.gym.envs.managers.rewards.distance_between_objects"DeltaQposTerm"resolves toembodichain.lab.gym.envs.managers.actions.DeltaQposTerm"get_object_pose"resolves toembodichain.lab.gym.envs.managers.observations.get_object_pose
When writing custom functors, make sure they are imported in the module’s __init__.py so the resolver can find them.
SceneEntityCfg in Config Files#
When referencing scene entities in JSON or YAML, use a dictionary with a uid key:
{"uid": "my_cube"}
This is automatically converted to a SceneEntityCfg object at runtime.
Tips#
Start from an existing config. Copy a config file from
configs/gym/orconfigs/agents/rl/and modify it for your task.Use Python configs for development. They provide IDE auto-completion and type checking.
Use JSON or YAML configs for experiments. YAML is often easier to read for nested structures; JSON remains fully supported.
Validate configs early. Run your environment with a short episode count to catch config errors before long training runs.
Keep config pairs together. For action-bank tasks, version
gym_configandaction_configtogether (either format).
See Also#
Custom Functors Guide — How to write observation, reward, event, and action functors
Embodied Environments — Full environment configuration reference
Tutorial: Modular Environment — Complete example using config-driven setup
Tutorial: RL Training — RL training configuration walkthrough