Utilities#
Helper functions and utilities for GenesisLab.
Overview#
Utility modules provide commonly used functions and tools:
ConfigClass: Configuration system decorator
Math: Mathematical operations and transformations
Timing: Performance profiling and timing
I/O: File loading and saving
Typing: Type definitions and hints
ConfigClass#
The configuration system using @configclass decorator.
Usage#
from genesislab.utils.configclass import configclass
from dataclasses import field
@configclass
class MyConfig:
# Basic types
name: str = "default"
value: float = 1.0
count: int = 10
enabled: bool = True
# Collections
values: list[float] = field(default_factory=lambda: [1.0, 2.0])
mapping: dict[str, float] = field(default_factory=dict)
# Nested configs
sub_config: SubConfig = SubConfig()
Critical Rule#
ALWAYS use @configclass, NEVER use @dataclass.
# ✅ Correct
from genesislab.utils.configclass import configclass
@configclass
class MyCfg:
value: float = 1.0
# ❌ Incorrect - Will cause errors!
from dataclasses import dataclass
@dataclass
class MyCfg:
value: float = 1.0
Math Utilities#
Quaternion Operations#
from genesislab.utils.math import (
quat_mul,
quat_conjugate,
quat_rotate,
quat_to_euler,
euler_to_quat
)
# Quaternion multiplication (WXYZ format)
q1 = torch.tensor([1.0, 0.0, 0.0, 0.0])
q2 = torch.tensor([0.707, 0.0, 0.707, 0.0])
q_result = quat_mul(q1, q2)
# Rotate vector by quaternion
vec = torch.tensor([1.0, 0.0, 0.0])
rotated = quat_rotate(q1, vec)
# Convert to Euler angles (roll, pitch, yaw)
euler = quat_to_euler(q1) # [roll, pitch, yaw]
# Convert from Euler angles
quat = euler_to_quat(euler)
Note: GenesisLab uses WXYZ quaternion format throughout.
Transformations#
from genesislab.utils.math import (
transform_points,
inverse_transform,
homogeneous_transform
)
# Transform points
points = torch.randn(100, 3) # [N, 3]
position = torch.tensor([1.0, 2.0, 3.0])
orientation = torch.tensor([1.0, 0.0, 0.0, 0.0]) # WXYZ quat
transformed = transform_points(points, position, orientation)
Sampling#
from genesislab.utils.math import (
sample_uniform,
sample_gaussian,
sample_uniform_sphere
)
# Uniform sampling in range
samples = sample_uniform(low=-1.0, high=1.0, size=(1000, 3))
# Gaussian sampling
samples = sample_gaussian(mean=0.0, std=1.0, size=(1000, 3))
# Uniform sampling on sphere
directions = sample_uniform_sphere(size=1000) # [1000, 3]
Timing Utilities#
Timer#
from genesislab.utils.timing import Timer
# Context manager
with Timer("simulation_step"):
env.step(actions)
# Manual timing
timer = Timer("my_operation")
timer.start()
# ... operation ...
elapsed = timer.stop()
print(f"Elapsed: {elapsed:.3f}s")
Performance Profiling#
from genesislab.utils.timing import profile_function
@profile_function
def my_expensive_function():
# ... computation ...
pass
# Call function - timing info is automatically logged
result = my_expensive_function()
FPS Counter#
from genesislab.utils.timing import FPSCounter
fps_counter = FPSCounter(window_size=100)
for _ in range(1000):
# ... simulation step ...
fps_counter.tick()
if fps_counter.frame_count % 100 == 0:
print(f"FPS: {fps_counter.fps:.0f}")
I/O Utilities#
Loading Assets#
from genesislab.utils.io import load_urdf, load_mesh
# Load URDF
robot = load_urdf("path/to/robot.urdf")
# Load mesh
mesh = load_mesh("path/to/mesh.obj")
Saving/Loading Checkpoints#
from genesislab.utils.io import save_checkpoint, load_checkpoint
# Save
checkpoint = {
"policy": policy.state_dict(),
"optimizer": optimizer.state_dict(),
"episode": episode
}
save_checkpoint(checkpoint, "checkpoint.pt")
# Load
checkpoint = load_checkpoint("checkpoint.pt")
policy.load_state_dict(checkpoint["policy"])
Configuration Files#
from genesislab.utils.io import save_config, load_config
# Save configuration
cfg = MyTaskCfg()
save_config(cfg, "config.yaml")
# Load configuration
cfg = load_config("config.yaml", MyTaskCfg)
Typing#
Common type definitions used throughout GenesisLab.
from genesislab.utils.typing import (
TensorType,
ObsDict,
InfoDict,
ConfigType
)
# Type hints
def compute_reward(
observations: ObsDict,
actions: TensorType
) -> TensorType:
"""
Compute reward.
Args:
observations: Dictionary of observation tensors
actions: Action tensor [num_envs, action_dim]
Returns:
Reward tensor [num_envs]
"""
pass
Logging#
Logger Setup#
from genesislab.utils.logging import setup_logger, get_logger
# Setup logger
setup_logger(
log_dir="logs/",
log_level="INFO",
log_to_file=True
)
# Get logger
logger = get_logger(__name__)
logger.info("Training started")
logger.warning("Learning rate adjusted")
TensorBoard Integration#
from genesislab.utils.logging import TensorBoardLogger
# Create logger
tb_logger = TensorBoardLogger(log_dir="logs/tensorboard")
# Log scalars
tb_logger.log_scalar("reward/mean", mean_reward, step)
tb_logger.log_scalar("policy/lr", learning_rate, step)
# Log histogram
tb_logger.log_histogram("actions", actions, step)
# Log image
tb_logger.log_image("observation/camera", image, step)
WandB Integration#
from genesislab.utils.logging import WandbLogger
# Create logger
wandb_logger = WandbLogger(
project="genesislab",
name="go2_flat",
config=vars(cfg)
)
# Log metrics
wandb_logger.log({
"reward": mean_reward,
"episode_length": mean_length
}, step=iteration)
Random Seed#
Setting Seeds#
from genesislab.utils.random import set_seed
# Set all random seeds (Python, NumPy, PyTorch, Genesis)
set_seed(42)
Device Management#
Device Utilities#
from genesislab.utils.device import get_device, to_device
# Get default device
device = get_device() # Returns cuda if available
# Move data to device
data = to_device(data, device)
Debugging Utilities#
Tensor Checks#
from genesislab.utils.debug import check_tensor, print_tensor_stats
# Check for NaN/Inf
check_tensor(tensor, name="my_tensor") # Raises if invalid
# Print statistics
print_tensor_stats(tensor, name="my_tensor")
# Output:
# my_tensor: shape=(4096, 48), min=-1.23, max=2.45, mean=0.12, std=0.89
Visualization Helpers#
from genesislab.utils.vis import (
plot_observations,
plot_rewards,
plot_trajectories
)
# Plot observation distribution
plot_observations(observations, save_path="obs.png")
# Plot reward components
plot_rewards(reward_terms, save_path="rewards.png")
# Plot robot trajectories
plot_trajectories(positions, save_path="trajectories.png")
Common Patterns#
Noise Application#
from genesislab.utils.noise import add_noise
# Add noise to observations
obs_noisy = add_noise(
obs,
noise_type="gaussian",
noise_params={"mean": 0.0, "std": 0.1}
)
Clamping and Scaling#
from genesislab.utils.math import scale_transform, saturate
# Scale from [-1, 1] to [a, b]
scaled = scale_transform(
actions,
input_range=(-1, 1),
output_range=(-0.5, 0.5)
)
# Clamp values
clamped = saturate(values, min_val=-1.0, max_val=1.0)
Example: Complete Utility Usage#
from genesislab.utils.configclass import configclass
from genesislab.utils.timing import Timer, FPSCounter
from genesislab.utils.logging import setup_logger, get_logger
from genesislab.utils.random import set_seed
from genesislab.utils.math import quat_to_euler
import torch
# Setup
set_seed(42)
setup_logger(log_dir="logs/")
logger = get_logger(__name__)
# Configuration
@configclass
class TrainCfg:
num_envs: int = 4096
learning_rate: float = 3e-4
max_iterations: int = 1000
cfg = TrainCfg()
logger.info(f"Starting training with {cfg.num_envs} environments")
# Training loop
fps_counter = FPSCounter()
for iteration in range(cfg.max_iterations):
with Timer("iteration"):
# ... training step ...
pass
fps_counter.tick()
if iteration % 100 == 0:
logger.info(f"Iteration {iteration}, FPS: {fps_counter.fps:.0f}")
Next Steps#
See engine API for core components
Check manager API for manager details
Review examples for usage patterns