Skip to main content

rfx.envs

Provides unified interfaces for simulation and real robot control, following the standard Gym API.
from rfx.envs import Go2Env

env = Go2Env(sim=True)
obs = env.reset()
for _ in range(1000):
    action = env.action_space.sample()
    obs, reward, done, info = env.step(action)
    if done:
        obs = env.reset()

Box

A box in R^n, representing continuous observation/action spaces.
from rfx.envs import Box
import numpy as np

space = Box(low=-1.0, high=1.0, shape=(12,))
action = space.sample()

Constructor

Box(
    low: np.ndarray,
    high: np.ndarray,
    shape: tuple[int, ...],
    dtype: np.dtype = np.float32
)
low
np.ndarray
required
Lower bounds for each dimension.
high
np.ndarray
required
Upper bounds for each dimension.
shape
tuple[int, ...]
required
Shape of the space.
dtype
np.dtype
default:"np.float32"
Data type of the space.

Methods

sample

space.sample() -> np.ndarray
Sample a random point from the space.
return
np.ndarray
Random sample within bounds.

contains

space.contains(x: np.ndarray) -> bool
Check if x is a valid member of the space.
x
np.ndarray
required
Value to check.
return
bool
True if x is within bounds and has correct shape.

clip

space.clip(x: np.ndarray) -> np.ndarray
Clip x to be within bounds.
x
np.ndarray
required
Value to clip.
return
np.ndarray
Clipped value within bounds.

BaseEnv

Abstract base class for robot environments. All environments should implement this interface for compatibility with training utilities.

Properties

observation_space
Box
The observation space.
action_space
Box
The action space.

Methods

reset

env.reset() -> np.ndarray
Reset the environment and return initial observation.
return
np.ndarray
Initial observation.

step

env.step(action: np.ndarray) -> tuple[np.ndarray, float, bool, dict]
Take a step in the environment.
action
np.ndarray
required
Action to take.
return
tuple[np.ndarray, float, bool, dict]
Tuple of (observation, reward, done, info).

close

env.close() -> None
Clean up resources.

render

env.render() -> None
Render the environment (optional).

Go2Env

Gym-like interface for the Unitree Go2 quadruped robot. Can run in simulation mode or on real hardware.

Spaces

Observation Space (48 dimensions):
  • Joint positions (12): Current joint angles
  • Joint velocities (12): Current joint velocities
  • Base angular velocity (3): IMU angular velocity
  • Projected gravity (3): Gravity vector in body frame
  • Commands (3): Velocity commands (vx, vy, yaw_rate)
  • Last actions (12): Previous action
  • Clock (3): Phase variables for gait timing
Action Space (12 dimensions):
  • Joint position targets, normalized to [-1, 1]
  • Scaled by action_scale to get actual joint deltas

Constructor

Go2Env(
    sim: bool = True,
    sim_config: Any = None,
    robot_ip: str | None = None,
    control_dt: float = 0.02,
    action_scale: float = 0.5
)
sim
bool
default:"True"
If True, use simulation backend; if False, connect to real robot.
sim_config
Any
default:"None"
Configuration for simulation (only used if sim=True).
robot_ip
str | None
default:"None"
IP address of real robot (only used if sim=False).
control_dt
float
default:"0.02"
Control timestep in seconds (default: 0.02s = 50Hz).
action_scale
float
default:"0.5"
Scaling factor for actions.

Methods

set_commands

env.set_commands(
    vx: float = 0.0,
    vy: float = 0.0,
    yaw_rate: float = 0.0
) -> None
Set velocity commands for the robot.
vx
float
default:"0.0"
Forward velocity command.
vy
float
default:"0.0"
Lateral velocity command.
yaw_rate
float
default:"0.0"
Yaw rate command.

Class Attributes

JOINT_LIMITS_LOW
np.ndarray
Lower joint limits for all 12 joints (radians).
JOINT_LIMITS_HIGH
np.ndarray
Upper joint limits for all 12 joints (radians).
DEFAULT_STANDING
np.ndarray
Default standing pose joint positions.

VecEnv

Vectorized environment for parallel rollouts. Runs multiple environments in parallel for faster data collection.
from rfx.envs import VecEnv, Go2Env

vec_env = VecEnv(lambda: Go2Env(sim=True), num_envs=8)
obs = vec_env.reset()  # (8, 48)
actions = vec_env.action_space.sample()  # (8, 12)
obs, rewards, dones, infos = vec_env.step(actions)

Constructor

VecEnv(
    env_fn: callable,
    num_envs: int
)
env_fn
callable
required
Function that creates a single environment.
num_envs
int
required
Number of parallel environments.

Methods

reset

vec_env.reset() -> np.ndarray
Reset all environments.
return
np.ndarray
Stacked observations of shape (num_envs, obs_dim).

step

vec_env.step(actions: np.ndarray) -> tuple[np.ndarray, np.ndarray, np.ndarray, list]
Step all environments. Automatically resets environments when they are done.
actions
np.ndarray
required
Actions for all environments, shape (num_envs, action_dim).
return
tuple[np.ndarray, np.ndarray, np.ndarray, list]
Tuple of (observations, rewards, dones, infos).

close

vec_env.close() -> None
Close all environments.

make_vec_env

Utility function to create a (vectorized) environment.
from rfx.envs import make_vec_env, Go2Env

# Single environment
env = make_vec_env(Go2Env, num_envs=1, sim=True)

# Vectorized environment
vec_env = make_vec_env(Go2Env, num_envs=8, sim=True)

Function Signature

make_vec_env(
    env_class: type = Go2Env,
    num_envs: int = 1,
    **kwargs
) -> VecEnv | BaseEnv
env_class
type
default:"Go2Env"
Environment class to instantiate.
num_envs
int
default:"1"
Number of parallel environments.
**kwargs
dict
Arguments passed to environment constructor.
return
VecEnv | BaseEnv
VecEnv if num_envs > 1, otherwise single environment.

Build docs developers (and LLMs) love