Implementation:Facebookresearch Habitat lab HabitatGymWrapper
| Knowledge Sources | |
|---|---|
| Domains | Embodied_AI, Reinforcement_Learning, Gym_Integration |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
Wraps a Habitat RLEnv into a standard OpenAI Gym-compatible interface, converting Habitat's hierarchical action and observation spaces into flat numpy arrays or dictionaries compatible with common RL libraries.
Description
HabGymWrapper extends gym.Wrapper to bridge the gap between Habitat's environment API and the standard Gym API expected by RL frameworks. Key transformations include:
Action Space Conversion:
- Continuous actions: Flattens nested
spaces.Dictaction spaces into a singlespaces.Box. The helpercreate_action_spacerecursively computes bounds. - Discrete actions: Converts to
spaces.Discretefor simple discrete tasks. - The
continuous_vector_action_to_hab_dictfunction converts flat numpy action vectors back into Habitat's hierarchical action dictionary format.
Observation Space Conversion:
- Filters observations to only include keys specified in
gym.obs_keysconfig. - Supports
desired_goal_keysandachieved_goal_keysfor goal-conditioned RL (HER-style). - When all observation shapes are 1D, smashes them into a single Box space; otherwise returns a Dict space.
Step and Reset:
step(action)accepts numpy arrays or ints, validates against the action space, converts to Habitat format, and returns (obs, reward, done, info).reset()delegates to the underlying environment and transforms observations.
Rendering:
- Supports
mode="rgb_array"(returns numpy array) andmode="human"(displays via pygame window).
Helper Functions:
filter_observation_space: Filters a Dict observation space by key names.smash_observation_space: Concatenates 1D observation spaces into a single Box._is_continuous: Determines if an action space requires continuous control.
Usage
Use HabGymWrapper to integrate Habitat environments with standard RL training libraries like Stable Baselines3, RLlib, or custom training loops that expect the Gym API. Configure which observations, actions, and goals to expose through the Habitat gym config.
Code Reference
Source Location
- Repository: Facebookresearch_Habitat_lab
- File: habitat-lab/habitat/gym/gym_wrapper.py
- Lines: 1-366
Signature
class HabGymWrapper(gym.Wrapper):
def __init__(
self,
env: "RLEnv",
save_orig_obs: bool = False,
): ...
def step(
self, action: Union[np.ndarray, int]
) -> Tuple[HabGymWrapperObsType, float, bool, dict]: ...
def reset(
self, *args, return_info: bool = False, **kwargs
) -> Union[HabGymWrapperObsType, Tuple[HabGymWrapperObsType, dict]]: ...
def render(self, mode: str = "human", **kwargs): ...
def close(self): ...
@property
def number_of_episodes(self) -> int: ...
def current_episode(self, all_info: bool = False) -> "BaseEpisode": ...
@property
def unwrapped(self) -> "RLEnv": ...
def create_action_space(original_space: gym.Space) -> gym.Space: ...
def continuous_vector_action_to_hab_dict(
original_action_space: spaces.Space,
vector_action_space: spaces.Box,
action: np.ndarray,
) -> Dict[str, Any]: ...
Import
from habitat.gym.gym_wrapper import (
HabGymWrapper,
create_action_space,
continuous_vector_action_to_hab_dict,
)
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| env | RLEnv | Yes | A Habitat RLEnv instance to be wrapped |
| save_orig_obs | bool | No | If True, stores the original unfiltered observations in self.orig_obs (default False) |
Outputs (step)
| Name | Type | Description |
|---|---|---|
| observation | Union[np.ndarray, Dict[str, np.ndarray]] | Filtered and transformed observation(s); a single array if all 1D, otherwise a dictionary |
| reward | float | Scalar reward from the environment |
| done | bool | Whether the episode has ended |
| info | dict | Additional information from the environment step |
Usage Examples
Basic Gym-Style Training Loop
from habitat.gym.gym_wrapper import HabGymWrapper
# env is a Habitat RLEnv
gym_env = HabGymWrapper(env)
obs = gym_env.reset()
done = False
while not done:
# Use a flat numpy action
action = gym_env.action_space.sample()
obs, reward, done, info = gym_env.step(action)
print(f"Reward: {reward}, Done: {done}")
gym_env.close()
Integration with Stable Baselines3
from stable_baselines3 import PPO
from habitat.gym.gym_wrapper import HabGymWrapper
gym_env = HabGymWrapper(habitat_rl_env)
model = PPO("MlpPolicy", gym_env, verbose=1)
model.learn(total_timesteps=100000)
# Evaluate
obs = gym_env.reset()
for _ in range(1000):
action, _ = model.predict(obs, deterministic=True)
obs, reward, done, info = gym_env.step(action)
if done:
obs = gym_env.reset()
Rendering with Pygame
gym_env = HabGymWrapper(env)
obs = gym_env.reset()
for _ in range(200):
action = gym_env.action_space.sample()
obs, reward, done, info = gym_env.step(action)
gym_env.render(mode="human")
if done:
obs = gym_env.reset()
gym_env.close()