Source code for pettingzoo.utils.wrappers.clip_out_of_bounds

from __future__ import annotations

from typing import Any

import numpy as np
from gymnasium.spaces import Box
from typing_extensions import override

from pettingzoo.utils.env import AECEnv
from pettingzoo.utils.env_logger import EnvLogger
from pettingzoo.utils.wrappers.base import BaseWrapper


[docs] class ClipOutOfBoundsWrapper(BaseWrapper[Any, Any, Any]): """Clips the input action to fit in the continuous action space (emitting a warning if it does so). Applied to continuous environments in pettingzoo. """ def __init__(self, env: AECEnv[Any, Any, Any]): super().__init__(env) assert isinstance(env, AECEnv), ( "ClipOutOfBoundsWrapper is only compatible with AEC environments." ) assert all( isinstance(self.action_space(agent), Box) for agent in getattr(self, "possible_agents", []) ), "should only use ClipOutOfBoundsWrapper for Box spaces" @override def step(self, action: np.ndarray | None) -> None: space = self.action_space(self.agent_selection) assert isinstance(space, Box), ( "should only use ClipOutOfBoundsWrapper for Box spaces" ) if action is not None and not space.contains(action): if np.isnan(action).any(): EnvLogger.error_nan_action() assert space.shape == action.shape, ( f"action should have shape {space.shape}, has shape {action.shape}" ) EnvLogger.warn_action_out_of_bound( action=action, action_space=space, backup_policy="clipping to space" ) action = np.clip( action, space.low, space.high, ) super().step(action) @override def __str__(self) -> str: return str(self.env)