
    h*                        S r SSKJr  SSKJr  SSKJr  SSKJr  SSK	r
SSKJr  SSKJrJr  SS	KJr  SS
KJrJr  SSKJrJrJrJr  SSKJr   " S S\5      r " S S\5      r " S S\5      r " S S\5      rg)z3Vectorizes action wrappers to work for `VectorEnv`.    )annotations)Callable)deepcopy)AnyN)Space)ActTypeEnv)warn)VectorActionWrapper	VectorEnv)batch_spaceconcatenatecreate_empty_arrayiterate)transform_actionc                  P   ^  \ rS rSrSr  S       SU 4S jjjrSS jrSrU =r$ )	TransformAction   aj  Transforms an action via a function provided to the wrapper.

The function :attr:`func` will be applied to all vector actions.
If the observations from :attr:`func` are outside the bounds of the ``env``'s action space,
provide an :attr:`action_space` which specifies the action space for the vectorized environment.

Example - Without action transformation:
    >>> import gymnasium as gym
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> for _ in range(10):
    ...     obs, rew, term, trunc, info = envs.step(envs.action_space.sample())
    ...
    >>> envs.close()
    >>> obs
    array([[-0.46553135, -0.00142543],
           [-0.498371  , -0.00715587],
           [-0.46515748, -0.00624371]], dtype=float32)

Example - With action transformation:
    >>> import gymnasium as gym
    >>> from gymnasium.spaces import Box
    >>> def shrink_action(act):
    ...     return act * 0.3
    ...
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> new_action_space = Box(low=shrink_action(envs.action_space.low), high=shrink_action(envs.action_space.high))
    >>> envs = TransformAction(env=envs, func=shrink_action, action_space=new_action_space)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> for _ in range(10):
    ...     obs, rew, term, trunc, info = envs.step(envs.action_space.sample())
    ...
    >>> envs.close()
    >>> obs
    array([[-0.48468155, -0.00372536],
           [-0.47599354, -0.00545912],
           [-0.46543318, -0.00615723]], dtype=float32)
c                p  > [         TU ]  U5        Uc$  Ub   X@l        [        X@R                  5      U l        OX0l        Ub  X@l        U R
                  [        U R                  U R                  5      :w  a<  [        SU SUR
                   S[        U R                  U R                  5       35        X l        g)an  Constructor for the lambda action wrapper.

Args:
    env: The vector environment to wrap
    func: A function that will transform an action. If this transformed action is outside the action space of ``env.action_space`` then provide an ``action_space``.
    action_space: The action spaces of the wrapper. If None, then it is computed from ``single_action_space``. If ``single_action_space`` is not provided either, then it is assumed to be the same as ``env.action_space``.
    single_action_space: The action space of the non-vectorized environment. If None, then it is assumed the same as ``env.single_action_space``.
NzFor z], the action space and the batched single action space don't match as expected, action_space=z, batched single_action_space=)super__init__single_action_spacer   num_envsaction_spacer
   func)selfenvr   r   r   	__class__s        d/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/wrappers/vector/vectorize_action.pyr   TransformAction.__init__=   s     	".+>($/0C]]$S! ,".+>(D,D,Ddmm TTsexy|  zJ  zJ  yK  Ki  ju  vz  vN  vN  PT  P]  P]  j^  i_  ` 	    c                $    U R                  U5      $ )z(Applies the :attr:`func` to the actions.)r   r   actionss     r   r$   TransformAction.actions^   s    yy!!r!   )r   r   r   )NN)r   r   r   zCallable[[ActType], Any]r   Space | Noner   r&   r$   r   returnr   )	__name__
__module____qualname____firstlineno____doc__r   r$   __static_attributes____classcell__r   s   @r   r   r      sL    'Z &*,0 ' #	
 * B" "r!   r   c                  \   ^  \ rS rSrSr " S S\5      r      SU 4S jjrS	S jrSr	U =r
$ )
VectorizeTransformActionc   a  Vectorizes a single-agent transform action wrapper for vector environments.

Example - Without action transformation:
    >>> import gymnasium as gym
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> obs, rew, term, trunc, info = envs.step(envs.action_space.sample())
    >>> envs.close()
    >>> obs
    array([[-4.6343064e-01,  9.8971417e-05],
           [-4.4488689e-01, -1.9375233e-03],
           [-4.3118435e-01, -1.5342437e-03]], dtype=float32)

Example - Adding a transform that applies a ReLU to the action:
    >>> import gymnasium as gym
    >>> from gymnasium.wrappers import TransformAction
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> envs = VectorizeTransformAction(envs, wrapper=TransformAction, func=lambda x: (x > 0.0) * x, action_space=envs.single_action_space)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> obs, rew, term, trunc, info = envs.step(envs.action_space.sample())
    >>> envs.close()
    >>> obs
    array([[-4.6343064e-01,  9.8971417e-05],
           [-4.4354835e-01, -5.9898634e-04],
           [-4.3034542e-01, -6.9532328e-04]], dtype=float32)
c                  "    \ rS rSrSrSS jrSrg)#VectorizeTransformAction._SingleEnv   z@Fake single-agent environment used for the single-agent wrapper.c                    Xl         g)z%Constructor for the fake environment.Nr   )r   r   s     r   r   ,VectorizeTransformAction._SingleEnv.__init__   s     ,r!   r8   N)r   r   )r)   r*   r+   r,   r-   r   r.    r!   r   
_SingleEnvr5      s
    N	-r!   r;   c                  > [         TU ]  U5        U" U R                  U R                  R                  5      40 UD6U l        U R
                  R                  U l        [        U R                  U R                  5      U l        U R                  U R                  R                  :H  U l	        [        U R                  R                  U R                  5      U l        g)zConstructor for the vectorized lambda action wrapper.

Args:
    env: The vector environment to wrap
    wrapper: The wrapper to vectorize
    **kwargs: Arguments for the LambdaAction wrapper
N)r   r   r;   r   r   wrapperr   r   r   same_outr   out)r   r   r=   kwargsr   s       r   r   !VectorizeTransformAction.__init__   s     	ttxx/K/KLWPVW#'<<#<#< '(@(@$--P))TXX-B-BB%dhh&B&BDMMRr!   c                l  ^  T R                   (       aH  [        T R                  R                  [	        U 4S j[        T R                  U5       5       5      U5      $ [        [        T R                  R                  [	        U 4S j[        T R                  U5       5       5      T R                  5      5      $ )zApplies the wrapper to each of the action.

Args:
    actions: The actions to apply the function to

Returns:
    The updated actions using the wrapper func
c              3  Z   >#    U  H   nTR                   R                  U5      v   M"     g 7fNr=   r   .0actionr   s     r   	<genexpr>3VectorizeTransformAction.actions.<locals>.<genexpr>   s*      "E LL%%f--"E   (+c              3  Z   >#    U  H   nTR                   R                  U5      v   M"     g 7frD   rE   rF   s     r   rI   rJ      s*      &IF ))&11&IrK   )	r>   r   r   r   tupler   r   r   r?   r#   s   ` r   r$    VectorizeTransformAction.actions   s     ==,, ")$*;*;W"E    HH00 &-d.?.?&I  HH	 	r!   )r   r?   r>   r   r=   )r   r   r=   z&type[transform_action.TransformAction]r@   r   r'   )r)   r*   r+   r,   r-   r	   r;   r   r$   r.   r/   r0   s   @r   r2   r2   c   sC    :-S -SS 8S 	S, r!   r2   c                  0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )
ClipAction   a  Clip the continuous action within the valid :class:`Box` observation space bound.

Example - Passing an out-of-bounds action to the environment to be clipped.
    >>> import numpy as np
    >>> import gymnasium as gym
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> envs = ClipAction(envs)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> obs, rew, term, trunc, info = envs.step(np.array([5.0, -5.0, 2.0]))
    >>> envs.close()
    >>> obs
    array([[-0.4624777 ,  0.00105192],
           [-0.44504836, -0.00209899],
           [-0.42884544,  0.00080468]], dtype=float32)
c                B   > [         TU ]  U[        R                  5        g)zXConstructor for the Clip Action wrapper.

Args:
    env: The vector environment to wrap
N)r   r   r   rP   )r   r   r   s     r   r   ClipAction.__init__   s     	.99:r!   r:   )r   r   r)   r*   r+   r,   r-   r   r.   r/   r0   s   @r   rP   rP      s    "; ;r!   rP   c                  <   ^  \ rS rSrSr      SU 4S jjrSrU =r$ )RescaleAction   a  Affinely rescales the continuous action space of the environment to the range [min_action, max_action].

Example - Without action scaling:
    >>> import numpy as np
    >>> import gymnasium as gym
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> for _ in range(10):
    ...     obs, rew, term, trunc, info = envs.step(0.5 * np.ones((3, 1)))
    ...
    >>> envs.close()
    >>> obs
    array([[-0.44799727,  0.00266526],
           [-0.4351738 ,  0.00133522],
           [-0.42683297,  0.00048403]], dtype=float32)

Example - With action scaling:
    >>> import numpy as np
    >>> import gymnasium as gym
    >>> envs = gym.make_vec("MountainCarContinuous-v0", num_envs=3)
    >>> envs = RescaleAction(envs, 0.0, 1.0)
    >>> _ = envs.action_space.seed(123)
    >>> obs, info = envs.reset(seed=123)
    >>> for _ in range(10):
    ...     obs, rew, term, trunc, info = envs.step(0.5 * np.ones((3, 1)))
    ...
    >>> envs.close()
    >>> obs
    array([[-0.48657528, -0.00395268],
           [-0.47377947, -0.00529102],
           [-0.46546045, -0.00614867]], dtype=float32)
c                B   > [         TU ]  U[        R                  UUS9  g)aI  Initializes the :class:`RescaleAction` wrapper.

Args:
    env (Env): The vector environment to wrap
    min_action (float, int or np.ndarray): The min values for each action. This may be a numpy array or a scalar.
    max_action (float, int or np.ndarray): The max values for each action. This may be a numpy array or a scalar.
)
min_action
max_actionN)r   r   r   rV   )r   r   rY   rZ   r   s       r   r   RescaleAction.__init__   s)     	**!!	 	 	
r!   r:   )r   r   rY   float | int | np.ndarrayrZ   r\   rT   r0   s   @r   rV   rV      s/     D

 -
 -	
 
r!   rV   ) r-   
__future__r   collections.abcr   copyr   typingr   numpynp	gymnasiumr   gymnasium.corer   r	   gymnasium.loggerr
   gymnasium.vectorr   r   gymnasium.vector.utilsr   r   r   r   gymnasium.wrappersr   r   r2   rP   rV   r:   r!   r   <module>ri      sf    9 " $     ' ! ; X X /M") M"`W2 Wt;) ;65
, 5
r!   