
    h?(                         S /r SSKJr  SSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  \R                  rSr " S S	\R                  5      rS
 rg)zCarlos Luis    )pathN)spaces)utils)DependencyNotInstalled      ?c                      ^  \ rS rSrSrSS/SS.rSS\S-  4S	 jjrS
 rSSS.S\	S-  S\
S-  4U 4S jjjrS rS rS rSrU =r$ )PendulumEnv   a  
## Description

The inverted pendulum swingup problem is based on the classic problem in control theory.
The system consists of a pendulum attached at one end to a fixed point, and the other end being free.
The pendulum starts in a random position and the goal is to apply torque on the free end to swing it
into an upright position, with its center of gravity right above the fixed point.

The diagram below specifies the coordinate system used for the implementation of the pendulum's
dynamic equations.

![Pendulum Coordinate System](/_static/diagrams/pendulum.png)

- `x-y`: cartesian coordinates of the pendulum's end in meters.
- `theta` : angle in radians.
- `tau`: torque in `N m`. Defined as positive _counter-clockwise_.

## Action Space

The action is a `ndarray` with shape `(1,)` representing the torque applied to free end of the pendulum.

| Num | Action | Min  | Max |
|-----|--------|------|-----|
| 0   | Torque | -2.0 | 2.0 |

## Observation Space

The observation is a `ndarray` with shape `(3,)` representing the x-y coordinates of the pendulum's free
end and its angular velocity.

| Num | Observation      | Min  | Max |
|-----|------------------|------|-----|
| 0   | x = cos(theta)   | -1.0 | 1.0 |
| 1   | y = sin(theta)   | -1.0 | 1.0 |
| 2   | Angular Velocity | -8.0 | 8.0 |

## Rewards

The reward function is defined as:

*r = -(theta<sup>2</sup> + 0.1 * theta_dt<sup>2</sup> + 0.001 * torque<sup>2</sup>)*

where `theta` is the pendulum's angle normalized between *[-pi, pi]* (with 0 being in the upright position).
Based on the above equation, the minimum reward that can be obtained is
*-(pi<sup>2</sup> + 0.1 * 8<sup>2</sup> + 0.001 * 2<sup>2</sup>) = -16.2736044*,
while the maximum reward is zero (pendulum is upright with zero velocity and no torque applied).

## Starting State

The starting state is a random angle in *[-pi, pi]* and a random angular velocity in *[-1,1]*.

## Episode Truncation

The episode truncates at 200 time steps.

## Arguments

- `g`: .

Pendulum has two parameters for `gymnasium.make` with `render_mode` and `g` representing
the acceleration of gravity measured in *(m s<sup>-2</sup>)* used to calculate the pendulum dynamics.
The default value is `g = 10.0`.
On reset, the `options` parameter allows the user to change the bounds used to determine the new random state.

```python
>>> import gymnasium as gym
>>> env = gym.make("Pendulum-v1", render_mode="rgb_array", g=9.81)  # default g=10.0
>>> env
<TimeLimit<OrderEnforcing<PassiveEnvChecker<PendulumEnv<Pendulum-v1>>>>>
>>> env.reset(seed=123, options={"low": -0.7, "high": 0.5})  # default low=-0.6, high=-0.5
(array([ 0.4123625 ,  0.91101986, -0.89235795], dtype=float32), {})

```

## Version History

* v1: Simplify the math equations, no difference in behavior.
* v0: Initial versions release
human	rgb_array   )render_modes
render_fpsNrender_modec                    SU l         SU l        SU l        X l        SU l        SU l        Xl        SU l        S U l        S U l	        SU l
        [        R                  " SSU R                   /[        R                  S9n[        R                  " U R                  * U R                  S[        R                  S	9U l        [        R                  " U* U[        R                  S
9U l        g )N   g       @皙?r   i  Tdtype)   )lowhighshaper   )r   r   r   )	max_speed
max_torquedtgmlr   
screen_dimscreenclockisopennparrayfloat32r   Boxaction_spaceobservation_space)selfr   r   r   s       a/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/envs/classic_control/pendulum.py__init__PendulumEnv.__init__g   s    &
xxc4>>2"**E #JJ td"**
 "(D

!S    c                    U R                   u  p#U R                  nU R                  nU R                  nU R                  n[
        R                  " XR                  * U R                  5      S   nXl        [        U5      S-  SUS-  -  -   SUS-  -  -   nUSU-  SU-  -  [
        R                  " U5      -  SXVS-  -  -  U-  -   U-  -   n	[
        R                  " XR                  * U R                  5      n	X)U-  -   n
[
        R                  " X/5      U l         U R                  S:X  a  U R                  5         U R                  5       U* SS0 4$ )	Nr      g?gMbP?   g      @r   F)stater   r   r   r   r$   clipr   last_uangle_normalizesinr   r%   r   render_get_obs)r*   uththdotr   r   r   r   costsnewthdotnewths              r+   stepPendulumEnv.step   s&   JJ	FFFFFFWWGGA'9!<#q(3>9EQTNJAEQUObffRj83!d(;Ka;OOSUUU778nn_dnnE]"XXu/0
w&KKM}}ub88r.   )seedoptionsrA   rB   c                  > [         TU ]  US9  Uc!  [        R                  " [        [
        /5      nO}SU;   a  UR                  S5      O[        nSU;   a  UR                  S5      O[
        n[        R                  " U5      n[        R                  " U5      n[        R                  " XE/5      nU* nU R                  R                  XcS9U l        S U l        U R                  S:X  a  U R                  5         U R                  5       0 4$ )N)rA   x_inity_init)r   r   r   )superresetr$   r%   	DEFAULT_X	DEFAULT_Ygetr   verify_number_and_cast	np_randomuniformr2   r4   r   r7   r8   )r*   rA   rB   r   xyr   	__class__s          r+   rG   PendulumEnv.reset   s    4 ?88Y	23D *2W)<H%)A)1W)<H%)A,,Q/A,,Q/A88QF#De^^+++?
w&KKM}}""r.   c                     U R                   u  p[        R                  " [        R                  " U5      [        R                  " U5      U/[        R
                  S9$ )Nr   )r2   r$   r%   cosr6   r&   )r*   thetathetadots      r+   r8   PendulumEnv._get_obs   s9    **xxux@

SSr.   c           
         U R                   cG  U R                  c   e[        R                  R	                  SU R                  R
                   S35        g  SS KnSSKJn  U R                  c  UR                  5         U R                   S:X  aQ  UR                  R                  5         UR                  R                  U R                  U R                  45      U l
        O,UR                  U R                  U R                  45      U l
        U R                   c  UR"                  R%                  5       U l        UR                  U R                  U R                  45      U l        U R&                  R)                  S5        SnU R                  US	-  -  nU R                  S	-  nS
U-  nSU-  nSXxS	-  U* S	-  4u  ppX4X4X4X4/n/ nU Ho  nUR*                  R-                  U5      R/                  U R0                  S   [2        R4                  S	-  -   5      nUS   U-   US
   U-   4nUR7                  U5        Mq     UR9                  U R&                  US5        UR;                  U R&                  US5        UR=                  U R&                  Xf[?        US	-  5      S5        URA                  U R&                  Xf[?        US	-  5      S5        US4nUR*                  R-                  U5      R/                  U R0                  S   [2        R4                  S	-  -   5      n[?        US   U-   5      [?        US
   U-   5      4nUR=                  U R&                  US   US
   [?        US	-  5      S5        URA                  U R&                  US   US
   [?        US	-  5      S5        [B        RD                  " [B        RF                  " [H        5      S5      nURJ                  RM                  U5      nU RN                  Gb  URP                  RS                  U[U        U[2        RV                  " U RN                  5      -  S	-  5      [U        U[2        RV                  " U RN                  5      -  S	-  5      45      n[Y        U RN                  S:  5      nURP                  R[                  UUS5      nU R&                  R]                  UUUR_                  5       R`                  -
  UUR_                  5       Rb                  -
  45        UR=                  U R&                  Xf[?        SU-  5      S5        URA                  U R&                  Xf[?        SU-  5      S5        URP                  R[                  U R&                  SS5      U l        U R                  R]                  U R&                  S5        U R                   S:X  a]  URd                  Rg                  5         U R                   Ri                  U Rj                  S   5        UR                  R[                  5         g [2        Rl                  " [2        Rn                  " URp                  Rs                  U R                  5      5      SS9$ ! [         a  n[        S5      UeS nAff = f)NzYou are calling render method without specifying any render mode. You can specify the render_mode at initialization, e.g. gym.make("z", render_mode="rgb_array")r   )gfxdrawzGpygame is not installed, run `pip install "gymnasium[classic_control]"`r   )   rY   rY   g@r0   r   g?)   M   r[   zassets/clockwise.pngTr   )r   r   r   F)r   r   r   )r   r   r0   )axes):r   specgymloggerwarnidpygamerX   ImportErrorr   r!   initdisplayset_moder    Surfacer"   timeClocksurffillmathVector2
rotate_radr2   r$   piappend	aapolygonfilled_polygonaacircleintfilled_circler   joindirname__file__imageloadr4   	transformsmoothscalefloatabsboolflipblitget_rectcenterxcenteryeventpumptickmetadata	transposer%   	surfarraypixels3d)r*   rb   rX   eboundscaleoffset
rod_length	rod_widthr   rtbcoordstransformed_coordscrod_endfnameimg	scale_imgis_flips                        r+   r7   PendulumEnv.render   sQ   #99(((JJOO""&)),,/JL
 	& ;;KKM7*##%$nn55__doo6 %nndoot-OP::**,DJNNDOOT__#EF			'519-A%Y
%K	
MI:>A
a&1&1&1&1A##A&11$**Q-"%%!)2KLA1!v.A%%a(  	$))%7Gtyy*<mLFC	A4FVIIvs9q='9=	
 q/++%%g.99$**Q-"%%RS):STwqzF*+Sf1D-EFIIwqz71:s9q=/A=	
 	IIwqz71:s9q=/A=	
 		$,,x02HIll&;;"((44%"&&"559:%"&&"559:I 4;;?+G((--i$GIIINNY//1999Y//1999 	FCu4EyQdiiTE\9JIV$$))$))UDA	F+w&LLJJOODMM,78NN! <<))224;;?@y g  	(Y	s   
Y 
Y.Y))Y.c                     U R                   b6  SS KnUR                  R                  5         UR                  5         SU l        g g )Nr   F)r!   rb   re   quitr#   )r*   rb   s     r+   closePendulumEnv.close  s4    ;;"NN!KKMDK #r.   )r(   r"   r   r   r#   r   r4   r   r   r   r)   r   r!   r    r2   rj   )Ng      $@)__name__
__module____qualname____firstlineno____doc__r   strr,   r?   rt   dictrG   r8   r7   r   __static_attributes____classcell__)rP   s   @r+   r	   r	      ss    Nb !+.H
TC$J T09. +/t #S4Z # # #(TbH   r.   r	   c                 r    U [         R                  -   S[         R                  -  -  [         R                  -
  $ )Nr0   )r$   ro   )rN   s    r+   r5   r5     s&    Y1ruu9%..r.   )__credits__osr   numpyr$   	gymnasiumr^   r   gymnasium.envs.classic_controlr   gymnasium.errorr   ro   rH   rI   Envr	   r5    r.   r+   <module>r      sF   o     0 2 EE		G #'' G T/r.   