Implementation:Farama Foundation Gymnasium Transform Action Wrappers
| Knowledge Sources | |
|---|---|
| Domains | Reinforcement_Learning, Wrappers |
| Last Updated | 2026-02-15 03:00 GMT |
Overview
A collection of action transformation wrappers that modify actions before they are passed to the underlying environment, including TransformAction, ClipAction, RescaleAction, and DiscretizeAction.
Description
This module provides four action wrappers built on a common TransformAction base:
- TransformAction -- Applies a user-provided function to the action before passing it to the environment's step function. Accepts an optional new action space specification.
- ClipAction -- Clips continuous actions to the environment's original action space bounds. The wrapper's own action space is set to infinite bounds (Box(-inf, inf)), allowing agents to output any value which gets clipped to valid bounds.
- RescaleAction -- Affinely rescales a Box action space to a new range [min_action, max_action]. Uses the
rescale_boxutility to compute gradient and intercept for the linear transformation.
- DiscretizeAction -- Uniformly discretizes a continuous Box action space into a Discrete or MultiDiscrete space. Computes bin centers for each dimension and maps discrete indices back to continuous actions. Supports both flattened Discrete (single integer) and MultiDiscrete (one index per dimension) modes.
Usage
Use these wrappers when you need to transform the action space: ClipAction for safety-clipping continuous actions, RescaleAction for normalizing action ranges to agent-friendly bounds, DiscretizeAction for using discrete algorithms on continuous environments, or TransformAction for custom transformations.
Code Reference
Source Location
- Repository: Farama_Foundation_Gymnasium
- File:
gymnasium/wrappers/transform_action.py
Signature
class TransformAction(gym.ActionWrapper[ObsType, WrapperActType, ActType], gym.utils.RecordConstructorArgs):
def __init__(self, env: gym.Env[ObsType, ActType], func: Callable[[WrapperActType], ActType], action_space: Space[WrapperActType] | None): ...
class ClipAction(TransformAction[ObsType, WrapperActType, ActType], gym.utils.RecordConstructorArgs):
def __init__(self, env: gym.Env[ObsType, ActType]): ...
class RescaleAction(TransformAction[ObsType, WrapperActType, ActType], gym.utils.RecordConstructorArgs):
def __init__(self, env: gym.Env[ObsType, ActType], min_action: np.floating | np.integer | np.ndarray, max_action: np.floating | np.integer | np.ndarray): ...
class DiscretizeAction(TransformAction[ObsType, WrapperActType, ActType], gym.utils.RecordConstructorArgs):
def __init__(self, env: gym.Env[ObsType, ActType], bins: int | tuple[int, ...], multidiscrete: bool = False): ...
Import
from gymnasium.wrappers import TransformAction, ClipAction, RescaleAction, DiscretizeAction
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| env | Env | Yes | The environment to wrap (must have Box action space for Clip/Rescale/Discretize) |
| func | Callable | Yes (TransformAction) | Function to apply to the action |
| action_space | Space or None | No (TransformAction) | Updated action space for the wrapper |
| min_action | float, int, or ndarray | Yes (RescaleAction) | Minimum values for the rescaled action space |
| max_action | float, int, or ndarray | Yes (RescaleAction) | Maximum values for the rescaled action space |
| bins | int or tuple[int, ...] | Yes (DiscretizeAction) | Number of bins per dimension for discretization |
| multidiscrete | bool | No (DiscretizeAction) | If True, use MultiDiscrete instead of flattened Discrete (default False) |
Outputs
| Name | Type | Description |
|---|---|---|
| action | ActType | The transformed action passed to the underlying environment |
Usage Examples
import numpy as np
import gymnasium as gym
from gymnasium.wrappers import ClipAction, RescaleAction, DiscretizeAction
# ClipAction: clip out-of-bounds actions to valid range
env = gym.make("Hopper-v4", disable_env_checker=True)
env = ClipAction(env)
_ = env.reset(seed=42)
_ = env.step(np.array([5.0, -2.0, 0.0], dtype=np.float32))
# The action [5.0, -2.0, 0.0] is clipped to [1.0, -1.0, 0.0]
# RescaleAction: rescale action space to [0, 1]
env = gym.make("Hopper-v4", disable_env_checker=True)
env = RescaleAction(env, min_action=-0.5, max_action=0.5)
env.action_space # Box(-0.5, 0.5, (3,), float32)
# DiscretizeAction: convert continuous to discrete actions
env = gym.make("Pendulum-v1")
env = DiscretizeAction(env, bins=10)
env.action_space # Discrete(10)
obs, _ = env.reset(seed=42)
obs, *_ = env.step(3) # pass a discrete action index